]>
Commit | Line | Data |
---|---|---|
54c1bf78 | 1 | // <bitset> -*- C++ -*- |
de96ac46 | 2 | |
7adcbafe | 3 | // Copyright (C) 2001-2022 Free Software Foundation, Inc. |
de96ac46 BK |
4 | // |
5 | // This file is part of the GNU ISO C++ Library. This library is free | |
6 | // software; you can redistribute it and/or modify it under the | |
7 | // terms of the GNU General Public License as published by the | |
748086b7 | 8 | // Free Software Foundation; either version 3, or (at your option) |
de96ac46 BK |
9 | // any later version. |
10 | ||
11 | // This library is distributed in the hope that it will be useful, | |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | // GNU General Public License for more details. | |
15 | ||
748086b7 JJ |
16 | // Under Section 7 of GPL version 3, you are granted additional |
17 | // permissions described in the GCC Runtime Library Exception, version | |
18 | // 3.1, as published by the Free Software Foundation. | |
de96ac46 | 19 | |
748086b7 JJ |
20 | // You should have received a copy of the GNU General Public License and |
21 | // a copy of the GCC Runtime Library Exception along with this program; | |
22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
23 | // <http://www.gnu.org/licenses/>. | |
de96ac46 | 24 | |
54c1bf78 BK |
25 | /* |
26 | * Copyright (c) 1998 | |
27 | * Silicon Graphics Computer Systems, Inc. | |
28 | * | |
29 | * Permission to use, copy, modify, distribute and sell this software | |
30 | * and its documentation for any purpose is hereby granted without fee, | |
31 | * provided that the above copyright notice appear in all copies and | |
32 | * that both that copyright notice and this permission notice appear | |
33 | * in supporting documentation. Silicon Graphics makes no | |
34 | * representations about the suitability of this software for any | |
35 | * purpose. It is provided "as is" without express or implied warranty. | |
b963aad8 | 36 | */ |
54c1bf78 | 37 | |
143c27b0 | 38 | /** @file include/bitset |
0aa06b18 | 39 | * This is a Standard C++ Library header. |
2f9d51b8 PE |
40 | */ |
41 | ||
1143680e SE |
42 | #ifndef _GLIBCXX_BITSET |
43 | #define _GLIBCXX_BITSET 1 | |
54c1bf78 BK |
44 | |
45 | #pragma GCC system_header | |
46 | ||
285b36d6 | 47 | #include <bits/functexcept.h> // For invalid_argument, out_of_range, |
b963aad8 | 48 | // overflow_error |
9194c139 JW |
49 | #if _GLIBCXX_HOSTED |
50 | # include <string> | |
51 | # include <iosfwd> | |
52 | # include <bits/cxxabi_forced.h> | |
53 | # if __cplusplus >= 201103L | |
54 | # include <bits/functional_hash.h> | |
55 | # endif | |
5dfb5e5b FD |
56 | #endif |
57 | ||
5da7fa30 | 58 | #define _GLIBCXX_BITSET_BITS_PER_WORD (__CHAR_BIT__ * __SIZEOF_LONG__) |
3d7c150e | 59 | #define _GLIBCXX_BITSET_WORDS(__n) \ |
fc99f780 LH |
60 | ((__n) / _GLIBCXX_BITSET_BITS_PER_WORD + \ |
61 | ((__n) % _GLIBCXX_BITSET_BITS_PER_WORD == 0 ? 0 : 1)) | |
54c1bf78 | 62 | |
5da7fa30 PC |
63 | #define _GLIBCXX_BITSET_BITS_PER_ULL (__CHAR_BIT__ * __SIZEOF_LONG_LONG__) |
64 | ||
12ffa228 BK |
65 | namespace std _GLIBCXX_VISIBILITY(default) |
66 | { | |
67 | _GLIBCXX_BEGIN_NAMESPACE_CONTAINER | |
3cbc7af0 | 68 | |
9194c139 JW |
69 | #if __cplusplus > 202002L && _GLIBCXX_HOSTED |
70 | # define __cpp_lib_constexpr_bitset 202202L | |
71 | #endif | |
72 | ||
b963aad8 | 73 | /** |
28dac70a | 74 | * Base class, general case. It is a class invariant that _Nw will be |
b963aad8 PE |
75 | * nonnegative. |
76 | * | |
77 | * See documentation for bitset. | |
b963aad8 | 78 | */ |
1cb7f91f | 79 | template<size_t _Nw> |
b963aad8 | 80 | struct _Base_bitset |
1cb7f91f BK |
81 | { |
82 | typedef unsigned long _WordT; | |
83 | ||
b963aad8 PE |
84 | /// 0 is the least significant word. |
85 | _WordT _M_w[_Nw]; | |
86 | ||
5d861bf2 | 87 | _GLIBCXX_CONSTEXPR _Base_bitset() _GLIBCXX_NOEXCEPT |
b6710d1a | 88 | : _M_w() { } |
94a86be0 | 89 | |
734f5023 | 90 | #if __cplusplus >= 201103L |
5d861bf2 | 91 | constexpr _Base_bitset(unsigned long long __val) noexcept |
9f1163b1 | 92 | : _M_w{ _WordT(__val) |
94a86be0 | 93 | #if __SIZEOF_LONG_LONG__ > __SIZEOF_LONG__ |
7350a361 | 94 | , _WordT(__val >> _GLIBCXX_BITSET_BITS_PER_WORD) |
94a86be0 | 95 | #endif |
9f1163b1 | 96 | } { } |
94a86be0 | 97 | #else |
b963aad8 | 98 | _Base_bitset(unsigned long __val) |
b6710d1a PC |
99 | : _M_w() |
100 | { _M_w[0] = __val; } | |
94a86be0 | 101 | #endif |
54c1bf78 | 102 | |
94a86be0 | 103 | static _GLIBCXX_CONSTEXPR size_t |
6aa67e7b | 104 | _S_whichword(size_t __pos) _GLIBCXX_NOEXCEPT |
3d7c150e | 105 | { return __pos / _GLIBCXX_BITSET_BITS_PER_WORD; } |
54c1bf78 | 106 | |
94a86be0 | 107 | static _GLIBCXX_CONSTEXPR size_t |
6aa67e7b | 108 | _S_whichbyte(size_t __pos) _GLIBCXX_NOEXCEPT |
3d7c150e | 109 | { return (__pos % _GLIBCXX_BITSET_BITS_PER_WORD) / __CHAR_BIT__; } |
54c1bf78 | 110 | |
94a86be0 | 111 | static _GLIBCXX_CONSTEXPR size_t |
6aa67e7b | 112 | _S_whichbit(size_t __pos) _GLIBCXX_NOEXCEPT |
3d7c150e | 113 | { return __pos % _GLIBCXX_BITSET_BITS_PER_WORD; } |
54c1bf78 | 114 | |
94a86be0 | 115 | static _GLIBCXX_CONSTEXPR _WordT |
6aa67e7b | 116 | _S_maskbit(size_t __pos) _GLIBCXX_NOEXCEPT |
1cb7f91f | 117 | { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); } |
54c1bf78 | 118 | |
9194c139 | 119 | _GLIBCXX14_CONSTEXPR _WordT& |
5d861bf2 | 120 | _M_getword(size_t __pos) _GLIBCXX_NOEXCEPT |
1cb7f91f | 121 | { return _M_w[_S_whichword(__pos)]; } |
54c1bf78 | 122 | |
07be6120 | 123 | _GLIBCXX_CONSTEXPR _WordT |
5d861bf2 | 124 | _M_getword(size_t __pos) const _GLIBCXX_NOEXCEPT |
1cb7f91f | 125 | { return _M_w[_S_whichword(__pos)]; } |
54c1bf78 | 126 | |
734f5023 | 127 | #if __cplusplus >= 201103L |
9194c139 | 128 | constexpr const _WordT* |
5d861bf2 | 129 | _M_getdata() const noexcept |
055f6a47 | 130 | { return _M_w; } |
ec7058d6 PC |
131 | #endif |
132 | ||
9194c139 | 133 | _GLIBCXX23_CONSTEXPR _WordT& |
5d861bf2 | 134 | _M_hiword() _GLIBCXX_NOEXCEPT |
5c33bb62 | 135 | { return _M_w[_Nw - 1]; } |
54c1bf78 | 136 | |
94a86be0 | 137 | _GLIBCXX_CONSTEXPR _WordT |
5d861bf2 | 138 | _M_hiword() const _GLIBCXX_NOEXCEPT |
5c33bb62 | 139 | { return _M_w[_Nw - 1]; } |
54c1bf78 | 140 | |
9194c139 | 141 | _GLIBCXX23_CONSTEXPR void |
5d861bf2 | 142 | _M_do_and(const _Base_bitset<_Nw>& __x) _GLIBCXX_NOEXCEPT |
1cb7f91f | 143 | { |
b963aad8 | 144 | for (size_t __i = 0; __i < _Nw; __i++) |
1cb7f91f BK |
145 | _M_w[__i] &= __x._M_w[__i]; |
146 | } | |
54c1bf78 | 147 | |
9194c139 | 148 | _GLIBCXX14_CONSTEXPR void |
5d861bf2 | 149 | _M_do_or(const _Base_bitset<_Nw>& __x) _GLIBCXX_NOEXCEPT |
1cb7f91f | 150 | { |
b963aad8 | 151 | for (size_t __i = 0; __i < _Nw; __i++) |
1cb7f91f BK |
152 | _M_w[__i] |= __x._M_w[__i]; |
153 | } | |
54c1bf78 | 154 | |
9194c139 | 155 | _GLIBCXX14_CONSTEXPR void |
5d861bf2 | 156 | _M_do_xor(const _Base_bitset<_Nw>& __x) _GLIBCXX_NOEXCEPT |
1cb7f91f BK |
157 | { |
158 | for (size_t __i = 0; __i < _Nw; __i++) | |
159 | _M_w[__i] ^= __x._M_w[__i]; | |
160 | } | |
54c1bf78 | 161 | |
9194c139 | 162 | _GLIBCXX14_CONSTEXPR void |
5d861bf2 | 163 | _M_do_left_shift(size_t __shift) _GLIBCXX_NOEXCEPT; |
1cb7f91f | 164 | |
9194c139 | 165 | _GLIBCXX14_CONSTEXPR void |
5d861bf2 | 166 | _M_do_right_shift(size_t __shift) _GLIBCXX_NOEXCEPT; |
b963aad8 | 167 | |
9194c139 | 168 | _GLIBCXX14_CONSTEXPR void |
5d861bf2 | 169 | _M_do_flip() _GLIBCXX_NOEXCEPT |
1cb7f91f | 170 | { |
b963aad8 | 171 | for (size_t __i = 0; __i < _Nw; __i++) |
1cb7f91f BK |
172 | _M_w[__i] = ~_M_w[__i]; |
173 | } | |
54c1bf78 | 174 | |
9194c139 | 175 | _GLIBCXX14_CONSTEXPR void |
5d861bf2 | 176 | _M_do_set() _GLIBCXX_NOEXCEPT |
1cb7f91f BK |
177 | { |
178 | for (size_t __i = 0; __i < _Nw; __i++) | |
179 | _M_w[__i] = ~static_cast<_WordT>(0); | |
180 | } | |
54c1bf78 | 181 | |
9194c139 | 182 | _GLIBCXX14_CONSTEXPR void |
5d861bf2 | 183 | _M_do_reset() _GLIBCXX_NOEXCEPT |
9194c139 JW |
184 | { |
185 | if (__builtin_is_constant_evaluated()) | |
186 | { | |
187 | for (_WordT& __w : _M_w) | |
188 | __w = 0; | |
189 | return; | |
190 | } | |
1cb7f91f | 191 | |
9194c139 JW |
192 | __builtin_memset(_M_w, 0, _Nw * sizeof(_WordT)); |
193 | } | |
194 | ||
195 | _GLIBCXX14_CONSTEXPR bool | |
5d861bf2 | 196 | _M_is_equal(const _Base_bitset<_Nw>& __x) const _GLIBCXX_NOEXCEPT |
1cb7f91f | 197 | { |
b963aad8 | 198 | for (size_t __i = 0; __i < _Nw; ++__i) |
b96817da PC |
199 | if (_M_w[__i] != __x._M_w[__i]) |
200 | return false; | |
1cb7f91f BK |
201 | return true; |
202 | } | |
54c1bf78 | 203 | |
0217ac04 | 204 | template<size_t _Nb> |
9194c139 | 205 | _GLIBCXX14_CONSTEXPR bool |
0217ac04 PC |
206 | _M_are_all() const _GLIBCXX_NOEXCEPT |
207 | { | |
208 | for (size_t __i = 0; __i < _Nw - 1; __i++) | |
209 | if (_M_w[__i] != ~static_cast<_WordT>(0)) | |
210 | return false; | |
211 | return _M_hiword() == (~static_cast<_WordT>(0) | |
212 | >> (_Nw * _GLIBCXX_BITSET_BITS_PER_WORD | |
213 | - _Nb)); | |
214 | } | |
b96817da | 215 | |
9194c139 | 216 | _GLIBCXX14_CONSTEXPR bool |
5d861bf2 | 217 | _M_is_any() const _GLIBCXX_NOEXCEPT |
1cb7f91f | 218 | { |
b963aad8 | 219 | for (size_t __i = 0; __i < _Nw; __i++) |
b96817da PC |
220 | if (_M_w[__i] != static_cast<_WordT>(0)) |
221 | return true; | |
1cb7f91f BK |
222 | return false; |
223 | } | |
54c1bf78 | 224 | |
9194c139 | 225 | _GLIBCXX14_CONSTEXPR size_t |
5d861bf2 | 226 | _M_do_count() const _GLIBCXX_NOEXCEPT |
1cb7f91f BK |
227 | { |
228 | size_t __result = 0; | |
348b0c31 FH |
229 | for (size_t __i = 0; __i < _Nw; __i++) |
230 | __result += __builtin_popcountl(_M_w[__i]); | |
1cb7f91f BK |
231 | return __result; |
232 | } | |
54c1bf78 | 233 | |
9194c139 | 234 | _GLIBCXX14_CONSTEXPR unsigned long |
b963aad8 | 235 | _M_do_to_ulong() const; |
1cb7f91f | 236 | |
734f5023 | 237 | #if __cplusplus >= 201103L |
9194c139 | 238 | _GLIBCXX14_CONSTEXPR unsigned long long |
700d2899 PC |
239 | _M_do_to_ullong() const; |
240 | #endif | |
241 | ||
1cb7f91f | 242 | // find first "on" bit |
9194c139 | 243 | _GLIBCXX14_CONSTEXPR size_t |
07be6120 | 244 | _M_do_find_first(size_t) const _GLIBCXX_NOEXCEPT; |
1cb7f91f BK |
245 | |
246 | // find the next "on" bit that follows "prev" | |
9194c139 | 247 | _GLIBCXX14_CONSTEXPR size_t |
07be6120 | 248 | _M_do_find_next(size_t, size_t) const _GLIBCXX_NOEXCEPT; |
1cb7f91f BK |
249 | }; |
250 | ||
251 | // Definitions of non-inline functions from _Base_bitset. | |
252 | template<size_t _Nw> | |
9194c139 | 253 | _GLIBCXX14_CONSTEXPR void |
5d861bf2 | 254 | _Base_bitset<_Nw>::_M_do_left_shift(size_t __shift) _GLIBCXX_NOEXCEPT |
1cb7f91f | 255 | { |
3bbfb3d9 | 256 | if (__builtin_expect(__shift != 0, 1)) |
1cb7f91f | 257 | { |
3d7c150e BK |
258 | const size_t __wshift = __shift / _GLIBCXX_BITSET_BITS_PER_WORD; |
259 | const size_t __offset = __shift % _GLIBCXX_BITSET_BITS_PER_WORD; | |
b963aad8 | 260 | |
1cb7f91f BK |
261 | if (__offset == 0) |
262 | for (size_t __n = _Nw - 1; __n >= __wshift; --__n) | |
263 | _M_w[__n] = _M_w[__n - __wshift]; | |
b963aad8 | 264 | else |
1cb7f91f | 265 | { |
33ac58d5 | 266 | const size_t __sub_offset = (_GLIBCXX_BITSET_BITS_PER_WORD |
5c33bb62 | 267 | - __offset); |
1cb7f91f | 268 | for (size_t __n = _Nw - 1; __n > __wshift; --__n) |
5c33bb62 PC |
269 | _M_w[__n] = ((_M_w[__n - __wshift] << __offset) |
270 | | (_M_w[__n - __wshift - 1] >> __sub_offset)); | |
1cb7f91f BK |
271 | _M_w[__wshift] = _M_w[0] << __offset; |
272 | } | |
b963aad8 | 273 | |
a8cad3e1 | 274 | std::fill(_M_w + 0, _M_w + __wshift, static_cast<_WordT>(0)); |
1cb7f91f | 275 | } |
54c1bf78 | 276 | } |
b963aad8 | 277 | |
1cb7f91f | 278 | template<size_t _Nw> |
9194c139 | 279 | _GLIBCXX14_CONSTEXPR void |
5d861bf2 | 280 | _Base_bitset<_Nw>::_M_do_right_shift(size_t __shift) _GLIBCXX_NOEXCEPT |
1cb7f91f | 281 | { |
3bbfb3d9 | 282 | if (__builtin_expect(__shift != 0, 1)) |
1cb7f91f | 283 | { |
3d7c150e BK |
284 | const size_t __wshift = __shift / _GLIBCXX_BITSET_BITS_PER_WORD; |
285 | const size_t __offset = __shift % _GLIBCXX_BITSET_BITS_PER_WORD; | |
1cb7f91f | 286 | const size_t __limit = _Nw - __wshift - 1; |
b963aad8 | 287 | |
1cb7f91f BK |
288 | if (__offset == 0) |
289 | for (size_t __n = 0; __n <= __limit; ++__n) | |
290 | _M_w[__n] = _M_w[__n + __wshift]; | |
b963aad8 | 291 | else |
1cb7f91f | 292 | { |
5c33bb62 PC |
293 | const size_t __sub_offset = (_GLIBCXX_BITSET_BITS_PER_WORD |
294 | - __offset); | |
1cb7f91f | 295 | for (size_t __n = 0; __n < __limit; ++__n) |
5c33bb62 PC |
296 | _M_w[__n] = ((_M_w[__n + __wshift] >> __offset) |
297 | | (_M_w[__n + __wshift + 1] << __sub_offset)); | |
1cb7f91f BK |
298 | _M_w[__limit] = _M_w[_Nw-1] >> __offset; |
299 | } | |
33ac58d5 | 300 | |
a8cad3e1 | 301 | std::fill(_M_w + __limit + 1, _M_w + _Nw, static_cast<_WordT>(0)); |
1cb7f91f | 302 | } |
54c1bf78 | 303 | } |
54c1bf78 | 304 | |
1cb7f91f | 305 | template<size_t _Nw> |
9194c139 | 306 | _GLIBCXX14_CONSTEXPR unsigned long |
1cb7f91f BK |
307 | _Base_bitset<_Nw>::_M_do_to_ulong() const |
308 | { | |
b963aad8 PE |
309 | for (size_t __i = 1; __i < _Nw; ++__i) |
310 | if (_M_w[__i]) | |
988ad90d | 311 | __throw_overflow_error(__N("_Base_bitset::_M_do_to_ulong")); |
1cb7f91f | 312 | return _M_w[0]; |
54c1bf78 | 313 | } |
54c1bf78 | 314 | |
734f5023 | 315 | #if __cplusplus >= 201103L |
700d2899 | 316 | template<size_t _Nw> |
9194c139 | 317 | _GLIBCXX14_CONSTEXPR unsigned long long |
700d2899 PC |
318 | _Base_bitset<_Nw>::_M_do_to_ullong() const |
319 | { | |
320 | const bool __dw = sizeof(unsigned long long) > sizeof(unsigned long); | |
321 | for (size_t __i = 1 + __dw; __i < _Nw; ++__i) | |
322 | if (_M_w[__i]) | |
323 | __throw_overflow_error(__N("_Base_bitset::_M_do_to_ullong")); | |
324 | ||
325 | if (__dw) | |
326 | return _M_w[0] + (static_cast<unsigned long long>(_M_w[1]) | |
327 | << _GLIBCXX_BITSET_BITS_PER_WORD); | |
328 | return _M_w[0]; | |
329 | } | |
330 | #endif | |
331 | ||
1cb7f91f | 332 | template<size_t _Nw> |
9194c139 | 333 | _GLIBCXX14_CONSTEXPR size_t |
5d861bf2 PC |
334 | _Base_bitset<_Nw>:: |
335 | _M_do_find_first(size_t __not_found) const _GLIBCXX_NOEXCEPT | |
1cb7f91f | 336 | { |
348b0c31 | 337 | for (size_t __i = 0; __i < _Nw; __i++) |
1cb7f91f BK |
338 | { |
339 | _WordT __thisword = _M_w[__i]; | |
348b0c31 | 340 | if (__thisword != static_cast<_WordT>(0)) |
5c33bb62 PC |
341 | return (__i * _GLIBCXX_BITSET_BITS_PER_WORD |
342 | + __builtin_ctzl(__thisword)); | |
1cb7f91f BK |
343 | } |
344 | // not found, so return an indication of failure. | |
345 | return __not_found; | |
54c1bf78 BK |
346 | } |
347 | ||
1cb7f91f | 348 | template<size_t _Nw> |
9194c139 | 349 | _GLIBCXX14_CONSTEXPR size_t |
5d861bf2 PC |
350 | _Base_bitset<_Nw>:: |
351 | _M_do_find_next(size_t __prev, size_t __not_found) const _GLIBCXX_NOEXCEPT | |
b963aad8 | 352 | { |
1cb7f91f BK |
353 | // make bound inclusive |
354 | ++__prev; | |
b963aad8 | 355 | |
1cb7f91f | 356 | // check out of bounds |
394ef95e | 357 | if (__prev >= _Nw * _GLIBCXX_BITSET_BITS_PER_WORD) |
1cb7f91f | 358 | return __not_found; |
b963aad8 | 359 | |
1cb7f91f BK |
360 | // search first word |
361 | size_t __i = _S_whichword(__prev); | |
362 | _WordT __thisword = _M_w[__i]; | |
b963aad8 | 363 | |
1cb7f91f | 364 | // mask off bits below bound |
394ef95e | 365 | __thisword &= (~static_cast<_WordT>(0)) << _S_whichbit(__prev); |
b963aad8 | 366 | |
348b0c31 | 367 | if (__thisword != static_cast<_WordT>(0)) |
5c33bb62 PC |
368 | return (__i * _GLIBCXX_BITSET_BITS_PER_WORD |
369 | + __builtin_ctzl(__thisword)); | |
b963aad8 | 370 | |
1cb7f91f BK |
371 | // check subsequent words |
372 | __i++; | |
5c33bb62 | 373 | for (; __i < _Nw; __i++) |
1cb7f91f BK |
374 | { |
375 | __thisword = _M_w[__i]; | |
348b0c31 | 376 | if (__thisword != static_cast<_WordT>(0)) |
5c33bb62 PC |
377 | return (__i * _GLIBCXX_BITSET_BITS_PER_WORD |
378 | + __builtin_ctzl(__thisword)); | |
1cb7f91f BK |
379 | } |
380 | // not found, so return an indication of failure. | |
381 | return __not_found; | |
382 | } // end _M_do_find_next | |
54c1bf78 | 383 | |
b963aad8 | 384 | /** |
b963aad8 PE |
385 | * Base class, specialization for a single word. |
386 | * | |
387 | * See documentation for bitset. | |
b963aad8 PE |
388 | */ |
389 | template<> | |
390 | struct _Base_bitset<1> | |
1cb7f91f BK |
391 | { |
392 | typedef unsigned long _WordT; | |
393 | _WordT _M_w; | |
54c1bf78 | 394 | |
5d861bf2 | 395 | _GLIBCXX_CONSTEXPR _Base_bitset() _GLIBCXX_NOEXCEPT |
5c33bb62 | 396 | : _M_w(0) |
5a4db26d | 397 | { } |
5c33bb62 | 398 | |
734f5023 | 399 | #if __cplusplus >= 201103L |
5d861bf2 | 400 | constexpr _Base_bitset(unsigned long long __val) noexcept |
0d6f2a80 | 401 | #else |
5c33bb62 | 402 | _Base_bitset(unsigned long __val) |
0d6f2a80 | 403 | #endif |
5c33bb62 | 404 | : _M_w(__val) |
5a4db26d | 405 | { } |
54c1bf78 | 406 | |
94a86be0 | 407 | static _GLIBCXX_CONSTEXPR size_t |
6aa67e7b | 408 | _S_whichword(size_t __pos) _GLIBCXX_NOEXCEPT |
3d7c150e | 409 | { return __pos / _GLIBCXX_BITSET_BITS_PER_WORD; } |
54c1bf78 | 410 | |
94a86be0 | 411 | static _GLIBCXX_CONSTEXPR size_t |
6aa67e7b | 412 | _S_whichbyte(size_t __pos) _GLIBCXX_NOEXCEPT |
3d7c150e | 413 | { return (__pos % _GLIBCXX_BITSET_BITS_PER_WORD) / __CHAR_BIT__; } |
54c1bf78 | 414 | |
94a86be0 | 415 | static _GLIBCXX_CONSTEXPR size_t |
6aa67e7b | 416 | _S_whichbit(size_t __pos) _GLIBCXX_NOEXCEPT |
3d7c150e | 417 | { return __pos % _GLIBCXX_BITSET_BITS_PER_WORD; } |
54c1bf78 | 418 | |
94a86be0 | 419 | static _GLIBCXX_CONSTEXPR _WordT |
6aa67e7b | 420 | _S_maskbit(size_t __pos) _GLIBCXX_NOEXCEPT |
1cb7f91f | 421 | { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); } |
54c1bf78 | 422 | |
9194c139 | 423 | _GLIBCXX14_CONSTEXPR _WordT& |
5d861bf2 | 424 | _M_getword(size_t) _GLIBCXX_NOEXCEPT |
5c33bb62 | 425 | { return _M_w; } |
54c1bf78 | 426 | |
07be6120 | 427 | _GLIBCXX_CONSTEXPR _WordT |
5d861bf2 | 428 | _M_getword(size_t) const _GLIBCXX_NOEXCEPT |
5c33bb62 | 429 | { return _M_w; } |
54c1bf78 | 430 | |
734f5023 | 431 | #if __cplusplus >= 201103L |
9194c139 | 432 | constexpr const _WordT* |
5d861bf2 | 433 | _M_getdata() const noexcept |
055f6a47 | 434 | { return &_M_w; } |
ec7058d6 PC |
435 | #endif |
436 | ||
9194c139 | 437 | _GLIBCXX14_CONSTEXPR _WordT& |
5d861bf2 | 438 | _M_hiword() _GLIBCXX_NOEXCEPT |
5c33bb62 | 439 | { return _M_w; } |
54c1bf78 | 440 | |
94a86be0 | 441 | _GLIBCXX_CONSTEXPR _WordT |
5d861bf2 | 442 | _M_hiword() const _GLIBCXX_NOEXCEPT |
5c33bb62 | 443 | { return _M_w; } |
54c1bf78 | 444 | |
9194c139 | 445 | _GLIBCXX14_CONSTEXPR void |
5d861bf2 | 446 | _M_do_and(const _Base_bitset<1>& __x) _GLIBCXX_NOEXCEPT |
5c33bb62 | 447 | { _M_w &= __x._M_w; } |
54c1bf78 | 448 | |
9194c139 | 449 | _GLIBCXX14_CONSTEXPR void |
5d861bf2 | 450 | _M_do_or(const _Base_bitset<1>& __x) _GLIBCXX_NOEXCEPT |
5c33bb62 | 451 | { _M_w |= __x._M_w; } |
54c1bf78 | 452 | |
9194c139 | 453 | _GLIBCXX14_CONSTEXPR void |
5d861bf2 | 454 | _M_do_xor(const _Base_bitset<1>& __x) _GLIBCXX_NOEXCEPT |
5c33bb62 | 455 | { _M_w ^= __x._M_w; } |
54c1bf78 | 456 | |
9194c139 | 457 | _GLIBCXX14_CONSTEXPR void |
5d861bf2 | 458 | _M_do_left_shift(size_t __shift) _GLIBCXX_NOEXCEPT |
5c33bb62 | 459 | { _M_w <<= __shift; } |
54c1bf78 | 460 | |
9194c139 | 461 | _GLIBCXX14_CONSTEXPR void |
5d861bf2 | 462 | _M_do_right_shift(size_t __shift) _GLIBCXX_NOEXCEPT |
5c33bb62 | 463 | { _M_w >>= __shift; } |
54c1bf78 | 464 | |
9194c139 | 465 | _GLIBCXX14_CONSTEXPR void |
5d861bf2 | 466 | _M_do_flip() _GLIBCXX_NOEXCEPT |
5c33bb62 | 467 | { _M_w = ~_M_w; } |
54c1bf78 | 468 | |
9194c139 | 469 | _GLIBCXX14_CONSTEXPR void |
5d861bf2 | 470 | _M_do_set() _GLIBCXX_NOEXCEPT |
5c33bb62 | 471 | { _M_w = ~static_cast<_WordT>(0); } |
54c1bf78 | 472 | |
9194c139 | 473 | _GLIBCXX14_CONSTEXPR void |
5d861bf2 | 474 | _M_do_reset() _GLIBCXX_NOEXCEPT |
5c33bb62 | 475 | { _M_w = 0; } |
54c1bf78 | 476 | |
9194c139 | 477 | _GLIBCXX14_CONSTEXPR bool |
5d861bf2 | 478 | _M_is_equal(const _Base_bitset<1>& __x) const _GLIBCXX_NOEXCEPT |
1cb7f91f | 479 | { return _M_w == __x._M_w; } |
54c1bf78 | 480 | |
0217ac04 | 481 | template<size_t _Nb> |
9194c139 | 482 | _GLIBCXX14_CONSTEXPR bool |
0217ac04 PC |
483 | _M_are_all() const _GLIBCXX_NOEXCEPT |
484 | { return _M_w == (~static_cast<_WordT>(0) | |
485 | >> (_GLIBCXX_BITSET_BITS_PER_WORD - _Nb)); } | |
b96817da | 486 | |
9194c139 | 487 | _GLIBCXX14_CONSTEXPR bool |
5d861bf2 | 488 | _M_is_any() const _GLIBCXX_NOEXCEPT |
5c33bb62 | 489 | { return _M_w != 0; } |
54c1bf78 | 490 | |
9194c139 | 491 | _GLIBCXX14_CONSTEXPR size_t |
5d861bf2 | 492 | _M_do_count() const _GLIBCXX_NOEXCEPT |
5c33bb62 | 493 | { return __builtin_popcountl(_M_w); } |
54c1bf78 | 494 | |
9194c139 | 495 | _GLIBCXX14_CONSTEXPR unsigned long |
5d861bf2 | 496 | _M_do_to_ulong() const _GLIBCXX_NOEXCEPT |
5c33bb62 | 497 | { return _M_w; } |
1cb7f91f | 498 | |
734f5023 | 499 | #if __cplusplus >= 201103L |
9194c139 | 500 | constexpr unsigned long long |
5d861bf2 | 501 | _M_do_to_ullong() const noexcept |
700d2899 PC |
502 | { return _M_w; } |
503 | #endif | |
504 | ||
9194c139 | 505 | _GLIBCXX14_CONSTEXPR size_t |
5d861bf2 | 506 | _M_do_find_first(size_t __not_found) const _GLIBCXX_NOEXCEPT |
348b0c31 FH |
507 | { |
508 | if (_M_w != 0) | |
509 | return __builtin_ctzl(_M_w); | |
510 | else | |
511 | return __not_found; | |
512 | } | |
1cb7f91f BK |
513 | |
514 | // find the next "on" bit that follows "prev" | |
9194c139 | 515 | _GLIBCXX14_CONSTEXPR size_t |
348b0c31 | 516 | _M_do_find_next(size_t __prev, size_t __not_found) const |
5d861bf2 | 517 | _GLIBCXX_NOEXCEPT |
348b0c31 FH |
518 | { |
519 | ++__prev; | |
3d7c150e | 520 | if (__prev >= ((size_t) _GLIBCXX_BITSET_BITS_PER_WORD)) |
348b0c31 FH |
521 | return __not_found; |
522 | ||
523 | _WordT __x = _M_w >> __prev; | |
524 | if (__x != 0) | |
525 | return __builtin_ctzl(__x) + __prev; | |
526 | else | |
527 | return __not_found; | |
528 | } | |
1cb7f91f BK |
529 | }; |
530 | ||
bb12c809 | 531 | /** |
bb12c809 PE |
532 | * Base class, specialization for no storage (zero-length %bitset). |
533 | * | |
534 | * See documentation for bitset. | |
bb12c809 PE |
535 | */ |
536 | template<> | |
537 | struct _Base_bitset<0> | |
538 | { | |
539 | typedef unsigned long _WordT; | |
540 | ||
5d861bf2 | 541 | _GLIBCXX_CONSTEXPR _Base_bitset() _GLIBCXX_NOEXCEPT |
5a4db26d | 542 | { } |
5c33bb62 | 543 | |
734f5023 | 544 | #if __cplusplus >= 201103L |
5d861bf2 | 545 | constexpr _Base_bitset(unsigned long long) noexcept |
0d6f2a80 | 546 | #else |
5c33bb62 | 547 | _Base_bitset(unsigned long) |
0d6f2a80 | 548 | #endif |
5a4db26d | 549 | { } |
bb12c809 | 550 | |
94a86be0 | 551 | static _GLIBCXX_CONSTEXPR size_t |
6aa67e7b | 552 | _S_whichword(size_t __pos) _GLIBCXX_NOEXCEPT |
3d7c150e | 553 | { return __pos / _GLIBCXX_BITSET_BITS_PER_WORD; } |
bb12c809 | 554 | |
94a86be0 | 555 | static _GLIBCXX_CONSTEXPR size_t |
6aa67e7b | 556 | _S_whichbyte(size_t __pos) _GLIBCXX_NOEXCEPT |
3d7c150e | 557 | { return (__pos % _GLIBCXX_BITSET_BITS_PER_WORD) / __CHAR_BIT__; } |
bb12c809 | 558 | |
94a86be0 | 559 | static _GLIBCXX_CONSTEXPR size_t |
6aa67e7b | 560 | _S_whichbit(size_t __pos) _GLIBCXX_NOEXCEPT |
3d7c150e | 561 | { return __pos % _GLIBCXX_BITSET_BITS_PER_WORD; } |
bb12c809 | 562 | |
94a86be0 | 563 | static _GLIBCXX_CONSTEXPR _WordT |
6aa67e7b | 564 | _S_maskbit(size_t __pos) _GLIBCXX_NOEXCEPT |
bb12c809 PE |
565 | { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); } |
566 | ||
567 | // This would normally give access to the data. The bounds-checking | |
568 | // in the bitset class will prevent the user from getting this far, | |
9194c139 JW |
569 | // but this must fail if the user calls _Unchecked_set directly. |
570 | // Let's not penalize zero-length users unless they actually | |
bb12c809 PE |
571 | // make an unchecked call; all the memory ugliness is therefore |
572 | // localized to this single should-never-get-this-far function. | |
9194c139 | 573 | __attribute__((__noreturn__)) |
bb12c809 | 574 | _WordT& |
5d861bf2 | 575 | _M_getword(size_t) _GLIBCXX_NOEXCEPT |
9194c139 | 576 | { __throw_out_of_range(__N("_Base_bitset::_M_getword")); } |
bb12c809 | 577 | |
07be6120 | 578 | _GLIBCXX_CONSTEXPR _WordT |
9ed83a33 | 579 | _M_getword(size_t) const _GLIBCXX_NOEXCEPT |
94a86be0 BK |
580 | { return 0; } |
581 | ||
582 | _GLIBCXX_CONSTEXPR _WordT | |
5d861bf2 | 583 | _M_hiword() const _GLIBCXX_NOEXCEPT |
5c33bb62 | 584 | { return 0; } |
bb12c809 | 585 | |
9194c139 | 586 | _GLIBCXX14_CONSTEXPR void |
5d861bf2 | 587 | _M_do_and(const _Base_bitset<0>&) _GLIBCXX_NOEXCEPT |
5a4db26d | 588 | { } |
bb12c809 | 589 | |
9194c139 | 590 | _GLIBCXX14_CONSTEXPR void |
5d861bf2 | 591 | _M_do_or(const _Base_bitset<0>&) _GLIBCXX_NOEXCEPT |
5a4db26d | 592 | { } |
bb12c809 | 593 | |
9194c139 | 594 | _GLIBCXX14_CONSTEXPR void |
5d861bf2 | 595 | _M_do_xor(const _Base_bitset<0>&) _GLIBCXX_NOEXCEPT |
5a4db26d | 596 | { } |
bb12c809 | 597 | |
9194c139 | 598 | _GLIBCXX14_CONSTEXPR void |
5d861bf2 | 599 | _M_do_left_shift(size_t) _GLIBCXX_NOEXCEPT |
5a4db26d | 600 | { } |
bb12c809 | 601 | |
9194c139 | 602 | _GLIBCXX14_CONSTEXPR void |
5d861bf2 | 603 | _M_do_right_shift(size_t) _GLIBCXX_NOEXCEPT |
5a4db26d | 604 | { } |
bb12c809 | 605 | |
9194c139 | 606 | _GLIBCXX14_CONSTEXPR void |
5d861bf2 | 607 | _M_do_flip() _GLIBCXX_NOEXCEPT |
5a4db26d | 608 | { } |
bb12c809 | 609 | |
9194c139 | 610 | _GLIBCXX14_CONSTEXPR void |
5d861bf2 | 611 | _M_do_set() _GLIBCXX_NOEXCEPT |
5a4db26d | 612 | { } |
bb12c809 | 613 | |
9194c139 | 614 | _GLIBCXX14_CONSTEXPR void |
5d861bf2 | 615 | _M_do_reset() _GLIBCXX_NOEXCEPT |
5a4db26d | 616 | { } |
bb12c809 PE |
617 | |
618 | // Are all empty bitsets equal to each other? Are they equal to | |
619 | // themselves? How to compare a thing which has no state? What is | |
620 | // the sound of one zero-length bitset clapping? | |
9194c139 | 621 | _GLIBCXX_CONSTEXPR bool |
5d861bf2 | 622 | _M_is_equal(const _Base_bitset<0>&) const _GLIBCXX_NOEXCEPT |
5c33bb62 | 623 | { return true; } |
bb12c809 | 624 | |
0217ac04 | 625 | template<size_t _Nb> |
9194c139 | 626 | _GLIBCXX_CONSTEXPR bool |
0217ac04 PC |
627 | _M_are_all() const _GLIBCXX_NOEXCEPT |
628 | { return true; } | |
b96817da | 629 | |
9194c139 | 630 | _GLIBCXX_CONSTEXPR bool |
5d861bf2 | 631 | _M_is_any() const _GLIBCXX_NOEXCEPT |
5c33bb62 | 632 | { return false; } |
bb12c809 | 633 | |
9194c139 | 634 | _GLIBCXX_CONSTEXPR size_t |
5d861bf2 | 635 | _M_do_count() const _GLIBCXX_NOEXCEPT |
5c33bb62 | 636 | { return 0; } |
bb12c809 | 637 | |
9194c139 | 638 | _GLIBCXX_CONSTEXPR unsigned long |
5d861bf2 | 639 | _M_do_to_ulong() const _GLIBCXX_NOEXCEPT |
5c33bb62 | 640 | { return 0; } |
bb12c809 | 641 | |
734f5023 | 642 | #if __cplusplus >= 201103L |
9194c139 | 643 | constexpr unsigned long long |
5d861bf2 | 644 | _M_do_to_ullong() const noexcept |
700d2899 PC |
645 | { return 0; } |
646 | #endif | |
647 | ||
bb12c809 PE |
648 | // Normally "not found" is the size, but that could also be |
649 | // misinterpreted as an index in this corner case. Oh well. | |
9194c139 | 650 | _GLIBCXX_CONSTEXPR size_t |
5d861bf2 | 651 | _M_do_find_first(size_t) const _GLIBCXX_NOEXCEPT |
5c33bb62 | 652 | { return 0; } |
bb12c809 | 653 | |
9194c139 | 654 | _GLIBCXX_CONSTEXPR size_t |
5d861bf2 | 655 | _M_do_find_next(size_t, size_t) const _GLIBCXX_NOEXCEPT |
5c33bb62 | 656 | { return 0; } |
bb12c809 PE |
657 | }; |
658 | ||
659 | ||
1cb7f91f | 660 | // Helper class to zero out the unused high-order bits in the highest word. |
b963aad8 PE |
661 | template<size_t _Extrabits> |
662 | struct _Sanitize | |
1cb7f91f | 663 | { |
94a86be0 BK |
664 | typedef unsigned long _WordT; |
665 | ||
9194c139 | 666 | static _GLIBCXX14_CONSTEXPR void |
5d861bf2 | 667 | _S_do_sanitize(_WordT& __val) _GLIBCXX_NOEXCEPT |
94a86be0 | 668 | { __val &= ~((~static_cast<_WordT>(0)) << _Extrabits); } |
1cb7f91f BK |
669 | }; |
670 | ||
b963aad8 PE |
671 | template<> |
672 | struct _Sanitize<0> | |
6aa67e7b | 673 | { |
94a86be0 BK |
674 | typedef unsigned long _WordT; |
675 | ||
9194c139 | 676 | static _GLIBCXX14_CONSTEXPR void |
33ac58d5 | 677 | _S_do_sanitize(_WordT) _GLIBCXX_NOEXCEPT { } |
94a86be0 | 678 | }; |
70e12fb9 | 679 | |
734f5023 | 680 | #if __cplusplus >= 201103L |
6b4f8906 | 681 | template<size_t _Nb, bool = (_Nb < _GLIBCXX_BITSET_BITS_PER_ULL)> |
5da7fa30 PC |
682 | struct _Sanitize_val |
683 | { | |
684 | static constexpr unsigned long long | |
685 | _S_do_sanitize_val(unsigned long long __val) | |
686 | { return __val; } | |
687 | }; | |
688 | ||
689 | template<size_t _Nb> | |
690 | struct _Sanitize_val<_Nb, true> | |
691 | { | |
692 | static constexpr unsigned long long | |
693 | _S_do_sanitize_val(unsigned long long __val) | |
694 | { return __val & ~((~static_cast<unsigned long long>(0)) << _Nb); } | |
695 | }; | |
696 | #endif | |
697 | ||
b963aad8 | 698 | /** |
fb3bc977 JW |
699 | * @brief The %bitset class represents a @e fixed-size sequence of bits. |
700 | * @ingroup utilities | |
b963aad8 | 701 | * |
e92a4045 PE |
702 | * (Note that %bitset does @e not meet the formal requirements of a |
703 | * <a href="tables.html#65">container</a>. Mainly, it lacks iterators.) | |
b963aad8 | 704 | * |
70e12fb9 PE |
705 | * The template argument, @a Nb, may be any non-negative number, |
706 | * specifying the number of bits (e.g., "0", "12", "1024*1024"). | |
b963aad8 | 707 | * |
70e12fb9 PE |
708 | * In the general unoptimized case, storage is allocated in word-sized |
709 | * blocks. Let B be the number of bits in a word, then (Nb+(B-1))/B | |
710 | * words will be used for storage. B - Nb%B bits are unused. (They are | |
711 | * the high-order bits in the highest word.) It is a class invariant | |
712 | * that those unused bits are always zero. | |
b963aad8 | 713 | * |
2a60a9f6 BK |
714 | * If you think of %bitset as <em>a simple array of bits</em>, be |
715 | * aware that your mental picture is reversed: a %bitset behaves | |
716 | * the same way as bits in integers do, with the bit at index 0 in | |
717 | * the <em>least significant / right-hand</em> position, and the bit at | |
718 | * index Nb-1 in the <em>most significant / left-hand</em> position. | |
719 | * Thus, unlike other containers, a %bitset's index <em>counts from | |
720 | * right to left</em>, to put it very loosely. | |
b963aad8 PE |
721 | * |
722 | * This behavior is preserved when translating to and from strings. For | |
723 | * example, the first line of the following program probably prints | |
2a60a9f6 | 724 | * <em>b('a') is 0001100001</em> on a modern ASCII system. |
b963aad8 PE |
725 | * |
726 | * @code | |
727 | * #include <bitset> | |
728 | * #include <iostream> | |
729 | * #include <sstream> | |
730 | * | |
731 | * using namespace std; | |
732 | * | |
733 | * int main() | |
734 | * { | |
735 | * long a = 'a'; | |
736 | * bitset<10> b(a); | |
737 | * | |
738 | * cout << "b('a') is " << b << endl; | |
739 | * | |
740 | * ostringstream s; | |
741 | * s << b; | |
742 | * string str = s.str(); | |
743 | * cout << "index 3 in the string is " << str[3] << " but\n" | |
744 | * << "index 3 in the bitset is " << b[3] << endl; | |
745 | * } | |
746 | * @endcode | |
747 | * | |
a40fff0e | 748 | * Also see: |
10d43d2f | 749 | * https://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_containers.html |
70e12fb9 | 750 | * for a description of extensions. |
b963aad8 | 751 | * |
b963aad8 PE |
752 | * Most of the actual code isn't contained in %bitset<> itself, but in the |
753 | * base class _Base_bitset. The base class works with whole words, not with | |
754 | * individual bits. This allows us to specialize _Base_bitset for the | |
755 | * important special case where the %bitset is only a single word. | |
756 | * | |
757 | * Extra confusion can result due to the fact that the storage for | |
758 | * _Base_bitset @e is a regular array, and is indexed as such. This is | |
759 | * carefully encapsulated. | |
b963aad8 | 760 | */ |
1cb7f91f | 761 | template<size_t _Nb> |
5c33bb62 PC |
762 | class bitset |
763 | : private _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)> | |
1cb7f91f | 764 | { |
5c33bb62 PC |
765 | private: |
766 | typedef _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)> _Base; | |
767 | typedef unsigned long _WordT; | |
54c1bf78 | 768 | |
9194c139 | 769 | #if _GLIBCXX_HOSTED |
9779c871 | 770 | template<class _CharT, class _Traits, class _Alloc> |
9194c139 | 771 | _GLIBCXX23_CONSTEXPR |
9779c871 PP |
772 | void |
773 | _M_check_initial_position(const std::basic_string<_CharT, _Traits, _Alloc>& __s, | |
774 | size_t __position) const | |
775 | { | |
776 | if (__position > __s.size()) | |
777 | __throw_out_of_range_fmt(__N("bitset::bitset: __position " | |
778 | "(which is %zu) > __s.size() " | |
779 | "(which is %zu)"), | |
780 | __position, __s.size()); | |
781 | } | |
9194c139 | 782 | #endif // HOSTED |
9779c871 | 783 | |
9194c139 | 784 | _GLIBCXX23_CONSTEXPR |
9779c871 PP |
785 | void _M_check(size_t __position, const char *__s) const |
786 | { | |
787 | if (__position >= _Nb) | |
788 | __throw_out_of_range_fmt(__N("%s: __position (which is %zu) " | |
789 | ">= _Nb (which is %zu)"), | |
790 | __s, __position, _Nb); | |
791 | } | |
792 | ||
9194c139 | 793 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 794 | void |
5d861bf2 | 795 | _M_do_sanitize() _GLIBCXX_NOEXCEPT |
33ac58d5 | 796 | { |
94a86be0 BK |
797 | typedef _Sanitize<_Nb % _GLIBCXX_BITSET_BITS_PER_WORD> __sanitize_type; |
798 | __sanitize_type::_S_do_sanitize(this->_M_hiword()); | |
799 | } | |
b963aad8 | 800 | |
734f5023 | 801 | #if __cplusplus >= 201103L |
5dfb5e5b | 802 | friend struct std::hash<bitset>; |
ec7058d6 PC |
803 | #endif |
804 | ||
5c33bb62 PC |
805 | public: |
806 | /** | |
807 | * This encapsulates the concept of a single bit. An instance of this | |
808 | * class is a proxy for an actual bit; this way the individual bit | |
809 | * operations are done as faster word-size bitwise instructions. | |
810 | * | |
811 | * Most users will never need to use this class directly; conversions | |
812 | * to and from bool are automatic and should be transparent. Overloaded | |
813 | * operators help to preserve the illusion. | |
814 | * | |
2a60a9f6 BK |
815 | * (On a typical system, this <em>bit %reference</em> is 64 |
816 | * times the size of an actual bit. Ha.) | |
5c33bb62 PC |
817 | */ |
818 | class reference | |
819 | { | |
820 | friend class bitset; | |
821 | ||
94a86be0 BK |
822 | _WordT* _M_wp; |
823 | size_t _M_bpos; | |
33ac58d5 | 824 | |
5c33bb62 PC |
825 | // left undefined |
826 | reference(); | |
33ac58d5 | 827 | |
5c33bb62 | 828 | public: |
9194c139 | 829 | _GLIBCXX23_CONSTEXPR |
5d861bf2 | 830 | reference(bitset& __b, size_t __pos) _GLIBCXX_NOEXCEPT |
5c33bb62 PC |
831 | { |
832 | _M_wp = &__b._M_getword(__pos); | |
833 | _M_bpos = _Base::_S_whichbit(__pos); | |
834 | } | |
b963aad8 | 835 | |
a1417556 JW |
836 | #if __cplusplus >= 201103L |
837 | reference(const reference&) = default; | |
838 | #endif | |
839 | ||
9194c139 JW |
840 | #if __cplusplus > 202002L && __cpp_constexpr_dynamic_alloc |
841 | constexpr | |
842 | #endif | |
5d861bf2 | 843 | ~reference() _GLIBCXX_NOEXCEPT |
5c33bb62 | 844 | { } |
b963aad8 | 845 | |
5c33bb62 | 846 | // For b[i] = __x; |
9194c139 | 847 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 848 | reference& |
5d861bf2 | 849 | operator=(bool __x) _GLIBCXX_NOEXCEPT |
5c33bb62 PC |
850 | { |
851 | if (__x) | |
852 | *_M_wp |= _Base::_S_maskbit(_M_bpos); | |
853 | else | |
854 | *_M_wp &= ~_Base::_S_maskbit(_M_bpos); | |
855 | return *this; | |
856 | } | |
857 | ||
858 | // For b[i] = b[__j]; | |
9194c139 | 859 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 860 | reference& |
5d861bf2 | 861 | operator=(const reference& __j) _GLIBCXX_NOEXCEPT |
5c33bb62 PC |
862 | { |
863 | if ((*(__j._M_wp) & _Base::_S_maskbit(__j._M_bpos))) | |
864 | *_M_wp |= _Base::_S_maskbit(_M_bpos); | |
865 | else | |
866 | *_M_wp &= ~_Base::_S_maskbit(_M_bpos); | |
867 | return *this; | |
868 | } | |
869 | ||
870 | // Flips the bit | |
9194c139 | 871 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 872 | bool |
5d861bf2 | 873 | operator~() const _GLIBCXX_NOEXCEPT |
5c33bb62 PC |
874 | { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) == 0; } |
875 | ||
876 | // For __x = b[i]; | |
9194c139 | 877 | _GLIBCXX23_CONSTEXPR |
5d861bf2 | 878 | operator bool() const _GLIBCXX_NOEXCEPT |
5c33bb62 PC |
879 | { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) != 0; } |
880 | ||
881 | // For b[i].flip(); | |
9194c139 | 882 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 883 | reference& |
5d861bf2 | 884 | flip() _GLIBCXX_NOEXCEPT |
5c33bb62 PC |
885 | { |
886 | *_M_wp ^= _Base::_S_maskbit(_M_bpos); | |
887 | return *this; | |
888 | } | |
889 | }; | |
890 | friend class reference; | |
891 | ||
892 | // 23.3.5.1 constructors: | |
893 | /// All bits set to zero. | |
5d861bf2 | 894 | _GLIBCXX_CONSTEXPR bitset() _GLIBCXX_NOEXCEPT |
5c33bb62 PC |
895 | { } |
896 | ||
897 | /// Initial bits bitwise-copied from a single word (others set to zero). | |
734f5023 | 898 | #if __cplusplus >= 201103L |
5d861bf2 | 899 | constexpr bitset(unsigned long long __val) noexcept |
5da7fa30 | 900 | : _Base(_Sanitize_val<_Nb>::_S_do_sanitize_val(__val)) { } |
0d6f2a80 | 901 | #else |
5c33bb62 PC |
902 | bitset(unsigned long __val) |
903 | : _Base(__val) | |
904 | { _M_do_sanitize(); } | |
94a86be0 | 905 | #endif |
5c33bb62 | 906 | |
9194c139 | 907 | #if _GLIBCXX_HOSTED |
5c33bb62 | 908 | /** |
7897a1c0 | 909 | * Use a subset of a string. |
93c66bc6 BK |
910 | * @param __s A string of @a 0 and @a 1 characters. |
911 | * @param __position Index of the first character in @a __s to use; | |
5c33bb62 | 912 | * defaults to zero. |
93c66bc6 | 913 | * @throw std::out_of_range If @a pos is bigger the size of @a __s. |
5c33bb62 | 914 | * @throw std::invalid_argument If a character appears in the string |
2a60a9f6 | 915 | * which is neither @a 0 nor @a 1. |
5c33bb62 PC |
916 | */ |
917 | template<class _CharT, class _Traits, class _Alloc> | |
9194c139 | 918 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 919 | explicit |
6323b34e | 920 | bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __s, |
5c33bb62 PC |
921 | size_t __position = 0) |
922 | : _Base() | |
923 | { | |
9779c871 | 924 | _M_check_initial_position(__s, __position); |
5c33bb62 | 925 | _M_copy_from_string(__s, __position, |
47cd1557 PC |
926 | std::basic_string<_CharT, _Traits, _Alloc>::npos, |
927 | _CharT('0'), _CharT('1')); | |
5c33bb62 PC |
928 | } |
929 | ||
930 | /** | |
7897a1c0 | 931 | * Use a subset of a string. |
93c66bc6 BK |
932 | * @param __s A string of @a 0 and @a 1 characters. |
933 | * @param __position Index of the first character in @a __s to use. | |
934 | * @param __n The number of characters to copy. | |
935 | * @throw std::out_of_range If @a __position is bigger the size | |
936 | * of @a __s. | |
5c33bb62 | 937 | * @throw std::invalid_argument If a character appears in the string |
2a60a9f6 | 938 | * which is neither @a 0 nor @a 1. |
5c33bb62 PC |
939 | */ |
940 | template<class _CharT, class _Traits, class _Alloc> | |
9194c139 | 941 | _GLIBCXX23_CONSTEXPR |
6323b34e | 942 | bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __s, |
5c33bb62 PC |
943 | size_t __position, size_t __n) |
944 | : _Base() | |
945 | { | |
9779c871 | 946 | _M_check_initial_position(__s, __position); |
47cd1557 PC |
947 | _M_copy_from_string(__s, __position, __n, _CharT('0'), _CharT('1')); |
948 | } | |
949 | ||
950 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
951 | // 396. what are characters zero and one. | |
952 | template<class _CharT, class _Traits, class _Alloc> | |
9194c139 | 953 | _GLIBCXX23_CONSTEXPR |
47cd1557 PC |
954 | bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __s, |
955 | size_t __position, size_t __n, | |
956 | _CharT __zero, _CharT __one = _CharT('1')) | |
957 | : _Base() | |
958 | { | |
9779c871 | 959 | _M_check_initial_position(__s, __position); |
47cd1557 | 960 | _M_copy_from_string(__s, __position, __n, __zero, __one); |
5c33bb62 | 961 | } |
0fda18dd | 962 | |
734f5023 | 963 | #if __cplusplus >= 201103L |
a1b418cb | 964 | /** |
7897a1c0 | 965 | * Construct from a character %array. |
93c66bc6 BK |
966 | * @param __str An %array of characters @a zero and @a one. |
967 | * @param __n The number of characters to use. | |
968 | * @param __zero The character corresponding to the value 0. | |
969 | * @param __one The character corresponding to the value 1. | |
970 | * @throw std::invalid_argument If a character appears in the string | |
971 | * which is neither @a __zero nor @a __one. | |
a1b418cb | 972 | */ |
a0a2a399 | 973 | template<typename _CharT> |
9194c139 JW |
974 | [[__gnu__::__nonnull__]] |
975 | _GLIBCXX23_CONSTEXPR | |
a0a2a399 PC |
976 | explicit |
977 | bitset(const _CharT* __str, | |
978 | typename std::basic_string<_CharT>::size_type __n | |
979 | = std::basic_string<_CharT>::npos, | |
980 | _CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) | |
981 | : _Base() | |
982 | { | |
983 | if (!__str) | |
984 | __throw_logic_error(__N("bitset::bitset(const _CharT*, ...)")); | |
985 | ||
986 | if (__n == std::basic_string<_CharT>::npos) | |
987 | __n = std::char_traits<_CharT>::length(__str); | |
988 | _M_copy_from_ptr<_CharT, std::char_traits<_CharT>>(__str, __n, 0, | |
989 | __n, __zero, | |
990 | __one); | |
991 | } | |
9194c139 JW |
992 | #endif // C++11 |
993 | #endif // HOSTED | |
a1b418cb | 994 | |
5c33bb62 | 995 | // 23.3.5.2 bitset operations: |
f0b88346 | 996 | ///@{ |
5c33bb62 | 997 | /** |
7897a1c0 | 998 | * Operations on bitsets. |
93c66bc6 | 999 | * @param __rhs A same-sized bitset. |
5c33bb62 PC |
1000 | * |
1001 | * These should be self-explanatory. | |
1002 | */ | |
9194c139 | 1003 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 1004 | bitset<_Nb>& |
5d861bf2 | 1005 | operator&=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT |
1cb7f91f | 1006 | { |
5c33bb62 PC |
1007 | this->_M_do_and(__rhs); |
1008 | return *this; | |
1cb7f91f | 1009 | } |
54c1bf78 | 1010 | |
9194c139 | 1011 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 1012 | bitset<_Nb>& |
5d861bf2 | 1013 | operator|=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT |
5c33bb62 PC |
1014 | { |
1015 | this->_M_do_or(__rhs); | |
1016 | return *this; | |
1017 | } | |
1cb7f91f | 1018 | |
9194c139 | 1019 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 1020 | bitset<_Nb>& |
5d861bf2 | 1021 | operator^=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT |
1cb7f91f | 1022 | { |
5c33bb62 PC |
1023 | this->_M_do_xor(__rhs); |
1024 | return *this; | |
1025 | } | |
f0b88346 | 1026 | ///@} |
33ac58d5 | 1027 | |
f0b88346 | 1028 | ///@{ |
5c33bb62 | 1029 | /** |
7897a1c0 | 1030 | * Operations on bitsets. |
93c66bc6 | 1031 | * @param __position The number of places to shift. |
5c33bb62 PC |
1032 | * |
1033 | * These should be self-explanatory. | |
1034 | */ | |
9194c139 | 1035 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 1036 | bitset<_Nb>& |
5d861bf2 | 1037 | operator<<=(size_t __position) _GLIBCXX_NOEXCEPT |
5c33bb62 PC |
1038 | { |
1039 | if (__builtin_expect(__position < _Nb, 1)) | |
1040 | { | |
1041 | this->_M_do_left_shift(__position); | |
1042 | this->_M_do_sanitize(); | |
1043 | } | |
1cb7f91f | 1044 | else |
5c33bb62 | 1045 | this->_M_do_reset(); |
1cb7f91f BK |
1046 | return *this; |
1047 | } | |
b963aad8 | 1048 | |
9194c139 | 1049 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 1050 | bitset<_Nb>& |
5d861bf2 | 1051 | operator>>=(size_t __position) _GLIBCXX_NOEXCEPT |
1cb7f91f | 1052 | { |
5c33bb62 PC |
1053 | if (__builtin_expect(__position < _Nb, 1)) |
1054 | { | |
1055 | this->_M_do_right_shift(__position); | |
1056 | this->_M_do_sanitize(); | |
1057 | } | |
1cb7f91f | 1058 | else |
5c33bb62 | 1059 | this->_M_do_reset(); |
1cb7f91f BK |
1060 | return *this; |
1061 | } | |
f0b88346 | 1062 | ///@} |
33ac58d5 | 1063 | |
f0b88346 | 1064 | ///@{ |
5c33bb62 PC |
1065 | /** |
1066 | * These versions of single-bit set, reset, flip, and test are | |
1067 | * extensions from the SGI version. They do no range checking. | |
1068 | * @ingroup SGIextensions | |
1069 | */ | |
9194c139 | 1070 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 1071 | bitset<_Nb>& |
5d861bf2 | 1072 | _Unchecked_set(size_t __pos) _GLIBCXX_NOEXCEPT |
1cb7f91f | 1073 | { |
5c33bb62 | 1074 | this->_M_getword(__pos) |= _Base::_S_maskbit(__pos); |
1cb7f91f BK |
1075 | return *this; |
1076 | } | |
5c33bb62 | 1077 | |
9194c139 | 1078 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 1079 | bitset<_Nb>& |
5d861bf2 | 1080 | _Unchecked_set(size_t __pos, int __val) _GLIBCXX_NOEXCEPT |
1cb7f91f | 1081 | { |
5c33bb62 PC |
1082 | if (__val) |
1083 | this->_M_getword(__pos) |= _Base::_S_maskbit(__pos); | |
1084 | else | |
1085 | this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos); | |
1086 | return *this; | |
1cb7f91f | 1087 | } |
54c1bf78 | 1088 | |
9194c139 | 1089 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 1090 | bitset<_Nb>& |
5d861bf2 | 1091 | _Unchecked_reset(size_t __pos) _GLIBCXX_NOEXCEPT |
1cb7f91f | 1092 | { |
5c33bb62 PC |
1093 | this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos); |
1094 | return *this; | |
1cb7f91f | 1095 | } |
54c1bf78 | 1096 | |
9194c139 | 1097 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 1098 | bitset<_Nb>& |
5d861bf2 | 1099 | _Unchecked_flip(size_t __pos) _GLIBCXX_NOEXCEPT |
5c33bb62 PC |
1100 | { |
1101 | this->_M_getword(__pos) ^= _Base::_S_maskbit(__pos); | |
1102 | return *this; | |
1103 | } | |
54c1bf78 | 1104 | |
07be6120 | 1105 | _GLIBCXX_CONSTEXPR bool |
5d861bf2 | 1106 | _Unchecked_test(size_t __pos) const _GLIBCXX_NOEXCEPT |
5c33bb62 PC |
1107 | { return ((this->_M_getword(__pos) & _Base::_S_maskbit(__pos)) |
1108 | != static_cast<_WordT>(0)); } | |
f0b88346 | 1109 | ///@} |
33ac58d5 | 1110 | |
5c33bb62 PC |
1111 | // Set, reset, and flip. |
1112 | /** | |
1113 | * @brief Sets every bit to true. | |
1114 | */ | |
9194c139 | 1115 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 1116 | bitset<_Nb>& |
5d861bf2 | 1117 | set() _GLIBCXX_NOEXCEPT |
5c33bb62 PC |
1118 | { |
1119 | this->_M_do_set(); | |
1120 | this->_M_do_sanitize(); | |
1121 | return *this; | |
1122 | } | |
54c1bf78 | 1123 | |
5c33bb62 PC |
1124 | /** |
1125 | * @brief Sets a given bit to a particular value. | |
93c66bc6 BK |
1126 | * @param __position The index of the bit. |
1127 | * @param __val Either true or false, defaults to true. | |
5c33bb62 PC |
1128 | * @throw std::out_of_range If @a pos is bigger the size of the %set. |
1129 | */ | |
9194c139 | 1130 | _GLIBCXX23_CONSTEXPR |
5c33bb62 PC |
1131 | bitset<_Nb>& |
1132 | set(size_t __position, bool __val = true) | |
1133 | { | |
9779c871 | 1134 | this->_M_check(__position, __N("bitset::set")); |
5c33bb62 PC |
1135 | return _Unchecked_set(__position, __val); |
1136 | } | |
54c1bf78 | 1137 | |
5c33bb62 PC |
1138 | /** |
1139 | * @brief Sets every bit to false. | |
1140 | */ | |
9194c139 | 1141 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 1142 | bitset<_Nb>& |
5d861bf2 | 1143 | reset() _GLIBCXX_NOEXCEPT |
5c33bb62 | 1144 | { |
3bbfb3d9 | 1145 | this->_M_do_reset(); |
5c33bb62 PC |
1146 | return *this; |
1147 | } | |
54c1bf78 | 1148 | |
5c33bb62 PC |
1149 | /** |
1150 | * @brief Sets a given bit to false. | |
93c66bc6 | 1151 | * @param __position The index of the bit. |
5c33bb62 PC |
1152 | * @throw std::out_of_range If @a pos is bigger the size of the %set. |
1153 | * | |
1154 | * Same as writing @c set(pos,false). | |
1155 | */ | |
9194c139 | 1156 | _GLIBCXX23_CONSTEXPR |
5c33bb62 PC |
1157 | bitset<_Nb>& |
1158 | reset(size_t __position) | |
1159 | { | |
9779c871 | 1160 | this->_M_check(__position, __N("bitset::reset")); |
5c33bb62 PC |
1161 | return _Unchecked_reset(__position); |
1162 | } | |
33ac58d5 | 1163 | |
5c33bb62 PC |
1164 | /** |
1165 | * @brief Toggles every bit to its opposite value. | |
1166 | */ | |
9194c139 | 1167 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 1168 | bitset<_Nb>& |
5d861bf2 | 1169 | flip() _GLIBCXX_NOEXCEPT |
5c33bb62 PC |
1170 | { |
1171 | this->_M_do_flip(); | |
1172 | this->_M_do_sanitize(); | |
1173 | return *this; | |
1174 | } | |
54c1bf78 | 1175 | |
5c33bb62 PC |
1176 | /** |
1177 | * @brief Toggles a given bit to its opposite value. | |
93c66bc6 | 1178 | * @param __position The index of the bit. |
5c33bb62 PC |
1179 | * @throw std::out_of_range If @a pos is bigger the size of the %set. |
1180 | */ | |
9194c139 | 1181 | _GLIBCXX23_CONSTEXPR |
5c33bb62 PC |
1182 | bitset<_Nb>& |
1183 | flip(size_t __position) | |
1184 | { | |
9779c871 | 1185 | this->_M_check(__position, __N("bitset::flip")); |
5c33bb62 PC |
1186 | return _Unchecked_flip(__position); |
1187 | } | |
33ac58d5 | 1188 | |
5c33bb62 | 1189 | /// See the no-argument flip(). |
9194c139 | 1190 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 1191 | bitset<_Nb> |
5d861bf2 | 1192 | operator~() const _GLIBCXX_NOEXCEPT |
5c33bb62 PC |
1193 | { return bitset<_Nb>(*this).flip(); } |
1194 | ||
f0b88346 | 1195 | ///@{ |
5c33bb62 PC |
1196 | /** |
1197 | * @brief Array-indexing support. | |
93c66bc6 | 1198 | * @param __position Index into the %bitset. |
94a86be0 BK |
1199 | * @return A bool for a <em>const %bitset</em>. For non-const |
1200 | * bitsets, an instance of the reference proxy class. | |
5c33bb62 PC |
1201 | * @note These operators do no range checking and throw no exceptions, |
1202 | * as required by DR 11 to the standard. | |
1203 | * | |
5c33bb62 PC |
1204 | * _GLIBCXX_RESOLVE_LIB_DEFECTS Note that this implementation already |
1205 | * resolves DR 11 (items 1 and 2), but does not do the range-checking | |
1206 | * required by that DR's resolution. -pme | |
1207 | * The DR has since been changed: range-checking is a precondition | |
1208 | * (users' responsibility), and these functions must not throw. -pme | |
5c33bb62 | 1209 | */ |
9194c139 | 1210 | _GLIBCXX23_CONSTEXPR |
5c33bb62 PC |
1211 | reference |
1212 | operator[](size_t __position) | |
94a86be0 | 1213 | { return reference(*this, __position); } |
54c1bf78 | 1214 | |
07be6120 | 1215 | _GLIBCXX_CONSTEXPR bool |
5c33bb62 PC |
1216 | operator[](size_t __position) const |
1217 | { return _Unchecked_test(__position); } | |
f0b88346 | 1218 | ///@} |
33ac58d5 | 1219 | |
5c33bb62 | 1220 | /** |
28dac70a | 1221 | * @brief Returns a numerical interpretation of the %bitset. |
5c33bb62 PC |
1222 | * @return The integral equivalent of the bits. |
1223 | * @throw std::overflow_error If there are too many bits to be | |
1224 | * represented in an @c unsigned @c long. | |
1225 | */ | |
9194c139 | 1226 | _GLIBCXX23_CONSTEXPR |
5c33bb62 PC |
1227 | unsigned long |
1228 | to_ulong() const | |
1229 | { return this->_M_do_to_ulong(); } | |
1230 | ||
734f5023 | 1231 | #if __cplusplus >= 201103L |
9194c139 | 1232 | _GLIBCXX23_CONSTEXPR |
700d2899 PC |
1233 | unsigned long long |
1234 | to_ullong() const | |
1235 | { return this->_M_do_to_ullong(); } | |
1236 | #endif | |
1237 | ||
9194c139 | 1238 | #if _GLIBCXX_HOSTED |
5c33bb62 | 1239 | /** |
28dac70a | 1240 | * @brief Returns a character interpretation of the %bitset. |
5c33bb62 PC |
1241 | * @return The string equivalent of the bits. |
1242 | * | |
1243 | * Note the ordering of the bits: decreasing character positions | |
1244 | * correspond to increasing bit positions (see the main class notes for | |
1245 | * an example). | |
5c33bb62 PC |
1246 | */ |
1247 | template<class _CharT, class _Traits, class _Alloc> | |
9194c139 | 1248 | _GLIBCXX23_CONSTEXPR |
6323b34e | 1249 | std::basic_string<_CharT, _Traits, _Alloc> |
5c33bb62 PC |
1250 | to_string() const |
1251 | { | |
6323b34e | 1252 | std::basic_string<_CharT, _Traits, _Alloc> __result; |
47cd1557 PC |
1253 | _M_copy_to_string(__result, _CharT('0'), _CharT('1')); |
1254 | return __result; | |
1255 | } | |
1256 | ||
1257 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
1258 | // 396. what are characters zero and one. | |
1259 | template<class _CharT, class _Traits, class _Alloc> | |
9194c139 | 1260 | _GLIBCXX23_CONSTEXPR |
47cd1557 PC |
1261 | std::basic_string<_CharT, _Traits, _Alloc> |
1262 | to_string(_CharT __zero, _CharT __one = _CharT('1')) const | |
1263 | { | |
1264 | std::basic_string<_CharT, _Traits, _Alloc> __result; | |
1265 | _M_copy_to_string(__result, __zero, __one); | |
5c33bb62 PC |
1266 | return __result; |
1267 | } | |
54c1bf78 | 1268 | |
14492f0b PC |
1269 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
1270 | // 434. bitset::to_string() hard to use. | |
1271 | template<class _CharT, class _Traits> | |
9194c139 | 1272 | _GLIBCXX23_CONSTEXPR |
6323b34e | 1273 | std::basic_string<_CharT, _Traits, std::allocator<_CharT> > |
14492f0b | 1274 | to_string() const |
6323b34e | 1275 | { return to_string<_CharT, _Traits, std::allocator<_CharT> >(); } |
14492f0b | 1276 | |
47cd1557 | 1277 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
19a6a2ea | 1278 | // 853. to_string needs updating with zero and one. |
47cd1557 | 1279 | template<class _CharT, class _Traits> |
9194c139 | 1280 | _GLIBCXX23_CONSTEXPR |
47cd1557 PC |
1281 | std::basic_string<_CharT, _Traits, std::allocator<_CharT> > |
1282 | to_string(_CharT __zero, _CharT __one = _CharT('1')) const | |
1283 | { return to_string<_CharT, _Traits, | |
1284 | std::allocator<_CharT> >(__zero, __one); } | |
1285 | ||
14492f0b | 1286 | template<class _CharT> |
9194c139 | 1287 | _GLIBCXX23_CONSTEXPR |
6323b34e PC |
1288 | std::basic_string<_CharT, std::char_traits<_CharT>, |
1289 | std::allocator<_CharT> > | |
14492f0b | 1290 | to_string() const |
6323b34e PC |
1291 | { |
1292 | return to_string<_CharT, std::char_traits<_CharT>, | |
1293 | std::allocator<_CharT> >(); | |
1294 | } | |
14492f0b | 1295 | |
47cd1557 | 1296 | template<class _CharT> |
9194c139 | 1297 | _GLIBCXX23_CONSTEXPR |
47cd1557 PC |
1298 | std::basic_string<_CharT, std::char_traits<_CharT>, |
1299 | std::allocator<_CharT> > | |
1300 | to_string(_CharT __zero, _CharT __one = _CharT('1')) const | |
1301 | { | |
1302 | return to_string<_CharT, std::char_traits<_CharT>, | |
1303 | std::allocator<_CharT> >(__zero, __one); | |
1304 | } | |
1305 | ||
9194c139 | 1306 | _GLIBCXX23_CONSTEXPR |
6323b34e | 1307 | std::basic_string<char, std::char_traits<char>, std::allocator<char> > |
14492f0b | 1308 | to_string() const |
6323b34e PC |
1309 | { |
1310 | return to_string<char, std::char_traits<char>, | |
1311 | std::allocator<char> >(); | |
1312 | } | |
14492f0b | 1313 | |
9194c139 | 1314 | _GLIBCXX23_CONSTEXPR |
47cd1557 PC |
1315 | std::basic_string<char, std::char_traits<char>, std::allocator<char> > |
1316 | to_string(char __zero, char __one = '1') const | |
1317 | { | |
1318 | return to_string<char, std::char_traits<char>, | |
1319 | std::allocator<char> >(__zero, __one); | |
1320 | } | |
1321 | ||
5c33bb62 | 1322 | // Helper functions for string operations. |
47cd1557 | 1323 | template<class _CharT, class _Traits> |
9194c139 | 1324 | _GLIBCXX23_CONSTEXPR |
0fda18dd | 1325 | void |
47cd1557 PC |
1326 | _M_copy_from_ptr(const _CharT*, size_t, size_t, size_t, |
1327 | _CharT, _CharT); | |
1328 | ||
1329 | template<class _CharT, class _Traits, class _Alloc> | |
9194c139 | 1330 | _GLIBCXX23_CONSTEXPR |
47cd1557 PC |
1331 | void |
1332 | _M_copy_from_string(const std::basic_string<_CharT, | |
1333 | _Traits, _Alloc>& __s, size_t __pos, size_t __n, | |
1334 | _CharT __zero, _CharT __one) | |
1335 | { _M_copy_from_ptr<_CharT, _Traits>(__s.data(), __s.size(), __pos, __n, | |
1336 | __zero, __one); } | |
1337 | ||
1338 | template<class _CharT, class _Traits, class _Alloc> | |
9194c139 | 1339 | _GLIBCXX23_CONSTEXPR |
47cd1557 PC |
1340 | void |
1341 | _M_copy_to_string(std::basic_string<_CharT, _Traits, _Alloc>&, | |
1342 | _CharT, _CharT) const; | |
0fda18dd | 1343 | |
47cd1557 | 1344 | // NB: Backward compat. |
5c33bb62 | 1345 | template<class _CharT, class _Traits, class _Alloc> |
9194c139 | 1346 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 1347 | void |
6323b34e | 1348 | _M_copy_from_string(const std::basic_string<_CharT, |
0fda18dd | 1349 | _Traits, _Alloc>& __s, size_t __pos, size_t __n) |
47cd1557 | 1350 | { _M_copy_from_string(__s, __pos, __n, _CharT('0'), _CharT('1')); } |
54c1bf78 | 1351 | |
5c33bb62 | 1352 | template<class _CharT, class _Traits, class _Alloc> |
9194c139 | 1353 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 1354 | void |
47cd1557 PC |
1355 | _M_copy_to_string(std::basic_string<_CharT, _Traits,_Alloc>& __s) const |
1356 | { _M_copy_to_string(__s, _CharT('0'), _CharT('1')); } | |
9194c139 | 1357 | #endif // HOSTED |
54c1bf78 | 1358 | |
5c33bb62 | 1359 | /// Returns the number of bits which are set. |
9194c139 | 1360 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 1361 | size_t |
5d861bf2 | 1362 | count() const _GLIBCXX_NOEXCEPT |
5c33bb62 | 1363 | { return this->_M_do_count(); } |
54c1bf78 | 1364 | |
5c33bb62 | 1365 | /// Returns the total number of bits. |
94a86be0 | 1366 | _GLIBCXX_CONSTEXPR size_t |
5d861bf2 | 1367 | size() const _GLIBCXX_NOEXCEPT |
5c33bb62 | 1368 | { return _Nb; } |
54c1bf78 | 1369 | |
f0b88346 | 1370 | ///@{ |
5c33bb62 | 1371 | /// These comparisons for equality/inequality are, well, @e bitwise. |
9194c139 | 1372 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 1373 | bool |
5d861bf2 | 1374 | operator==(const bitset<_Nb>& __rhs) const _GLIBCXX_NOEXCEPT |
5c33bb62 | 1375 | { return this->_M_is_equal(__rhs); } |
54c1bf78 | 1376 | |
596676d6 | 1377 | #if __cpp_impl_three_way_comparison < 201907L |
9194c139 | 1378 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 1379 | bool |
5d861bf2 | 1380 | operator!=(const bitset<_Nb>& __rhs) const _GLIBCXX_NOEXCEPT |
5c33bb62 | 1381 | { return !this->_M_is_equal(__rhs); } |
596676d6 | 1382 | #endif |
f0b88346 | 1383 | ///@} |
33ac58d5 | 1384 | |
5c33bb62 PC |
1385 | /** |
1386 | * @brief Tests the value of a bit. | |
93c66bc6 | 1387 | * @param __position The index of a bit. |
5c33bb62 PC |
1388 | * @return The value at @a pos. |
1389 | * @throw std::out_of_range If @a pos is bigger the size of the %set. | |
1390 | */ | |
9194c139 | 1391 | _GLIBCXX23_CONSTEXPR |
5c33bb62 PC |
1392 | bool |
1393 | test(size_t __position) const | |
1cb7f91f | 1394 | { |
9779c871 | 1395 | this->_M_check(__position, __N("bitset::test")); |
5c33bb62 | 1396 | return _Unchecked_test(__position); |
1cb7f91f | 1397 | } |
b96817da PC |
1398 | |
1399 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
1400 | // DR 693. std::bitset::all() missing. | |
1401 | /** | |
1402 | * @brief Tests whether all the bits are on. | |
1403 | * @return True if all the bits are set. | |
1404 | */ | |
9194c139 | 1405 | _GLIBCXX23_CONSTEXPR |
b96817da | 1406 | bool |
5d861bf2 | 1407 | all() const _GLIBCXX_NOEXCEPT |
0217ac04 | 1408 | { return this->template _M_are_all<_Nb>(); } |
b96817da | 1409 | |
5c33bb62 PC |
1410 | /** |
1411 | * @brief Tests whether any of the bits are on. | |
1412 | * @return True if at least one bit is set. | |
1413 | */ | |
9194c139 | 1414 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 1415 | bool |
5d861bf2 | 1416 | any() const _GLIBCXX_NOEXCEPT |
5c33bb62 | 1417 | { return this->_M_is_any(); } |
54c1bf78 | 1418 | |
5c33bb62 PC |
1419 | /** |
1420 | * @brief Tests whether any of the bits are on. | |
1421 | * @return True if none of the bits are set. | |
1422 | */ | |
9194c139 | 1423 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 1424 | bool |
5d861bf2 | 1425 | none() const _GLIBCXX_NOEXCEPT |
5c33bb62 PC |
1426 | { return !this->_M_is_any(); } |
1427 | ||
f0b88346 | 1428 | ///@{ |
5c33bb62 | 1429 | /// Self-explanatory. |
9194c139 | 1430 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 1431 | bitset<_Nb> |
5d861bf2 | 1432 | operator<<(size_t __position) const _GLIBCXX_NOEXCEPT |
5c33bb62 PC |
1433 | { return bitset<_Nb>(*this) <<= __position; } |
1434 | ||
9194c139 | 1435 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 1436 | bitset<_Nb> |
5d861bf2 | 1437 | operator>>(size_t __position) const _GLIBCXX_NOEXCEPT |
5c33bb62 | 1438 | { return bitset<_Nb>(*this) >>= __position; } |
f0b88346 | 1439 | ///@} |
33ac58d5 | 1440 | |
5c33bb62 PC |
1441 | /** |
1442 | * @brief Finds the index of the first "on" bit. | |
1443 | * @return The index of the first bit set, or size() if not found. | |
1444 | * @ingroup SGIextensions | |
1445 | * @sa _Find_next | |
1446 | */ | |
9194c139 | 1447 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 1448 | size_t |
5d861bf2 | 1449 | _Find_first() const _GLIBCXX_NOEXCEPT |
5c33bb62 PC |
1450 | { return this->_M_do_find_first(_Nb); } |
1451 | ||
1452 | /** | |
1453 | * @brief Finds the index of the next "on" bit after prev. | |
1454 | * @return The index of the next bit set, or size() if not found. | |
93c66bc6 | 1455 | * @param __prev Where to start searching. |
5c33bb62 PC |
1456 | * @ingroup SGIextensions |
1457 | * @sa _Find_first | |
1458 | */ | |
9194c139 | 1459 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 1460 | size_t |
6aa67e7b | 1461 | _Find_next(size_t __prev) const _GLIBCXX_NOEXCEPT |
5c33bb62 PC |
1462 | { return this->_M_do_find_next(__prev, _Nb); } |
1463 | }; | |
54c1bf78 | 1464 | |
9194c139 | 1465 | #if _GLIBCXX_HOSTED |
1cb7f91f BK |
1466 | // Definitions of non-inline member functions. |
1467 | template<size_t _Nb> | |
47cd1557 | 1468 | template<class _CharT, class _Traits> |
9194c139 | 1469 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 1470 | void |
e7c59a0e | 1471 | bitset<_Nb>:: |
0fda18dd | 1472 | _M_copy_from_ptr(const _CharT* __s, size_t __len, |
47cd1557 | 1473 | size_t __pos, size_t __n, _CharT __zero, _CharT __one) |
5c33bb62 PC |
1474 | { |
1475 | reset(); | |
58651854 | 1476 | const size_t __nbits = std::min(_Nb, std::min(__n, size_t(__len - __pos))); |
e7c59a0e | 1477 | for (size_t __i = __nbits; __i > 0; --__i) |
5c33bb62 | 1478 | { |
47cd1557 PC |
1479 | const _CharT __c = __s[__pos + __nbits - __i]; |
1480 | if (_Traits::eq(__c, __zero)) | |
1481 | ; | |
1482 | else if (_Traits::eq(__c, __one)) | |
1483 | _Unchecked_set(__i - 1); | |
1484 | else | |
1485 | __throw_invalid_argument(__N("bitset::_M_copy_from_ptr")); | |
5c33bb62 PC |
1486 | } |
1487 | } | |
54c1bf78 | 1488 | |
1cb7f91f BK |
1489 | template<size_t _Nb> |
1490 | template<class _CharT, class _Traits, class _Alloc> | |
9194c139 | 1491 | _GLIBCXX23_CONSTEXPR |
5c33bb62 | 1492 | void |
e7c59a0e | 1493 | bitset<_Nb>:: |
47cd1557 PC |
1494 | _M_copy_to_string(std::basic_string<_CharT, _Traits, _Alloc>& __s, |
1495 | _CharT __zero, _CharT __one) const | |
5c33bb62 | 1496 | { |
47cd1557 | 1497 | __s.assign(_Nb, __zero); |
e7c59a0e PC |
1498 | for (size_t __i = _Nb; __i > 0; --__i) |
1499 | if (_Unchecked_test(__i - 1)) | |
47cd1557 | 1500 | _Traits::assign(__s[_Nb - __i], __one); |
5c33bb62 | 1501 | } |
9194c139 | 1502 | #endif // HOSTED |
54c1bf78 | 1503 | |
1cb7f91f | 1504 | // 23.3.5.3 bitset operations: |
f0b88346 | 1505 | ///@{ |
b963aad8 PE |
1506 | /** |
1507 | * @brief Global bitwise operations on bitsets. | |
93c66bc6 BK |
1508 | * @param __x A bitset. |
1509 | * @param __y A bitset of the same size as @a __x. | |
b963aad8 PE |
1510 | * @return A new bitset. |
1511 | * | |
1512 | * These should be self-explanatory. | |
1513 | */ | |
1cb7f91f | 1514 | template<size_t _Nb> |
9194c139 | 1515 | _GLIBCXX23_CONSTEXPR |
b963aad8 | 1516 | inline bitset<_Nb> |
5d861bf2 | 1517 | operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT |
1cb7f91f BK |
1518 | { |
1519 | bitset<_Nb> __result(__x); | |
1520 | __result &= __y; | |
1521 | return __result; | |
54c1bf78 BK |
1522 | } |
1523 | ||
1cb7f91f | 1524 | template<size_t _Nb> |
9194c139 | 1525 | _GLIBCXX23_CONSTEXPR |
b963aad8 | 1526 | inline bitset<_Nb> |
5d861bf2 | 1527 | operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT |
1cb7f91f BK |
1528 | { |
1529 | bitset<_Nb> __result(__x); | |
1530 | __result |= __y; | |
1531 | return __result; | |
1532 | } | |
54c1bf78 | 1533 | |
1cb7f91f | 1534 | template <size_t _Nb> |
9194c139 | 1535 | _GLIBCXX23_CONSTEXPR |
b963aad8 | 1536 | inline bitset<_Nb> |
5d861bf2 | 1537 | operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT |
1cb7f91f BK |
1538 | { |
1539 | bitset<_Nb> __result(__x); | |
1540 | __result ^= __y; | |
1541 | return __result; | |
1542 | } | |
f0b88346 | 1543 | ///@} |
b963aad8 | 1544 | |
9194c139 | 1545 | #if _GLIBCXX_HOSTED |
f0b88346 | 1546 | ///@{ |
b963aad8 PE |
1547 | /** |
1548 | * @brief Global I/O operators for bitsets. | |
1549 | * | |
1550 | * Direct I/O between streams and bitsets is supported. Output is | |
2a60a9f6 | 1551 | * straightforward. Input will skip whitespace, only accept @a 0 and @a 1 |
b963aad8 PE |
1552 | * characters, and will only extract as many digits as the %bitset will |
1553 | * hold. | |
1554 | */ | |
1cb7f91f | 1555 | template<class _CharT, class _Traits, size_t _Nb> |
6323b34e PC |
1556 | std::basic_istream<_CharT, _Traits>& |
1557 | operator>>(std::basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x) | |
1cb7f91f | 1558 | { |
f4e39278 PC |
1559 | typedef typename _Traits::char_type char_type; |
1560 | typedef std::basic_istream<_CharT, _Traits> __istream_type; | |
1561 | typedef typename __istream_type::ios_base __ios_base; | |
1562 | ||
6323b34e | 1563 | std::basic_string<_CharT, _Traits> __tmp; |
1cb7f91f | 1564 | __tmp.reserve(_Nb); |
b963aad8 | 1565 | |
47cd1557 PC |
1566 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
1567 | // 303. Bitset input operator underspecified | |
1568 | const char_type __zero = __is.widen('0'); | |
1569 | const char_type __one = __is.widen('1'); | |
1570 | ||
f4e39278 PC |
1571 | typename __ios_base::iostate __state = __ios_base::goodbit; |
1572 | typename __istream_type::sentry __sentry(__is); | |
b963aad8 | 1573 | if (__sentry) |
1cb7f91f | 1574 | { |
bc2631e0 | 1575 | __try |
1cb7f91f | 1576 | { |
e7c59a0e | 1577 | for (size_t __i = _Nb; __i > 0; --__i) |
1cb7f91f | 1578 | { |
7f1156ed | 1579 | static typename _Traits::int_type __eof = _Traits::eof(); |
33ac58d5 | 1580 | |
11202768 | 1581 | typename _Traits::int_type __c1 = __is.rdbuf()->sbumpc(); |
7f1156ed | 1582 | if (_Traits::eq_int_type(__c1, __eof)) |
1cb7f91f | 1583 | { |
f4e39278 | 1584 | __state |= __ios_base::eofbit; |
1cb7f91f BK |
1585 | break; |
1586 | } | |
7f1156ed PC |
1587 | else |
1588 | { | |
5c33bb62 | 1589 | const char_type __c2 = _Traits::to_char_type(__c1); |
47cd1557 PC |
1590 | if (_Traits::eq(__c2, __zero)) |
1591 | __tmp.push_back(__zero); | |
1592 | else if (_Traits::eq(__c2, __one)) | |
1593 | __tmp.push_back(__one); | |
11202768 PC |
1594 | else if (_Traits:: |
1595 | eq_int_type(__is.rdbuf()->sputbackc(__c2), | |
1596 | __eof)) | |
7f1156ed | 1597 | { |
f4e39278 | 1598 | __state |= __ios_base::failbit; |
7f1156ed PC |
1599 | break; |
1600 | } | |
1601 | } | |
1cb7f91f BK |
1602 | } |
1603 | } | |
bc2631e0 | 1604 | __catch(__cxxabiv1::__forced_unwind&) |
d05f74f1 | 1605 | { |
33ac58d5 | 1606 | __is._M_setstate(__ios_base::badbit); |
d05f74f1 JM |
1607 | __throw_exception_again; |
1608 | } | |
bc2631e0 | 1609 | __catch(...) |
f4e39278 | 1610 | { __is._M_setstate(__ios_base::badbit); } |
1cb7f91f BK |
1611 | } |
1612 | ||
7f1156ed | 1613 | if (__tmp.empty() && _Nb) |
f4e39278 | 1614 | __state |= __ios_base::failbit; |
7f1156ed | 1615 | else |
47cd1557 PC |
1616 | __x._M_copy_from_string(__tmp, static_cast<size_t>(0), _Nb, |
1617 | __zero, __one); | |
7f1156ed PC |
1618 | if (__state) |
1619 | __is.setstate(__state); | |
1cb7f91f BK |
1620 | return __is; |
1621 | } | |
54c1bf78 | 1622 | |
1cb7f91f | 1623 | template <class _CharT, class _Traits, size_t _Nb> |
6323b34e PC |
1624 | std::basic_ostream<_CharT, _Traits>& |
1625 | operator<<(std::basic_ostream<_CharT, _Traits>& __os, | |
1626 | const bitset<_Nb>& __x) | |
1cb7f91f | 1627 | { |
6323b34e | 1628 | std::basic_string<_CharT, _Traits> __tmp; |
47cd1557 PC |
1629 | |
1630 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
1631 | // 396. what are characters zero and one. | |
1632 | const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__os.getloc()); | |
1633 | __x._M_copy_to_string(__tmp, __ct.widen('0'), __ct.widen('1')); | |
1cb7f91f BK |
1634 | return __os << __tmp; |
1635 | } | |
f0b88346 | 1636 | ///@} |
9194c139 | 1637 | #endif // HOSTED |
3cbc7af0 | 1638 | |
12ffa228 BK |
1639 | _GLIBCXX_END_NAMESPACE_CONTAINER |
1640 | } // namespace std | |
54c1bf78 | 1641 | |
3d7c150e BK |
1642 | #undef _GLIBCXX_BITSET_WORDS |
1643 | #undef _GLIBCXX_BITSET_BITS_PER_WORD | |
5da7fa30 | 1644 | #undef _GLIBCXX_BITSET_BITS_PER_ULL |
54c1bf78 | 1645 | |
9194c139 | 1646 | #if __cplusplus >= 201103L && _GLIBCXX_HOSTED |
4cd533a7 | 1647 | |
12ffa228 BK |
1648 | namespace std _GLIBCXX_VISIBILITY(default) |
1649 | { | |
1650 | _GLIBCXX_BEGIN_NAMESPACE_VERSION | |
4cd533a7 | 1651 | |
ec7058d6 PC |
1652 | // DR 1182. |
1653 | /// std::hash specialization for bitset. | |
1654 | template<size_t _Nb> | |
12ffa228 BK |
1655 | struct hash<_GLIBCXX_STD_C::bitset<_Nb>> |
1656 | : public __hash_base<size_t, _GLIBCXX_STD_C::bitset<_Nb>> | |
ec7058d6 PC |
1657 | { |
1658 | size_t | |
72f1c34b | 1659 | operator()(const _GLIBCXX_STD_C::bitset<_Nb>& __b) const noexcept |
ec7058d6 | 1660 | { |
055f6a47 | 1661 | const size_t __clength = (_Nb + __CHAR_BIT__ - 1) / __CHAR_BIT__; |
e7f72940 | 1662 | return std::_Hash_impl::hash(__b._M_getdata(), __clength); |
ec7058d6 PC |
1663 | } |
1664 | }; | |
4cd533a7 PC |
1665 | |
1666 | template<> | |
12ffa228 BK |
1667 | struct hash<_GLIBCXX_STD_C::bitset<0>> |
1668 | : public __hash_base<size_t, _GLIBCXX_STD_C::bitset<0>> | |
4cd533a7 PC |
1669 | { |
1670 | size_t | |
72f1c34b | 1671 | operator()(const _GLIBCXX_STD_C::bitset<0>&) const noexcept |
4cd533a7 PC |
1672 | { return 0; } |
1673 | }; | |
1674 | ||
12ffa228 BK |
1675 | _GLIBCXX_END_NAMESPACE_VERSION |
1676 | } // namespace | |
4cd533a7 | 1677 | |
734f5023 | 1678 | #endif // C++11 |
ec7058d6 | 1679 | |
9194c139 | 1680 | #ifdef _GLIBCXX_DEBUG && _GLIBCXX_HOSTED |
285b36d6 BK |
1681 | # include <debug/bitset> |
1682 | #endif | |
1683 | ||
1143680e | 1684 | #endif /* _GLIBCXX_BITSET */ |