xref: /aoo42x/main/sfx2/source/bastyp/bitset.cxx (revision 30acf5e8)
1d119d52dSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3d119d52dSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4d119d52dSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5d119d52dSAndrew Rist  * distributed with this work for additional information
6d119d52dSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7d119d52dSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8d119d52dSAndrew Rist  * "License"); you may not use this file except in compliance
9d119d52dSAndrew Rist  * with the License.  You may obtain a copy of the License at
10d119d52dSAndrew Rist  *
11d119d52dSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12d119d52dSAndrew Rist  *
13d119d52dSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14d119d52dSAndrew Rist  * software distributed under the License is distributed on an
15d119d52dSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16d119d52dSAndrew Rist  * KIND, either express or implied.  See the License for the
17d119d52dSAndrew Rist  * specific language governing permissions and limitations
18d119d52dSAndrew Rist  * under the License.
19d119d52dSAndrew Rist  *
20d119d52dSAndrew Rist  *************************************************************/
21d119d52dSAndrew Rist 
22d119d52dSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sfx2.hxx"
26cdf0e10cSrcweir #include <tools/debug.hxx>
27cdf0e10cSrcweir #ifndef GCC
28cdf0e10cSrcweir #endif
29cdf0e10cSrcweir 
30cdf0e10cSrcweir #include "bitset.hxx"
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include <string.h>		// memset(), memcpy()
33cdf0e10cSrcweir #include <limits.h>		// USHRT_MAX
34cdf0e10cSrcweir 
35cdf0e10cSrcweir //====================================================================
36cdf0e10cSrcweir // add nOffset to each bit-value in the set
37cdf0e10cSrcweir 
operator <<(sal_uInt16 nOffset) const38cdf0e10cSrcweir BitSet BitSet::operator<<( sal_uInt16 nOffset ) const
39cdf0e10cSrcweir {
40cdf0e10cSrcweir 	DBG_MEMTEST();
41cdf0e10cSrcweir 	// create a work-copy, return it if nothing to shift
42cdf0e10cSrcweir 	BitSet aSet(*this);
43cdf0e10cSrcweir 	if ( nOffset == 0 )
44cdf0e10cSrcweir 		return aSet;
45cdf0e10cSrcweir 
46cdf0e10cSrcweir 	// compute the shiftment in long-words and bits
47cdf0e10cSrcweir 	sal_uInt16 nBlockDiff = nOffset / 32;
48cdf0e10cSrcweir 	sal_uIntPtr nBitValDiff = nOffset % 32;
49cdf0e10cSrcweir 
50cdf0e10cSrcweir 	// compute the new number of bits
51cdf0e10cSrcweir 	for ( sal_uInt16 nBlock = 0; nBlock < nBlockDiff; ++nBlock )
52cdf0e10cSrcweir 		aSet.nCount = aSet.nCount - CountBits( *(aSet.pBitmap+nBlock) );
53cdf0e10cSrcweir 	aSet.nCount = aSet.nCount -
54cdf0e10cSrcweir         CountBits( *(aSet.pBitmap+nBlockDiff) >> (32-nBitValDiff) );
55cdf0e10cSrcweir 
56cdf0e10cSrcweir 	// shift complete long-words
57cdf0e10cSrcweir 	sal_uInt16 nTarget, nSource;
58cdf0e10cSrcweir 	for ( nTarget = 0, nSource = nBlockDiff;
59cdf0e10cSrcweir 		  (nSource+1) < aSet.nBlocks;
60cdf0e10cSrcweir 		  ++nTarget, ++nSource )
61cdf0e10cSrcweir 		*(aSet.pBitmap+nTarget) =
62cdf0e10cSrcweir 			( *(aSet.pBitmap+nSource) << nBitValDiff ) |
63cdf0e10cSrcweir 			( *(aSet.pBitmap+nSource+1) >> (32-nBitValDiff) );
64cdf0e10cSrcweir 
65cdf0e10cSrcweir 	// shift the remainder (if in total minor 32 bits, only this)
66cdf0e10cSrcweir 	*(aSet.pBitmap+nTarget) = *(aSet.pBitmap+nSource) << nBitValDiff;
67cdf0e10cSrcweir 
68cdf0e10cSrcweir 	// determine the last used block
69cdf0e10cSrcweir 	while ( *(aSet.pBitmap+nTarget) == 0 )
70cdf0e10cSrcweir 		--nTarget;
71cdf0e10cSrcweir 
72cdf0e10cSrcweir 	// shorten the block-array
73cdf0e10cSrcweir 	if ( nTarget < aSet.nBlocks )
74cdf0e10cSrcweir 	{
75cdf0e10cSrcweir 		sal_uIntPtr* pNewMap = new sal_uIntPtr[nTarget];
76cdf0e10cSrcweir 		memcpy( pNewMap, aSet.pBitmap, 4 * nTarget );
77cdf0e10cSrcweir         delete [] aSet.pBitmap;
78cdf0e10cSrcweir 		aSet.pBitmap = pNewMap;
79cdf0e10cSrcweir 		aSet.nBlocks = nTarget;
80cdf0e10cSrcweir 	}
81cdf0e10cSrcweir 
82cdf0e10cSrcweir 	return aSet;
83cdf0e10cSrcweir }
84cdf0e10cSrcweir 
85cdf0e10cSrcweir //--------------------------------------------------------------------
86cdf0e10cSrcweir 
8786e1cf34SPedro Giffuni // subtracts nOffset from each bit-value in the set
88cdf0e10cSrcweir 
operator >>(sal_uInt16) const89cdf0e10cSrcweir BitSet BitSet::operator>>( sal_uInt16 ) const
90cdf0e10cSrcweir {
91cdf0e10cSrcweir 	DBG_MEMTEST();
92cdf0e10cSrcweir 	return BitSet();
93cdf0e10cSrcweir }
94cdf0e10cSrcweir 
95cdf0e10cSrcweir //--------------------------------------------------------------------
96cdf0e10cSrcweir 
97cdf0e10cSrcweir // internal code for operator= and copy-ctor
98cdf0e10cSrcweir 
CopyFrom(const BitSet & rSet)99cdf0e10cSrcweir void BitSet::CopyFrom( const BitSet& rSet )
100cdf0e10cSrcweir {
101cdf0e10cSrcweir 	DBG_MEMTEST();
102cdf0e10cSrcweir 	nCount = rSet.nCount;
103cdf0e10cSrcweir 	nBlocks = rSet.nBlocks;
104cdf0e10cSrcweir 	if ( rSet.nBlocks )
105cdf0e10cSrcweir 	{
106cdf0e10cSrcweir 		DBG_MEMTEST();
107cdf0e10cSrcweir 		pBitmap = new sal_uIntPtr[nBlocks];
108cdf0e10cSrcweir 		memcpy( pBitmap, rSet.pBitmap, 4 * nBlocks );
109cdf0e10cSrcweir 	}
110cdf0e10cSrcweir 	else
111cdf0e10cSrcweir 		pBitmap = 0;
112cdf0e10cSrcweir }
113cdf0e10cSrcweir 
114cdf0e10cSrcweir //--------------------------------------------------------------------
115cdf0e10cSrcweir 
116cdf0e10cSrcweir // creates an empty bitset
117cdf0e10cSrcweir 
BitSet()118cdf0e10cSrcweir BitSet::BitSet()
119cdf0e10cSrcweir {
120cdf0e10cSrcweir 	DBG_MEMTEST();
121cdf0e10cSrcweir 	nCount = 0;
122cdf0e10cSrcweir 	nBlocks = 0;
123cdf0e10cSrcweir 	pBitmap = 0;
124cdf0e10cSrcweir }
125cdf0e10cSrcweir 
126cdf0e10cSrcweir //--------------------------------------------------------------------
127cdf0e10cSrcweir 
128cdf0e10cSrcweir // creates a copy of bitset rOrig
129cdf0e10cSrcweir 
BitSet(const BitSet & rOrig)130cdf0e10cSrcweir BitSet::BitSet( const BitSet& rOrig )
131cdf0e10cSrcweir {
132cdf0e10cSrcweir 	DBG_MEMTEST();
133cdf0e10cSrcweir 	CopyFrom(rOrig);
134cdf0e10cSrcweir }
135cdf0e10cSrcweir 
136cdf0e10cSrcweir //--------------------------------------------------------------------
137cdf0e10cSrcweir 
138cdf0e10cSrcweir // creates a bitset from an array
139cdf0e10cSrcweir 
BitSet(sal_uInt16 * pArray,sal_uInt16 nSize)140cdf0e10cSrcweir BitSet::BitSet( sal_uInt16* pArray, sal_uInt16 nSize ):
141cdf0e10cSrcweir 	nCount(nSize)
142cdf0e10cSrcweir {
143cdf0e10cSrcweir 	DBG_MEMTEST();
144cdf0e10cSrcweir 	// find the highest bit to set
145cdf0e10cSrcweir 	sal_uInt16 nMax = 0;
146cdf0e10cSrcweir 	for ( sal_uInt16 n = 0; n < nCount; ++n )
147cdf0e10cSrcweir 		if ( pArray[n] > nMax )
148cdf0e10cSrcweir 			nMax = pArray[n];
149cdf0e10cSrcweir 
150cdf0e10cSrcweir 	// if there are bits at all
151cdf0e10cSrcweir 	if ( nMax > 0 )
152cdf0e10cSrcweir 	{
153cdf0e10cSrcweir 		// allocate memory for all blocks needed
154cdf0e10cSrcweir 		nBlocks = nMax / 32 + 1;
155cdf0e10cSrcweir 		pBitmap = new sal_uIntPtr[nBlocks];
156cdf0e10cSrcweir 		memset( pBitmap, 0, 4 * nBlocks );
157cdf0e10cSrcweir 
158cdf0e10cSrcweir 		// set all the bits
159cdf0e10cSrcweir 		for ( sal_uInt16 n = 0; n < nCount; ++n )
160cdf0e10cSrcweir 		{
161cdf0e10cSrcweir 			// compute the block no. and bitvalue
162cdf0e10cSrcweir 			sal_uInt16 nBlock = n / 32;
163cdf0e10cSrcweir 			sal_uIntPtr nBitVal = 1L << (n % 32);
164cdf0e10cSrcweir 
165cdf0e10cSrcweir 			// set a single bit
166cdf0e10cSrcweir 			if ( ( *(pBitmap+nBlock) & nBitVal ) == 0 )
167cdf0e10cSrcweir 			{
168cdf0e10cSrcweir 				*(pBitmap+nBlock) |= nBitVal;
169cdf0e10cSrcweir 				++nCount;
170cdf0e10cSrcweir 			}
171cdf0e10cSrcweir 		}
172cdf0e10cSrcweir 	}
173cdf0e10cSrcweir 	else
174cdf0e10cSrcweir 	{
175*30acf5e8Spfg 		// initialize emtpy set
176cdf0e10cSrcweir 		nBlocks = 0;
177cdf0e10cSrcweir 		pBitmap = 0;
178cdf0e10cSrcweir 	}
179cdf0e10cSrcweir }
180cdf0e10cSrcweir 
181cdf0e10cSrcweir //--------------------------------------------------------------------
182cdf0e10cSrcweir 
183cdf0e10cSrcweir // frees the storage
184cdf0e10cSrcweir 
~BitSet()185cdf0e10cSrcweir BitSet::~BitSet()
186cdf0e10cSrcweir {
187cdf0e10cSrcweir 	DBG_MEMTEST();
188cdf0e10cSrcweir     delete [] pBitmap;
189cdf0e10cSrcweir }
190cdf0e10cSrcweir 
191cdf0e10cSrcweir //--------------------------------------------------------------------
192cdf0e10cSrcweir 
193cdf0e10cSrcweir // creates a bitmap with all bits in rRange set
194cdf0e10cSrcweir 
BitSet(const Range &)195cdf0e10cSrcweir BitSet::BitSet( const Range& )
196cdf0e10cSrcweir {
197cdf0e10cSrcweir 	DBG_MEMTEST();
198cdf0e10cSrcweir }
199cdf0e10cSrcweir 
200cdf0e10cSrcweir //--------------------------------------------------------------------
201cdf0e10cSrcweir 
202cdf0e10cSrcweir // assignment from another bitset
203cdf0e10cSrcweir 
operator =(const BitSet & rOrig)204cdf0e10cSrcweir BitSet& BitSet::operator=( const BitSet& rOrig )
205cdf0e10cSrcweir {
206cdf0e10cSrcweir 	DBG_MEMTEST();
207cdf0e10cSrcweir 	if ( this != &rOrig )
208cdf0e10cSrcweir 	{
209cdf0e10cSrcweir         delete [] pBitmap;
210cdf0e10cSrcweir 		CopyFrom(rOrig);
211cdf0e10cSrcweir 	}
212cdf0e10cSrcweir 	return *this;
213cdf0e10cSrcweir }
214cdf0e10cSrcweir 
215cdf0e10cSrcweir //--------------------------------------------------------------------
216cdf0e10cSrcweir 
217cdf0e10cSrcweir // assignment from a single bit
218cdf0e10cSrcweir 
operator =(sal_uInt16 nBit)219cdf0e10cSrcweir BitSet& BitSet::operator=( sal_uInt16 nBit )
220cdf0e10cSrcweir {
221cdf0e10cSrcweir 	DBG_MEMTEST();
222cdf0e10cSrcweir     delete [] pBitmap;
223cdf0e10cSrcweir 
224cdf0e10cSrcweir 	nBlocks = nBit / 32;
225cdf0e10cSrcweir 	sal_uIntPtr nBitVal = 1L << (nBit % 32);
226cdf0e10cSrcweir 	nCount = 1;
227cdf0e10cSrcweir 
228cdf0e10cSrcweir 	pBitmap = new sal_uIntPtr[nBlocks];
229cdf0e10cSrcweir 	memset( pBitmap + nBlocks, 0, 4 * nBlocks );
230cdf0e10cSrcweir 
231cdf0e10cSrcweir 	*(pBitmap+nBlocks) = nBitVal;
232cdf0e10cSrcweir 
233cdf0e10cSrcweir 	return *this;
234cdf0e10cSrcweir }
235cdf0e10cSrcweir 
236cdf0e10cSrcweir //--------------------------------------------------------------------
237cdf0e10cSrcweir 
238cdf0e10cSrcweir // creates the asymetric difference with another bitset
239cdf0e10cSrcweir 
operator -=(sal_uInt16 nBit)240cdf0e10cSrcweir BitSet& BitSet::operator-=(sal_uInt16 nBit)
241cdf0e10cSrcweir {
242cdf0e10cSrcweir 	DBG_MEMTEST();
243cdf0e10cSrcweir 	sal_uInt16 nBlock = nBit / 32;
244cdf0e10cSrcweir 	sal_uIntPtr nBitVal = 1L << (nBit % 32);
245cdf0e10cSrcweir 
246cdf0e10cSrcweir 	if ( nBlock >= nBlocks )
247cdf0e10cSrcweir 	  return *this;
248cdf0e10cSrcweir 
249cdf0e10cSrcweir 	if ( (*(pBitmap+nBlock) & nBitVal) )
250cdf0e10cSrcweir 	{
251cdf0e10cSrcweir 		*(pBitmap+nBlock) &= ~nBitVal;
252cdf0e10cSrcweir 		--nCount;
253cdf0e10cSrcweir 	}
254cdf0e10cSrcweir 
255cdf0e10cSrcweir 	return *this;
256cdf0e10cSrcweir }
257cdf0e10cSrcweir 
258cdf0e10cSrcweir //--------------------------------------------------------------------
259cdf0e10cSrcweir 
260cdf0e10cSrcweir // unites with the bits of rSet
261cdf0e10cSrcweir 
operator |=(const BitSet & rSet)262cdf0e10cSrcweir BitSet& BitSet::operator|=( const BitSet& rSet )
263cdf0e10cSrcweir {
264cdf0e10cSrcweir 	DBG_MEMTEST();
265cdf0e10cSrcweir 	sal_uInt16 nMax = Min(nBlocks, rSet.nBlocks);
266cdf0e10cSrcweir 
267cdf0e10cSrcweir 	// expand the bitmap
268cdf0e10cSrcweir 	if ( nBlocks < rSet.nBlocks )
269cdf0e10cSrcweir 	{
270cdf0e10cSrcweir 		sal_uIntPtr *pNewMap = new sal_uIntPtr[rSet.nBlocks];
271cdf0e10cSrcweir 		memset( pNewMap + nBlocks, 0, 4 * (rSet.nBlocks - nBlocks) );
272cdf0e10cSrcweir 
273cdf0e10cSrcweir 		if ( pBitmap )
274cdf0e10cSrcweir 		{
275cdf0e10cSrcweir 			memcpy( pNewMap, pBitmap, 4 * nBlocks );
276cdf0e10cSrcweir             delete [] pBitmap;
277cdf0e10cSrcweir 		}
278cdf0e10cSrcweir 		pBitmap = pNewMap;
279cdf0e10cSrcweir 		nBlocks = rSet.nBlocks;
280cdf0e10cSrcweir 	}
281cdf0e10cSrcweir 
282cdf0e10cSrcweir 	// add the bits blocks by block
283cdf0e10cSrcweir 	for ( sal_uInt16 nBlock = 0; nBlock < nMax; ++nBlock )
284cdf0e10cSrcweir 	{
285cdf0e10cSrcweir 		// compute numberof additional bits
286cdf0e10cSrcweir 		sal_uIntPtr nDiff = ~*(pBitmap+nBlock) & *(rSet.pBitmap+nBlock);
287cdf0e10cSrcweir 		nCount = nCount + CountBits(nDiff);
288cdf0e10cSrcweir 
289cdf0e10cSrcweir 		*(pBitmap+nBlock) |= *(rSet.pBitmap+nBlock);
290cdf0e10cSrcweir 	}
291cdf0e10cSrcweir 
292cdf0e10cSrcweir 	return *this;
293cdf0e10cSrcweir }
294cdf0e10cSrcweir 
295cdf0e10cSrcweir //--------------------------------------------------------------------
296cdf0e10cSrcweir 
297cdf0e10cSrcweir // unites with a single bit
298cdf0e10cSrcweir 
operator |=(sal_uInt16 nBit)299cdf0e10cSrcweir BitSet& BitSet::operator|=( sal_uInt16 nBit )
300cdf0e10cSrcweir {
301cdf0e10cSrcweir 	DBG_MEMTEST();
302cdf0e10cSrcweir 	sal_uInt16 nBlock = nBit / 32;
303cdf0e10cSrcweir 	sal_uIntPtr nBitVal = 1L << (nBit % 32);
304cdf0e10cSrcweir 
305cdf0e10cSrcweir 	if ( nBlock >= nBlocks )
306cdf0e10cSrcweir 	{
307cdf0e10cSrcweir 		sal_uIntPtr *pNewMap = new sal_uIntPtr[nBlock+1];
308cdf0e10cSrcweir 		memset( pNewMap + nBlocks, 0, 4 * (nBlock - nBlocks + 1) );
309cdf0e10cSrcweir 
310cdf0e10cSrcweir 		if ( pBitmap )
311cdf0e10cSrcweir 		{
312cdf0e10cSrcweir 			memcpy( pNewMap, pBitmap, 4 * nBlocks );
313cdf0e10cSrcweir             delete [] pBitmap;
314cdf0e10cSrcweir 		}
315cdf0e10cSrcweir 		pBitmap = pNewMap;
316cdf0e10cSrcweir 		nBlocks = nBlock+1;
317cdf0e10cSrcweir 	}
318cdf0e10cSrcweir 
319cdf0e10cSrcweir 	if ( (*(pBitmap+nBlock) & nBitVal) == 0 )
320cdf0e10cSrcweir 	{
321cdf0e10cSrcweir 		*(pBitmap+nBlock) |= nBitVal;
322cdf0e10cSrcweir 		++nCount;
323cdf0e10cSrcweir 	}
324cdf0e10cSrcweir 
325cdf0e10cSrcweir 	return *this;
326cdf0e10cSrcweir }
327cdf0e10cSrcweir 
328cdf0e10cSrcweir //--------------------------------------------------------------------
329cdf0e10cSrcweir 
330cdf0e10cSrcweir // determines if the bit is set (may be the only one)
331cdf0e10cSrcweir 
Contains(sal_uInt16 nBit) const332cdf0e10cSrcweir sal_Bool BitSet::Contains( sal_uInt16 nBit ) const
333cdf0e10cSrcweir {
334cdf0e10cSrcweir 	DBG_MEMTEST();
335cdf0e10cSrcweir 	sal_uInt16 nBlock = nBit / 32;
336cdf0e10cSrcweir 	sal_uIntPtr nBitVal = 1L << (nBit % 32);
337cdf0e10cSrcweir 
338cdf0e10cSrcweir 	if ( nBlock >= nBlocks )
339cdf0e10cSrcweir 		return sal_False;
340cdf0e10cSrcweir 	return ( nBitVal & *(pBitmap+nBlock) ) == nBitVal;
341cdf0e10cSrcweir }
342cdf0e10cSrcweir 
343cdf0e10cSrcweir //--------------------------------------------------------------------
344cdf0e10cSrcweir 
345cdf0e10cSrcweir // determines if the bitsets are equal
346cdf0e10cSrcweir 
operator ==(const BitSet & rSet) const347cdf0e10cSrcweir sal_Bool BitSet::operator==( const BitSet& rSet ) const
348cdf0e10cSrcweir {
349cdf0e10cSrcweir 	DBG_MEMTEST();
350cdf0e10cSrcweir 	if ( nBlocks != rSet.nBlocks )
351cdf0e10cSrcweir 		return sal_False;
352cdf0e10cSrcweir 
353cdf0e10cSrcweir 	sal_uInt16 nBlock = nBlocks;
354cdf0e10cSrcweir 	while ( nBlock-- > 0 )
355cdf0e10cSrcweir 		if ( *(pBitmap+nBlock) != *(rSet.pBitmap+nBlock) )
356cdf0e10cSrcweir 			return sal_False;
357cdf0e10cSrcweir 
358cdf0e10cSrcweir 	return sal_True;
359cdf0e10cSrcweir }
360cdf0e10cSrcweir 
361cdf0e10cSrcweir //--------------------------------------------------------------------
362cdf0e10cSrcweir 
363cdf0e10cSrcweir // counts the number of 1-bits in the parameter
364cdf0e10cSrcweir 
CountBits(sal_uIntPtr nBits)365cdf0e10cSrcweir sal_uInt16 BitSet::CountBits( sal_uIntPtr nBits )
366cdf0e10cSrcweir {
367cdf0e10cSrcweir 	sal_uInt16 nCount = 0;
368cdf0e10cSrcweir 	int nBit = 32;
369cdf0e10cSrcweir 	while ( nBit-- && nBits )
370cdf0e10cSrcweir 	{   if ( ( (long)nBits ) < 0 )
371cdf0e10cSrcweir 			++nCount;
372cdf0e10cSrcweir 		nBits = nBits << 1;
373cdf0e10cSrcweir 	}
374cdf0e10cSrcweir 	return nCount;
375cdf0e10cSrcweir }
376cdf0e10cSrcweir 
377cdf0e10cSrcweir //--------------------------------------------------------------------
378cdf0e10cSrcweir 
GetFreeIndex()379cdf0e10cSrcweir sal_uInt16 IndexBitSet::GetFreeIndex()
380cdf0e10cSrcweir {
381cdf0e10cSrcweir   for(sal_uInt16 i=0;i<USHRT_MAX;i++)
382cdf0e10cSrcweir 	if(!Contains(i))
383cdf0e10cSrcweir 	  {
384cdf0e10cSrcweir 		*this|=i;
385cdf0e10cSrcweir 		return i;
386cdf0e10cSrcweir 	  }
387cdf0e10cSrcweir   DBG_ASSERT(sal_False, "IndexBitSet enthaelt mehr als USHRT_MAX Eintraege");
388cdf0e10cSrcweir   return 0;
389cdf0e10cSrcweir }
390cdf0e10cSrcweir 
391cdf0e10cSrcweir 
392