diff options
author | kan <kan@FreeBSD.org> | 2007-05-19 01:25:07 +0000 |
---|---|---|
committer | kan <kan@FreeBSD.org> | 2007-05-19 01:25:07 +0000 |
commit | 7865836f4b0f698454c31b4593effcb032c22c1e (patch) | |
tree | ea6c2718dc1e45ed535d194df808ef31f0ebac92 /contrib/libstdc++/include/std/std_bitset.h | |
parent | 1f9ea4d0a40cca64d60cf4dab152349da7b9dddf (diff) | |
download | FreeBSD-src-7865836f4b0f698454c31b4593effcb032c22c1e.zip FreeBSD-src-7865836f4b0f698454c31b4593effcb032c22c1e.tar.gz |
GCC 4.2.0 release C++ standard library and runtime support code.
Diffstat (limited to 'contrib/libstdc++/include/std/std_bitset.h')
-rw-r--r-- | contrib/libstdc++/include/std/std_bitset.h | 1171 |
1 files changed, 643 insertions, 528 deletions
diff --git a/contrib/libstdc++/include/std/std_bitset.h b/contrib/libstdc++/include/std/std_bitset.h index 01e3f90..860e775 100644 --- a/contrib/libstdc++/include/std/std_bitset.h +++ b/contrib/libstdc++/include/std/std_bitset.h @@ -1,6 +1,7 @@ // <bitset> -*- C++ -*- -// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 +// Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -15,7 +16,7 @@ // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software @@ -40,9 +41,8 @@ * purpose. It is provided "as is" without express or implied warranty. */ -/** @file bitset - * This is a Standard C++ Library header. You should @c #include this header - * in your programs, rather than any of the "st[dl]_*.h" implementation files. +/** @file include/bitset + * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_BITSET @@ -61,10 +61,11 @@ #define _GLIBCXX_BITSET_BITS_PER_WORD numeric_limits<unsigned long>::digits #define _GLIBCXX_BITSET_WORDS(__n) \ - ((__n) < 1 ? 0 : ((__n) + _GLIBCXX_BITSET_BITS_PER_WORD - 1)/_GLIBCXX_BITSET_BITS_PER_WORD) + ((__n) < 1 ? 0 : ((__n) + _GLIBCXX_BITSET_BITS_PER_WORD - 1) \ + / _GLIBCXX_BITSET_BITS_PER_WORD) + +_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD) -namespace _GLIBCXX_STD -{ /** * @if maint * Base class, general case. It is a class inveriant that _Nw will be @@ -81,7 +82,9 @@ namespace _GLIBCXX_STD /// 0 is the least significant word. _WordT _M_w[_Nw]; - _Base_bitset() { _M_do_reset(); } + _Base_bitset() + { _M_do_reset(); } + _Base_bitset(unsigned long __val) { _M_do_reset(); @@ -113,10 +116,12 @@ namespace _GLIBCXX_STD { return _M_w[_S_whichword(__pos)]; } _WordT& - _M_hiword() { return _M_w[_Nw - 1]; } + _M_hiword() + { return _M_w[_Nw - 1]; } _WordT - _M_hiword() const { return _M_w[_Nw - 1]; } + _M_hiword() const + { return _M_w[_Nw - 1]; } void _M_do_and(const _Base_bitset<_Nw>& __x) @@ -160,7 +165,8 @@ namespace _GLIBCXX_STD } void - _M_do_reset() { memset(_M_w, 0, _Nw * sizeof(_WordT)); } + _M_do_reset() + { std::memset(_M_w, 0, _Nw * sizeof(_WordT)); } bool _M_is_equal(const _Base_bitset<_Nw>& __x) const @@ -220,10 +226,11 @@ namespace _GLIBCXX_STD _M_w[__n] = _M_w[__n - __wshift]; else { - const size_t __sub_offset = _GLIBCXX_BITSET_BITS_PER_WORD - __offset; + const size_t __sub_offset = (_GLIBCXX_BITSET_BITS_PER_WORD + - __offset); for (size_t __n = _Nw - 1; __n > __wshift; --__n) - _M_w[__n] = (_M_w[__n - __wshift] << __offset) | - (_M_w[__n - __wshift - 1] >> __sub_offset); + _M_w[__n] = ((_M_w[__n - __wshift] << __offset) + | (_M_w[__n - __wshift - 1] >> __sub_offset)); _M_w[__wshift] = _M_w[0] << __offset; } @@ -246,10 +253,11 @@ namespace _GLIBCXX_STD _M_w[__n] = _M_w[__n + __wshift]; else { - const size_t __sub_offset = _GLIBCXX_BITSET_BITS_PER_WORD - __offset; + const size_t __sub_offset = (_GLIBCXX_BITSET_BITS_PER_WORD + - __offset); for (size_t __n = 0; __n < __limit; ++__n) - _M_w[__n] = (_M_w[__n + __wshift] >> __offset) | - (_M_w[__n + __wshift + 1] << __sub_offset); + _M_w[__n] = ((_M_w[__n + __wshift] >> __offset) + | (_M_w[__n + __wshift + 1] << __sub_offset)); _M_w[__limit] = _M_w[_Nw-1] >> __offset; } @@ -275,8 +283,8 @@ namespace _GLIBCXX_STD { _WordT __thisword = _M_w[__i]; if (__thisword != static_cast<_WordT>(0)) - return __i * _GLIBCXX_BITSET_BITS_PER_WORD - + __builtin_ctzl(__thisword); + return (__i * _GLIBCXX_BITSET_BITS_PER_WORD + + __builtin_ctzl(__thisword)); } // not found, so return an indication of failure. return __not_found; @@ -301,23 +309,22 @@ namespace _GLIBCXX_STD __thisword &= (~static_cast<_WordT>(0)) << _S_whichbit(__prev); if (__thisword != static_cast<_WordT>(0)) - return __i * _GLIBCXX_BITSET_BITS_PER_WORD - + __builtin_ctzl(__thisword); + return (__i * _GLIBCXX_BITSET_BITS_PER_WORD + + __builtin_ctzl(__thisword)); // check subsequent words __i++; - for ( ; __i < _Nw; __i++ ) + for (; __i < _Nw; __i++) { __thisword = _M_w[__i]; if (__thisword != static_cast<_WordT>(0)) - return __i * _GLIBCXX_BITSET_BITS_PER_WORD - + __builtin_ctzl(__thisword); + return (__i * _GLIBCXX_BITSET_BITS_PER_WORD + + __builtin_ctzl(__thisword)); } // not found, so return an indication of failure. return __not_found; } // end _M_do_find_next - /** * @if maint * Base class, specialization for a single word. @@ -331,8 +338,13 @@ namespace _GLIBCXX_STD typedef unsigned long _WordT; _WordT _M_w; - _Base_bitset( void ) : _M_w(0) {} - _Base_bitset(unsigned long __val) : _M_w(__val) {} + _Base_bitset(void) + : _M_w(0) + { } + + _Base_bitset(unsigned long __val) + : _M_w(__val) + { } static size_t _S_whichword(size_t __pos ) @@ -351,53 +363,68 @@ namespace _GLIBCXX_STD { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); } _WordT& - _M_getword(size_t) { return _M_w; } + _M_getword(size_t) + { return _M_w; } _WordT - _M_getword(size_t) const { return _M_w; } + _M_getword(size_t) const + { return _M_w; } _WordT& - _M_hiword() { return _M_w; } + _M_hiword() + { return _M_w; } _WordT - _M_hiword() const { return _M_w; } + _M_hiword() const + { return _M_w; } void - _M_do_and(const _Base_bitset<1>& __x) { _M_w &= __x._M_w; } + _M_do_and(const _Base_bitset<1>& __x) + { _M_w &= __x._M_w; } void - _M_do_or(const _Base_bitset<1>& __x) { _M_w |= __x._M_w; } + _M_do_or(const _Base_bitset<1>& __x) + { _M_w |= __x._M_w; } void - _M_do_xor(const _Base_bitset<1>& __x) { _M_w ^= __x._M_w; } + _M_do_xor(const _Base_bitset<1>& __x) + { _M_w ^= __x._M_w; } void - _M_do_left_shift(size_t __shift) { _M_w <<= __shift; } + _M_do_left_shift(size_t __shift) + { _M_w <<= __shift; } void - _M_do_right_shift(size_t __shift) { _M_w >>= __shift; } + _M_do_right_shift(size_t __shift) + { _M_w >>= __shift; } void - _M_do_flip() { _M_w = ~_M_w; } + _M_do_flip() + { _M_w = ~_M_w; } void - _M_do_set() { _M_w = ~static_cast<_WordT>(0); } + _M_do_set() + { _M_w = ~static_cast<_WordT>(0); } void - _M_do_reset() { _M_w = 0; } + _M_do_reset() + { _M_w = 0; } bool _M_is_equal(const _Base_bitset<1>& __x) const { return _M_w == __x._M_w; } bool - _M_is_any() const { return _M_w != 0; } + _M_is_any() const + { return _M_w != 0; } size_t - _M_do_count() const { return __builtin_popcountl(_M_w); } + _M_do_count() const + { return __builtin_popcountl(_M_w); } unsigned long - _M_do_to_ulong() const { return _M_w; } + _M_do_to_ulong() const + { return _M_w; } size_t _M_do_find_first(size_t __not_found) const @@ -424,7 +451,6 @@ namespace _GLIBCXX_STD } }; - /** * @if maint * Base class, specialization for no storage (zero-length %bitset). @@ -437,8 +463,11 @@ namespace _GLIBCXX_STD { typedef unsigned long _WordT; - _Base_bitset() {} - _Base_bitset(unsigned long) {} + _Base_bitset() + { } + + _Base_bitset(unsigned long) + { } static size_t _S_whichword(size_t __pos ) @@ -471,54 +500,69 @@ namespace _GLIBCXX_STD } _WordT - _M_hiword() const { return 0; } + _M_hiword() const + { return 0; } void - _M_do_and(const _Base_bitset<0>&) { } + _M_do_and(const _Base_bitset<0>&) + { } void - _M_do_or(const _Base_bitset<0>&) { } + _M_do_or(const _Base_bitset<0>&) + { } void - _M_do_xor(const _Base_bitset<0>&) { } + _M_do_xor(const _Base_bitset<0>&) + { } void - _M_do_left_shift(size_t) { } + _M_do_left_shift(size_t) + { } void - _M_do_right_shift(size_t) { } + _M_do_right_shift(size_t) + { } void - _M_do_flip() { } + _M_do_flip() + { } void - _M_do_set() { } + _M_do_set() + { } void - _M_do_reset() { } + _M_do_reset() + { } // Are all empty bitsets equal to each other? Are they equal to // themselves? How to compare a thing which has no state? What is // the sound of one zero-length bitset clapping? bool - _M_is_equal(const _Base_bitset<0>&) const { return true; } + _M_is_equal(const _Base_bitset<0>&) const + { return true; } bool - _M_is_any() const { return false; } + _M_is_any() const + { return false; } size_t - _M_do_count() const { return 0; } + _M_do_count() const + { return 0; } unsigned long - _M_do_to_ulong() const { return 0; } + _M_do_to_ulong() const + { return 0; } // Normally "not found" is the size, but that could also be // misinterpreted as an index in this corner case. Oh well. size_t - _M_do_find_first(size_t) const { return 0; } + _M_do_find_first(size_t) const + { return 0; } size_t - _M_do_find_next(size_t, size_t) const { return 0; } + _M_do_find_next(size_t, size_t) const + { return 0; } }; @@ -532,8 +576,7 @@ namespace _GLIBCXX_STD template<> struct _Sanitize<0> - { static void _S_do_sanitize(unsigned long) { } }; - + { static void _S_do_sanitize(unsigned long) {} }; /** * @brief The %bitset class represents a @e fixed-size sequence of bits. @@ -600,508 +643,540 @@ namespace _GLIBCXX_STD * @endif */ template<size_t _Nb> - class bitset : private _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)> - { - private: - typedef _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)> _Base; - typedef unsigned long _WordT; - - void - _M_do_sanitize() + class bitset + : private _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)> { - _Sanitize<_Nb%_GLIBCXX_BITSET_BITS_PER_WORD>:: - _S_do_sanitize(this->_M_hiword()); - } + private: + typedef _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)> _Base; + typedef unsigned long _WordT; - public: - /** - * This encapsulates the concept of a single bit. An instance of this - * class is a proxy for an actual bit; this way the individual bit - * operations are done as faster word-size bitwise instructions. - * - * Most users will never need to use this class directly; conversions - * to and from bool are automatic and should be transparent. Overloaded - * operators help to preserve the illusion. - * - * (On a typical system, this "bit %reference" is 64 times the size of - * an actual bit. Ha.) - */ - class reference - { - friend class bitset; + void + _M_do_sanitize() + { + _Sanitize<_Nb % _GLIBCXX_BITSET_BITS_PER_WORD>:: + _S_do_sanitize(this->_M_hiword()); + } + + public: + /** + * This encapsulates the concept of a single bit. An instance of this + * class is a proxy for an actual bit; this way the individual bit + * operations are done as faster word-size bitwise instructions. + * + * Most users will never need to use this class directly; conversions + * to and from bool are automatic and should be transparent. Overloaded + * operators help to preserve the illusion. + * + * (On a typical system, this "bit %reference" is 64 times the size of + * an actual bit. Ha.) + */ + class reference + { + friend class bitset; + + _WordT *_M_wp; + size_t _M_bpos; + + // left undefined + reference(); + + public: + reference(bitset& __b, size_t __pos) + { + _M_wp = &__b._M_getword(__pos); + _M_bpos = _Base::_S_whichbit(__pos); + } - _WordT *_M_wp; - size_t _M_bpos; + ~reference() + { } - // left undefined - reference(); + // For b[i] = __x; + reference& + operator=(bool __x) + { + if (__x) + *_M_wp |= _Base::_S_maskbit(_M_bpos); + else + *_M_wp &= ~_Base::_S_maskbit(_M_bpos); + return *this; + } - public: - reference(bitset& __b, size_t __pos) + // For b[i] = b[__j]; + reference& + operator=(const reference& __j) + { + if ((*(__j._M_wp) & _Base::_S_maskbit(__j._M_bpos))) + *_M_wp |= _Base::_S_maskbit(_M_bpos); + else + *_M_wp &= ~_Base::_S_maskbit(_M_bpos); + return *this; + } + + // Flips the bit + bool + operator~() const + { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) == 0; } + + // For __x = b[i]; + operator bool() const + { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) != 0; } + + // For b[i].flip(); + reference& + flip() + { + *_M_wp ^= _Base::_S_maskbit(_M_bpos); + return *this; + } + }; + friend class reference; + + // 23.3.5.1 constructors: + /// All bits set to zero. + bitset() + { } + + /// Initial bits bitwise-copied from a single word (others set to zero). + bitset(unsigned long __val) + : _Base(__val) + { _M_do_sanitize(); } + + /** + * @brief Use a subset of a string. + * @param s A string of '0' and '1' characters. + * @param position Index of the first character in @a s to use; + * defaults to zero. + * @throw std::out_of_range If @a pos is bigger the size of @a s. + * @throw std::invalid_argument If a character appears in the string + * which is neither '0' nor '1'. + */ + template<class _CharT, class _Traits, class _Alloc> + explicit + bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __s, + size_t __position = 0) + : _Base() + { + if (__position > __s.size()) + __throw_out_of_range(__N("bitset::bitset initial position " + "not valid")); + _M_copy_from_string(__s, __position, + std::basic_string<_CharT, _Traits, _Alloc>::npos); + } + + /** + * @brief Use a subset of a string. + * @param s A string of '0' and '1' characters. + * @param position Index of the first character in @a s to use. + * @param n The number of characters to copy. + * @throw std::out_of_range If @a pos is bigger the size of @a s. + * @throw std::invalid_argument If a character appears in the string + * which is neither '0' nor '1'. + */ + template<class _CharT, class _Traits, class _Alloc> + bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __s, + size_t __position, size_t __n) + : _Base() + { + if (__position > __s.size()) + __throw_out_of_range(__N("bitset::bitset initial position " + "not valid")); + _M_copy_from_string(__s, __position, __n); + } + + // 23.3.5.2 bitset operations: + //@{ + /** + * @brief Operations on bitsets. + * @param rhs A same-sized bitset. + * + * These should be self-explanatory. + */ + bitset<_Nb>& + operator&=(const bitset<_Nb>& __rhs) { - _M_wp = &__b._M_getword(__pos); - _M_bpos = _Base::_S_whichbit(__pos); + this->_M_do_and(__rhs); + return *this; } - ~reference() { } + bitset<_Nb>& + operator|=(const bitset<_Nb>& __rhs) + { + this->_M_do_or(__rhs); + return *this; + } - // For b[i] = __x; - reference& - operator=(bool __x) + bitset<_Nb>& + operator^=(const bitset<_Nb>& __rhs) + { + this->_M_do_xor(__rhs); + return *this; + } + //@} + + //@{ + /** + * @brief Operations on bitsets. + * @param position The number of places to shift. + * + * These should be self-explanatory. + */ + bitset<_Nb>& + operator<<=(size_t __position) { - if ( __x ) - *_M_wp |= _Base::_S_maskbit(_M_bpos); + if (__builtin_expect(__position < _Nb, 1)) + { + this->_M_do_left_shift(__position); + this->_M_do_sanitize(); + } else - *_M_wp &= ~_Base::_S_maskbit(_M_bpos); + this->_M_do_reset(); return *this; } - // For b[i] = b[__j]; - reference& - operator=(const reference& __j) + bitset<_Nb>& + operator>>=(size_t __position) { - if ( (*(__j._M_wp) & _Base::_S_maskbit(__j._M_bpos)) ) - *_M_wp |= _Base::_S_maskbit(_M_bpos); + if (__builtin_expect(__position < _Nb, 1)) + { + this->_M_do_right_shift(__position); + this->_M_do_sanitize(); + } else - *_M_wp &= ~_Base::_S_maskbit(_M_bpos); + this->_M_do_reset(); + return *this; + } + //@} + + //@{ + /** + * These versions of single-bit set, reset, flip, and test are + * extensions from the SGI version. They do no range checking. + * @ingroup SGIextensions + */ + bitset<_Nb>& + _Unchecked_set(size_t __pos) + { + this->_M_getword(__pos) |= _Base::_S_maskbit(__pos); return *this; } - // Flips the bit - bool - operator~() const - { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) == 0; } - - // For __x = b[i]; - operator bool() const - { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) != 0; } - - // For b[i].flip(); - reference& - flip() + bitset<_Nb>& + _Unchecked_set(size_t __pos, int __val) { - *_M_wp ^= _Base::_S_maskbit(_M_bpos); + if (__val) + this->_M_getword(__pos) |= _Base::_S_maskbit(__pos); + else + this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos); return *this; } - }; - friend class reference; - - // 23.3.5.1 constructors: - /// All bits set to zero. - bitset() { } - - /// Initial bits bitwise-copied from a single word (others set to zero). - bitset(unsigned long __val) : _Base(__val) - { _M_do_sanitize(); } - - /** - * @brief Use a subset of a string. - * @param s A string of '0' and '1' characters. - * @param position Index of the first character in @a s to use; defaults - * to zero. - * @throw std::out_of_range If @a pos is bigger the size of @a s. - * @throw std::invalid_argument If a character appears in the string - * which is neither '0' nor '1'. - */ - template<class _CharT, class _Traits, class _Alloc> - explicit bitset(const basic_string<_CharT, _Traits, _Alloc>& __s, - size_t __position = 0) : _Base() + + bitset<_Nb>& + _Unchecked_reset(size_t __pos) { - if (__position > __s.size()) - __throw_out_of_range(__N("bitset::bitset initial position " - "not valid")); - _M_copy_from_string(__s, __position, - basic_string<_CharT, _Traits, _Alloc>::npos); + this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos); + return *this; } - /** - * @brief Use a subset of a string. - * @param s A string of '0' and '1' characters. - * @param position Index of the first character in @a s to use. - * @param n The number of characters to copy. - * @throw std::out_of_range If @a pos is bigger the size of @a s. - * @throw std::invalid_argument If a character appears in the string - * which is neither '0' nor '1'. - */ - template<class _CharT, class _Traits, class _Alloc> - bitset(const basic_string<_CharT, _Traits, _Alloc>& __s, - size_t __position, size_t __n) : _Base() + bitset<_Nb>& + _Unchecked_flip(size_t __pos) { - if (__position > __s.size()) - __throw_out_of_range(__N("bitset::bitset initial position " - "not valid")); - _M_copy_from_string(__s, __position, __n); + this->_M_getword(__pos) ^= _Base::_S_maskbit(__pos); + return *this; } - // 23.3.5.2 bitset operations: - //@{ - /** - * @brief Operations on bitsets. - * @param rhs A same-sized bitset. - * - * These should be self-explanatory. - */ - bitset<_Nb>& - operator&=(const bitset<_Nb>& __rhs) - { - this->_M_do_and(__rhs); - return *this; - } + bool + _Unchecked_test(size_t __pos) const + { return ((this->_M_getword(__pos) & _Base::_S_maskbit(__pos)) + != static_cast<_WordT>(0)); } + //@} + + // Set, reset, and flip. + /** + * @brief Sets every bit to true. + */ + bitset<_Nb>& + set() + { + this->_M_do_set(); + this->_M_do_sanitize(); + return *this; + } - bitset<_Nb>& - operator|=(const bitset<_Nb>& __rhs) - { - this->_M_do_or(__rhs); - return *this; - } + /** + * @brief Sets a given bit to a particular value. + * @param position The index of the bit. + * @param val Either true or false, defaults to true. + * @throw std::out_of_range If @a pos is bigger the size of the %set. + */ + bitset<_Nb>& + set(size_t __position, bool __val = true) + { + if (__position >= _Nb) + __throw_out_of_range(__N("bitset::set")); + return _Unchecked_set(__position, __val); + } - bitset<_Nb>& - operator^=(const bitset<_Nb>& __rhs) - { - this->_M_do_xor(__rhs); - return *this; - } - //@} - - //@{ - /** - * @brief Operations on bitsets. - * @param position The number of places to shift. - * - * These should be self-explanatory. - */ - bitset<_Nb>& - operator<<=(size_t __position) - { - if (__builtin_expect(__position < _Nb, 1)) - { - this->_M_do_left_shift(__position); - this->_M_do_sanitize(); - } - else + /** + * @brief Sets every bit to false. + */ + bitset<_Nb>& + reset() + { this->_M_do_reset(); - return *this; - } + return *this; + } - bitset<_Nb>& - operator>>=(size_t __position) - { - if (__builtin_expect(__position < _Nb, 1)) - { - this->_M_do_right_shift(__position); - this->_M_do_sanitize(); - } - else - this->_M_do_reset(); - return *this; - } - //@} - - //@{ - /** - * These versions of single-bit set, reset, flip, and test are - * extensions from the SGI version. They do no range checking. - * @ingroup SGIextensions - */ - bitset<_Nb>& - _Unchecked_set(size_t __pos) - { - this->_M_getword(__pos) |= _Base::_S_maskbit(__pos); - return *this; - } + /** + * @brief Sets a given bit to false. + * @param position The index of the bit. + * @throw std::out_of_range If @a pos is bigger the size of the %set. + * + * Same as writing @c set(pos,false). + */ + bitset<_Nb>& + reset(size_t __position) + { + if (__position >= _Nb) + __throw_out_of_range(__N("bitset::reset")); + return _Unchecked_reset(__position); + } + + /** + * @brief Toggles every bit to its opposite value. + */ + bitset<_Nb>& + flip() + { + this->_M_do_flip(); + this->_M_do_sanitize(); + return *this; + } - bitset<_Nb>& - _Unchecked_set(size_t __pos, int __val) - { - if (__val) - this->_M_getword(__pos) |= _Base::_S_maskbit(__pos); - else - this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos); - return *this; - } + /** + * @brief Toggles a given bit to its opposite value. + * @param position The index of the bit. + * @throw std::out_of_range If @a pos is bigger the size of the %set. + */ + bitset<_Nb>& + flip(size_t __position) + { + if (__position >= _Nb) + __throw_out_of_range(__N("bitset::flip")); + return _Unchecked_flip(__position); + } + + /// See the no-argument flip(). + bitset<_Nb> + operator~() const + { return bitset<_Nb>(*this).flip(); } + + //@{ + /** + * @brief Array-indexing support. + * @param position Index into the %bitset. + * @return A bool for a 'const %bitset'. For non-const bitsets, an + * instance of the reference proxy class. + * @note These operators do no range checking and throw no exceptions, + * as required by DR 11 to the standard. + * + * @if maint + * _GLIBCXX_RESOLVE_LIB_DEFECTS Note that this implementation already + * resolves DR 11 (items 1 and 2), but does not do the range-checking + * required by that DR's resolution. -pme + * The DR has since been changed: range-checking is a precondition + * (users' responsibility), and these functions must not throw. -pme + * @endif + */ + reference + operator[](size_t __position) + { return reference(*this,__position); } - bitset<_Nb>& - _Unchecked_reset(size_t __pos) - { - this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos); - return *this; - } + bool + operator[](size_t __position) const + { return _Unchecked_test(__position); } + //@} + + /** + * @brief Retuns a numerical interpretation of the %bitset. + * @return The integral equivalent of the bits. + * @throw std::overflow_error If there are too many bits to be + * represented in an @c unsigned @c long. + */ + unsigned long + to_ulong() const + { return this->_M_do_to_ulong(); } + + /** + * @brief Retuns a character interpretation of the %bitset. + * @return The string equivalent of the bits. + * + * Note the ordering of the bits: decreasing character positions + * correspond to increasing bit positions (see the main class notes for + * an example). + */ + template<class _CharT, class _Traits, class _Alloc> + std::basic_string<_CharT, _Traits, _Alloc> + to_string() const + { + std::basic_string<_CharT, _Traits, _Alloc> __result; + _M_copy_to_string(__result); + return __result; + } - bitset<_Nb>& - _Unchecked_flip(size_t __pos) - { - this->_M_getword(__pos) ^= _Base::_S_maskbit(__pos); - return *this; - } + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 434. bitset::to_string() hard to use. + template<class _CharT, class _Traits> + std::basic_string<_CharT, _Traits, std::allocator<_CharT> > + to_string() const + { return to_string<_CharT, _Traits, std::allocator<_CharT> >(); } + + template<class _CharT> + std::basic_string<_CharT, std::char_traits<_CharT>, + std::allocator<_CharT> > + to_string() const + { + return to_string<_CharT, std::char_traits<_CharT>, + std::allocator<_CharT> >(); + } - bool - _Unchecked_test(size_t __pos) const - { - return (this->_M_getword(__pos) & _Base::_S_maskbit(__pos)) - != static_cast<_WordT>(0); - } - //@} - - // Set, reset, and flip. - /** - * @brief Sets every bit to true. - */ - bitset<_Nb>& - set() - { - this->_M_do_set(); - this->_M_do_sanitize(); - return *this; - } + std::basic_string<char, std::char_traits<char>, std::allocator<char> > + to_string() const + { + return to_string<char, std::char_traits<char>, + std::allocator<char> >(); + } - /** - * @brief Sets a given bit to a particular value. - * @param position The index of the bit. - * @param val Either true or false, defaults to true. - * @throw std::out_of_range If @a pos is bigger the size of the %set. - */ - bitset<_Nb>& - set(size_t __position, bool __val = true) - { - if (__position >= _Nb) - __throw_out_of_range(__N("bitset::set")); - return _Unchecked_set(__position, __val); - } + // Helper functions for string operations. + template<class _CharT, class _Traits, class _Alloc> + void + _M_copy_from_string(const std::basic_string<_CharT, + _Traits, _Alloc>& __s, + size_t, size_t); - /** - * @brief Sets every bit to false. - */ - bitset<_Nb>& - reset() - { - this->_M_do_reset(); - return *this; - } + template<class _CharT, class _Traits, class _Alloc> + void + _M_copy_to_string(std::basic_string<_CharT, _Traits, _Alloc>&) const; - /** - * @brief Sets a given bit to false. - * @param position The index of the bit. - * @throw std::out_of_range If @a pos is bigger the size of the %set. - * - * Same as writing @c set(pos,false). - */ - bitset<_Nb>& - reset(size_t __position) - { - if (__position >= _Nb) - __throw_out_of_range(__N("bitset::reset")); - return _Unchecked_reset(__position); - } + /// Returns the number of bits which are set. + size_t + count() const + { return this->_M_do_count(); } - /** - * @brief Toggles every bit to its opposite value. - */ - bitset<_Nb>& - flip() - { - this->_M_do_flip(); - this->_M_do_sanitize(); - return *this; - } + /// Returns the total number of bits. + size_t + size() const + { return _Nb; } - /** - * @brief Toggles a given bit to its opposite value. - * @param position The index of the bit. - * @throw std::out_of_range If @a pos is bigger the size of the %set. - */ - bitset<_Nb>& - flip(size_t __position) - { - if (__position >= _Nb) - __throw_out_of_range(__N("bitset::flip")); - return _Unchecked_flip(__position); - } + //@{ + /// These comparisons for equality/inequality are, well, @e bitwise. + bool + operator==(const bitset<_Nb>& __rhs) const + { return this->_M_is_equal(__rhs); } - /// See the no-argument flip(). - bitset<_Nb> - operator~() const { return bitset<_Nb>(*this).flip(); } - - //@{ - /** - * @brief Array-indexing support. - * @param position Index into the %bitset. - * @return A bool for a 'const %bitset'. For non-const bitsets, an - * instance of the reference proxy class. - * @note These operators do no range checking and throw no exceptions, - * as required by DR 11 to the standard. - * - * @if maint - * _GLIBCXX_RESOLVE_LIB_DEFECTS Note that this implementation already - * resolves DR 11 (items 1 and 2), but does not do the range-checking - * required by that DR's resolution. -pme - * The DR has since been changed: range-checking is a precondition - * (users' responsibility), and these functions must not throw. -pme - * @endif - */ - reference - operator[](size_t __position) { return reference(*this,__position); } - - bool - operator[](size_t __position) const { return _Unchecked_test(__position); } - //@} - - /** - * @brief Retuns a numerical interpretation of the %bitset. - * @return The integral equivalent of the bits. - * @throw std::overflow_error If there are too many bits to be - * represented in an @c unsigned @c long. - */ - unsigned long - to_ulong() const { return this->_M_do_to_ulong(); } - - /** - * @brief Retuns a character interpretation of the %bitset. - * @return The string equivalent of the bits. - * - * Note the ordering of the bits: decreasing character positions - * correspond to increasing bit positions (see the main class notes for - * an example). - * - * Also note that you must specify the string's template parameters - * explicitly. Given a bitset @c bs and a string @s: - * @code - * s = bs.to_string<char,char_traits<char>,allocator<char> >(); - * @endcode - */ - template<class _CharT, class _Traits, class _Alloc> - basic_string<_CharT, _Traits, _Alloc> - to_string() const + bool + operator!=(const bitset<_Nb>& __rhs) const + { return !this->_M_is_equal(__rhs); } + //@} + + /** + * @brief Tests the value of a bit. + * @param position The index of a bit. + * @return The value at @a pos. + * @throw std::out_of_range If @a pos is bigger the size of the %set. + */ + bool + test(size_t __position) const { - basic_string<_CharT, _Traits, _Alloc> __result; - _M_copy_to_string(__result); - return __result; + if (__position >= _Nb) + __throw_out_of_range(__N("bitset::test")); + return _Unchecked_test(__position); } + + /** + * @brief Tests whether any of the bits are on. + * @return True if at least one bit is set. + */ + bool + any() const + { return this->_M_is_any(); } - // Helper functions for string operations. - template<class _CharT, class _Traits, class _Alloc> - void - _M_copy_from_string(const basic_string<_CharT,_Traits,_Alloc>& __s, - size_t, size_t); - - template<class _CharT, class _Traits, class _Alloc> - void - _M_copy_to_string(basic_string<_CharT,_Traits,_Alloc>&) const; - - /// Returns the number of bits which are set. - size_t - count() const { return this->_M_do_count(); } - - /// Returns the total number of bits. - size_t - size() const { return _Nb; } - - //@{ - /// These comparisons for equality/inequality are, well, @e bitwise. - bool - operator==(const bitset<_Nb>& __rhs) const - { return this->_M_is_equal(__rhs); } - - bool - operator!=(const bitset<_Nb>& __rhs) const - { return !this->_M_is_equal(__rhs); } - //@} - - /** - * @brief Tests the value of a bit. - * @param position The index of a bit. - * @return The value at @a pos. - * @throw std::out_of_range If @a pos is bigger the size of the %set. - */ - bool - test(size_t __position) const - { - if (__position >= _Nb) - __throw_out_of_range(__N("bitset::test")); - return _Unchecked_test(__position); - } - - /** - * @brief Tests whether any of the bits are on. - * @return True if at least one bit is set. - */ - bool - any() const { return this->_M_is_any(); } - - /** - * @brief Tests whether any of the bits are on. - * @return True if none of the bits are set. - */ - bool - none() const { return !this->_M_is_any(); } - - //@{ - /// Self-explanatory. - bitset<_Nb> - operator<<(size_t __position) const - { return bitset<_Nb>(*this) <<= __position; } - - bitset<_Nb> - operator>>(size_t __position) const - { return bitset<_Nb>(*this) >>= __position; } - //@} - - /** - * @brief Finds the index of the first "on" bit. - * @return The index of the first bit set, or size() if not found. - * @ingroup SGIextensions - * @sa _Find_next - */ - size_t - _Find_first() const - { return this->_M_do_find_first(_Nb); } - - /** - * @brief Finds the index of the next "on" bit after prev. - * @return The index of the next bit set, or size() if not found. - * @param prev Where to start searching. - * @ingroup SGIextensions - * @sa _Find_first - */ - size_t - _Find_next(size_t __prev ) const - { return this->_M_do_find_next(__prev, _Nb); } - }; + /** + * @brief Tests whether any of the bits are on. + * @return True if none of the bits are set. + */ + bool + none() const + { return !this->_M_is_any(); } + + //@{ + /// Self-explanatory. + bitset<_Nb> + operator<<(size_t __position) const + { return bitset<_Nb>(*this) <<= __position; } + + bitset<_Nb> + operator>>(size_t __position) const + { return bitset<_Nb>(*this) >>= __position; } + //@} + + /** + * @brief Finds the index of the first "on" bit. + * @return The index of the first bit set, or size() if not found. + * @ingroup SGIextensions + * @sa _Find_next + */ + size_t + _Find_first() const + { return this->_M_do_find_first(_Nb); } + + /** + * @brief Finds the index of the next "on" bit after prev. + * @return The index of the next bit set, or size() if not found. + * @param prev Where to start searching. + * @ingroup SGIextensions + * @sa _Find_first + */ + size_t + _Find_next(size_t __prev ) const + { return this->_M_do_find_next(__prev, _Nb); } + }; // Definitions of non-inline member functions. template<size_t _Nb> template<class _CharT, class _Traits, class _Alloc> - void - bitset<_Nb>::_M_copy_from_string(const basic_string<_CharT, _Traits, - _Alloc>& __s, size_t __pos, size_t __n) - { - reset(); - const size_t __nbits = std::min(_Nb, std::min(__n, __s.size() - __pos)); - for (size_t __i = 0; __i < __nbits; ++__i) - { - switch(__s[__pos + __nbits - __i - 1]) - { - case '0': - break; - case '1': - set(__i); - break; - default: - __throw_invalid_argument(__N("bitset::_M_copy_from_string")); - } - } - } + void + bitset<_Nb>:: + _M_copy_from_string(const std::basic_string<_CharT, _Traits, + _Alloc>& __s, size_t __pos, size_t __n) + { + reset(); + const size_t __nbits = std::min(_Nb, std::min(__n, __s.size() - __pos)); + for (size_t __i = __nbits; __i > 0; --__i) + { + switch(__s[__pos + __nbits - __i]) + { + case '0': + break; + case '1': + _Unchecked_set(__i - 1); + break; + default: + __throw_invalid_argument(__N("bitset::_M_copy_from_string")); + } + } + } template<size_t _Nb> template<class _CharT, class _Traits, class _Alloc> - void - bitset<_Nb>::_M_copy_to_string(basic_string<_CharT, _Traits, - _Alloc>& __s) const - { - __s.assign(_Nb, '0'); - for (size_t __i = 0; __i < _Nb; ++__i) - if (_Unchecked_test(__i)) - __s[_Nb - 1 - __i] = '1'; - } + void + bitset<_Nb>:: + _M_copy_to_string(std::basic_string<_CharT, _Traits, _Alloc>& __s) const + { + __s.assign(_Nb, '0'); + for (size_t __i = _Nb; __i > 0; --__i) + if (_Unchecked_test(__i - 1)) + __s[_Nb - __i] = '1'; + } // 23.3.5.3 bitset operations: //@{ @@ -1151,15 +1226,15 @@ namespace _GLIBCXX_STD * hold. */ template<class _CharT, class _Traits, size_t _Nb> - basic_istream<_CharT, _Traits>& - operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x) + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x) { typedef typename _Traits::char_type char_type; - basic_string<_CharT, _Traits> __tmp; + std::basic_string<_CharT, _Traits> __tmp; __tmp.reserve(_Nb); - ios_base::iostate __state = ios_base::goodbit; - typename basic_istream<_CharT, _Traits>::sentry __sentry(__is); + std::ios_base::iostate __state = std::ios_base::goodbit; + typename std::basic_istream<_CharT, _Traits>::sentry __sentry(__is); if (__sentry) { try @@ -1169,19 +1244,19 @@ namespace _GLIBCXX_STD // 303. Bitset input operator underspecified const char_type __zero = __is.widen('0'); const char_type __one = __is.widen('1'); - for (size_t __i = 0; __i < _Nb; ++__i) + for (size_t __i = _Nb; __i > 0; --__i) { static typename _Traits::int_type __eof = _Traits::eof(); typename _Traits::int_type __c1 = __buf->sbumpc(); if (_Traits::eq_int_type(__c1, __eof)) { - __state |= ios_base::eofbit; + __state |= std::ios_base::eofbit; break; } else { - char_type __c2 = _Traits::to_char_type(__c1); + const char_type __c2 = _Traits::to_char_type(__c1); if (__c2 == __zero) __tmp.push_back('0'); else if (__c2 == __one) @@ -1189,18 +1264,18 @@ namespace _GLIBCXX_STD else if (_Traits::eq_int_type(__buf->sputbackc(__c2), __eof)) { - __state |= ios_base::failbit; + __state |= std::ios_base::failbit; break; } } } } catch(...) - { __is._M_setstate(ios_base::badbit); } + { __is._M_setstate(std::ios_base::badbit); } } if (__tmp.empty() && _Nb) - __state |= ios_base::failbit; + __state |= std::ios_base::failbit; else __x._M_copy_from_string(__tmp, static_cast<size_t>(0), _Nb); if (__state) @@ -1209,15 +1284,55 @@ namespace _GLIBCXX_STD } template <class _CharT, class _Traits, size_t _Nb> - basic_ostream<_CharT, _Traits>& - operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Nb>& __x) + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const bitset<_Nb>& __x) { - basic_string<_CharT, _Traits> __tmp; + std::basic_string<_CharT, _Traits> __tmp; __x._M_copy_to_string(__tmp); return __os << __tmp; } + + // Specializations for zero-sized bitsets, to avoid "unsigned comparison + // with zero" warnings. + template<> + inline bitset<0>& + bitset<0>:: + set(size_t, bool) + { + __throw_out_of_range(__N("bitset::set")); + return *this; + } + + template<> + inline bitset<0>& + bitset<0>:: + reset(size_t) + { + __throw_out_of_range(__N("bitset::reset")); + return *this; + } + + template<> + inline bitset<0>& + bitset<0>:: + flip(size_t) + { + __throw_out_of_range(__N("bitset::flip")); + return *this; + } + + template<> + inline bool + bitset<0>:: + test(size_t) const + { + __throw_out_of_range(__N("bitset::test")); + return false; + } //@} -} // namespace std + +_GLIBCXX_END_NESTED_NAMESPACE #undef _GLIBCXX_BITSET_WORDS #undef _GLIBCXX_BITSET_BITS_PER_WORD |