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