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.

472 lines
12 KiB

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