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