1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include <tools/debug.hxx>
33 #include <string.h> // memset(), memcpy()
34 #include <limits.h> // USHRT_MAX
36 //====================================================================
37 // add nOffset to each bit-value in the set
39 BitSet
BitSet::operator<<( sal_uInt16 nOffset
) const
41 // create a work-copy, return it if nothing to shift
46 // compute the shiftment in long-words and bits
47 sal_uInt16 nBlockDiff
= nOffset
/ 32;
48 sal_uIntPtr nBitValDiff
= nOffset
% 32;
50 // compute the new number of bits
51 for ( sal_uInt16 nBlock
= 0; nBlock
< nBlockDiff
; ++nBlock
)
52 aSet
.nCount
= aSet
.nCount
- CountBits( *(aSet
.pBitmap
+nBlock
) );
53 aSet
.nCount
= aSet
.nCount
-
54 CountBits( *(aSet
.pBitmap
+nBlockDiff
) >> (32-nBitValDiff
) );
56 // shift complete long-words
57 sal_uInt16 nTarget
, nSource
;
58 for ( nTarget
= 0, nSource
= nBlockDiff
;
59 (nSource
+1) < aSet
.nBlocks
;
60 ++nTarget
, ++nSource
)
61 *(aSet
.pBitmap
+nTarget
) =
62 ( *(aSet
.pBitmap
+nSource
) << nBitValDiff
) |
63 ( *(aSet
.pBitmap
+nSource
+1) >> (32-nBitValDiff
) );
65 // shift the remainder (if in total minor 32 bits, only this)
66 *(aSet
.pBitmap
+nTarget
) = *(aSet
.pBitmap
+nSource
) << nBitValDiff
;
68 // determine the last used block
69 while ( *(aSet
.pBitmap
+nTarget
) == 0 )
72 // shorten the block-array
73 if ( nTarget
< aSet
.nBlocks
)
75 sal_uIntPtr
* pNewMap
= new sal_uIntPtr
[nTarget
];
76 memcpy( pNewMap
, aSet
.pBitmap
, 4 * nTarget
);
77 delete [] aSet
.pBitmap
;
78 aSet
.pBitmap
= pNewMap
;
79 aSet
.nBlocks
= nTarget
;
85 //--------------------------------------------------------------------
87 // substracts nOffset from each bit-value in the set
89 BitSet
BitSet::operator>>( sal_uInt16
) const
94 //--------------------------------------------------------------------
96 // internal code for operator= and copy-ctor
98 void BitSet::CopyFrom( const BitSet
& rSet
)
100 nCount
= rSet
.nCount
;
101 nBlocks
= rSet
.nBlocks
;
104 pBitmap
= new sal_uIntPtr
[nBlocks
];
105 memcpy( pBitmap
, rSet
.pBitmap
, 4 * nBlocks
);
111 //--------------------------------------------------------------------
113 // creates an empty bitset
122 //--------------------------------------------------------------------
124 // creates a copy of bitset rOrig
126 BitSet::BitSet( const BitSet
& rOrig
)
131 //--------------------------------------------------------------------
140 //--------------------------------------------------------------------
142 // assignment from another bitset
144 BitSet
& BitSet::operator=( const BitSet
& rOrig
)
146 if ( this != &rOrig
)
154 //--------------------------------------------------------------------
156 // assignment from a single bit
158 BitSet
& BitSet::operator=( sal_uInt16 nBit
)
163 sal_uIntPtr nBitVal
= 1L << (nBit
% 32);
166 pBitmap
= new sal_uIntPtr
[nBlocks
+ 1];
167 memset( pBitmap
, 0, 4 * (nBlocks
+ 1) );
169 *(pBitmap
+nBlocks
) = nBitVal
;
174 //--------------------------------------------------------------------
176 // creates the asymetric difference with another bitset
178 BitSet
& BitSet::operator-=(sal_uInt16 nBit
)
180 sal_uInt16 nBlock
= nBit
/ 32;
181 sal_uIntPtr nBitVal
= 1L << (nBit
% 32);
183 if ( nBlock
>= nBlocks
)
186 if ( (*(pBitmap
+nBlock
) & nBitVal
) )
188 *(pBitmap
+nBlock
) &= ~nBitVal
;
195 //--------------------------------------------------------------------
197 // unites with the bits of rSet
199 BitSet
& BitSet::operator|=( const BitSet
& rSet
)
201 sal_uInt16 nMax
= Min(nBlocks
, rSet
.nBlocks
);
204 if ( nBlocks
< rSet
.nBlocks
)
206 sal_uIntPtr
*pNewMap
= new sal_uIntPtr
[rSet
.nBlocks
];
207 memset( pNewMap
+ nBlocks
, 0, 4 * (rSet
.nBlocks
- nBlocks
) );
211 memcpy( pNewMap
, pBitmap
, 4 * nBlocks
);
215 nBlocks
= rSet
.nBlocks
;
218 // add the bits blocks by block
219 for ( sal_uInt16 nBlock
= 0; nBlock
< nMax
; ++nBlock
)
221 // compute numberof additional bits
222 sal_uIntPtr nDiff
= ~*(pBitmap
+nBlock
) & *(rSet
.pBitmap
+nBlock
);
223 nCount
= nCount
+ CountBits(nDiff
);
225 *(pBitmap
+nBlock
) |= *(rSet
.pBitmap
+nBlock
);
231 //--------------------------------------------------------------------
233 // unites with a single bit
235 BitSet
& BitSet::operator|=( sal_uInt16 nBit
)
237 sal_uInt16 nBlock
= nBit
/ 32;
238 sal_uIntPtr nBitVal
= 1L << (nBit
% 32);
240 if ( nBlock
>= nBlocks
)
242 sal_uIntPtr
*pNewMap
= new sal_uIntPtr
[nBlock
+1];
243 memset( pNewMap
+ nBlocks
, 0, 4 * (nBlock
- nBlocks
+ 1) );
247 memcpy( pNewMap
, pBitmap
, 4 * nBlocks
);
254 if ( (*(pBitmap
+nBlock
) & nBitVal
) == 0 )
256 *(pBitmap
+nBlock
) |= nBitVal
;
263 //--------------------------------------------------------------------
265 // determines if the bit is set (may be the only one)
267 sal_Bool
BitSet::Contains( sal_uInt16 nBit
) const
269 sal_uInt16 nBlock
= nBit
/ 32;
270 sal_uIntPtr nBitVal
= 1L << (nBit
% 32);
272 if ( nBlock
>= nBlocks
)
274 return ( nBitVal
& *(pBitmap
+nBlock
) ) == nBitVal
;
277 //--------------------------------------------------------------------
279 // determines if the bitsets are equal
281 sal_Bool
BitSet::operator==( const BitSet
& rSet
) const
283 if ( nBlocks
!= rSet
.nBlocks
)
286 sal_uInt16 nBlock
= nBlocks
;
287 while ( nBlock
-- > 0 )
288 if ( *(pBitmap
+nBlock
) != *(rSet
.pBitmap
+nBlock
) )
294 //--------------------------------------------------------------------
296 // counts the number of 1-bits in the parameter
298 sal_uInt16
BitSet::CountBits( sal_uIntPtr nBits
)
300 sal_uInt16 nCount
= 0;
302 while ( nBit
-- && nBits
)
303 { if ( ( (long)nBits
) < 0 )
310 //--------------------------------------------------------------------
312 sal_uInt16
IndexBitSet::GetFreeIndex()
314 for(sal_uInt16 i
=0;i
<USHRT_MAX
;i
++)
320 DBG_ASSERT(sal_False
, "IndexBitSet enthaelt mehr als USHRT_MAX Eintraege");
325 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */