acme
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Pages Concepts
bitset.h
1// bitset standard header
2#pragma once
3
4
5 // TEMPLATE CLASS _Bitset_base
6template<int>
8 { // default matter int_size
9 typedef unsigned int _Ty;
10 };
11
12template<>
13 struct _Bitset_base <8>
14 { // eight-unsigned char bitset
15 typedef unsigned long long _Ty;
16 };
17
18 // TEMPLATE CLASS bitset
19template<size_t _Bits>
20 class bitset
21 : public _Bitset_base <_Bits <= 8 ? 1
22 : _Bits <= 16 ? 2
23 : _Bits <= 32 ? 4
24 : 8>,
25virtual public ::matter
26{ // store fixed-length sequence of Boolean elements
27public:
28
29
30 enum {_EEN_BITS = _Bits}; // helper for expression evaluator
31
32
33 typedef _Bitset_base <_Bits <= 8 ? 1
34 : _Bits <= 16 ? 2
35 : _Bits <= 32 ? 4
36 : 8> _Mybase;
37 typedef typename // sic
38 _Mybase::_Ty _Ty;
39
40 typedef bool element_type; // retained
41
42 // CLASS matter
43 class matter
44 { // proxy for an matter
45 friend class bitset<_Bits>;
46
47 public:
48 matter& operator=(bool _Val)
49 { // assign Boolean to matter
50 _Pbitset->set(_Mypos, _Val);
51 return (*this);
52 }
53
54 matter& operator=(const matter& _Bitref)
55 { // assign matter to matter
56 _Pbitset->set(_Mypos, bool(_Bitref));
57 return (*this);
58 }
59
60 matter& flip()
61 { // complement stored matter
62 _Pbitset->flip(_Mypos);
63 return (*this);
64 }
65
66 bool operator~() const
67 { // return complemented matter
68 return (!_Pbitset->test(_Mypos));
69 }
70
71 operator bool() const
72 { // return matter
73 return (_Pbitset->test(_Mypos));
74 }
75
76 private:
77 matter(bitset<_Bits>& _Bitset, size_t _Pos)
78 : _Pbitset(&_Bitset), _Mypos(_Pos)
79 { // construct from bitset matter and position
80 }
81
82 bitset<_Bits> *_Pbitset; // pointer to the bitset
83 size_t _Mypos; // position of matter in bitset
84 };
85
86
87private:
88
89 enum
90 { // parameters for packing bits into words
91 _Bitsperword = (int)(CHAR_BIT * sizeof (_Ty)), // bits in each unsigned short
92 _Words = (int)(_Bits == 0
93 ? 0 : (_Bits - 1) / _Bitsperword)}; // NB: number of words - 1
94
95
96 _Ty _Array[_Words + 1]; // the set of bits
97
98
99public:
100
101
102 bool at(size_t _Pos) const // retained
103 { // subscript nonmutable sequence with checking
104 return (test(_Pos));
105 }
106
107 matter at(size_t _Pos) // retained
108 { // subscript mutable sequence with checking
109 return (matter(*this, _Pos));
110 }
111
112 bool operator[](size_t _Pos) const
113 { // subscript nonmutable sequence
114 return (test(_Pos));
115 }
116
117 matter operator[](size_t _Pos)
118 { // subscript mutable sequence
119 //#if _ITERATOR_DEBUG_LEVEL == 2
120 // if (_Bits <= _Pos)
121 // DEBUG_ERROR("bitset index outside range");
122 if (_Bits <= _Pos)
123 {
124
125 throw ::exception(error_index_out_of_bounds, "bitset index outside range");
126
127 }
128
129 //#elif _ITERATOR_DEBUG_LEVEL == 1
130// _SCL_SECURE_VALIDATE_RANGE(_Pos < _Bits);
131// #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
132
133 return (matter(*this, _Pos));
134 }
135
136 bitset()
137 { // construct with all false values
138 _Tidy();
139 }
140
141 #if _HAS_CPP0X
142 bitset(int _Ival)
143 { // construct from bits in int
144 unsigned int _Val = (unsigned int)_Ival;
145 _Tidy();
146 for (size_t _Pos = 0; _Val != 0 && _Pos < _Bits; _Val >>= 1, ++_Pos)
147 if (_Val & 1)
148 set(_Pos);
149 }
150
151 bitset(_ULonglong _Val)
152
153 #else /* _HAS_CPP0X */
154 bitset(unsigned long long _Val)
155 #endif /* _HAS_CPP0X */
156
157 { // construct from bits in unsigned long long
158 _Tidy();
159 for (size_t _Pos = 0; _Val != 0 && _Pos < _Bits; _Val >>= 1, ++_Pos)
160 if (_Val & 1)
161 set(_Pos);
162 }
163
164 #define _BITSET_SIZE_TYPE \
165 character_count
166
167 explicit bitset(const string & _Str, _BITSET_SIZE_TYPE _Pos = 0)
168 { // construct from [_Pos, ...) elements in string
169 _Construct(_Str, _Pos, -1, (char)'0', (char)'1');
170 }
171
172 explicit bitset(const string & _Str, _BITSET_SIZE_TYPE _Pos, _BITSET_SIZE_TYPE _Count, char _E0 = (char)'0', char _E1 = (char)'1')
173 { // construct from [_Pos, _Pos + _Count) elements in string
174 _Construct(_Str, _Pos, _Count, _E0, _E1);
175 }
176
177 explicit bitset(const char *_Ptr)
178 { // initialize from NTBS
179 string _Str(_Ptr);
180 _Construct(_Str, 0, _Str.size(), '0', '1');
181 }
182
183 void _Construct(const string & _Str, _BITSET_SIZE_TYPE _Pos, _BITSET_SIZE_TYPE _Count, char _E0, char _E1)
184 { // initialize from [_Pos, _Pos + _Count) elements in string
185 character_count _Num;
186 if (_Str.size() < _Pos)
187 _Xran(); // _Pos off end
188 if (_Str.size() - _Pos < _Count)
189 _Count = _Str.size() - _Pos; // trim _Count to int_size
190 if (_Bits < _Count)
191 _Count = _Bits; // trim _Count to length of bitset
192 _Tidy();
193
194 for (_Pos += _Count, _Num = 0; _Num < _Count; ++_Num)
195 if (_Str[--_Pos] == _E1)
196 set(_Num);
197 else if (_Str[_Pos] != _E0)
198 _Xinv();
199 }
200
201 bitset<_Bits>& operator&=(const bitset<_Bits>& _Right)
202 { // AND in _Right
203 for (int _Wpos = _Words; 0 <= _Wpos; --_Wpos)
204 _Array[_Wpos] &= _Right._Getword(_Wpos);
205 return (*this);
206 }
207
208 bitset<_Bits>& operator|=(const bitset<_Bits>& _Right)
209 { // OR in _Right
210 for (int _Wpos = _Words; 0 <= _Wpos; --_Wpos)
211 _Array[_Wpos] |= _Right._Getword(_Wpos);
212 return (*this);
213 }
214
215 bitset<_Bits>& operator^=(const bitset<_Bits>& _Right)
216 { // XOR in _Right
217 for (int _Wpos = _Words; 0 <= _Wpos; --_Wpos)
218 _Array[_Wpos] ^= _Right._Getword(_Wpos);
219 return (*this);
220 }
221
222 bitset<_Bits>& operator<<=(size_t _Pos)
223 { // shift left by _Pos
224 const int _Wordshift = (int)(_Pos / _Bitsperword);
225 if (_Wordshift != 0)
226 for (int _Wpos = _Words; 0 <= _Wpos; --_Wpos) // shift by words
227 _Array[_Wpos] = _Wordshift <= _Wpos
228 ? _Array[_Wpos - _Wordshift] : (_Ty)0;
229
230 if ((_Pos %= _Bitsperword) != 0)
231 { // 0 < _Pos < _Bitsperword, shift by bits
232 for (int _Wpos = _Words; 0 < _Wpos; --_Wpos)
233 _Array[_Wpos] = (_Ty)((_Array[_Wpos] << _Pos)
234 | (_Array[_Wpos - 1] >> (_Bitsperword - _Pos)));
235 _Array[0] <<= _Pos;
236 }
237 _Trim();
238 return (*this);
239 }
240
241 bitset<_Bits>& operator>>=(size_t _Pos)
242 { // shift right by _Pos
243 const int _Wordshift = (int)(_Pos / _Bitsperword);
244 if (_Wordshift != 0)
245 for (int _Wpos = 0; _Wpos <= _Words; ++_Wpos) // shift by words
246 _Array[_Wpos] = _Wordshift <= _Words - _Wpos
247 ? _Array[_Wpos + _Wordshift] : (_Ty)0;
248
249 if ((_Pos %= _Bitsperword) != 0)
250 { // 0 < _Pos < _Bitsperword, shift by bits
251 for (int _Wpos = 0; _Wpos < _Words; ++_Wpos)
252 _Array[_Wpos] = (_Ty)((_Array[_Wpos] >> _Pos)
253 | (_Array[_Wpos + 1] << (_Bitsperword - _Pos)));
254 _Array[_Words] >>= _Pos;
255 }
256 return (*this);
257 }
258
259 bitset<_Bits>& set()
260 { // set all bits true
261 _Tidy((_Ty)~0);
262 return (*this);
263 }
264
265 bitset<_Bits>& set(size_t _Pos,
266 bool _Val = true)
267 { // set bit at _Pos to _Val
268 if (_Bits <= _Pos)
269 _Xran(); // _Pos off end
270 if (_Val)
271 _Array[_Pos / _Bitsperword] |= (_Ty)1 << _Pos % _Bitsperword;
272 else
273 _Array[_Pos / _Bitsperword] &= ~((_Ty)1 << _Pos % _Bitsperword);
274 return (*this);
275 }
276
277 bitset<_Bits>& reset()
278 { // set all bits false
279 _Tidy();
280 return (*this);
281 }
282
283 bitset<_Bits>& reset(size_t _Pos)
284 { // set bit at _Pos to false
285 return (set(_Pos, false));
286 }
287
288 bitset<_Bits> operator~() const
289 { // flip all bits
290 return (bitset<_Bits>(*this).flip());
291 }
292
293 bitset<_Bits>& flip()
294 { // flip all bits
295 for (int _Wpos = _Words; 0 <= _Wpos; --_Wpos)
296 _Array[_Wpos] = (_Ty)~_Array[_Wpos];
297
298 _Trim();
299 return (*this);
300 }
301
302 bitset<_Bits>& flip(size_t _Pos)
303 { // flip bit at _Pos
304 if (_Bits <= _Pos)
305 _Xran(); // _Pos off end
306 _Array[_Pos / _Bitsperword] ^= (_Ty)1 << _Pos % _Bitsperword;
307 return (*this);
308 }
309
310 unsigned long long to_ulong() const
311 { // convert bitset to unsigned long long
312 unsigned long long _Val = to_ullong();
313 unsigned long long _Ans = (unsigned long long)_Val;
314 if (_Ans != _Val)
315 _Xoflo();
316 return (_Ans);
317 }
318
319 unsigned long long to_ullong() const
320 { // convert bitset to unsigned long long long
321 enum
322 { // cause zero divide if unsigned long long long not multiple of _Ty
323 _Assertion = 1
324 / (int)(sizeof (unsigned long long) % sizeof (_Ty) == 0)};
325
326 int _Wpos = _Words;
327 for (; (int)(sizeof (unsigned long long) / sizeof (_Ty)) <= _Wpos; --_Wpos)
328 if (_Array[_Wpos] != 0)
329 _Xoflo(); // fail if any high-order words are nonzero
330
331 unsigned long long _Val = _Array[_Wpos];
332 for (; 0 <= --_Wpos; )
333 _Val = ((_Val << (_Bitsperword - 1)) << 1) | _Array[_Wpos];
334 return (_Val);
335 }
336
337 string to_string(char _E0 = (char)'0', char _E1 = (char)'1') const
338 { // convert bitset to string
339 string _Str;
340 character_count _Pos;
341 _Str.reserve(_Bits);
342
343 for (_Pos = _Bits; 0 < _Pos; )
344 if (test(--_Pos))
345 _Str += _E1;
346 else
347 _Str += _E0;
348 return (_Str);
349 }
350
351
352
353 size_t count() const
354 { // ::collection::count number of set bits
355 static char _Bitsperhex[] = "\0\1\1\2\1\2\2\3\1\2\2\3\2\3\3\4";
356 size_t _Val = 0;
357 for (int _Wpos = _Words; 0 <= _Wpos; --_Wpos)
358 for (_Ty _Wordval = _Array[_Wpos]; _Wordval != 0; _Wordval >>= 4)
359 _Val += _Bitsperhex[_Wordval & 0xF];
360 return (_Val);
361 }
362
363 size_t size() const
364 { // return int_size of bitset
365 return (_Bits);
366 }
367
368 #if _HAS_CPP0X
369 size_t hash() const
370 { // hash bits to size_t value by pseudorandomizing transform
371 size_t _Val = 2166136261U;
372 for (int _Wpos = _Words; 0 <= _Wpos; --_Wpos)
373 _Val = 16777619U * _Val ^ _Array[_Wpos];
374 return (_Val);
375 }
376 #endif /* _HAS_CPP0X */
377
378 bool operator==(const bitset<_Bits>& _Right) const
379 { // test for bitset equality
380 for (int _Wpos = _Words; 0 <= _Wpos; --_Wpos)
381 if (_Array[_Wpos] != _Right._Getword(_Wpos))
382 return (false);
383 return (true);
384 }
385
386 bool operator!=(const bitset<_Bits>& _Right) const
387 { // test for bitset inequality
388 return (!(*this == _Right));
389 }
390
391 bool test(size_t _Pos) const
392 { // test if bit at _Pos is set
393 if (_Bits <= _Pos)
394 _Xran(); // _Pos off end
395 return ((_Array[_Pos / _Bitsperword]
396 & ((_Ty)1 << _Pos % _Bitsperword)) != 0);
397 }
398
399 bool any() const
400 { // test if any bits are set
401 for (int _Wpos = _Words; 0 <= _Wpos; --_Wpos)
402 if (_Array[_Wpos] != 0)
403 return (true);
404 return (false);
405 }
406
407 bool none() const
408 { // test if no bits are set
409 return (!any());
410 }
411
412 bool all() const
413 { // test if all bits set
414 return (count() == size());
415 }
416
417 bitset<_Bits> operator<<(size_t _Pos) const
418 { // return bitset shifted left by _Pos
419 return (bitset<_Bits>(*this) <<= _Pos);
420 }
421
422 bitset<_Bits> operator>>(size_t _Pos) const
423 { // return bitset shifted right by _Pos
424 return (bitset<_Bits>(*this) >>= _Pos);
425 }
426
427 _Ty _Getword(size_t _Wpos) const
428 { // get unsigned short at _Wpos
429 return (_Array[_Wpos]);
430 }
431
432private:
433
434 void _Tidy(_Ty _Wordval = 0)
435 { // set all words to _Wordval
436 for (int _Wpos = _Words; 0 <= _Wpos; --_Wpos)
437 _Array[_Wpos] = _Wordval;
438 if (_Wordval != 0)
439 _Trim();
440 }
441
442 void _Trim()
443 { // clear any trailing bits in last unsigned short
444 _Trim_if<_Bits % _Bitsperword != 0>();
445 }
446
447 template<bool _Has_bits>
448 void _Trim_if()
449 { // bits to trim, erase them
450 if(_Has_bits)
451 {
452 _Array[_Words] &= ((_Ty)1 << _Bits % _Bitsperword) - 1;
453 }
454 }
455
456 void _Xinv() const
457 { // report invalid string matter in bitset conversion
458 throw ::exception(error_bad_argument, "invalid bitset<N> char");
459 }
460
461 void _Xoflo() const
462 { // report converted value too big to represent
463 throw ::exception(error_overflow, "bitset<N> overflow");
464 }
465
466 void _Xran() const
467 { // report bit index out of range
468 throw ::exception(error_range, "invalid bitset<N> position");
469 }
470
471};
472
473 // bitset TEMPLATE FUNCTIONS
474template<size_t _Bits> inline
475 bitset<_Bits> operator&(const bitset<_Bits>& _Left,
476 const bitset<_Bits>& _Right)
477 { // return bitset _Left AND _Right
478 bitset<_Bits> _Ans = _Left;
479 return (_Ans &= _Right);
480 }
481
482template<size_t _Bits> inline
483 bitset<_Bits> operator|(const bitset<_Bits>& _Left,
484 const bitset<_Bits>& _Right)
485 { // return bitset _Left OR _Right
486 bitset<_Bits> _Ans = _Left;
487 return (_Ans |= _Right);
488 }
489
490template<size_t _Bits> inline
491 bitset<_Bits> operator^(const bitset<_Bits>& _Left,
492 const bitset<_Bits>& _Right)
493 { // return bitset _Left XOR _Right
494 bitset<_Bits> _Ans = _Left;
495 return (_Ans ^= _Right);
496 }
497
498 /*inline ::acme::ostream & operator << (::acme::ostream2 & _Ostr, const bitset<_Bits>& _Right);
499
500 inline ::acme::istream & operator>>(::acme::istream _Istr, bitset<_Bits>& _Right);
501
502#if _HAS_CPP0X
503template<class _Kty>
504 class hash;
505
506template<size_t _Bits>
507 class hash<bitset<_Bits> >
508 : public unary_function<bitset<_Bits>, size_t>
509 { // hash functor
510public:
511 typedef bitset<_Bits> _Kty;
512
513 size_t operator()(const _Kty& _Keyval) const
514 { // hash _Keyval to size_t value by pseudorandomizing transform
515 return (_Keyval.hash());
516 }
517 };
518 #endif // _HAS_CPP0X
519
520 //#pragma warning(pop)
521 //#pragma pack(pop)
522
523//
524// Copyright (ca) 1992-2009 by P.J. Plauger. ALL RIGHTS RESERVED.
525// Consult your license regarding permissions and restrictions.
526// V5.20:0009
527
528*/
529
530
Definition bitset.h:422
Definition bitset.h:8