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