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.

281 lines
8.7KB

  1. // TR2 <dynamic_bitset> -*- C++ -*-
  2. // Copyright (C) 2009-2020 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 tr2/dynamic_bitset.tcc
  21. * This is an internal header file, included by other library headers.
  22. * Do not attempt to use it directly. @headername{tr2/dynamic_bitset}
  23. */
  24. #ifndef _GLIBCXX_TR2_DYNAMIC_BITSET_TCC
  25. #define _GLIBCXX_TR2_DYNAMIC_BITSET_TCC 1
  26. #pragma GCC system_header
  27. namespace std _GLIBCXX_VISIBILITY(default)
  28. {
  29. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  30. namespace tr2
  31. {
  32. // Definitions of non-inline functions from __dynamic_bitset_base.
  33. template<typename _WordT, typename _Alloc>
  34. void
  35. __dynamic_bitset_base<_WordT, _Alloc>::_M_do_left_shift(size_t __shift)
  36. {
  37. if (__builtin_expect(__shift != 0, 1))
  38. {
  39. const size_t __wshift = __shift / _S_bits_per_block;
  40. const size_t __offset = __shift % _S_bits_per_block;
  41. if (__offset == 0)
  42. for (size_t __n = this->_M_w.size() - 1; __n >= __wshift; --__n)
  43. this->_M_w[__n] = this->_M_w[__n - __wshift];
  44. else
  45. {
  46. const size_t __sub_offset = _S_bits_per_block - __offset;
  47. for (size_t __n = _M_w.size() - 1; __n > __wshift; --__n)
  48. this->_M_w[__n] = ((this->_M_w[__n - __wshift] << __offset)
  49. | (this->_M_w[__n - __wshift - 1] >> __sub_offset));
  50. this->_M_w[__wshift] = this->_M_w[0] << __offset;
  51. }
  52. //// std::fill(this->_M_w.begin(), this->_M_w.begin() + __wshift,
  53. //// static_cast<_WordT>(0));
  54. }
  55. }
  56. template<typename _WordT, typename _Alloc>
  57. void
  58. __dynamic_bitset_base<_WordT, _Alloc>::_M_do_right_shift(size_t __shift)
  59. {
  60. if (__builtin_expect(__shift != 0, 1))
  61. {
  62. const size_t __wshift = __shift / _S_bits_per_block;
  63. const size_t __offset = __shift % _S_bits_per_block;
  64. const size_t __limit = this->_M_w.size() - __wshift - 1;
  65. if (__offset == 0)
  66. for (size_t __n = 0; __n <= __limit; ++__n)
  67. this->_M_w[__n] = this->_M_w[__n + __wshift];
  68. else
  69. {
  70. const size_t __sub_offset = (_S_bits_per_block
  71. - __offset);
  72. for (size_t __n = 0; __n < __limit; ++__n)
  73. this->_M_w[__n] = ((this->_M_w[__n + __wshift] >> __offset)
  74. | (this->_M_w[__n + __wshift + 1] << __sub_offset));
  75. this->_M_w[__limit] = this->_M_w[_M_w.size()-1] >> __offset;
  76. }
  77. ////std::fill(this->_M_w.begin() + __limit + 1, this->_M_w.end(),
  78. //// static_cast<_WordT>(0));
  79. }
  80. }
  81. template<typename _WordT, typename _Alloc>
  82. unsigned long
  83. __dynamic_bitset_base<_WordT, _Alloc>::_M_do_to_ulong() const
  84. {
  85. size_t __n = sizeof(unsigned long) / sizeof(block_type);
  86. for (size_t __i = __n; __i < this->_M_w.size(); ++__i)
  87. if (this->_M_w[__i])
  88. __throw_overflow_error(__N("__dynamic_bitset_base::_M_do_to_ulong"));
  89. unsigned long __res = 0UL;
  90. for (size_t __i = 0; __i < __n && __i < this->_M_w.size(); ++__i)
  91. __res += this->_M_w[__i] << (__i * _S_bits_per_block);
  92. return __res;
  93. }
  94. template<typename _WordT, typename _Alloc>
  95. unsigned long long
  96. __dynamic_bitset_base<_WordT, _Alloc>::_M_do_to_ullong() const
  97. {
  98. size_t __n = sizeof(unsigned long long) / sizeof(block_type);
  99. for (size_t __i = __n; __i < this->_M_w.size(); ++__i)
  100. if (this->_M_w[__i])
  101. __throw_overflow_error(__N("__dynamic_bitset_base::_M_do_to_ullong"));
  102. unsigned long long __res = 0ULL;
  103. for (size_t __i = 0; __i < __n && __i < this->_M_w.size(); ++__i)
  104. __res += this->_M_w[__i] << (__i * _S_bits_per_block);
  105. return __res;
  106. }
  107. template<typename _WordT, typename _Alloc>
  108. size_t
  109. __dynamic_bitset_base<_WordT, _Alloc>
  110. ::_M_do_find_first(size_t __not_found) const
  111. {
  112. for (size_t __i = 0; __i < this->_M_w.size(); ++__i)
  113. {
  114. _WordT __thisword = this->_M_w[__i];
  115. if (__thisword != static_cast<_WordT>(0))
  116. return (__i * _S_bits_per_block
  117. + __builtin_ctzll(__thisword));
  118. }
  119. // not found, so return an indication of failure.
  120. return __not_found;
  121. }
  122. template<typename _WordT, typename _Alloc>
  123. size_t
  124. __dynamic_bitset_base<_WordT, _Alloc>
  125. ::_M_do_find_next(size_t __prev, size_t __not_found) const
  126. {
  127. // make bound inclusive
  128. ++__prev;
  129. // check out of bounds
  130. if (__prev >= this->_M_w.size() * _S_bits_per_block)
  131. return __not_found;
  132. // search first word
  133. size_t __i = _S_whichword(__prev);
  134. _WordT __thisword = this->_M_w[__i];
  135. // mask off bits below bound
  136. __thisword &= (~static_cast<_WordT>(0)) << _S_whichbit(__prev);
  137. if (__thisword != static_cast<_WordT>(0))
  138. return (__i * _S_bits_per_block
  139. + __builtin_ctzll(__thisword));
  140. // check subsequent words
  141. for (++__i; __i < this->_M_w.size(); ++__i)
  142. {
  143. __thisword = this->_M_w[__i];
  144. if (__thisword != static_cast<_WordT>(0))
  145. return (__i * _S_bits_per_block
  146. + __builtin_ctzll(__thisword));
  147. }
  148. // not found, so return an indication of failure.
  149. return __not_found;
  150. } // end _M_do_find_next
  151. // Definitions of non-inline member functions.
  152. template<typename _WordT, typename _Alloc>
  153. template<typename _Traits, typename _CharT>
  154. void
  155. dynamic_bitset<_WordT, _Alloc>::
  156. _M_copy_from_ptr(const _CharT* __str, size_t __len,
  157. size_t __pos, size_t __n, _CharT __zero, _CharT __one)
  158. {
  159. reset();
  160. const size_t __nbits = std::min(_M_Nb, std::min(__n, __len - __pos));
  161. for (size_t __i = __nbits; __i > 0; --__i)
  162. {
  163. const _CharT __c = __str[__pos + __nbits - __i];
  164. if (_Traits::eq(__c, __zero))
  165. ;
  166. else if (_Traits::eq(__c, __one))
  167. _M_unchecked_set(__i - 1);
  168. else
  169. __throw_invalid_argument(__N("dynamic_bitset::_M_copy_from_ptr"));
  170. }
  171. }
  172. /**
  173. * @brief Stream input operator for dynamic_bitset.
  174. * @ingroup dynamic_bitset
  175. *
  176. * Input will skip whitespace and only accept '0' and '1' characters.
  177. * The %dynamic_bitset will grow as necessary to hold the string of bits.
  178. */
  179. template<typename _CharT, typename _Traits,
  180. typename _WordT, typename _Alloc>
  181. std::basic_istream<_CharT, _Traits>&
  182. operator>>(std::basic_istream<_CharT, _Traits>& __is,
  183. dynamic_bitset<_WordT, _Alloc>& __x)
  184. {
  185. typedef typename _Traits::char_type char_type;
  186. typedef std::basic_istream<_CharT, _Traits> __istream_type;
  187. typedef typename __istream_type::ios_base __ios_base;
  188. std::basic_string<_CharT, _Traits> __tmp;
  189. __tmp.reserve(__x.size());
  190. const char_type __zero = __is.widen('0');
  191. const char_type __one = __is.widen('1');
  192. typename __ios_base::iostate __state = __ios_base::goodbit;
  193. typename __istream_type::sentry __sentry(__is);
  194. if (__sentry)
  195. {
  196. __try
  197. {
  198. while (1)
  199. {
  200. static typename _Traits::int_type __eof = _Traits::eof();
  201. typename _Traits::int_type __c1 = __is.rdbuf()->sbumpc();
  202. if (_Traits::eq_int_type(__c1, __eof))
  203. {
  204. __state |= __ios_base::eofbit;
  205. break;
  206. }
  207. else
  208. {
  209. const char_type __c2 = _Traits::to_char_type(__c1);
  210. if (_Traits::eq(__c2, __zero))
  211. __tmp.push_back(__zero);
  212. else if (_Traits::eq(__c2, __one))
  213. __tmp.push_back(__one);
  214. else if (_Traits::
  215. eq_int_type(__is.rdbuf()->sputbackc(__c2),
  216. __eof))
  217. {
  218. __state |= __ios_base::failbit;
  219. break;
  220. }
  221. else
  222. break;
  223. }
  224. }
  225. }
  226. __catch(__cxxabiv1::__forced_unwind&)
  227. {
  228. __is._M_setstate(__ios_base::badbit);
  229. __throw_exception_again;
  230. }
  231. __catch(...)
  232. { __is._M_setstate(__ios_base::badbit); }
  233. }
  234. __x.resize(__tmp.size());
  235. if (__tmp.empty() && __x.size())
  236. __state |= __ios_base::failbit;
  237. else
  238. __x._M_copy_from_string(__tmp, static_cast<size_t>(0), __x.size(),
  239. __zero, __one);
  240. if (__state)
  241. __is.setstate(__state);
  242. return __is;
  243. }
  244. } // tr2
  245. _GLIBCXX_END_NAMESPACE_VERSION
  246. } // std
  247. #endif /* _GLIBCXX_TR2_DYNAMIC_BITSET_TCC */