libstdc++
|
00001 // Debugging bitset implementation -*- C++ -*- 00002 00003 // Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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 another 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__))) _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 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 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 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 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 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 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 #ifndef __GXX_EXPERIMENTAL_CXX0X__ 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 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 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 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 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