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