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
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_D::bitset<_Nb>, 
00045       public __gnu_debug::_Safe_sequence_base
00046     {
00047       typedef _GLIBCXX_STD_D::bitset<_Nb> _Base;
00048       typedef __gnu_debug::_Safe_sequence_base  _Safe_base;
00049 
00050     public:
00051       // bit reference:
00052       class reference
00053       : private _Base::reference, public __gnu_debug::_Safe_iterator_base
00054       {
00055     typedef typename _Base::reference _Base_ref;
00056 
00057     friend class bitset;
00058     reference();
00059 
00060     reference(const _Base_ref& __base, bitset* __seq)
00061     : _Base_ref(__base), _Safe_iterator_base(__seq, false)
00062     { }
00063 
00064       public:
00065     reference(const reference& __x)
00066     : _Base_ref(__x), _Safe_iterator_base(__x, false)
00067     { }
00068 
00069     reference&
00070     operator=(bool __x)
00071     {
00072       _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
00073                   _M_message(__gnu_debug::__msg_bad_bitset_write)
00074                 ._M_iterator(*this));
00075       *static_cast<_Base_ref*>(this) = __x;
00076       return *this;
00077     }
00078 
00079     reference&
00080     operator=(const reference& __x)
00081     {
00082       _GLIBCXX_DEBUG_VERIFY(! __x._M_singular(),
00083                    _M_message(__gnu_debug::__msg_bad_bitset_read)
00084                 ._M_iterator(__x));
00085       _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
00086                   _M_message(__gnu_debug::__msg_bad_bitset_write)
00087                 ._M_iterator(*this));
00088       *static_cast<_Base_ref*>(this) = __x;
00089       return *this;
00090     }
00091 
00092     bool
00093     operator~() const
00094     {
00095       _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
00096                    _M_message(__gnu_debug::__msg_bad_bitset_read)
00097                 ._M_iterator(*this));
00098       return ~(*static_cast<const _Base_ref*>(this));
00099     }
00100 
00101     operator bool() const
00102     {
00103       _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
00104                   _M_message(__gnu_debug::__msg_bad_bitset_read)
00105                 ._M_iterator(*this));
00106       return *static_cast<const _Base_ref*>(this);
00107     }
00108 
00109     reference&
00110     flip()
00111     {
00112       _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
00113                   _M_message(__gnu_debug::__msg_bad_bitset_flip)
00114                 ._M_iterator(*this));
00115       _Base_ref::flip();
00116       return *this;
00117     }
00118       };
00119 
00120       // 23.3.5.1 constructors:
00121       bitset() : _Base() { }
00122 
00123 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00124       bitset(unsigned long long __val)
00125 #else
00126       bitset(unsigned long __val)
00127 #endif
00128       : _Base(__val) { }
00129 
00130       template<typename _CharT, typename _Traits, typename _Alloc>
00131         explicit
00132         bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str,
00133            typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
00134            __pos = 0,
00135            typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
00136            __n = (std::basic_string<_CharT, _Traits, _Alloc>::npos))
00137     : _Base(__str, __pos, __n) { }
00138 
00139       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00140       // 396. what are characters zero and one.
00141       template<class _CharT, class _Traits, class _Alloc>
00142     bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str,
00143            typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
00144            __pos,
00145            typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
00146            __n,
00147            _CharT __zero, _CharT __one = _CharT('1'))
00148     : _Base(__str, __pos, __n, __zero, __one) { }
00149 
00150       bitset(const _Base& __x) : _Base(__x), _Safe_base() { }
00151 
00152 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00153       explicit
00154       bitset(const char* __str) : _Base(__str) { }
00155 #endif
00156 
00157       // 23.3.5.2 bitset operations:
00158       bitset<_Nb>&
00159       operator&=(const bitset<_Nb>& __rhs)
00160       {
00161     _M_base() &= __rhs;
00162     return *this;
00163       }
00164 
00165       bitset<_Nb>&
00166       operator|=(const bitset<_Nb>& __rhs)
00167       {
00168     _M_base() |= __rhs;
00169     return *this;
00170       }
00171 
00172       bitset<_Nb>&
00173       operator^=(const bitset<_Nb>& __rhs)
00174       {
00175     _M_base() ^= __rhs;
00176     return *this;
00177       }
00178 
00179       bitset<_Nb>&
00180       operator<<=(size_t __pos)
00181       {
00182     _M_base() <<= __pos;
00183     return *this;
00184       }
00185 
00186       bitset<_Nb>&
00187       operator>>=(size_t __pos)
00188       {
00189     _M_base() >>= __pos;
00190     return *this;
00191       }
00192 
00193       bitset<_Nb>&
00194       set()
00195       {
00196     _Base::set();
00197     return *this;
00198       }
00199 
00200       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00201       // 186. bitset::set() second parameter should be bool
00202       bitset<_Nb>&
00203       set(size_t __pos, bool __val = true)
00204       {
00205     _Base::set(__pos, __val);
00206     return *this;
00207       }
00208 
00209       bitset<_Nb>&
00210       reset()
00211       {
00212     _Base::reset();
00213     return *this;
00214       }
00215 
00216       bitset<_Nb>&
00217       reset(size_t __pos)
00218       {
00219     _Base::reset(__pos);
00220     return *this;
00221       }
00222 
00223       bitset<_Nb> operator~() const { return bitset(~_M_base()); }
00224 
00225       bitset<_Nb>&
00226       flip()
00227       {
00228     _Base::flip();
00229     return *this;
00230       }
00231 
00232       bitset<_Nb>&
00233       flip(size_t __pos)
00234       {
00235     _Base::flip(__pos);
00236     return *this;
00237       }
00238 
00239       // element access:
00240       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00241       // 11. Bitset minor problems
00242       reference
00243       operator[](size_t __pos)
00244       {
00245     __glibcxx_check_subscript(__pos);
00246     return reference(_M_base()[__pos], this);
00247       }
00248 
00249       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00250       // 11. Bitset minor problems
00251       bool
00252       operator[](size_t __pos) const
00253       {
00254     __glibcxx_check_subscript(__pos);
00255     return _M_base()[__pos];
00256       }
00257 
00258       using _Base::to_ulong;
00259 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00260       using _Base::to_ullong;
00261 #endif
00262 
00263       template <typename _CharT, typename _Traits, typename _Alloc>
00264         std::basic_string<_CharT, _Traits, _Alloc>
00265         to_string() const
00266         { return _M_base().template to_string<_CharT, _Traits, _Alloc>(); }
00267 
00268       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00269       // 396. what are characters zero and one.
00270       template<class _CharT, class _Traits, class _Alloc>
00271     std::basic_string<_CharT, _Traits, _Alloc>
00272     to_string(_CharT __zero, _CharT __one = _CharT('1')) const
00273     {
00274       return _M_base().template
00275         to_string<_CharT, _Traits, _Alloc>(__zero, __one);
00276     }
00277 
00278       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00279       // 434. bitset::to_string() hard to use.
00280       template<typename _CharT, typename _Traits>
00281         std::basic_string<_CharT, _Traits, std::allocator<_CharT> >
00282         to_string() const
00283         { return to_string<_CharT, _Traits, std::allocator<_CharT> >(); }
00284 
00285       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00286       // 853. to_string needs updating with zero and one.
00287       template<class _CharT, class _Traits>
00288     std::basic_string<_CharT, _Traits, std::allocator<_CharT> >
00289     to_string(_CharT __zero, _CharT __one = _CharT('1')) const
00290     { return to_string<_CharT, _Traits,
00291                        std::allocator<_CharT> >(__zero, __one); }
00292 
00293       template<typename _CharT>
00294         std::basic_string<_CharT, std::char_traits<_CharT>,
00295                           std::allocator<_CharT> >
00296         to_string() const
00297         {
00298           return to_string<_CharT, std::char_traits<_CharT>,
00299                            std::allocator<_CharT> >();
00300         }
00301 
00302       template<class _CharT>
00303     std::basic_string<_CharT, std::char_traits<_CharT>,
00304                       std::allocator<_CharT> >
00305     to_string(_CharT __zero, _CharT __one = _CharT('1')) const
00306     {
00307       return to_string<_CharT, std::char_traits<_CharT>,
00308                        std::allocator<_CharT> >(__zero, __one);
00309     }
00310 
00311       std::basic_string<char, std::char_traits<char>, std::allocator<char> >
00312       to_string() const
00313       {
00314     return to_string<char,std::char_traits<char>,std::allocator<char> >();
00315       }
00316 
00317       std::basic_string<char, std::char_traits<char>, std::allocator<char> >
00318       to_string(char __zero, char __one = '1') const
00319       {
00320     return to_string<char, std::char_traits<char>,
00321                      std::allocator<char> >(__zero, __one);
00322       }
00323 
00324       using _Base::count;
00325       using _Base::size;
00326 
00327       bool
00328       operator==(const bitset<_Nb>& __rhs) const
00329       { return _M_base() == __rhs; }
00330 
00331       bool
00332       operator!=(const bitset<_Nb>& __rhs) const
00333       { return _M_base() != __rhs; }
00334 
00335       using _Base::test;
00336       using _Base::all;
00337       using _Base::any;
00338       using _Base::none;
00339 
00340       bitset<_Nb>
00341       operator<<(size_t __pos) const
00342       { return bitset<_Nb>(_M_base() << __pos); }
00343 
00344       bitset<_Nb>
00345       operator>>(size_t __pos) const
00346       { return bitset<_Nb>(_M_base() >> __pos); }
00347 
00348       _Base&
00349       _M_base() { return *this; }
00350 
00351       const _Base&
00352       _M_base() const { return *this; }
00353     };
00354 
00355   template<size_t _Nb>
00356     bitset<_Nb>
00357     operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y)
00358     { return bitset<_Nb>(__x) &= __y; }
00359 
00360   template<size_t _Nb>
00361     bitset<_Nb>
00362     operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y)
00363     { return bitset<_Nb>(__x) |= __y; }
00364 
00365   template<size_t _Nb>
00366     bitset<_Nb>
00367     operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y)
00368     { return bitset<_Nb>(__x) ^= __y; }
00369 
00370   template<typename _CharT, typename _Traits, size_t _Nb>
00371     std::basic_istream<_CharT, _Traits>&
00372     operator>>(std::basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x)
00373     { return __is >> __x._M_base(); }
00374 
00375   template<typename _CharT, typename _Traits, size_t _Nb>
00376     std::basic_ostream<_CharT, _Traits>&
00377     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
00378            const bitset<_Nb>& __x)
00379     { return __os << __x._M_base(); }
00380 
00381 } // namespace __debug
00382 
00383 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00384   // DR 1182.
00385   /// std::hash specialization for bitset.
00386   template<size_t _Nb>
00387     struct hash<__debug::bitset<_Nb>>
00388     : public std::unary_function<__debug::bitset<_Nb>, size_t>
00389     {
00390       size_t
00391       operator()(const __debug::bitset<_Nb>& __b) const
00392       { return std::hash<_GLIBCXX_STD_D::bitset<_Nb>>()(__b._M_base()); }
00393     };
00394 #endif
00395 
00396 } // namespace std
00397 
00398 #endif