libstdc++
debug/bitset
Go to the documentation of this file.
00001 // Debugging bitset implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
00004 // Free Software Foundation, Inc.
00005 //
00006 // This file is part of the GNU ISO C++ Library.  This library is free
00007 // software; you can redistribute it and/or modify it under the
00008 // terms of the GNU General Public License as published by the
00009 // Free Software Foundation; either version 3, or (at your option)
00010 // any later version.
00011 
00012 // This library is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 
00017 // Under Section 7 of GPL version 3, you are granted additional
00018 // permissions described in the GCC Runtime Library Exception, version
00019 // 3.1, as published by the Free Software Foundation.
00020 
00021 // You should have received a copy of the GNU General Public License and
00022 // a copy of the GCC Runtime Library Exception along with this program;
00023 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00024 // <http://www.gnu.org/licenses/>.
00025 
00026 /** @file debug/bitset
00027  *  This file is a GNU debug extension to the Standard C++ Library.
00028  */
00029 
00030 #ifndef _GLIBCXX_DEBUG_BITSET
00031 #define _GLIBCXX_DEBUG_BITSET
00032 
00033 #include <bitset>
00034 #include <debug/safe_sequence.h>
00035 #include <debug/safe_iterator.h>
00036 
00037 namespace std _GLIBCXX_VISIBILITY(default)
00038 {
00039 namespace __debug
00040 {
00041   /// Class std::bitset with additional safety/checking/debug instrumentation.
00042   template<size_t _Nb>
00043     class bitset
00044     : public _GLIBCXX_STD_C::bitset<_Nb>
00045 #ifndef __GXX_EXPERIMENTAL_CXX0X__
00046     , public __gnu_debug::_Safe_sequence_base
00047 #endif
00048     {
00049       typedef _GLIBCXX_STD_C::bitset<_Nb> _Base;
00050 
00051     public:
00052       // In C++0x we rely on normal reference type to preserve the property
00053       // of bitset to be use as a literal.
00054       // TODO: Find an other solution.
00055 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00056       typedef typename _Base::reference reference;
00057 #else
00058       // bit reference:
00059       class reference
00060       : private _Base::reference
00061         , public __gnu_debug::_Safe_iterator_base
00062       {
00063     typedef typename _Base::reference _Base_ref;
00064 
00065     friend class bitset;
00066     reference();
00067 
00068     reference(const _Base_ref& __base,
00069           bitset* __seq __attribute__((__unused__)))
00070     : _Base_ref(__base)
00071     , _Safe_iterator_base(__seq, false)
00072     { }
00073 
00074       public:
00075     reference(const reference& __x)
00076     : _Base_ref(__x)
00077     , _Safe_iterator_base(__x, false)
00078     { }
00079 
00080     reference&
00081     operator=(bool __x)
00082     {
00083       _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
00084                   _M_message(__gnu_debug::__msg_bad_bitset_write)
00085                 ._M_iterator(*this));
00086       *static_cast<_Base_ref*>(this) = __x;
00087       return *this;
00088     }
00089 
00090     reference&
00091     operator=(const reference& __x)
00092     {
00093       _GLIBCXX_DEBUG_VERIFY(! __x._M_singular(),
00094                    _M_message(__gnu_debug::__msg_bad_bitset_read)
00095                 ._M_iterator(__x));
00096       _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
00097                   _M_message(__gnu_debug::__msg_bad_bitset_write)
00098                 ._M_iterator(*this));
00099       *static_cast<_Base_ref*>(this) = __x;
00100       return *this;
00101     }
00102 
00103     bool
00104     operator~() const
00105     {
00106       _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
00107                    _M_message(__gnu_debug::__msg_bad_bitset_read)
00108                 ._M_iterator(*this));
00109       return ~(*static_cast<const _Base_ref*>(this));
00110     }
00111 
00112     operator bool() const
00113     {
00114       _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
00115                   _M_message(__gnu_debug::__msg_bad_bitset_read)
00116                 ._M_iterator(*this));
00117       return *static_cast<const _Base_ref*>(this);
00118     }
00119 
00120     reference&
00121     flip()
00122     {
00123       _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
00124                   _M_message(__gnu_debug::__msg_bad_bitset_flip)
00125                 ._M_iterator(*this));
00126       _Base_ref::flip();
00127       return *this;
00128     }
00129       };
00130 #endif
00131 
00132       // 23.3.5.1 constructors:
00133       _GLIBCXX_CONSTEXPR bitset() : _Base() { }
00134 
00135 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00136       constexpr bitset(unsigned long long __val)
00137 #else
00138       bitset(unsigned long __val)
00139 #endif
00140       : _Base(__val) { }
00141 
00142       template<typename _CharT, typename _Traits, typename _Alloc>
00143         explicit
00144         bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str,
00145            typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
00146            __pos = 0,
00147            typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
00148            __n = (std::basic_string<_CharT, _Traits, _Alloc>::npos))
00149     : _Base(__str, __pos, __n) { }
00150 
00151       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00152       // 396. what are characters zero and one.
00153       template<class _CharT, class _Traits, class _Alloc>
00154     bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str,
00155            typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
00156            __pos,
00157            typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
00158            __n,
00159            _CharT __zero, _CharT __one = _CharT('1'))
00160     : _Base(__str, __pos, __n, __zero, __one) { }
00161 
00162       bitset(const _Base& __x) : _Base(__x) { }
00163 
00164 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00165       template<typename _CharT>
00166         explicit
00167         bitset(const _CharT* __str,
00168            typename std::basic_string<_CharT>::size_type __n
00169            = std::basic_string<_CharT>::npos,
00170            _CharT __zero = _CharT('0'), _CharT __one = _CharT('1'))
00171     : _Base(__str, __n, __zero, __one) { }
00172 #endif
00173 
00174       // 23.3.5.2 bitset operations:
00175       bitset<_Nb>&
00176       operator&=(const bitset<_Nb>& __rhs)
00177       {
00178     _M_base() &= __rhs;
00179     return *this;
00180       }
00181 
00182       bitset<_Nb>&
00183       operator|=(const bitset<_Nb>& __rhs)
00184       {
00185     _M_base() |= __rhs;
00186     return *this;
00187       }
00188 
00189       bitset<_Nb>&
00190       operator^=(const bitset<_Nb>& __rhs)
00191       {
00192     _M_base() ^= __rhs;
00193     return *this;
00194       }
00195 
00196       bitset<_Nb>&
00197       operator<<=(size_t __pos)
00198       {
00199     _M_base() <<= __pos;
00200     return *this;
00201       }
00202 
00203       bitset<_Nb>&
00204       operator>>=(size_t __pos)
00205       {
00206     _M_base() >>= __pos;
00207     return *this;
00208       }
00209 
00210       bitset<_Nb>&
00211       set()
00212       {
00213     _Base::set();
00214     return *this;
00215       }
00216 
00217       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00218       // 186. bitset::set() second parameter should be bool
00219       bitset<_Nb>&
00220       set(size_t __pos, bool __val = true)
00221       {
00222     _Base::set(__pos, __val);
00223     return *this;
00224       }
00225 
00226       bitset<_Nb>&
00227       reset()
00228       {
00229     _Base::reset();
00230     return *this;
00231       }
00232 
00233       bitset<_Nb>&
00234       reset(size_t __pos)
00235       {
00236     _Base::reset(__pos);
00237     return *this;
00238       }
00239 
00240       bitset<_Nb> operator~() const { return bitset(~_M_base()); }
00241 
00242       bitset<_Nb>&
00243       flip()
00244       {
00245     _Base::flip();
00246     return *this;
00247       }
00248 
00249       bitset<_Nb>&
00250       flip(size_t __pos)
00251       {
00252     _Base::flip(__pos);
00253     return *this;
00254       }
00255 
00256       // element access:
00257       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00258       // 11. Bitset minor problems
00259       reference
00260       operator[](size_t __pos)
00261       {
00262     __glibcxx_check_subscript(__pos);
00263 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00264     return _M_base()[__pos];
00265 #else
00266     return reference(_M_base()[__pos], this);
00267 #endif
00268       }
00269 
00270       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00271       // 11. Bitset minor problems
00272       bool
00273       operator[](size_t __pos) const
00274       {
00275     __glibcxx_check_subscript(__pos);
00276     return _M_base()[__pos];
00277       }
00278 
00279       using _Base::to_ulong;
00280 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00281       using _Base::to_ullong;
00282 #endif
00283 
00284       template <typename _CharT, typename _Traits, typename _Alloc>
00285         std::basic_string<_CharT, _Traits, _Alloc>
00286         to_string() const
00287         { return _M_base().template to_string<_CharT, _Traits, _Alloc>(); }
00288 
00289       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00290       // 396. what are characters zero and one.
00291       template<class _CharT, class _Traits, class _Alloc>
00292     std::basic_string<_CharT, _Traits, _Alloc>
00293     to_string(_CharT __zero, _CharT __one = _CharT('1')) const
00294     {
00295       return _M_base().template
00296         to_string<_CharT, _Traits, _Alloc>(__zero, __one);
00297     }
00298 
00299       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00300       // 434. bitset::to_string() hard to use.
00301       template<typename _CharT, typename _Traits>
00302         std::basic_string<_CharT, _Traits, std::allocator<_CharT> >
00303         to_string() const
00304         { return to_string<_CharT, _Traits, std::allocator<_CharT> >(); }
00305 
00306       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00307       // 853. to_string needs updating with zero and one.
00308       template<class _CharT, class _Traits>
00309     std::basic_string<_CharT, _Traits, std::allocator<_CharT> >
00310     to_string(_CharT __zero, _CharT __one = _CharT('1')) const
00311     { return to_string<_CharT, _Traits,
00312                        std::allocator<_CharT> >(__zero, __one); }
00313 
00314       template<typename _CharT>
00315         std::basic_string<_CharT, std::char_traits<_CharT>,
00316                           std::allocator<_CharT> >
00317         to_string() const
00318         {
00319           return to_string<_CharT, std::char_traits<_CharT>,
00320                            std::allocator<_CharT> >();
00321         }
00322 
00323       template<class _CharT>
00324     std::basic_string<_CharT, std::char_traits<_CharT>,
00325                       std::allocator<_CharT> >
00326     to_string(_CharT __zero, _CharT __one = _CharT('1')) const
00327     {
00328       return to_string<_CharT, std::char_traits<_CharT>,
00329                        std::allocator<_CharT> >(__zero, __one);
00330     }
00331 
00332       std::basic_string<char, std::char_traits<char>, std::allocator<char> >
00333       to_string() const
00334       {
00335     return to_string<char,std::char_traits<char>,std::allocator<char> >();
00336       }
00337 
00338       std::basic_string<char, std::char_traits<char>, std::allocator<char> >
00339       to_string(char __zero, char __one = '1') const
00340       {
00341     return to_string<char, std::char_traits<char>,
00342                      std::allocator<char> >(__zero, __one);
00343       }
00344 
00345       using _Base::count;
00346       using _Base::size;
00347 
00348       bool
00349       operator==(const bitset<_Nb>& __rhs) const
00350       { return _M_base() == __rhs; }
00351 
00352       bool
00353       operator!=(const bitset<_Nb>& __rhs) const
00354       { return _M_base() != __rhs; }
00355 
00356       using _Base::test;
00357       using _Base::all;
00358       using _Base::any;
00359       using _Base::none;
00360 
00361       bitset<_Nb>
00362       operator<<(size_t __pos) const
00363       { return bitset<_Nb>(_M_base() << __pos); }
00364 
00365       bitset<_Nb>
00366       operator>>(size_t __pos) const
00367       { return bitset<_Nb>(_M_base() >> __pos); }
00368 
00369       _Base&
00370       _M_base() { return *this; }
00371 
00372       const _Base&
00373       _M_base() const { return *this; }
00374     };
00375 
00376   template<size_t _Nb>
00377     bitset<_Nb>
00378     operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y)
00379     { return bitset<_Nb>(__x) &= __y; }
00380 
00381   template<size_t _Nb>
00382     bitset<_Nb>
00383     operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y)
00384     { return bitset<_Nb>(__x) |= __y; }
00385 
00386   template<size_t _Nb>
00387     bitset<_Nb>
00388     operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y)
00389     { return bitset<_Nb>(__x) ^= __y; }
00390 
00391   template<typename _CharT, typename _Traits, size_t _Nb>
00392     std::basic_istream<_CharT, _Traits>&
00393     operator>>(std::basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x)
00394     { return __is >> __x._M_base(); }
00395 
00396   template<typename _CharT, typename _Traits, size_t _Nb>
00397     std::basic_ostream<_CharT, _Traits>&
00398     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
00399            const bitset<_Nb>& __x)
00400     { return __os << __x._M_base(); }
00401 
00402 } // namespace __debug
00403 
00404 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00405   // DR 1182.
00406   /// std::hash specialization for bitset.
00407   template<size_t _Nb>
00408     struct hash<__debug::bitset<_Nb>>
00409     : public __hash_base<size_t, __debug::bitset<_Nb>>
00410     {
00411       size_t
00412       operator()(const __debug::bitset<_Nb>& __b) const
00413       { return std::hash<_GLIBCXX_STD_C::bitset<_Nb>>()(__b._M_base()); }
00414     };
00415 #endif
00416 
00417 } // namespace std
00418 
00419 #endif