update dev300-m58
[ooovba.git] / sfx2 / source / bastyp / bitset.cxx
blob34aa3efdf80319d2f1cb5d4af70062e0258f321d
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: bitset.cxx,v $
10 * $Revision: 1.8 $
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>
34 #ifndef GCC
35 #endif
37 #include "bitset.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
47 DBG_MEMTEST();
48 // create a work-copy, return it if nothing to shift
49 BitSet aSet(*this);
50 if ( nOffset == 0 )
51 return aSet;
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 )
77 --nTarget;
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;
89 return aSet;
92 //--------------------------------------------------------------------
94 // substracts nOffset from each bit-value in the set
96 BitSet BitSet::operator>>( USHORT ) const
98 DBG_MEMTEST();
99 return BitSet();
102 //--------------------------------------------------------------------
104 // internal code for operator= and copy-ctor
106 void BitSet::CopyFrom( const BitSet& rSet )
108 DBG_MEMTEST();
109 nCount = rSet.nCount;
110 nBlocks = rSet.nBlocks;
111 if ( rSet.nBlocks )
113 DBG_MEMTEST();
114 pBitmap = new ULONG[nBlocks];
115 memcpy( pBitmap, rSet.pBitmap, 4 * nBlocks );
117 else
118 pBitmap = 0;
121 //--------------------------------------------------------------------
123 // creates an empty bitset
125 BitSet::BitSet()
127 DBG_MEMTEST();
128 nCount = 0;
129 nBlocks = 0;
130 pBitmap = 0;
133 //--------------------------------------------------------------------
135 // creates a copy of bitset rOrig
137 BitSet::BitSet( const BitSet& rOrig )
139 DBG_MEMTEST();
140 CopyFrom(rOrig);
143 //--------------------------------------------------------------------
145 // creates a bitset from an array
147 BitSet::BitSet( USHORT* pArray, USHORT nSize ):
148 nCount(nSize)
150 DBG_MEMTEST();
151 // find the highest bit to set
152 USHORT nMax = 0;
153 for ( USHORT n = 0; n < nCount; ++n )
154 if ( pArray[n] > nMax )
155 nMax = pArray[n];
157 // if there are bits at all
158 if ( nMax > 0 )
160 // allocate memory for all blocks needed
161 nBlocks = nMax / 32 + 1;
162 pBitmap = new ULONG[nBlocks];
163 memset( pBitmap, 0, 4 * nBlocks );
165 // set all the bits
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);
172 // set a single bit
173 if ( ( *(pBitmap+nBlock) & nBitVal ) == 0 )
175 *(pBitmap+nBlock) |= nBitVal;
176 ++nCount;
180 else
182 // initalize emtpy set
183 nBlocks = 0;
184 pBitmap = 0;
188 //--------------------------------------------------------------------
190 // frees the storage
192 BitSet::~BitSet()
194 DBG_MEMTEST();
195 delete [] pBitmap;
198 //--------------------------------------------------------------------
200 // creates a bitmap with all bits in rRange set
202 BitSet::BitSet( const Range& )
204 DBG_MEMTEST();
207 //--------------------------------------------------------------------
209 // assignment from another bitset
211 BitSet& BitSet::operator=( const BitSet& rOrig )
213 DBG_MEMTEST();
214 if ( this != &rOrig )
216 delete [] pBitmap;
217 CopyFrom(rOrig);
219 return *this;
222 //--------------------------------------------------------------------
224 // assignment from a single bit
226 BitSet& BitSet::operator=( USHORT nBit )
228 DBG_MEMTEST();
229 delete [] pBitmap;
231 nBlocks = nBit / 32;
232 ULONG nBitVal = 1L << (nBit % 32);
233 nCount = 1;
235 pBitmap = new ULONG[nBlocks];
236 memset( pBitmap + nBlocks, 0, 4 * nBlocks );
238 *(pBitmap+nBlocks) = nBitVal;
240 return *this;
243 //--------------------------------------------------------------------
245 // creates the asymetric difference with another bitset
247 BitSet& BitSet::operator-=(USHORT nBit)
249 DBG_MEMTEST();
250 USHORT nBlock = nBit / 32;
251 ULONG nBitVal = 1L << (nBit % 32);
253 if ( nBlock >= nBlocks )
254 return *this;
256 if ( (*(pBitmap+nBlock) & nBitVal) )
258 *(pBitmap+nBlock) &= ~nBitVal;
259 --nCount;
262 return *this;
265 //--------------------------------------------------------------------
267 // unites with the bits of rSet
269 BitSet& BitSet::operator|=( const BitSet& rSet )
271 DBG_MEMTEST();
272 USHORT nMax = Min(nBlocks, rSet.nBlocks);
274 // expand the bitmap
275 if ( nBlocks < rSet.nBlocks )
277 ULONG *pNewMap = new ULONG[rSet.nBlocks];
278 memset( pNewMap + nBlocks, 0, 4 * (rSet.nBlocks - nBlocks) );
280 if ( pBitmap )
282 memcpy( pNewMap, pBitmap, 4 * nBlocks );
283 delete [] pBitmap;
285 pBitmap = pNewMap;
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);
299 return *this;
302 //--------------------------------------------------------------------
304 // unites with a single bit
306 BitSet& BitSet::operator|=( USHORT nBit )
308 DBG_MEMTEST();
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) );
317 if ( pBitmap )
319 memcpy( pNewMap, pBitmap, 4 * nBlocks );
320 delete [] pBitmap;
322 pBitmap = pNewMap;
323 nBlocks = nBlock+1;
326 if ( (*(pBitmap+nBlock) & nBitVal) == 0 )
328 *(pBitmap+nBlock) |= nBitVal;
329 ++nCount;
332 return *this;
335 //--------------------------------------------------------------------
337 // determines if the bit is set (may be the only one)
339 BOOL BitSet::Contains( USHORT nBit ) const
341 DBG_MEMTEST();
342 USHORT nBlock = nBit / 32;
343 ULONG nBitVal = 1L << (nBit % 32);
345 if ( nBlock >= nBlocks )
346 return FALSE;
347 return ( nBitVal & *(pBitmap+nBlock) ) == nBitVal;
350 //--------------------------------------------------------------------
352 // determines if the bitsets are equal
354 BOOL BitSet::operator==( const BitSet& rSet ) const
356 DBG_MEMTEST();
357 if ( nBlocks != rSet.nBlocks )
358 return FALSE;
360 USHORT nBlock = nBlocks;
361 while ( nBlock-- > 0 )
362 if ( *(pBitmap+nBlock) != *(rSet.pBitmap+nBlock) )
363 return FALSE;
365 return TRUE;
368 //--------------------------------------------------------------------
370 // counts the number of 1-bits in the parameter
372 USHORT BitSet::CountBits( ULONG nBits )
374 USHORT nCount = 0;
375 int nBit = 32;
376 while ( nBit-- && nBits )
377 { if ( ( (long)nBits ) < 0 )
378 ++nCount;
379 nBits = nBits << 1;
381 return nCount;
384 //--------------------------------------------------------------------
386 USHORT IndexBitSet::GetFreeIndex()
388 for(USHORT i=0;i<USHRT_MAX;i++)
389 if(!Contains(i))
391 *this|=i;
392 return i;
394 DBG_ASSERT(FALSE, "IndexBitSet enthaelt mehr als USHRT_MAX Eintraege");
395 return 0;