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