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 37namespace std 38{ 39namespace __debug 40{ 41 /// Class std::bitset with additional safety/checking/debug instrumentation. 42 template<size_t _Nb> 43 class bitset 44 : public _GLIBCXX_STD_D::bitset<_Nb>, 45 public __gnu_debug::_Safe_sequence_base 46 { 47 typedef _GLIBCXX_STD_D::bitset<_Nb> _Base; 48 typedef __gnu_debug::_Safe_sequence_base _Safe_base; 49 50 public: 51 // bit reference: 52 class reference 53 : private _Base::reference, public __gnu_debug::_Safe_iterator_base 54 { 55 typedef typename _Base::reference _Base_ref; 56 57 friend class bitset; 58 reference(); 59 60 reference(const _Base_ref& __base, bitset* __seq) 61 : _Base_ref(__base), _Safe_iterator_base(__seq, false) 62 { } 63 64 public: 65 reference(const reference& __x) 66 : _Base_ref(__x), _Safe_iterator_base(__x, false) 67 { } 68 69 reference& 70 operator=(bool __x) 71 { 72 _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), 73 _M_message(__gnu_debug::__msg_bad_bitset_write) 74 ._M_iterator(*this)); 75 *static_cast<_Base_ref*>(this) = __x; 76 return *this; 77 } 78 79 reference& 80 operator=(const reference& __x) 81 { 82 _GLIBCXX_DEBUG_VERIFY(! __x._M_singular(), 83 _M_message(__gnu_debug::__msg_bad_bitset_read) 84 ._M_iterator(__x)); 85 _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), 86 _M_message(__gnu_debug::__msg_bad_bitset_write) 87 ._M_iterator(*this)); 88 *static_cast<_Base_ref*>(this) = __x; 89 return *this; 90 } 91 92 bool 93 operator~() const 94 { 95 _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), 96 _M_message(__gnu_debug::__msg_bad_bitset_read) 97 ._M_iterator(*this)); 98 return ~(*static_cast<const _Base_ref*>(this)); 99 } 100 101 operator bool() const 102 { 103 _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), 104 _M_message(__gnu_debug::__msg_bad_bitset_read) 105 ._M_iterator(*this)); 106 return *static_cast<const _Base_ref*>(this); 107 } 108 109 reference& 110 flip() 111 { 112 _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), 113 _M_message(__gnu_debug::__msg_bad_bitset_flip) 114 ._M_iterator(*this)); 115 _Base_ref::flip(); 116 return *this; 117 } 118 }; 119 120 // 23.3.5.1 constructors: 121 bitset() : _Base() { } 122 123#ifdef __GXX_EXPERIMENTAL_CXX0X__ 124 bitset(unsigned long long __val) 125#else 126 bitset(unsigned long __val) 127#endif 128 : _Base(__val) { } 129 130 template<typename _CharT, typename _Traits, typename _Alloc> 131 explicit 132 bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str, 133 typename std::basic_string<_CharT, _Traits, _Alloc>::size_type 134 __pos = 0, 135 typename std::basic_string<_CharT, _Traits, _Alloc>::size_type 136 __n = (std::basic_string<_CharT, _Traits, _Alloc>::npos)) 137 : _Base(__str, __pos, __n) { } 138 139 // _GLIBCXX_RESOLVE_LIB_DEFECTS 140 // 396. what are characters zero and one. 141 template<class _CharT, class _Traits, class _Alloc> 142 bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str, 143 typename std::basic_string<_CharT, _Traits, _Alloc>::size_type 144 __pos, 145 typename std::basic_string<_CharT, _Traits, _Alloc>::size_type 146 __n, 147 _CharT __zero, _CharT __one = _CharT('1')) 148 : _Base(__str, __pos, __n, __zero, __one) { } 149 150 bitset(const _Base& __x) : _Base(__x), _Safe_base() { } 151 152#ifdef __GXX_EXPERIMENTAL_CXX0X__ 153 explicit 154 bitset(const char* __str) : _Base(__str) { } 155#endif 156 157 // 23.3.5.2 bitset operations: 158 bitset<_Nb>& 159 operator&=(const bitset<_Nb>& __rhs) 160 { 161 _M_base() &= __rhs; 162 return *this; 163 } 164 165 bitset<_Nb>& 166 operator|=(const bitset<_Nb>& __rhs) 167 { 168 _M_base() |= __rhs; 169 return *this; 170 } 171 172 bitset<_Nb>& 173 operator^=(const bitset<_Nb>& __rhs) 174 { 175 _M_base() ^= __rhs; 176 return *this; 177 } 178 179 bitset<_Nb>& 180 operator<<=(size_t __pos) 181 { 182 _M_base() <<= __pos; 183 return *this; 184 } 185 186 bitset<_Nb>& 187 operator>>=(size_t __pos) 188 { 189 _M_base() >>= __pos; 190 return *this; 191 } 192 193 bitset<_Nb>& 194 set() 195 { 196 _Base::set(); 197 return *this; 198 } 199 200 // _GLIBCXX_RESOLVE_LIB_DEFECTS 201 // 186. bitset::set() second parameter should be bool 202 bitset<_Nb>& 203 set(size_t __pos, bool __val = true) 204 { 205 _Base::set(__pos, __val); 206 return *this; 207 } 208 209 bitset<_Nb>& 210 reset() 211 { 212 _Base::reset(); 213 return *this; 214 } 215 216 bitset<_Nb>& 217 reset(size_t __pos) 218 { 219 _Base::reset(__pos); 220 return *this; 221 } 222 223 bitset<_Nb> operator~() const { return bitset(~_M_base()); } 224 225 bitset<_Nb>& 226 flip() 227 { 228 _Base::flip(); 229 return *this; 230 } 231 232 bitset<_Nb>& 233 flip(size_t __pos) 234 { 235 _Base::flip(__pos); 236 return *this; 237 } 238 239 // element access: 240 // _GLIBCXX_RESOLVE_LIB_DEFECTS 241 // 11. Bitset minor problems 242 reference 243 operator[](size_t __pos) 244 { 245 __glibcxx_check_subscript(__pos); 246 return reference(_M_base()[__pos], this); 247 } 248 249 // _GLIBCXX_RESOLVE_LIB_DEFECTS 250 // 11. Bitset minor problems 251 bool 252 operator[](size_t __pos) const 253 { 254 __glibcxx_check_subscript(__pos); 255 return _M_base()[__pos]; 256 } 257 258 using _Base::to_ulong; 259#ifdef __GXX_EXPERIMENTAL_CXX0X__ 260 using _Base::to_ullong; 261#endif 262 263 template <typename _CharT, typename _Traits, typename _Alloc> 264 std::basic_string<_CharT, _Traits, _Alloc> 265 to_string() const 266 { return _M_base().template to_string<_CharT, _Traits, _Alloc>(); } 267 268 // _GLIBCXX_RESOLVE_LIB_DEFECTS 269 // 396. what are characters zero and one. 270 template<class _CharT, class _Traits, class _Alloc> 271 std::basic_string<_CharT, _Traits, _Alloc> 272 to_string(_CharT __zero, _CharT __one = _CharT('1')) const 273 { 274 return _M_base().template 275 to_string<_CharT, _Traits, _Alloc>(__zero, __one); 276 } 277 278 // _GLIBCXX_RESOLVE_LIB_DEFECTS 279 // 434. bitset::to_string() hard to use. 280 template<typename _CharT, typename _Traits> 281 std::basic_string<_CharT, _Traits, std::allocator<_CharT> > 282 to_string() const 283 { return to_string<_CharT, _Traits, std::allocator<_CharT> >(); } 284 285 // _GLIBCXX_RESOLVE_LIB_DEFECTS 286 // 853. to_string needs updating with zero and one. 287 template<class _CharT, class _Traits> 288 std::basic_string<_CharT, _Traits, std::allocator<_CharT> > 289 to_string(_CharT __zero, _CharT __one = _CharT('1')) const 290 { return to_string<_CharT, _Traits, 291 std::allocator<_CharT> >(__zero, __one); } 292 293 template<typename _CharT> 294 std::basic_string<_CharT, std::char_traits<_CharT>, 295 std::allocator<_CharT> > 296 to_string() const 297 { 298 return to_string<_CharT, std::char_traits<_CharT>, 299 std::allocator<_CharT> >(); 300 } 301 302 template<class _CharT> 303 std::basic_string<_CharT, std::char_traits<_CharT>, 304 std::allocator<_CharT> > 305 to_string(_CharT __zero, _CharT __one = _CharT('1')) const 306 { 307 return to_string<_CharT, std::char_traits<_CharT>, 308 std::allocator<_CharT> >(__zero, __one); 309 } 310 311 std::basic_string<char, std::char_traits<char>, std::allocator<char> > 312 to_string() const 313 { 314 return to_string<char,std::char_traits<char>,std::allocator<char> >(); 315 } 316 317 std::basic_string<char, std::char_traits<char>, std::allocator<char> > 318 to_string(char __zero, char __one = '1') const 319 { 320 return to_string<char, std::char_traits<char>, 321 std::allocator<char> >(__zero, __one); 322 } 323 324 using _Base::count; 325 using _Base::size; 326 327 bool 328 operator==(const bitset<_Nb>& __rhs) const 329 { return _M_base() == __rhs; } 330 331 bool 332 operator!=(const bitset<_Nb>& __rhs) const 333 { return _M_base() != __rhs; } 334 335 using _Base::test; 336 using _Base::all; 337 using _Base::any; 338 using _Base::none; 339 340 bitset<_Nb> 341 operator<<(size_t __pos) const 342 { return bitset<_Nb>(_M_base() << __pos); } 343 344 bitset<_Nb> 345 operator>>(size_t __pos) const 346 { return bitset<_Nb>(_M_base() >> __pos); } 347 348 _Base& 349 _M_base() { return *this; } 350 351 const _Base& 352 _M_base() const { return *this; } 353 }; 354 355 template<size_t _Nb> 356 bitset<_Nb> 357 operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y) 358 { return bitset<_Nb>(__x) &= __y; } 359 360 template<size_t _Nb> 361 bitset<_Nb> 362 operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y) 363 { return bitset<_Nb>(__x) |= __y; } 364 365 template<size_t _Nb> 366 bitset<_Nb> 367 operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y) 368 { return bitset<_Nb>(__x) ^= __y; } 369 370 template<typename _CharT, typename _Traits, size_t _Nb> 371 std::basic_istream<_CharT, _Traits>& 372 operator>>(std::basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x) 373 { return __is >> __x._M_base(); } 374 375 template<typename _CharT, typename _Traits, size_t _Nb> 376 std::basic_ostream<_CharT, _Traits>& 377 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 378 const bitset<_Nb>& __x) 379 { return __os << __x._M_base(); } 380 381} // namespace __debug 382 383#ifdef __GXX_EXPERIMENTAL_CXX0X__ 384 // DR 1182. 385 /// std::hash specialization for bitset. 386 template<size_t _Nb> 387 struct hash<__debug::bitset<_Nb>> 388 : public std::unary_function<__debug::bitset<_Nb>, size_t> 389 { 390 size_t 391 operator()(const __debug::bitset<_Nb>& __b) const 392 { return std::hash<_GLIBCXX_STD_D::bitset<_Nb>>()(__b._M_base()); } 393 }; 394#endif 395 396} // namespace std 397 398#endif 399