1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <tools/debug.hxx>
24 #include <string.h> // memset(), memcpy()
25 #include <limits.h> // USHRT_MAX
28 //====================================================================
29 // add nOffset to each bit-value in the set
31 BitSet
BitSet::operator<<( sal_uInt16 nOffset
) const
33 // create a work-copy, return it if nothing to shift
38 // compute the shiftment in long-words and bits
39 sal_uInt16 nBlockDiff
= nOffset
/ 32;
40 sal_uIntPtr nBitValDiff
= nOffset
% 32;
42 // compute the new number of bits
43 for ( sal_uInt16 nBlock
= 0; nBlock
< nBlockDiff
; ++nBlock
)
44 aSet
.nCount
= aSet
.nCount
- CountBits( *(aSet
.pBitmap
+nBlock
) );
45 aSet
.nCount
= aSet
.nCount
-
46 CountBits( *(aSet
.pBitmap
+nBlockDiff
) >> (32-nBitValDiff
) );
48 // shift complete long-words
49 sal_uInt16 nTarget
, nSource
;
50 for ( nTarget
= 0, nSource
= nBlockDiff
;
51 (nSource
+1) < aSet
.nBlocks
;
52 ++nTarget
, ++nSource
)
53 *(aSet
.pBitmap
+nTarget
) =
54 ( *(aSet
.pBitmap
+nSource
) << nBitValDiff
) |
55 ( *(aSet
.pBitmap
+nSource
+1) >> (32-nBitValDiff
) );
57 // shift the remainder (if in total minor 32 bits, only this)
58 *(aSet
.pBitmap
+nTarget
) = *(aSet
.pBitmap
+nSource
) << nBitValDiff
;
60 // determine the last used block
61 while ( *(aSet
.pBitmap
+nTarget
) == 0 )
64 // shorten the block-array
65 if ( nTarget
< aSet
.nBlocks
)
67 sal_uIntPtr
* pNewMap
= new sal_uIntPtr
[nTarget
];
68 memcpy( pNewMap
, aSet
.pBitmap
, 4 * nTarget
);
69 delete [] aSet
.pBitmap
;
70 aSet
.pBitmap
= pNewMap
;
71 aSet
.nBlocks
= nTarget
;
77 //--------------------------------------------------------------------
79 // substracts nOffset from each bit-value in the set
81 BitSet
BitSet::operator>>( sal_uInt16
) const
86 //--------------------------------------------------------------------
88 // internal code for operator= and copy-ctor
90 void BitSet::CopyFrom( const BitSet
& rSet
)
93 nBlocks
= rSet
.nBlocks
;
96 pBitmap
= new sal_uIntPtr
[nBlocks
];
97 memcpy( pBitmap
, rSet
.pBitmap
, 4 * nBlocks
);
103 //--------------------------------------------------------------------
105 // creates an empty bitset
114 //--------------------------------------------------------------------
116 // creates a copy of bitset rOrig
118 BitSet::BitSet( const BitSet
& rOrig
)
123 //--------------------------------------------------------------------
132 //--------------------------------------------------------------------
134 // assignment from another bitset
136 BitSet
& BitSet::operator=( const BitSet
& rOrig
)
138 if ( this != &rOrig
)
146 //--------------------------------------------------------------------
148 // assignment from a single bit
150 BitSet
& BitSet::operator=( sal_uInt16 nBit
)
155 sal_uIntPtr nBitVal
= 1L << (nBit
% 32);
158 pBitmap
= new sal_uIntPtr
[nBlocks
+ 1];
159 memset( pBitmap
, 0, 4 * (nBlocks
+ 1) );
161 *(pBitmap
+nBlocks
) = nBitVal
;
166 //--------------------------------------------------------------------
168 // creates the asymetric difference with another bitset
170 BitSet
& BitSet::operator-=(sal_uInt16 nBit
)
172 sal_uInt16 nBlock
= nBit
/ 32;
173 sal_uIntPtr nBitVal
= 1L << (nBit
% 32);
175 if ( nBlock
>= nBlocks
)
178 if ( (*(pBitmap
+nBlock
) & nBitVal
) )
180 *(pBitmap
+nBlock
) &= ~nBitVal
;
187 //--------------------------------------------------------------------
189 // unites with the bits of rSet
191 BitSet
& BitSet::operator|=( const BitSet
& rSet
)
193 sal_uInt16 nMax
= std::min(nBlocks
, rSet
.nBlocks
);
196 if ( nBlocks
< rSet
.nBlocks
)
198 sal_uIntPtr
*pNewMap
= new sal_uIntPtr
[rSet
.nBlocks
];
199 memset( pNewMap
+ nBlocks
, 0, 4 * (rSet
.nBlocks
- nBlocks
) );
203 memcpy( pNewMap
, pBitmap
, 4 * nBlocks
);
207 nBlocks
= rSet
.nBlocks
;
210 // add the bits blocks by block
211 for ( sal_uInt16 nBlock
= 0; nBlock
< nMax
; ++nBlock
)
213 // compute numberof additional bits
214 sal_uIntPtr nDiff
= ~*(pBitmap
+nBlock
) & *(rSet
.pBitmap
+nBlock
);
215 nCount
= nCount
+ CountBits(nDiff
);
217 *(pBitmap
+nBlock
) |= *(rSet
.pBitmap
+nBlock
);
223 //--------------------------------------------------------------------
225 // unites with a single bit
227 BitSet
& BitSet::operator|=( sal_uInt16 nBit
)
229 sal_uInt16 nBlock
= nBit
/ 32;
230 sal_uIntPtr nBitVal
= 1L << (nBit
% 32);
232 if ( nBlock
>= nBlocks
)
234 sal_uIntPtr
*pNewMap
= new sal_uIntPtr
[nBlock
+1];
235 memset( pNewMap
+ nBlocks
, 0, 4 * (nBlock
- nBlocks
+ 1) );
239 memcpy( pNewMap
, pBitmap
, 4 * nBlocks
);
246 if ( (*(pBitmap
+nBlock
) & nBitVal
) == 0 )
248 *(pBitmap
+nBlock
) |= nBitVal
;
255 //--------------------------------------------------------------------
257 // determines if the bit is set (may be the only one)
259 sal_Bool
BitSet::Contains( sal_uInt16 nBit
) const
261 sal_uInt16 nBlock
= nBit
/ 32;
262 sal_uIntPtr nBitVal
= 1L << (nBit
% 32);
264 if ( nBlock
>= nBlocks
)
266 return ( nBitVal
& *(pBitmap
+nBlock
) ) == nBitVal
;
269 //--------------------------------------------------------------------
271 // determines if the bitsets are equal
273 sal_Bool
BitSet::operator==( const BitSet
& rSet
) const
275 if ( nBlocks
!= rSet
.nBlocks
)
278 sal_uInt16 nBlock
= nBlocks
;
279 while ( nBlock
-- > 0 )
280 if ( *(pBitmap
+nBlock
) != *(rSet
.pBitmap
+nBlock
) )
286 //--------------------------------------------------------------------
288 // counts the number of 1-bits in the parameter
290 sal_uInt16
BitSet::CountBits( sal_uIntPtr nBits
)
292 sal_uInt16 nCount
= 0;
294 while ( nBit
-- && nBits
)
295 { if ( ( (long)nBits
) < 0 )
302 //--------------------------------------------------------------------
304 sal_uInt16
IndexBitSet::GetFreeIndex()
306 for(sal_uInt16 i
=0;i
<USHRT_MAX
;i
++)
312 DBG_ASSERT(sal_False
, "IndexBitSet enthaelt mehr als USHRT_MAX Eintraege");
317 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */