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