libstdc++
bitset
Go to the documentation of this file.
00001 // Debugging bitset implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2003-2019 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 #pragma GCC system_header
00033 
00034 #include <bitset>
00035 #include <debug/safe_sequence.h>
00036 #include <debug/safe_iterator.h>
00037 
00038 namespace std _GLIBCXX_VISIBILITY(default)
00039 {
00040 namespace __debug
00041 {
00042   /// Class std::bitset with additional safety/checking/debug instrumentation.
00043   template<size_t _Nb>
00044     class bitset
00045     : public _GLIBCXX_STD_C::bitset<_Nb>
00046 #if __cplusplus < 201103L
00047     , public __gnu_debug::_Safe_sequence_base
00048 #endif
00049     {
00050       typedef _GLIBCXX_STD_C::bitset<_Nb> _Base;
00051 
00052     public:
00053       // In C++11 we rely on normal reference type to preserve the property
00054       // of bitset to be use as a literal.
00055       // TODO: Find another solution.
00056 #if __cplusplus >= 201103L
00057       typedef typename _Base::reference reference;
00058 #else
00059       // bit reference:
00060       class reference
00061       : private _Base::reference
00062         , public __gnu_debug::_Safe_iterator_base
00063       {
00064         typedef typename _Base::reference _Base_ref;
00065 
00066         friend class bitset;
00067         reference();
00068 
00069         reference(const _Base_ref& __base, bitset* __seq) _GLIBCXX_NOEXCEPT
00070         : _Base_ref(__base)
00071         , _Safe_iterator_base(__seq, false)
00072         { }
00073 
00074       public:
00075         reference(const reference& __x) _GLIBCXX_NOEXCEPT
00076         : _Base_ref(__x)
00077         , _Safe_iterator_base(__x, false)
00078         { }
00079 
00080         reference&
00081         operator=(bool __x) _GLIBCXX_NOEXCEPT
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) _GLIBCXX_NOEXCEPT
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 _GLIBCXX_NOEXCEPT
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 _GLIBCXX_NOEXCEPT
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() _GLIBCXX_NOEXCEPT
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() _GLIBCXX_NOEXCEPT
00134       : _Base() { }
00135 
00136 #if __cplusplus >= 201103L
00137       constexpr bitset(unsigned long long __val) noexcept
00138 #else
00139       bitset(unsigned long __val)
00140 #endif
00141       : _Base(__val) { }
00142 
00143       template<typename _CharT, typename _Traits, typename _Alloc>
00144         explicit
00145         bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str,
00146                typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
00147                __pos = 0,
00148                typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
00149                __n = (std::basic_string<_CharT, _Traits, _Alloc>::npos))
00150         : _Base(__str, __pos, __n) { }
00151 
00152       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00153       // 396. what are characters zero and one.
00154       template<class _CharT, class _Traits, class _Alloc>
00155         bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str,
00156                typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
00157                __pos,
00158                typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
00159                __n,
00160                _CharT __zero, _CharT __one = _CharT('1'))
00161         : _Base(__str, __pos, __n, __zero, __one) { }
00162 
00163       bitset(const _Base& __x) : _Base(__x) { }
00164 
00165 #if __cplusplus >= 201103L
00166       template<typename _CharT>
00167         explicit
00168         bitset(const _CharT* __str,
00169                typename std::basic_string<_CharT>::size_type __n
00170                = std::basic_string<_CharT>::npos,
00171                _CharT __zero = _CharT('0'), _CharT __one = _CharT('1'))
00172         : _Base(__str, __n, __zero, __one) { }
00173 #endif
00174 
00175       // 23.3.5.2 bitset operations:
00176       bitset<_Nb>&
00177       operator&=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT
00178       {
00179         _M_base() &= __rhs;
00180         return *this;
00181       }
00182 
00183       bitset<_Nb>&
00184       operator|=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT
00185       {
00186         _M_base() |= __rhs;
00187         return *this;
00188       }
00189 
00190       bitset<_Nb>&
00191       operator^=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT
00192       {
00193         _M_base() ^= __rhs;
00194         return *this;
00195       }
00196 
00197       bitset<_Nb>&
00198       operator<<=(size_t __pos) _GLIBCXX_NOEXCEPT
00199       {
00200         _M_base() <<= __pos;
00201         return *this;
00202       }
00203 
00204       bitset<_Nb>&
00205       operator>>=(size_t __pos) _GLIBCXX_NOEXCEPT
00206       {
00207         _M_base() >>= __pos;
00208         return *this;
00209       }
00210 
00211       bitset<_Nb>&
00212       set() _GLIBCXX_NOEXCEPT
00213       {
00214         _Base::set();
00215         return *this;
00216       }
00217 
00218       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00219       // 186. bitset::set() second parameter should be bool
00220       bitset<_Nb>&
00221       set(size_t __pos, bool __val = true)
00222       {
00223         _Base::set(__pos, __val);
00224         return *this;
00225       }
00226 
00227       bitset<_Nb>&
00228       reset() _GLIBCXX_NOEXCEPT
00229       {
00230         _Base::reset();
00231         return *this;
00232       }
00233 
00234       bitset<_Nb>&
00235       reset(size_t __pos)
00236       {
00237         _Base::reset(__pos);
00238         return *this;
00239       }
00240 
00241       bitset<_Nb>
00242       operator~() const _GLIBCXX_NOEXCEPT
00243       { return bitset(~_M_base()); }
00244 
00245       bitset<_Nb>&
00246       flip() _GLIBCXX_NOEXCEPT
00247       {
00248         _Base::flip();
00249         return *this;
00250       }
00251 
00252       bitset<_Nb>&
00253       flip(size_t __pos)
00254       {
00255         _Base::flip(__pos);
00256         return *this;
00257       }
00258 
00259       // element access:
00260       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00261       // 11. Bitset minor problems
00262       reference
00263       operator[](size_t __pos)
00264       {
00265         __glibcxx_check_subscript(__pos);
00266 #if __cplusplus >= 201103L
00267         return _M_base()[__pos];
00268 #else
00269         return reference(_M_base()[__pos], this);
00270 #endif
00271       }
00272 
00273       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00274       // 11. Bitset minor problems
00275       _GLIBCXX_CONSTEXPR bool
00276       operator[](size_t __pos) const
00277       {
00278 #if __cplusplus < 201103L
00279         // TODO: Check in debug-mode too.
00280         __glibcxx_check_subscript(__pos);
00281 #endif
00282         return _Base::operator[](__pos);
00283       }
00284 
00285       using _Base::to_ulong;
00286 #if __cplusplus >= 201103L
00287       using _Base::to_ullong;
00288 #endif
00289 
00290       template <typename _CharT, typename _Traits, typename _Alloc>
00291         std::basic_string<_CharT, _Traits, _Alloc>
00292         to_string() const
00293         { return _M_base().template to_string<_CharT, _Traits, _Alloc>(); }
00294 
00295       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00296       // 396. what are characters zero and one.
00297       template<class _CharT, class _Traits, class _Alloc>
00298         std::basic_string<_CharT, _Traits, _Alloc>
00299         to_string(_CharT __zero, _CharT __one = _CharT('1')) const
00300         {
00301           return _M_base().template
00302             to_string<_CharT, _Traits, _Alloc>(__zero, __one);
00303         }
00304 
00305       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00306       // 434. bitset::to_string() hard to use.
00307       template<typename _CharT, typename _Traits>
00308         std::basic_string<_CharT, _Traits, std::allocator<_CharT> >
00309         to_string() const
00310         { return to_string<_CharT, _Traits, std::allocator<_CharT> >(); }
00311 
00312       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00313       // 853. to_string needs updating with zero and one.
00314       template<class _CharT, class _Traits>
00315         std::basic_string<_CharT, _Traits, std::allocator<_CharT> >
00316         to_string(_CharT __zero, _CharT __one = _CharT('1')) const
00317         { return to_string<_CharT, _Traits,
00318                            std::allocator<_CharT> >(__zero, __one); }
00319 
00320       template<typename _CharT>
00321         std::basic_string<_CharT, std::char_traits<_CharT>,
00322                           std::allocator<_CharT> >
00323         to_string() const
00324         {
00325           return to_string<_CharT, std::char_traits<_CharT>,
00326                            std::allocator<_CharT> >();
00327         }
00328 
00329       template<class _CharT>
00330         std::basic_string<_CharT, std::char_traits<_CharT>,
00331                           std::allocator<_CharT> >
00332         to_string(_CharT __zero, _CharT __one = _CharT('1')) const
00333         {
00334           return to_string<_CharT, std::char_traits<_CharT>,
00335                            std::allocator<_CharT> >(__zero, __one);
00336         }
00337 
00338       std::basic_string<char, std::char_traits<char>, std::allocator<char> >
00339       to_string() const
00340       {
00341         return to_string<char,std::char_traits<char>,std::allocator<char> >();
00342       }
00343 
00344       std::basic_string<char, std::char_traits<char>, std::allocator<char> >
00345       to_string(char __zero, char __one = '1') const
00346       {
00347         return to_string<char, std::char_traits<char>,
00348                          std::allocator<char> >(__zero, __one);
00349       }
00350 
00351       using _Base::count;
00352       using _Base::size;
00353 
00354       bool
00355       operator==(const bitset<_Nb>& __rhs) const _GLIBCXX_NOEXCEPT
00356       { return _M_base() == __rhs; }
00357 
00358       bool
00359       operator!=(const bitset<_Nb>& __rhs) const _GLIBCXX_NOEXCEPT
00360       { return _M_base() != __rhs; }
00361 
00362       using _Base::test;
00363       using _Base::all;
00364       using _Base::any;
00365       using _Base::none;
00366 
00367       bitset<_Nb>
00368       operator<<(size_t __pos) const _GLIBCXX_NOEXCEPT
00369       { return bitset<_Nb>(_M_base() << __pos); }
00370 
00371       bitset<_Nb>
00372       operator>>(size_t __pos) const _GLIBCXX_NOEXCEPT
00373       { return bitset<_Nb>(_M_base() >> __pos); }
00374 
00375       _Base& 
00376       _M_base() _GLIBCXX_NOEXCEPT
00377       { return *this; }
00378 
00379       const _Base&
00380       _M_base() const _GLIBCXX_NOEXCEPT
00381       { return *this; }
00382     };
00383 
00384   template<size_t _Nb>
00385     bitset<_Nb>
00386     operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT
00387     { return bitset<_Nb>(__x) &= __y; }
00388 
00389   template<size_t _Nb>
00390     bitset<_Nb>
00391     operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT
00392     { return bitset<_Nb>(__x) |= __y; }
00393 
00394   template<size_t _Nb>
00395     bitset<_Nb>
00396     operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT
00397     { return bitset<_Nb>(__x) ^= __y; }
00398 
00399   template<typename _CharT, typename _Traits, size_t _Nb>
00400     std::basic_istream<_CharT, _Traits>&
00401     operator>>(std::basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x)
00402     { return __is >> __x._M_base(); }
00403 
00404   template<typename _CharT, typename _Traits, size_t _Nb>
00405     std::basic_ostream<_CharT, _Traits>&
00406     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
00407                const bitset<_Nb>& __x)
00408     { return __os << __x._M_base(); }
00409 
00410 } // namespace __debug
00411 
00412 #if __cplusplus >= 201103L
00413   // DR 1182.
00414   /// std::hash specialization for bitset.
00415   template<size_t _Nb>
00416     struct hash<__debug::bitset<_Nb>>
00417     : public __hash_base<size_t, __debug::bitset<_Nb>>
00418     {
00419       size_t
00420       operator()(const __debug::bitset<_Nb>& __b) const noexcept
00421       { return std::hash<_GLIBCXX_STD_C::bitset<_Nb>>()(__b._M_base()); }
00422     };
00423 #endif
00424 
00425 } // namespace std
00426 
00427 #endif