Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

258 lines
6.5 KiB

  1. // bitset standard header
  2. #ifndef _BITSET_
  3. #define _BITSET_
  4. #include <istream>
  5. #ifdef _MSC_VER
  6. #pragma pack(push,8)
  7. #endif /* _MSC_VER */
  8. // TEMPLATE CLASS bitset
  9. _STD_BEGIN
  10. template<size_t _N> class bitset {
  11. typedef unsigned long _Ty;
  12. public:
  13. typedef bool element_type;
  14. class reference {
  15. friend class bitset<_N>;
  16. public:
  17. reference& operator=(bool _X)
  18. {_Pbs->set(_Off, _X);
  19. return (*this); }
  20. reference& operator=(const reference& _Bs)
  21. {_Pbs->set(_Off, bool(_Bs));
  22. return (*this); }
  23. reference& flip()
  24. {_Pbs->flip(_Off);
  25. return (*this); }
  26. bool operator~() const
  27. {return (!_Pbs->test(_Off)); }
  28. operator bool() const
  29. {return (_Pbs->test(_Off)); }
  30. private:
  31. reference(bitset<_N>& _X, size_t _P)
  32. : _Pbs(&_X), _Off(_P) {}
  33. bitset<_N> *_Pbs;
  34. size_t _Off;
  35. };
  36. _STCONS(size_t, bitset_size, _N);
  37. bool at(size_t _P) const
  38. {if (_N <= _P)
  39. _Xran();
  40. return (test(_P)); }
  41. reference at(size_t _P)
  42. {if (_N <= _P)
  43. _Xran();
  44. return (reference(*this, _P)); }
  45. bool operator[](size_t _P) const
  46. {return (test(_P)); }
  47. reference operator[](size_t _P)
  48. {return (reference(*this, _P)); }
  49. bitset()
  50. {_Tidy(); }
  51. bitset(unsigned long _X)
  52. {_Tidy();
  53. for (size_t _P = 0; _X != 0 && _P < _N; _X >>= 1, ++_P)
  54. if (_X & 1)
  55. set(_P); }
  56. explicit bitset(const string& _S, size_t _P = 0,
  57. size_t _L = (size_t)(-1))
  58. {size_t _I;
  59. if (_S.size() < _P)
  60. _Xran();
  61. if (_S.size() - _P < _L)
  62. _L = _S.size() - _P;
  63. if (_N < _L)
  64. _L = _N;
  65. _Tidy(), _P += _L;
  66. for (_I = 0; _I < _L; ++_I)
  67. if (_S[--_P] == '1')
  68. set(_I);
  69. else if (_S[_P] != '0')
  70. _Xinv(); }
  71. bitset<_N>& operator&=(const bitset<_N>& _R)
  72. {for (int _I = _Nw; 0 <= _I; --_I)
  73. _A[_I] &= _R._W(_I);
  74. return (*this); }
  75. bitset<_N>& operator|=(const bitset<_N>& _R)
  76. {for (int _I = _Nw; 0 <= _I; --_I)
  77. _A[_I] |= _R._W(_I);
  78. return (*this); }
  79. bitset<_N>& operator^=(const bitset<_N>& _R)
  80. {for (int _I = _Nw; 0 <= _I; --_I)
  81. _A[_I] ^= _R._W(_I);
  82. return (*this); }
  83. bitset<_N>& operator<<=(size_t _P)
  84. {if (_P < 0)
  85. return (*this >>= -_P);
  86. const int _D = _P / _Nb;
  87. if (_D != 0)
  88. for (int _I = _Nw; 0 <= _I; --_I)
  89. _A[_I] = _D <= _I ? _A[_I - _D] : 0;
  90. if ((_P %= _Nb) != 0)
  91. {for (int _I = _Nw; 0 < _I; --_I)
  92. _A[_I] = (_A[_I] << _P)
  93. | (_A[_I - 1] >> (_Nb - _P));
  94. _A[0] <<= _P, _Trim(); }
  95. return (*this); }
  96. bitset<_N>& operator>>=(size_t _P)
  97. {if (_P < 0)
  98. return (*this <<= -_P);
  99. const int _D = _P / _Nb;
  100. if (_D != 0)
  101. for (int _I = 0; _I <= _Nw; ++_I)
  102. _A[_I] = _D <= _Nw - _I ? _A[_I + _D] : 0;
  103. if ((_P %= _Nb) != 0)
  104. {for (int _I = 0; _I < _Nw; ++_I)
  105. _A[_I] = (_A[_I] >> _P)
  106. | (_A[_I + 1] << (_Nb - _P));
  107. _A[_Nw] >>= _P; }
  108. return (*this); }
  109. bitset<_N>& set()
  110. {_Tidy(~(_Ty)0);
  111. return (*this); }
  112. bitset<_N>& set(size_t _P, bool _X = true)
  113. {if (_N <= _P)
  114. _Xran();
  115. if (_X)
  116. _A[_P / _Nb] |= (_Ty)1 << _P % _Nb;
  117. else
  118. _A[_P / _Nb] &= ~((_Ty)1 << _P % _Nb);
  119. return (*this); }
  120. bitset<_N>& reset()
  121. {_Tidy();
  122. return (*this); }
  123. bitset<_N>& reset(size_t _P)
  124. {return (set(_P, 0)); }
  125. bitset<_N> operator~() const
  126. {return (bitset<_N>(*this).flip()); }
  127. bitset<_N>& flip()
  128. {for (int _I = _Nw; 0 <= _I; --_I)
  129. _A[_I] = ~_A[_I];
  130. _Trim();
  131. return (*this); }
  132. bitset<_N>& flip(size_t _P)
  133. {if (_N <= _P)
  134. _Xran();
  135. _A[_P / _Nb] ^= (_Ty)1 << _P % _Nb;
  136. return (*this); }
  137. unsigned long to_ulong() const
  138. {enum {_Assertion = 1 /
  139. (sizeof (unsigned long) % sizeof (_Ty) == 0)};
  140. int _I = _Nw;
  141. for (; sizeof (unsigned long) / sizeof (_Ty) <= _I; --_I)
  142. if (_A[_I] != 0)
  143. _Xoflo();
  144. unsigned long _V = _A[_I];
  145. for (; 0 <= --_I; )
  146. _V = _V << _Nb | _A[_I];
  147. return (_V); }
  148. string to_string() const
  149. {string _S;
  150. _S.reserve(_N);
  151. for (size_t _P = _N; 0 < _P; )
  152. _S += test(--_P) ? '1' : '0';
  153. return (_S); }
  154. size_t count() const
  155. {size_t _V = 0;
  156. for (int _I = _Nw; 0 <= _I; --_I)
  157. for (_Ty _X = _A[_I]; _X != 0; _X >>= 4)
  158. _V += "\0\1\1\2\1\2\2\3"
  159. "\1\2\2\3\2\3\3\4"[_X & 0xF];
  160. return (_V); }
  161. size_t size() const
  162. {return (_N); }
  163. bool operator==(const bitset<_N>& _R) const
  164. {for (int _I = _Nw; 0 <= _I; --_I)
  165. if (_A[_I] != _R._W(_I))
  166. return (false);
  167. return (true); }
  168. bool operator!=(const bitset<_N>& _R) const
  169. {return (!(*this == _R)); }
  170. bool test(size_t _P) const
  171. {if (_N <= _P)
  172. _Xran();
  173. return ((_A[_P / _Nb] & ((_Ty)1 << _P % _Nb)) != 0); }
  174. bool any() const
  175. {for (int _I = _Nw; 0 <= _I; --_I)
  176. if (_A[_I] != 0)
  177. return (true);
  178. return (false); }
  179. bool none() const
  180. {return (!any()); }
  181. bitset<_N> operator<<(size_t _R) const
  182. {return (bitset<_N>(*this) <<= _R); }
  183. bitset<_N> operator>>(size_t _R) const
  184. {return (bitset<_N>(*this) >>= _R); }
  185. friend bitset<_N> operator&(const bitset<_N>& _L,
  186. const bitset<_N>& _R)
  187. {return (bitset<_N>(_L) &= _R); }
  188. friend bitset<_N> operator|(const bitset<_N>& _L,
  189. const bitset<_N>& _R)
  190. {return (bitset<_N>(_L) |= _R); }
  191. friend bitset<_N> operator^(const bitset<_N>& _L,
  192. const bitset<_N>& _R)
  193. {return (bitset<_N>(_L) ^= _R); }
  194. friend ostream& operator<<(ostream& _O, const bitset<_N>& _R)
  195. {for (size_t _P = _N; 0 < _P; )
  196. _O << (_R.test(--_P) ? '1' : '0');
  197. return (_O); }
  198. // TEMPLATE operator>>
  199. friend istream& operator>>(istream& _I, bitset<_N>& _R)
  200. {ios_base::iostate _St = ios_base::goodbit;
  201. bool _Chg = false;
  202. string _X;
  203. const istream::sentry _Ok(_I);
  204. if (_Ok)
  205. {_TRY_IO_BEGIN
  206. int _C = _I.rdbuf()->sgetc();
  207. for (size_t _M = _R.size(); 0 < _M;
  208. _C = _I.rdbuf()->snextc(), --_M)
  209. {if (_C == EOF)
  210. {_St |= ios_base::eofbit;
  211. break; }
  212. else if (_C != '0' && _C != '1')
  213. break;
  214. else if (_X.max_size() <= _X.size())
  215. {_St |= ios_base::failbit;
  216. break; }
  217. else
  218. _X.append(1, (char)_C), _Chg = true; }
  219. _CATCH_IO_(_I); }
  220. if (!_Chg)
  221. _St |= ios_base::failbit;
  222. _I.setstate(_St);
  223. _R = bitset<_N>(_X);
  224. return (_I); }
  225. _Ty _W(size_t _I) const
  226. {return (_A[_I]); }
  227. private:
  228. enum {_Nb = CHAR_BIT * sizeof (_Ty),
  229. _Nw = _N == 0 ? 0 : (_N - 1) / _Nb};
  230. void _Tidy(_Ty _X = 0)
  231. {for (int _I = _Nw; 0 <= _I; --_I)
  232. _A[_I] = _X;
  233. if (_X != 0)
  234. _Trim(); }
  235. void _Trim()
  236. {if (_N % _Nb != 0)
  237. _A[_Nw] &= ((_Ty)1 << _N % _Nb) - 1; }
  238. void _Xinv() const
  239. {_THROW(invalid_argument, "invalid bitset<N> char"); }
  240. void _Xoflo() const
  241. {_THROW(overflow_error,
  242. "bitset<N> conversion overflow"); }
  243. void _Xran() const
  244. {_THROW(out_of_range, "invalid bitset<N> position"); }
  245. _Ty _A[_Nw + 1];
  246. };
  247. _STD_END
  248. #ifdef _MSC_VER
  249. #pragma pack(pop)
  250. #endif /* _MSC_VER */
  251. #endif /* _BITSET */
  252. /*
  253. * Copyright (c) 1994 by P.J. Plauger. ALL RIGHTS RESERVED.
  254. * Consult your license regarding permissions and restrictions.
  255. */