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