bitset 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. // Debugging bitset implementation -*- C++ -*-
  2. // Copyright (C) 2003-2023 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library 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 General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file debug/bitset
  21. * This file is a GNU debug extension to the Standard C++ Library.
  22. */
  23. #ifndef _GLIBCXX_DEBUG_BITSET
  24. #define _GLIBCXX_DEBUG_BITSET
  25. #pragma GCC system_header
  26. #include <bitset>
  27. #include <debug/safe_sequence.h>
  28. #include <debug/safe_iterator.h>
  29. namespace std _GLIBCXX_VISIBILITY(default)
  30. {
  31. namespace __debug
  32. {
  33. /// Class std::bitset with additional safety/checking/debug instrumentation.
  34. template<size_t _Nb>
  35. class bitset
  36. : public _GLIBCXX_STD_C::bitset<_Nb>
  37. #if __cplusplus < 201103L
  38. , public __gnu_debug::_Safe_sequence_base
  39. #endif
  40. {
  41. typedef _GLIBCXX_STD_C::bitset<_Nb> _Base;
  42. public:
  43. // In C++11 we rely on normal reference type to preserve the property
  44. // of bitset to be use as a literal.
  45. // TODO: Find another solution.
  46. #if __cplusplus >= 201103L
  47. typedef typename _Base::reference reference;
  48. #else
  49. // bit reference:
  50. class reference
  51. : private _Base::reference
  52. , public __gnu_debug::_Safe_iterator_base
  53. {
  54. typedef typename _Base::reference _Base_ref;
  55. friend class bitset;
  56. reference();
  57. reference(const _Base_ref& __base, bitset* __seq) _GLIBCXX_NOEXCEPT
  58. : _Base_ref(__base)
  59. , _Safe_iterator_base(__seq, false)
  60. { }
  61. public:
  62. reference(const reference& __x) _GLIBCXX_NOEXCEPT
  63. : _Base_ref(__x)
  64. , _Safe_iterator_base(__x, false)
  65. { }
  66. reference&
  67. operator=(bool __x) _GLIBCXX_NOEXCEPT
  68. {
  69. _GLIBCXX_DEBUG_VERIFY(!this->_M_singular(),
  70. _M_message(__gnu_debug::__msg_bad_bitset_write)
  71. ._M_iterator(*this));
  72. *static_cast<_Base_ref*>(this) = __x;
  73. return *this;
  74. }
  75. reference&
  76. operator=(const reference& __x) _GLIBCXX_NOEXCEPT
  77. {
  78. _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(),
  79. _M_message(__gnu_debug::__msg_bad_bitset_read)
  80. ._M_iterator(__x));
  81. _GLIBCXX_DEBUG_VERIFY(!this->_M_singular(),
  82. _M_message(__gnu_debug::__msg_bad_bitset_write)
  83. ._M_iterator(*this));
  84. *static_cast<_Base_ref*>(this) = __x;
  85. return *this;
  86. }
  87. bool
  88. operator~() const _GLIBCXX_NOEXCEPT
  89. {
  90. _GLIBCXX_DEBUG_VERIFY(!this->_M_singular(),
  91. _M_message(__gnu_debug::__msg_bad_bitset_read)
  92. ._M_iterator(*this));
  93. return ~(*static_cast<const _Base_ref*>(this));
  94. }
  95. operator bool() const _GLIBCXX_NOEXCEPT
  96. {
  97. _GLIBCXX_DEBUG_VERIFY(!this->_M_singular(),
  98. _M_message(__gnu_debug::__msg_bad_bitset_read)
  99. ._M_iterator(*this));
  100. return *static_cast<const _Base_ref*>(this);
  101. }
  102. reference&
  103. flip() _GLIBCXX_NOEXCEPT
  104. {
  105. _GLIBCXX_DEBUG_VERIFY(!this->_M_singular(),
  106. _M_message(__gnu_debug::__msg_bad_bitset_flip)
  107. ._M_iterator(*this));
  108. _Base_ref::flip();
  109. return *this;
  110. }
  111. };
  112. #endif
  113. // 23.3.5.1 constructors:
  114. _GLIBCXX_CONSTEXPR bitset() _GLIBCXX_NOEXCEPT
  115. : _Base() { }
  116. #if __cplusplus >= 201103L
  117. constexpr bitset(unsigned long long __val) noexcept
  118. #else
  119. bitset(unsigned long __val)
  120. #endif
  121. : _Base(__val) { }
  122. template<typename _CharT, typename _Traits, typename _Alloc>
  123. _GLIBCXX23_CONSTEXPR
  124. explicit
  125. bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str,
  126. typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
  127. __pos = 0,
  128. typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
  129. __n = (std::basic_string<_CharT, _Traits, _Alloc>::npos))
  130. : _Base(__str, __pos, __n) { }
  131. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  132. // 396. what are characters zero and one.
  133. template<class _CharT, class _Traits, class _Alloc>
  134. _GLIBCXX23_CONSTEXPR
  135. bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str,
  136. typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
  137. __pos,
  138. typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
  139. __n,
  140. _CharT __zero, _CharT __one = _CharT('1'))
  141. : _Base(__str, __pos, __n, __zero, __one) { }
  142. _GLIBCXX23_CONSTEXPR
  143. bitset(const _Base& __x) : _Base(__x) { }
  144. #if __cplusplus >= 201103L
  145. template<typename _CharT>
  146. _GLIBCXX23_CONSTEXPR
  147. explicit
  148. bitset(const _CharT* __str,
  149. typename std::basic_string<_CharT>::size_type __n
  150. = std::basic_string<_CharT>::npos,
  151. _CharT __zero = _CharT('0'), _CharT __one = _CharT('1'))
  152. : _Base(__str, __n, __zero, __one) { }
  153. #endif
  154. // 23.3.5.2 bitset operations:
  155. _GLIBCXX23_CONSTEXPR
  156. bitset<_Nb>&
  157. operator&=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT
  158. {
  159. _M_base() &= __rhs;
  160. return *this;
  161. }
  162. _GLIBCXX23_CONSTEXPR
  163. bitset<_Nb>&
  164. operator|=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT
  165. {
  166. _M_base() |= __rhs;
  167. return *this;
  168. }
  169. _GLIBCXX23_CONSTEXPR
  170. bitset<_Nb>&
  171. operator^=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT
  172. {
  173. _M_base() ^= __rhs;
  174. return *this;
  175. }
  176. _GLIBCXX23_CONSTEXPR
  177. bitset<_Nb>&
  178. operator<<=(size_t __pos) _GLIBCXX_NOEXCEPT
  179. {
  180. _M_base() <<= __pos;
  181. return *this;
  182. }
  183. _GLIBCXX23_CONSTEXPR
  184. bitset<_Nb>&
  185. operator>>=(size_t __pos) _GLIBCXX_NOEXCEPT
  186. {
  187. _M_base() >>= __pos;
  188. return *this;
  189. }
  190. _GLIBCXX23_CONSTEXPR
  191. bitset<_Nb>&
  192. set() _GLIBCXX_NOEXCEPT
  193. {
  194. _Base::set();
  195. return *this;
  196. }
  197. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  198. // 186. bitset::set() second parameter should be bool
  199. _GLIBCXX23_CONSTEXPR
  200. bitset<_Nb>&
  201. set(size_t __pos, bool __val = true)
  202. {
  203. _Base::set(__pos, __val);
  204. return *this;
  205. }
  206. _GLIBCXX23_CONSTEXPR
  207. bitset<_Nb>&
  208. reset() _GLIBCXX_NOEXCEPT
  209. {
  210. _Base::reset();
  211. return *this;
  212. }
  213. _GLIBCXX23_CONSTEXPR
  214. bitset<_Nb>&
  215. reset(size_t __pos)
  216. {
  217. _Base::reset(__pos);
  218. return *this;
  219. }
  220. _GLIBCXX23_CONSTEXPR
  221. bitset<_Nb>
  222. operator~() const _GLIBCXX_NOEXCEPT
  223. { return bitset(~_M_base()); }
  224. _GLIBCXX23_CONSTEXPR
  225. bitset<_Nb>&
  226. flip() _GLIBCXX_NOEXCEPT
  227. {
  228. _Base::flip();
  229. return *this;
  230. }
  231. _GLIBCXX23_CONSTEXPR
  232. bitset<_Nb>&
  233. flip(size_t __pos)
  234. {
  235. _Base::flip(__pos);
  236. return *this;
  237. }
  238. // element access:
  239. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  240. // 11. Bitset minor problems
  241. _GLIBCXX23_CONSTEXPR
  242. reference
  243. operator[](size_t __pos)
  244. {
  245. __glibcxx_check_subscript(__pos);
  246. #if __cplusplus >= 201103L
  247. return _M_base()[__pos];
  248. #else
  249. return reference(_M_base()[__pos], this);
  250. #endif
  251. }
  252. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  253. // 11. Bitset minor problems
  254. _GLIBCXX_CONSTEXPR bool
  255. operator[](size_t __pos) const
  256. {
  257. #if __cplusplus < 201103L
  258. // TODO: Check in debug-mode too.
  259. __glibcxx_check_subscript(__pos);
  260. #endif
  261. return _Base::operator[](__pos);
  262. }
  263. using _Base::to_ulong;
  264. #if __cplusplus >= 201103L
  265. using _Base::to_ullong;
  266. #endif
  267. template <typename _CharT, typename _Traits, typename _Alloc>
  268. _GLIBCXX23_CONSTEXPR
  269. std::basic_string<_CharT, _Traits, _Alloc>
  270. to_string() const
  271. { return _M_base().template to_string<_CharT, _Traits, _Alloc>(); }
  272. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  273. // 396. what are characters zero and one.
  274. template<class _CharT, class _Traits, class _Alloc>
  275. _GLIBCXX23_CONSTEXPR
  276. std::basic_string<_CharT, _Traits, _Alloc>
  277. to_string(_CharT __zero, _CharT __one = _CharT('1')) const
  278. {
  279. return _M_base().template
  280. to_string<_CharT, _Traits, _Alloc>(__zero, __one);
  281. }
  282. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  283. // 434. bitset::to_string() hard to use.
  284. template<typename _CharT, typename _Traits>
  285. _GLIBCXX23_CONSTEXPR
  286. std::basic_string<_CharT, _Traits, std::allocator<_CharT> >
  287. to_string() const
  288. { return to_string<_CharT, _Traits, std::allocator<_CharT> >(); }
  289. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  290. // 853. to_string needs updating with zero and one.
  291. template<class _CharT, class _Traits>
  292. _GLIBCXX23_CONSTEXPR
  293. std::basic_string<_CharT, _Traits, std::allocator<_CharT> >
  294. to_string(_CharT __zero, _CharT __one = _CharT('1')) const
  295. { return to_string<_CharT, _Traits,
  296. std::allocator<_CharT> >(__zero, __one); }
  297. template<typename _CharT>
  298. _GLIBCXX23_CONSTEXPR
  299. std::basic_string<_CharT, std::char_traits<_CharT>,
  300. std::allocator<_CharT> >
  301. to_string() const
  302. {
  303. return to_string<_CharT, std::char_traits<_CharT>,
  304. std::allocator<_CharT> >();
  305. }
  306. template<class _CharT>
  307. _GLIBCXX23_CONSTEXPR
  308. std::basic_string<_CharT, std::char_traits<_CharT>,
  309. std::allocator<_CharT> >
  310. to_string(_CharT __zero, _CharT __one = _CharT('1')) const
  311. {
  312. return to_string<_CharT, std::char_traits<_CharT>,
  313. std::allocator<_CharT> >(__zero, __one);
  314. }
  315. _GLIBCXX23_CONSTEXPR
  316. std::basic_string<char, std::char_traits<char>, std::allocator<char> >
  317. to_string() const
  318. {
  319. return to_string<char,std::char_traits<char>,std::allocator<char> >();
  320. }
  321. _GLIBCXX23_CONSTEXPR
  322. std::basic_string<char, std::char_traits<char>, std::allocator<char> >
  323. to_string(char __zero, char __one = '1') const
  324. {
  325. return to_string<char, std::char_traits<char>,
  326. std::allocator<char> >(__zero, __one);
  327. }
  328. using _Base::count;
  329. using _Base::size;
  330. _GLIBCXX23_CONSTEXPR
  331. bool
  332. operator==(const bitset<_Nb>& __rhs) const _GLIBCXX_NOEXCEPT
  333. { return _M_base() == __rhs._M_base(); }
  334. #if __cpp_impl_three_way_comparison < 201907L
  335. bool
  336. operator!=(const bitset<_Nb>& __rhs) const _GLIBCXX_NOEXCEPT
  337. { return _M_base() != __rhs._M_base(); }
  338. #endif
  339. using _Base::test;
  340. using _Base::all;
  341. using _Base::any;
  342. using _Base::none;
  343. _GLIBCXX23_CONSTEXPR
  344. bitset<_Nb>
  345. operator<<(size_t __pos) const _GLIBCXX_NOEXCEPT
  346. { return bitset<_Nb>(_M_base() << __pos); }
  347. _GLIBCXX23_CONSTEXPR
  348. bitset<_Nb>
  349. operator>>(size_t __pos) const _GLIBCXX_NOEXCEPT
  350. { return bitset<_Nb>(_M_base() >> __pos); }
  351. _GLIBCXX23_CONSTEXPR
  352. _Base&
  353. _M_base() _GLIBCXX_NOEXCEPT
  354. { return *this; }
  355. _GLIBCXX23_CONSTEXPR
  356. const _Base&
  357. _M_base() const _GLIBCXX_NOEXCEPT
  358. { return *this; }
  359. };
  360. template<size_t _Nb>
  361. _GLIBCXX23_CONSTEXPR
  362. inline bitset<_Nb>
  363. operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT
  364. { return bitset<_Nb>(__x) &= __y; }
  365. template<size_t _Nb>
  366. _GLIBCXX23_CONSTEXPR
  367. inline bitset<_Nb>
  368. operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT
  369. { return bitset<_Nb>(__x) |= __y; }
  370. template<size_t _Nb>
  371. _GLIBCXX23_CONSTEXPR
  372. inline bitset<_Nb>
  373. operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT
  374. { return bitset<_Nb>(__x) ^= __y; }
  375. template<typename _CharT, typename _Traits, size_t _Nb>
  376. inline std::basic_istream<_CharT, _Traits>&
  377. operator>>(std::basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x)
  378. { return __is >> __x._M_base(); }
  379. template<typename _CharT, typename _Traits, size_t _Nb>
  380. inline std::basic_ostream<_CharT, _Traits>&
  381. operator<<(std::basic_ostream<_CharT, _Traits>& __os,
  382. const bitset<_Nb>& __x)
  383. { return __os << __x._M_base(); }
  384. } // namespace __debug
  385. #if __cplusplus >= 201103L
  386. // DR 1182.
  387. /// std::hash specialization for bitset.
  388. template<size_t _Nb>
  389. struct hash<__debug::bitset<_Nb>>
  390. : public __hash_base<size_t, __debug::bitset<_Nb>>
  391. {
  392. size_t
  393. operator()(const __debug::bitset<_Nb>& __b) const noexcept
  394. { return std::hash<_GLIBCXX_STD_C::bitset<_Nb>>()(__b._M_base()); }
  395. };
  396. #endif
  397. } // namespace std
  398. #endif