1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: bitset.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sfx2.hxx"
33 #include <tools/debug.hxx>
39 #include <string.h> // memset(), memcpy()
40 #include <limits.h> // USHRT_MAX
42 //====================================================================
43 // add nOffset to each bit-value in the set
45 BitSet
BitSet::operator<<( USHORT nOffset
) const
48 // create a work-copy, return it if nothing to shift
53 // compute the shiftment in long-words and bits
54 USHORT nBlockDiff
= nOffset
/ 32;
55 ULONG nBitValDiff
= nOffset
% 32;
57 // compute the new number of bits
58 for ( USHORT nBlock
= 0; nBlock
< nBlockDiff
; ++nBlock
)
59 aSet
.nCount
= aSet
.nCount
- CountBits( *(aSet
.pBitmap
+nBlock
) );
60 aSet
.nCount
= aSet
.nCount
-
61 CountBits( *(aSet
.pBitmap
+nBlockDiff
) >> (32-nBitValDiff
) );
63 // shift complete long-words
64 USHORT nTarget
, nSource
;
65 for ( nTarget
= 0, nSource
= nBlockDiff
;
66 (nSource
+1) < aSet
.nBlocks
;
67 ++nTarget
, ++nSource
)
68 *(aSet
.pBitmap
+nTarget
) =
69 ( *(aSet
.pBitmap
+nSource
) << nBitValDiff
) |
70 ( *(aSet
.pBitmap
+nSource
+1) >> (32-nBitValDiff
) );
72 // shift the remainder (if in total minor 32 bits, only this)
73 *(aSet
.pBitmap
+nTarget
) = *(aSet
.pBitmap
+nSource
) << nBitValDiff
;
75 // determine the last used block
76 while ( *(aSet
.pBitmap
+nTarget
) == 0 )
79 // shorten the block-array
80 if ( nTarget
< aSet
.nBlocks
)
82 ULONG
* pNewMap
= new ULONG
[nTarget
];
83 memcpy( pNewMap
, aSet
.pBitmap
, 4 * nTarget
);
84 delete [] aSet
.pBitmap
;
85 aSet
.pBitmap
= pNewMap
;
86 aSet
.nBlocks
= nTarget
;
92 //--------------------------------------------------------------------
94 // substracts nOffset from each bit-value in the set
96 BitSet
BitSet::operator>>( USHORT
) const
102 //--------------------------------------------------------------------
104 // internal code for operator= and copy-ctor
106 void BitSet::CopyFrom( const BitSet
& rSet
)
109 nCount
= rSet
.nCount
;
110 nBlocks
= rSet
.nBlocks
;
114 pBitmap
= new ULONG
[nBlocks
];
115 memcpy( pBitmap
, rSet
.pBitmap
, 4 * nBlocks
);
121 //--------------------------------------------------------------------
123 // creates an empty bitset
133 //--------------------------------------------------------------------
135 // creates a copy of bitset rOrig
137 BitSet::BitSet( const BitSet
& rOrig
)
143 //--------------------------------------------------------------------
145 // creates a bitset from an array
147 BitSet::BitSet( USHORT
* pArray
, USHORT nSize
):
151 // find the highest bit to set
153 for ( USHORT n
= 0; n
< nCount
; ++n
)
154 if ( pArray
[n
] > nMax
)
157 // if there are bits at all
160 // allocate memory for all blocks needed
161 nBlocks
= nMax
/ 32 + 1;
162 pBitmap
= new ULONG
[nBlocks
];
163 memset( pBitmap
, 0, 4 * nBlocks
);
166 for ( USHORT n
= 0; n
< nCount
; ++n
)
168 // compute the block no. and bitvalue
169 USHORT nBlock
= n
/ 32;
170 ULONG nBitVal
= 1L << (n
% 32);
173 if ( ( *(pBitmap
+nBlock
) & nBitVal
) == 0 )
175 *(pBitmap
+nBlock
) |= nBitVal
;
182 // initalize emtpy set
188 //--------------------------------------------------------------------
198 //--------------------------------------------------------------------
200 // creates a bitmap with all bits in rRange set
202 BitSet::BitSet( const Range
& )
207 //--------------------------------------------------------------------
209 // assignment from another bitset
211 BitSet
& BitSet::operator=( const BitSet
& rOrig
)
214 if ( this != &rOrig
)
222 //--------------------------------------------------------------------
224 // assignment from a single bit
226 BitSet
& BitSet::operator=( USHORT nBit
)
232 ULONG nBitVal
= 1L << (nBit
% 32);
235 pBitmap
= new ULONG
[nBlocks
];
236 memset( pBitmap
+ nBlocks
, 0, 4 * nBlocks
);
238 *(pBitmap
+nBlocks
) = nBitVal
;
243 //--------------------------------------------------------------------
245 // creates the asymetric difference with another bitset
247 BitSet
& BitSet::operator-=(USHORT nBit
)
250 USHORT nBlock
= nBit
/ 32;
251 ULONG nBitVal
= 1L << (nBit
% 32);
253 if ( nBlock
>= nBlocks
)
256 if ( (*(pBitmap
+nBlock
) & nBitVal
) )
258 *(pBitmap
+nBlock
) &= ~nBitVal
;
265 //--------------------------------------------------------------------
267 // unites with the bits of rSet
269 BitSet
& BitSet::operator|=( const BitSet
& rSet
)
272 USHORT nMax
= Min(nBlocks
, rSet
.nBlocks
);
275 if ( nBlocks
< rSet
.nBlocks
)
277 ULONG
*pNewMap
= new ULONG
[rSet
.nBlocks
];
278 memset( pNewMap
+ nBlocks
, 0, 4 * (rSet
.nBlocks
- nBlocks
) );
282 memcpy( pNewMap
, pBitmap
, 4 * nBlocks
);
286 nBlocks
= rSet
.nBlocks
;
289 // add the bits blocks by block
290 for ( USHORT nBlock
= 0; nBlock
< nMax
; ++nBlock
)
292 // compute numberof additional bits
293 ULONG nDiff
= ~*(pBitmap
+nBlock
) & *(rSet
.pBitmap
+nBlock
);
294 nCount
= nCount
+ CountBits(nDiff
);
296 *(pBitmap
+nBlock
) |= *(rSet
.pBitmap
+nBlock
);
302 //--------------------------------------------------------------------
304 // unites with a single bit
306 BitSet
& BitSet::operator|=( USHORT nBit
)
309 USHORT nBlock
= nBit
/ 32;
310 ULONG nBitVal
= 1L << (nBit
% 32);
312 if ( nBlock
>= nBlocks
)
314 ULONG
*pNewMap
= new ULONG
[nBlock
+1];
315 memset( pNewMap
+ nBlocks
, 0, 4 * (nBlock
- nBlocks
+ 1) );
319 memcpy( pNewMap
, pBitmap
, 4 * nBlocks
);
326 if ( (*(pBitmap
+nBlock
) & nBitVal
) == 0 )
328 *(pBitmap
+nBlock
) |= nBitVal
;
335 //--------------------------------------------------------------------
337 // determines if the bit is set (may be the only one)
339 BOOL
BitSet::Contains( USHORT nBit
) const
342 USHORT nBlock
= nBit
/ 32;
343 ULONG nBitVal
= 1L << (nBit
% 32);
345 if ( nBlock
>= nBlocks
)
347 return ( nBitVal
& *(pBitmap
+nBlock
) ) == nBitVal
;
350 //--------------------------------------------------------------------
352 // determines if the bitsets are equal
354 BOOL
BitSet::operator==( const BitSet
& rSet
) const
357 if ( nBlocks
!= rSet
.nBlocks
)
360 USHORT nBlock
= nBlocks
;
361 while ( nBlock
-- > 0 )
362 if ( *(pBitmap
+nBlock
) != *(rSet
.pBitmap
+nBlock
) )
368 //--------------------------------------------------------------------
370 // counts the number of 1-bits in the parameter
372 USHORT
BitSet::CountBits( ULONG nBits
)
376 while ( nBit
-- && nBits
)
377 { if ( ( (long)nBits
) < 0 )
384 //--------------------------------------------------------------------
386 USHORT
IndexBitSet::GetFreeIndex()
388 for(USHORT i
=0;i
<USHRT_MAX
;i
++)
394 DBG_ASSERT(FALSE
, "IndexBitSet enthaelt mehr als USHRT_MAX Eintraege");