1 // Debugging bitset implementation -*- C++ -*- 2 3 // Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 4 // Free Software Foundation, Inc. 5 // 6 // This file is part of the GNU ISO C++ Library. This library is free 7 // software; you can redistribute it and/or modify it under the 8 // terms of the GNU General Public License as published by the 9 // Free Software Foundation; either version 3, or (at your option) 10 // any later version. 11 12 // This library is distributed in the hope that it will be useful, 13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 // GNU General Public License for more details. 16 17 // Under Section 7 of GPL version 3, you are granted additional 18 // permissions described in the GCC Runtime Library Exception, version 19 // 3.1, as published by the Free Software Foundation. 20 21 // You should have received a copy of the GNU General Public License and 22 // a copy of the GCC Runtime Library Exception along with this program; 23 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24 // <http://www.gnu.org/licenses/>. 25 26 /** @file debug/bitset 27 * This file is a GNU debug extension to the Standard C++ Library. 28 */ 29 30 #ifndef _GLIBCXX_DEBUG_BITSET 31 #define _GLIBCXX_DEBUG_BITSET 32 33 #include <bitset> 34 #include <debug/safe_sequence.h> 35 #include <debug/safe_iterator.h> 36 37 namespace std _GLIBCXX_VISIBILITY(default) 38 { 39 namespace __debug 40 { 41 /// Class std::bitset with additional safety/checking/debug instrumentation. 42 template<size_t _Nb> 43 class bitset 44 : public _GLIBCXX_STD_C::bitset<_Nb> 45 #ifndef __GXX_EXPERIMENTAL_CXX0X__ 46 , public __gnu_debug::_Safe_sequence_base 47 #endif 48 { 49 typedef _GLIBCXX_STD_C::bitset<_Nb> _Base; 50 51 public: 52 // In C++0x we rely on normal reference type to preserve the property 53 // of bitset to be use as a literal. 54 // TODO: Find an other solution. 55 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 56 typedef typename _Base::reference reference; 57 #else 58 // bit reference: 59 class reference 60 : private _Base::reference 61 , public __gnu_debug::_Safe_iterator_base 62 { 63 typedef typename _Base::reference _Base_ref; 64 65 friend class bitset; 66 reference(); 67 68 reference(const _Base_ref& __base, 69 bitset* __seq __attribute__((__unused__))) 70 : _Base_ref(__base) 71 , _Safe_iterator_base(__seq, false) 72 { } 73 74 public: 75 reference(const reference& __x) 76 : _Base_ref(__x) 77 , _Safe_iterator_base(__x, false) 78 { } 79 80 reference& 81 operator=(bool __x) 82 { 83 _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), 84 _M_message(__gnu_debug::__msg_bad_bitset_write) 85 ._M_iterator(*this)); 86 *static_cast<_Base_ref*>(this) = __x; 87 return *this; 88 } 89 90 reference& 91 operator=(const reference& __x) 92 { 93 _GLIBCXX_DEBUG_VERIFY(! __x._M_singular(), 94 _M_message(__gnu_debug::__msg_bad_bitset_read) 95 ._M_iterator(__x)); 96 _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), 97 _M_message(__gnu_debug::__msg_bad_bitset_write) 98 ._M_iterator(*this)); 99 *static_cast<_Base_ref*>(this) = __x; 100 return *this; 101 } 102 103 bool 104 operator~() const 105 { 106 _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), 107 _M_message(__gnu_debug::__msg_bad_bitset_read) 108 ._M_iterator(*this)); 109 return ~(*static_cast<const _Base_ref*>(this)); 110 } 111 112 operator bool() const 113 { 114 _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), 115 _M_message(__gnu_debug::__msg_bad_bitset_read) 116 ._M_iterator(*this)); 117 return *static_cast<const _Base_ref*>(this); 118 } 119 120 reference& 121 flip() 122 { 123 _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), 124 _M_message(__gnu_debug::__msg_bad_bitset_flip) 125 ._M_iterator(*this)); 126 _Base_ref::flip(); 127 return *this; 128 } 129 }; 130 #endif 131 132 // 23.3.5.1 constructors: 133 _GLIBCXX_CONSTEXPR bitset() : _Base() { } 134 135 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 136 constexpr bitset(unsigned long long __val) 137 #else 138 bitset(unsigned long __val) 139 #endif 140 : _Base(__val) { } 141 142 template<typename _CharT, typename _Traits, typename _Alloc> 143 explicit 144 bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str, 145 typename std::basic_string<_CharT, _Traits, _Alloc>::size_type 146 __pos = 0, 147 typename std::basic_string<_CharT, _Traits, _Alloc>::size_type 148 __n = (std::basic_string<_CharT, _Traits, _Alloc>::npos)) 149 : _Base(__str, __pos, __n) { } 150 151 // _GLIBCXX_RESOLVE_LIB_DEFECTS 152 // 396. what are characters zero and one. 153 template<class _CharT, class _Traits, class _Alloc> 154 bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str, 155 typename std::basic_string<_CharT, _Traits, _Alloc>::size_type 156 __pos, 157 typename std::basic_string<_CharT, _Traits, _Alloc>::size_type 158 __n, 159 _CharT __zero, _CharT __one = _CharT('1')) 160 : _Base(__str, __pos, __n, __zero, __one) { } 161 162 bitset(const _Base& __x) : _Base(__x) { } 163 164 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 165 template<typename _CharT> 166 explicit 167 bitset(const _CharT* __str, 168 typename std::basic_string<_CharT>::size_type __n 169 = std::basic_string<_CharT>::npos, 170 _CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) 171 : _Base(__str, __n, __zero, __one) { } 172 #endif 173 174 // 23.3.5.2 bitset operations: 175 bitset<_Nb>& 176 operator&=(const bitset<_Nb>& __rhs) 177 { 178 _M_base() &= __rhs; 179 return *this; 180 } 181 182 bitset<_Nb>& 183 operator|=(const bitset<_Nb>& __rhs) 184 { 185 _M_base() |= __rhs; 186 return *this; 187 } 188 189 bitset<_Nb>& 190 operator^=(const bitset<_Nb>& __rhs) 191 { 192 _M_base() ^= __rhs; 193 return *this; 194 } 195 196 bitset<_Nb>& 197 operator<<=(size_t __pos) 198 { 199 _M_base() <<= __pos; 200 return *this; 201 } 202 203 bitset<_Nb>& 204 operator>>=(size_t __pos) 205 { 206 _M_base() >>= __pos; 207 return *this; 208 } 209 210 bitset<_Nb>& 211 set() 212 { 213 _Base::set(); 214 return *this; 215 } 216 217 // _GLIBCXX_RESOLVE_LIB_DEFECTS 218 // 186. bitset::set() second parameter should be bool 219 bitset<_Nb>& 220 set(size_t __pos, bool __val = true) 221 { 222 _Base::set(__pos, __val); 223 return *this; 224 } 225 226 bitset<_Nb>& 227 reset() 228 { 229 _Base::reset(); 230 return *this; 231 } 232 233 bitset<_Nb>& 234 reset(size_t __pos) 235 { 236 _Base::reset(__pos); 237 return *this; 238 } 239 240 bitset<_Nb> operator~() const { return bitset(~_M_base()); } 241 242 bitset<_Nb>& 243 flip() 244 { 245 _Base::flip(); 246 return *this; 247 } 248 249 bitset<_Nb>& 250 flip(size_t __pos) 251 { 252 _Base::flip(__pos); 253 return *this; 254 } 255 256 // element access: 257 // _GLIBCXX_RESOLVE_LIB_DEFECTS 258 // 11. Bitset minor problems 259 reference 260 operator[](size_t __pos) 261 { 262 __glibcxx_check_subscript(__pos); 263 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 264 return _M_base()[__pos]; 265 #else 266 return reference(_M_base()[__pos], this); 267 #endif 268 } 269 270 // _GLIBCXX_RESOLVE_LIB_DEFECTS 271 // 11. Bitset minor problems 272 bool 273 operator[](size_t __pos) const 274 { 275 __glibcxx_check_subscript(__pos); 276 return _M_base()[__pos]; 277 } 278 279 using _Base::to_ulong; 280 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 281 using _Base::to_ullong; 282 #endif 283 284 template <typename _CharT, typename _Traits, typename _Alloc> 285 std::basic_string<_CharT, _Traits, _Alloc> 286 to_string() const 287 { return _M_base().template to_string<_CharT, _Traits, _Alloc>(); } 288 289 // _GLIBCXX_RESOLVE_LIB_DEFECTS 290 // 396. what are characters zero and one. 291 template<class _CharT, class _Traits, class _Alloc> 292 std::basic_string<_CharT, _Traits, _Alloc> 293 to_string(_CharT __zero, _CharT __one = _CharT('1')) const 294 { 295 return _M_base().template 296 to_string<_CharT, _Traits, _Alloc>(__zero, __one); 297 } 298 299 // _GLIBCXX_RESOLVE_LIB_DEFECTS 300 // 434. bitset::to_string() hard to use. 301 template<typename _CharT, typename _Traits> 302 std::basic_string<_CharT, _Traits, std::allocator<_CharT> > 303 to_string() const 304 { return to_string<_CharT, _Traits, std::allocator<_CharT> >(); } 305 306 // _GLIBCXX_RESOLVE_LIB_DEFECTS 307 // 853. to_string needs updating with zero and one. 308 template<class _CharT, class _Traits> 309 std::basic_string<_CharT, _Traits, std::allocator<_CharT> > 310 to_string(_CharT __zero, _CharT __one = _CharT('1')) const 311 { return to_string<_CharT, _Traits, 312 std::allocator<_CharT> >(__zero, __one); } 313 314 template<typename _CharT> 315 std::basic_string<_CharT, std::char_traits<_CharT>, 316 std::allocator<_CharT> > 317 to_string() const 318 { 319 return to_string<_CharT, std::char_traits<_CharT>, 320 std::allocator<_CharT> >(); 321 } 322 323 template<class _CharT> 324 std::basic_string<_CharT, std::char_traits<_CharT>, 325 std::allocator<_CharT> > 326 to_string(_CharT __zero, _CharT __one = _CharT('1')) const 327 { 328 return to_string<_CharT, std::char_traits<_CharT>, 329 std::allocator<_CharT> >(__zero, __one); 330 } 331 332 std::basic_string<char, std::char_traits<char>, std::allocator<char> > 333 to_string() const 334 { 335 return to_string<char,std::char_traits<char>,std::allocator<char> >(); 336 } 337 338 std::basic_string<char, std::char_traits<char>, std::allocator<char> > 339 to_string(char __zero, char __one = '1') const 340 { 341 return to_string<char, std::char_traits<char>, 342 std::allocator<char> >(__zero, __one); 343 } 344 345 using _Base::count; 346 using _Base::size; 347 348 bool 349 operator==(const bitset<_Nb>& __rhs) const 350 { return _M_base() == __rhs; } 351 352 bool 353 operator!=(const bitset<_Nb>& __rhs) const 354 { return _M_base() != __rhs; } 355 356 using _Base::test; 357 using _Base::all; 358 using _Base::any; 359 using _Base::none; 360 361 bitset<_Nb> 362 operator<<(size_t __pos) const 363 { return bitset<_Nb>(_M_base() << __pos); } 364 365 bitset<_Nb> 366 operator>>(size_t __pos) const 367 { return bitset<_Nb>(_M_base() >> __pos); } 368 369 _Base& 370 _M_base() { return *this; } 371 372 const _Base& 373 _M_base() const { return *this; } 374 }; 375 376 template<size_t _Nb> 377 bitset<_Nb> 378 operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y) 379 { return bitset<_Nb>(__x) &= __y; } 380 381 template<size_t _Nb> 382 bitset<_Nb> 383 operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y) 384 { return bitset<_Nb>(__x) |= __y; } 385 386 template<size_t _Nb> 387 bitset<_Nb> 388 operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y) 389 { return bitset<_Nb>(__x) ^= __y; } 390 391 template<typename _CharT, typename _Traits, size_t _Nb> 392 std::basic_istream<_CharT, _Traits>& 393 operator>>(std::basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x) 394 { return __is >> __x._M_base(); } 395 396 template<typename _CharT, typename _Traits, size_t _Nb> 397 std::basic_ostream<_CharT, _Traits>& 398 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 399 const bitset<_Nb>& __x) 400 { return __os << __x._M_base(); } 401 402 } // namespace __debug 403 404 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 405 // DR 1182. 406 /// std::hash specialization for bitset. 407 template<size_t _Nb> 408 struct hash<__debug::bitset<_Nb>> 409 : public __hash_base<size_t, __debug::bitset<_Nb>> 410 { 411 size_t 412 operator()(const __debug::bitset<_Nb>& __b) const noexcept 413 { return std::hash<_GLIBCXX_STD_C::bitset<_Nb>>()(__b._M_base()); } 414 }; 415 #endif 416 417 } // namespace std 418 419 #endif 420