libstdc++
debug/bitset
Go to the documentation of this file.
1 // Debugging bitset implementation -*- C++ -*-
2 
3 // Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 // Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library. This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 3, or (at your option)
10 // any later version.
11 
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 
17 // Under Section 7 of GPL version 3, you are granted additional
18 // permissions described in the GCC Runtime Library Exception, version
19 // 3.1, as published by the Free Software Foundation.
20 
21 // You should have received a copy of the GNU General Public License and
22 // a copy of the GCC Runtime Library Exception along with this program;
23 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 // <http://www.gnu.org/licenses/>.
25 
26 /** @file debug/bitset
27  * This file is a GNU debug extension to the Standard C++ Library.
28  */
29 
30 #ifndef _GLIBCXX_DEBUG_BITSET
31 #define _GLIBCXX_DEBUG_BITSET
32 
33 #include <bitset>
34 #include <debug/safe_sequence.h>
35 #include <debug/safe_iterator.h>
36 
37 namespace std _GLIBCXX_VISIBILITY(default)
38 {
39 namespace __debug
40 {
41  /// Class std::bitset with additional safety/checking/debug instrumentation.
42  template<size_t _Nb>
43  class bitset
44  : public _GLIBCXX_STD_C::bitset<_Nb>
45 #ifndef __GXX_EXPERIMENTAL_CXX0X__
47 #endif
48  {
49  typedef _GLIBCXX_STD_C::bitset<_Nb> _Base;
50 
51  public:
52  // In C++0x we rely on normal reference type to preserve the property
53  // of bitset to be use as a literal.
54  // TODO: Find an other solution.
55 #ifdef __GXX_EXPERIMENTAL_CXX0X__
56  typedef typename _Base::reference reference;
57 #else
58  // bit reference:
59  class reference
60  : private _Base::reference
62  {
63  typedef typename _Base::reference _Base_ref;
64 
65  friend class bitset;
66  reference();
67 
68  reference(const _Base_ref& __base,
69  bitset* __seq __attribute__((__unused__)))
70  : _Base_ref(__base)
71  , _Safe_iterator_base(__seq, false)
72  { }
73 
74  public:
75  reference(const reference& __x)
76  : _Base_ref(__x)
77  , _Safe_iterator_base(__x, false)
78  { }
79 
80  reference&
81  operator=(bool __x)
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)
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
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
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()
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() : _Base() { }
134 
135 #ifdef __GXX_EXPERIMENTAL_CXX0X__
136  constexpr bitset(unsigned long long __val)
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
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 #ifdef __GXX_EXPERIMENTAL_CXX0X__
165  template<typename _CharT>
166  explicit
167  bitset(const _CharT* __str,
168  typename std::basic_string<_CharT>::size_type __n
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)
177  {
178  _M_base() &= __rhs;
179  return *this;
180  }
181 
182  bitset<_Nb>&
183  operator|=(const bitset<_Nb>& __rhs)
184  {
185  _M_base() |= __rhs;
186  return *this;
187  }
188 
189  bitset<_Nb>&
190  operator^=(const bitset<_Nb>& __rhs)
191  {
192  _M_base() ^= __rhs;
193  return *this;
194  }
195 
196  bitset<_Nb>&
197  operator<<=(size_t __pos)
198  {
199  _M_base() <<= __pos;
200  return *this;
201  }
202 
203  bitset<_Nb>&
204  operator>>=(size_t __pos)
205  {
206  _M_base() >>= __pos;
207  return *this;
208  }
209 
210  bitset<_Nb>&
211  set()
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()
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> operator~() const { return bitset(~_M_base()); }
241 
242  bitset<_Nb>&
243  flip()
244  {
245  _Base::flip();
246  return *this;
247  }
248 
249  bitset<_Nb>&
250  flip(size_t __pos)
251  {
252  _Base::flip(__pos);
253  return *this;
254  }
255 
256  // element access:
257  // _GLIBCXX_RESOLVE_LIB_DEFECTS
258  // 11. Bitset minor problems
259  reference
260  operator[](size_t __pos)
261  {
262  __glibcxx_check_subscript(__pos);
263 #ifdef __GXX_EXPERIMENTAL_CXX0X__
264  return _M_base()[__pos];
265 #else
266  return reference(_M_base()[__pos], this);
267 #endif
268  }
269 
270  // _GLIBCXX_RESOLVE_LIB_DEFECTS
271  // 11. Bitset minor problems
272  bool
273  operator[](size_t __pos) const
274  {
275  __glibcxx_check_subscript(__pos);
276  return _M_base()[__pos];
277  }
278 
279  using _Base::to_ulong;
280 #ifdef __GXX_EXPERIMENTAL_CXX0X__
281  using _Base::to_ullong;
282 #endif
283 
284  template <typename _CharT, typename _Traits, typename _Alloc>
286  to_string() const
287  { return _M_base().template to_string<_CharT, _Traits, _Alloc>(); }
288 
289  // _GLIBCXX_RESOLVE_LIB_DEFECTS
290  // 396. what are characters zero and one.
291  template<class _CharT, class _Traits, class _Alloc>
293  to_string(_CharT __zero, _CharT __one = _CharT('1')) const
294  {
295  return _M_base().template
296  to_string<_CharT, _Traits, _Alloc>(__zero, __one);
297  }
298 
299  // _GLIBCXX_RESOLVE_LIB_DEFECTS
300  // 434. bitset::to_string() hard to use.
301  template<typename _CharT, typename _Traits>
303  to_string() const
304  { return to_string<_CharT, _Traits, std::allocator<_CharT> >(); }
305 
306  // _GLIBCXX_RESOLVE_LIB_DEFECTS
307  // 853. to_string needs updating with zero and one.
308  template<class _CharT, class _Traits>
310  to_string(_CharT __zero, _CharT __one = _CharT('1')) const
311  { return to_string<_CharT, _Traits,
312  std::allocator<_CharT> >(__zero, __one); }
313 
314  template<typename _CharT>
317  to_string() const
318  {
319  return to_string<_CharT, std::char_traits<_CharT>,
321  }
322 
323  template<class _CharT>
326  to_string(_CharT __zero, _CharT __one = _CharT('1')) const
327  {
328  return to_string<_CharT, std::char_traits<_CharT>,
329  std::allocator<_CharT> >(__zero, __one);
330  }
331 
333  to_string() const
334  {
335  return to_string<char,std::char_traits<char>,std::allocator<char> >();
336  }
337 
339  to_string(char __zero, char __one = '1') const
340  {
341  return to_string<char, std::char_traits<char>,
342  std::allocator<char> >(__zero, __one);
343  }
344 
345  using _Base::count;
346  using _Base::size;
347 
348  bool
349  operator==(const bitset<_Nb>& __rhs) const
350  { return _M_base() == __rhs; }
351 
352  bool
353  operator!=(const bitset<_Nb>& __rhs) const
354  { return _M_base() != __rhs; }
355 
356  using _Base::test;
357  using _Base::all;
358  using _Base::any;
359  using _Base::none;
360 
362  operator<<(size_t __pos) const
363  { return bitset<_Nb>(_M_base() << __pos); }
364 
366  operator>>(size_t __pos) const
367  { return bitset<_Nb>(_M_base() >> __pos); }
368 
369  _Base&
370  _M_base() { return *this; }
371 
372  const _Base&
373  _M_base() const { return *this; }
374  };
375 
376  template<size_t _Nb>
378  operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y)
379  { return bitset<_Nb>(__x) &= __y; }
380 
381  template<size_t _Nb>
382  bitset<_Nb>
383  operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y)
384  { return bitset<_Nb>(__x) |= __y; }
385 
386  template<size_t _Nb>
387  bitset<_Nb>
388  operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y)
389  { return bitset<_Nb>(__x) ^= __y; }
390 
391  template<typename _CharT, typename _Traits, size_t _Nb>
393  operator>>(std::basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x)
394  { return __is >> __x._M_base(); }
395 
396  template<typename _CharT, typename _Traits, size_t _Nb>
398  operator<<(std::basic_ostream<_CharT, _Traits>& __os,
399  const bitset<_Nb>& __x)
400  { return __os << __x._M_base(); }
401 
402 } // namespace __debug
403 
404 #ifdef __GXX_EXPERIMENTAL_CXX0X__
405  // DR 1182.
406  /// std::hash specialization for bitset.
407  template<size_t _Nb>
408  struct hash<__debug::bitset<_Nb>>
409  : public __hash_base<size_t, __debug::bitset<_Nb>>
410  {
411  size_t
412  operator()(const __debug::bitset<_Nb>& __b) const
413  { return std::hash<_GLIBCXX_STD_C::bitset<_Nb>>()(__b._M_base()); }
414  };
415 #endif
416 
417 } // namespace std
418 
419 #endif