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