libstdc++
debug/bitset
Go to the documentation of this file.
1 // Debugging bitset implementation -*- C++ -*-
2 
3 // Copyright (C) 2003-2023 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 
38 namespace std _GLIBCXX_VISIBILITY(default)
39 {
40 namespace __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  _GLIBCXX23_CONSTEXPR
145  explicit
146  bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str,
147  typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
148  __pos = 0,
149  typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
150  __n = (std::basic_string<_CharT, _Traits, _Alloc>::npos))
151  : _Base(__str, __pos, __n) { }
152 
153  // _GLIBCXX_RESOLVE_LIB_DEFECTS
154  // 396. what are characters zero and one.
155  template<class _CharT, class _Traits, class _Alloc>
156  _GLIBCXX23_CONSTEXPR
157  bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str,
158  typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
159  __pos,
160  typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
161  __n,
162  _CharT __zero, _CharT __one = _CharT('1'))
163  : _Base(__str, __pos, __n, __zero, __one) { }
164 
165  _GLIBCXX23_CONSTEXPR
166  bitset(const _Base& __x) : _Base(__x) { }
167 
168 #if __cplusplus >= 201103L
169  template<typename _CharT>
170  _GLIBCXX23_CONSTEXPR
171  explicit
172  bitset(const _CharT* __str,
173  typename std::basic_string<_CharT>::size_type __n
174  = std::basic_string<_CharT>::npos,
175  _CharT __zero = _CharT('0'), _CharT __one = _CharT('1'))
176  : _Base(__str, __n, __zero, __one) { }
177 #endif
178 
179  // 23.3.5.2 bitset operations:
180  _GLIBCXX23_CONSTEXPR
181  bitset<_Nb>&
182  operator&=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT
183  {
184  _M_base() &= __rhs;
185  return *this;
186  }
187 
188  _GLIBCXX23_CONSTEXPR
189  bitset<_Nb>&
190  operator|=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT
191  {
192  _M_base() |= __rhs;
193  return *this;
194  }
195 
196  _GLIBCXX23_CONSTEXPR
197  bitset<_Nb>&
198  operator^=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT
199  {
200  _M_base() ^= __rhs;
201  return *this;
202  }
203 
204  _GLIBCXX23_CONSTEXPR
205  bitset<_Nb>&
206  operator<<=(size_t __pos) _GLIBCXX_NOEXCEPT
207  {
208  _M_base() <<= __pos;
209  return *this;
210  }
211 
212  _GLIBCXX23_CONSTEXPR
213  bitset<_Nb>&
214  operator>>=(size_t __pos) _GLIBCXX_NOEXCEPT
215  {
216  _M_base() >>= __pos;
217  return *this;
218  }
219 
220  _GLIBCXX23_CONSTEXPR
221  bitset<_Nb>&
222  set() _GLIBCXX_NOEXCEPT
223  {
224  _Base::set();
225  return *this;
226  }
227 
228  // _GLIBCXX_RESOLVE_LIB_DEFECTS
229  // 186. bitset::set() second parameter should be bool
230  _GLIBCXX23_CONSTEXPR
231  bitset<_Nb>&
232  set(size_t __pos, bool __val = true)
233  {
234  _Base::set(__pos, __val);
235  return *this;
236  }
237 
238  _GLIBCXX23_CONSTEXPR
239  bitset<_Nb>&
240  reset() _GLIBCXX_NOEXCEPT
241  {
242  _Base::reset();
243  return *this;
244  }
245 
246  _GLIBCXX23_CONSTEXPR
247  bitset<_Nb>&
248  reset(size_t __pos)
249  {
250  _Base::reset(__pos);
251  return *this;
252  }
253 
254  _GLIBCXX23_CONSTEXPR
255  bitset<_Nb>
256  operator~() const _GLIBCXX_NOEXCEPT
257  { return bitset(~_M_base()); }
258 
259  _GLIBCXX23_CONSTEXPR
260  bitset<_Nb>&
261  flip() _GLIBCXX_NOEXCEPT
262  {
263  _Base::flip();
264  return *this;
265  }
266 
267  _GLIBCXX23_CONSTEXPR
268  bitset<_Nb>&
269  flip(size_t __pos)
270  {
271  _Base::flip(__pos);
272  return *this;
273  }
274 
275  // element access:
276  // _GLIBCXX_RESOLVE_LIB_DEFECTS
277  // 11. Bitset minor problems
278  _GLIBCXX23_CONSTEXPR
279  reference
280  operator[](size_t __pos)
281  {
282  __glibcxx_check_subscript(__pos);
283 #if __cplusplus >= 201103L
284  return _M_base()[__pos];
285 #else
286  return reference(_M_base()[__pos], this);
287 #endif
288  }
289 
290  // _GLIBCXX_RESOLVE_LIB_DEFECTS
291  // 11. Bitset minor problems
292  _GLIBCXX_CONSTEXPR bool
293  operator[](size_t __pos) const
294  {
295 #if __cplusplus < 201103L
296  // TODO: Check in debug-mode too.
297  __glibcxx_check_subscript(__pos);
298 #endif
299  return _Base::operator[](__pos);
300  }
301 
302  using _Base::to_ulong;
303 #if __cplusplus >= 201103L
304  using _Base::to_ullong;
305 #endif
306 
307  template <typename _CharT, typename _Traits, typename _Alloc>
308  _GLIBCXX23_CONSTEXPR
309  std::basic_string<_CharT, _Traits, _Alloc>
310  to_string() const
311  { return _M_base().template to_string<_CharT, _Traits, _Alloc>(); }
312 
313  // _GLIBCXX_RESOLVE_LIB_DEFECTS
314  // 396. what are characters zero and one.
315  template<class _CharT, class _Traits, class _Alloc>
316  _GLIBCXX23_CONSTEXPR
317  std::basic_string<_CharT, _Traits, _Alloc>
318  to_string(_CharT __zero, _CharT __one = _CharT('1')) const
319  {
320  return _M_base().template
321  to_string<_CharT, _Traits, _Alloc>(__zero, __one);
322  }
323 
324  // _GLIBCXX_RESOLVE_LIB_DEFECTS
325  // 434. bitset::to_string() hard to use.
326  template<typename _CharT, typename _Traits>
327  _GLIBCXX23_CONSTEXPR
328  std::basic_string<_CharT, _Traits, std::allocator<_CharT> >
329  to_string() const
330  { return to_string<_CharT, _Traits, std::allocator<_CharT> >(); }
331 
332  // _GLIBCXX_RESOLVE_LIB_DEFECTS
333  // 853. to_string needs updating with zero and one.
334  template<class _CharT, class _Traits>
335  _GLIBCXX23_CONSTEXPR
336  std::basic_string<_CharT, _Traits, std::allocator<_CharT> >
337  to_string(_CharT __zero, _CharT __one = _CharT('1')) const
338  { return to_string<_CharT, _Traits,
339  std::allocator<_CharT> >(__zero, __one); }
340 
341  template<typename _CharT>
342  _GLIBCXX23_CONSTEXPR
343  std::basic_string<_CharT, std::char_traits<_CharT>,
344  std::allocator<_CharT> >
345  to_string() const
346  {
347  return to_string<_CharT, std::char_traits<_CharT>,
348  std::allocator<_CharT> >();
349  }
350 
351  template<class _CharT>
352  _GLIBCXX23_CONSTEXPR
353  std::basic_string<_CharT, std::char_traits<_CharT>,
354  std::allocator<_CharT> >
355  to_string(_CharT __zero, _CharT __one = _CharT('1')) const
356  {
357  return to_string<_CharT, std::char_traits<_CharT>,
358  std::allocator<_CharT> >(__zero, __one);
359  }
360 
361  _GLIBCXX23_CONSTEXPR
362  std::basic_string<char, std::char_traits<char>, std::allocator<char> >
363  to_string() const
364  {
365  return to_string<char,std::char_traits<char>,std::allocator<char> >();
366  }
367 
368  _GLIBCXX23_CONSTEXPR
369  std::basic_string<char, std::char_traits<char>, std::allocator<char> >
370  to_string(char __zero, char __one = '1') const
371  {
372  return to_string<char, std::char_traits<char>,
373  std::allocator<char> >(__zero, __one);
374  }
375 
376  using _Base::count;
377  using _Base::size;
378 
379  _GLIBCXX23_CONSTEXPR
380  bool
381  operator==(const bitset<_Nb>& __rhs) const _GLIBCXX_NOEXCEPT
382  { return _M_base() == __rhs._M_base(); }
383 
384 #if __cpp_impl_three_way_comparison < 201907L
385  bool
386  operator!=(const bitset<_Nb>& __rhs) const _GLIBCXX_NOEXCEPT
387  { return _M_base() != __rhs._M_base(); }
388 #endif
389 
390  using _Base::test;
391  using _Base::all;
392  using _Base::any;
393  using _Base::none;
394 
395  _GLIBCXX23_CONSTEXPR
396  bitset<_Nb>
397  operator<<(size_t __pos) const _GLIBCXX_NOEXCEPT
398  { return bitset<_Nb>(_M_base() << __pos); }
399 
400  _GLIBCXX23_CONSTEXPR
401  bitset<_Nb>
402  operator>>(size_t __pos) const _GLIBCXX_NOEXCEPT
403  { return bitset<_Nb>(_M_base() >> __pos); }
404 
405  _GLIBCXX23_CONSTEXPR
406  _Base&
407  _M_base() _GLIBCXX_NOEXCEPT
408  { return *this; }
409 
410  _GLIBCXX23_CONSTEXPR
411  const _Base&
412  _M_base() const _GLIBCXX_NOEXCEPT
413  { return *this; }
414  };
415 
416  template<size_t _Nb>
417  _GLIBCXX23_CONSTEXPR
418  inline bitset<_Nb>
419  operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT
420  { return bitset<_Nb>(__x) &= __y; }
421 
422  template<size_t _Nb>
423  _GLIBCXX23_CONSTEXPR
424  inline bitset<_Nb>
425  operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT
426  { return bitset<_Nb>(__x) |= __y; }
427 
428  template<size_t _Nb>
429  _GLIBCXX23_CONSTEXPR
430  inline bitset<_Nb>
431  operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT
432  { return bitset<_Nb>(__x) ^= __y; }
433 
434  template<typename _CharT, typename _Traits, size_t _Nb>
435  inline std::basic_istream<_CharT, _Traits>&
436  operator>>(std::basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x)
437  { return __is >> __x._M_base(); }
438 
439  template<typename _CharT, typename _Traits, size_t _Nb>
440  inline std::basic_ostream<_CharT, _Traits>&
441  operator<<(std::basic_ostream<_CharT, _Traits>& __os,
442  const bitset<_Nb>& __x)
443  { return __os << __x._M_base(); }
444 
445 } // namespace __debug
446 
447 #if __cplusplus >= 201103L
448  // DR 1182.
449  /// std::hash specialization for bitset.
450  template<size_t _Nb>
451  struct hash<__debug::bitset<_Nb>>
452  : public __hash_base<size_t, __debug::bitset<_Nb>>
453  {
454  size_t
455  operator()(const __debug::bitset<_Nb>& __b) const noexcept
456  { return std::hash<_GLIBCXX_STD_C::bitset<_Nb>>()(__b._M_base()); }
457  };
458 #endif
459 
460 } // namespace std
461 
462 #endif