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