1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "nel/misc/bit_set.h"
30 // must be defined elsewhere
32 #define min(a,b) (((a) < (b)) ? (a) : (b))
37 // ***************************************************************************
40 /* ***********************************************
41 * WARNING: This Class/Method must be thread-safe (ctor/dtor/serial): no static access for instance
42 * It can be loaded/called through CAsyncFileManager for instance
43 * ***********************************************/
47 CBitSet::CBitSet(uint numBits
)
49 /* ***********************************************
50 * WARNING: This Class/Method must be thread-safe (ctor/dtor/serial): no static access for instance
51 * It can be loaded/called through CAsyncFileManager for instance
52 * ***********************************************/
57 CBitSet::CBitSet(const CBitSet
&bs
)
59 /* ***********************************************
60 * WARNING: This Class/Method must be thread-safe (ctor/dtor/serial): no static access for instance
61 * It can be loaded/called through CAsyncFileManager for instance
62 * ***********************************************/
64 MaskLast
= bs
.MaskLast
;
69 /* ***********************************************
70 * WARNING: This Class/Method must be thread-safe (ctor/dtor/serial): no static access for instance
71 * It can be loaded/called through CAsyncFileManager for instance
72 * ***********************************************/
74 CBitSet
&CBitSet::operator=(const CBitSet
&bs
)
77 MaskLast
= bs
.MaskLast
;
84 // ***************************************************************************
91 void CBitSet::resize(uint numBits
)
97 Array
.resize( (NumBits
+NL_BITLEN
-1) / NL_BITLEN
);
98 uint nLastBits
= NumBits
& (NL_BITLEN
-1) ;
99 // Generate the mask for the last word.
101 MaskLast
= ~((uint
)0);
103 MaskLast
= (1<< nLastBits
) -1;
108 void CBitSet::resizeNoReset(uint numBits
, bool value
)
115 Array
.resize( (NumBits
+NL_BITLEN
-1) / NL_BITLEN
);
116 uint nLastBits
= NumBits
& (NL_BITLEN
-1) ;
117 // Generate the mask for the last word.
119 MaskLast
= ~((uint
)0);
121 MaskLast
= (1<< nLastBits
) -1;
123 // Set new bit to value
124 for (uint i
=oldNum
; i
<(uint
)NumBits
; i
++)
127 void CBitSet::setAll()
129 const vector
<uint32
>::size_type s
= Array
.size();
130 fill_n(Array
.begin(), s
, ~((uint
)0));
133 Array
[s
-1]&= MaskLast
;
135 void CBitSet::clearAll()
137 fill_n(Array
.begin(), Array
.size(), 0);
141 // ***************************************************************************
142 CBitSet
CBitSet::operator~() const
150 CBitSet
CBitSet::operator&(const CBitSet
&bs
) const
158 CBitSet
CBitSet::operator|(const CBitSet
&bs
) const
166 CBitSet
CBitSet::operator^(const CBitSet
&bs
) const
176 // ***************************************************************************
182 for(sint i
=0;i
<(sint
)Array
.size();i
++)
185 Array
[Array
.size()-1]&= MaskLast
;
187 CBitSet
&CBitSet::operator&=(const CBitSet
&bs
)
192 vector
<uint32
>::size_type minSize
= min(Array
.size(), bs
.Array
.size());
193 vector
<uint32
>::size_type i
;
194 for(i
=0;i
<minSize
;i
++)
195 Array
[i
]= Array
[i
] & bs
.Array
[i
];
196 for(i
=minSize
;i
<Array
.size();i
++)
199 Array
[Array
.size()-1]&= MaskLast
;
203 CBitSet
&CBitSet::operator|=(const CBitSet
&bs
)
208 vector
<uint32
>::size_type minSize
= min(Array
.size(), bs
.Array
.size());
209 vector
<uint32
>::size_type i
;
210 for(i
=0;i
<minSize
;i
++)
211 Array
[i
]= Array
[i
] | bs
.Array
[i
];
212 // Do nothing for bits word from minSize to Array.size().
214 Array
[Array
.size()-1]&= MaskLast
;
218 CBitSet
&CBitSet::operator^=(const CBitSet
&bs
)
223 vector
<uint32
>::size_type minSize
= min(Array
.size(), bs
.Array
.size());
224 vector
<uint32
>::size_type i
;
225 for(i
=0;i
<minSize
;i
++)
226 Array
[i
]= Array
[i
] ^ bs
.Array
[i
];
227 // Do nothing for bits word from minSize to Array.size().
229 Array
[Array
.size()-1]&= MaskLast
;
235 // ***************************************************************************
236 bool CBitSet::operator==(const CBitSet
&bs
) const
238 if(NumBits
!=bs
.NumBits
)
241 for(sint i
=0;i
<(sint
)Array
.size();i
++)
243 if(Array
[i
]!=bs
.Array
[i
])
248 bool CBitSet::operator!=(const CBitSet
&bs
) const
250 return (!operator==(bs
));
252 bool CBitSet::compareRestrict(const CBitSet
&bs
) const
254 sint n
=min(NumBits
, bs
.NumBits
);
255 if(n
==0) return true;
257 sint nA
= (n
+NL_BITLEN
-1) / NL_BITLEN
;
260 uint nLastBits
= n
& (NL_BITLEN
-1) ;
261 // Generate the mask for the last common word.
265 mask
= (1<< nLastBits
) -1;
268 for(sint i
=0;i
<nA
-1;i
++)
270 if(Array
[i
]!=bs
.Array
[i
])
273 if( (Array
[nA
-1]&mask
) != (bs
.Array
[nA
-1]&mask
) )
279 bool CBitSet::allSet()
283 for(sint i
=0;i
<(sint
)Array
.size()-1;i
++)
285 if( Array
[i
]!= (~((uint
)0)) )
288 if( Array
[Array
.size()-1]!= MaskLast
)
292 bool CBitSet::allCleared()
296 for(sint i
=0;i
<(sint
)Array
.size();i
++)
306 void CBitSet::serial(IStream
&f
)
308 /* ***********************************************
309 * WARNING: This Class/Method must be thread-safe (ctor/dtor/serial): no static access for instance
310 * It can be loaded/called through CAsyncFileManager for instance
311 * ***********************************************/
313 (void)f
.serialVersion(0);
315 vector
<uint32
> array32
;
317 // Must support any size of uint.
323 f
.serialCont(array32
);
324 for(sint i
=0;i
<(sint
)sz
;i
++)
326 uint32 a
=array32
[i
/32];
336 array32
.resize(sz
/32);
337 fill_n(array32
.begin(), array32
.size(), 0);
338 for(sint i
=0;i
<(sint
)sz
;i
++)
341 array32
[i
/32]|= 1<<(i
&31);
343 f
.serialCont(array32
);
349 * Return a string representing the bitfield with 1 and 0 (from left to right)
351 std::string
CBitSet::toString() const
354 for ( sint i
=0; i
!=(sint
)size(); ++i
)
356 s
+= (get(i
) ? '1' : '0');