diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 6b447610520..bb7f593732f 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,7 @@ +2004-05-15 Paolo Carlini + + * include/std/std_bitset.h: Trivial formatting fixes. + 2004-05-14 Paolo Carlini Ivan Godard diff --git a/libstdc++-v3/include/std/std_bitset.h b/libstdc++-v3/include/std/std_bitset.h index 01e3f904e47..8fa1756812c 100644 --- a/libstdc++-v3/include/std/std_bitset.h +++ b/libstdc++-v3/include/std/std_bitset.h @@ -61,7 +61,8 @@ #define _GLIBCXX_BITSET_BITS_PER_WORD numeric_limits::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) namespace _GLIBCXX_STD { @@ -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,521 @@ namespace _GLIBCXX_STD * @endif */ template - 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; - - _WordT *_M_wp; - size_t _M_bpos; - - // left undefined - reference(); + void + _M_do_sanitize() + { + _Sanitize<_Nb % _GLIBCXX_BITSET_BITS_PER_WORD>:: + _S_do_sanitize(this->_M_hiword()); + } public: - reference(bitset& __b, size_t __pos) + /** + * 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 { - _M_wp = &__b._M_getword(__pos); - _M_bpos = _Base::_S_whichbit(__pos); - } + friend class bitset; - ~reference() { } + _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); + } - // For b[i] = __x; - reference& - operator=(bool __x) + ~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; + } + + // 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 + explicit + bitset(const 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, + 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 + bitset(const 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) { - if ( __x ) - *_M_wp |= _Base::_S_maskbit(_M_bpos); - else - *_M_wp &= ~_Base::_S_maskbit(_M_bpos); + this->_M_do_and(__rhs); return *this; } - // For b[i] = b[__j]; - reference& - operator=(const reference& __j) + bitset<_Nb>& + operator|=(const bitset<_Nb>& __rhs) { - 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); + this->_M_do_or(__rhs); + return *this; + } + + 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 + this->_M_do_reset(); + 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; + } + + 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; + } + + bitset<_Nb>& + _Unchecked_reset(size_t __pos) + { + this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos); + return *this; + } + + bitset<_Nb>& + _Unchecked_flip(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; } + _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; + } - // For __x = b[i]; - operator bool() const - { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) != 0; } + /** + * @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); + } - // For b[i].flip(); - reference& + /** + * @brief Sets every bit to false. + */ + bitset<_Nb>& + reset() + { + this->_M_do_reset(); + 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() { - *_M_wp ^= _Base::_S_maskbit(_M_bpos); + this->_M_do_flip(); + this->_M_do_sanitize(); 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); } + + 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,allocator >(); + * @endcode + */ + template + basic_string<_CharT, _Traits, _Alloc> + to_string() const + { + basic_string<_CharT, _Traits, _Alloc> __result; + _M_copy_to_string(__result); + return __result; + } + + // Helper functions for string operations. + template + void + _M_copy_from_string(const basic_string<_CharT, _Traits, _Alloc>& __s, + size_t, size_t); + + template + 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); } }; - 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 - explicit bitset(const 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, - 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 - bitset(const 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) - { - this->_M_do_and(__rhs); - return *this; - } - - bitset<_Nb>& - operator|=(const bitset<_Nb>& __rhs) - { - this->_M_do_or(__rhs); - return *this; - } - - 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 - this->_M_do_reset(); - 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; - } - - 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; - } - - bitset<_Nb>& - _Unchecked_reset(size_t __pos) - { - this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos); - return *this; - } - - bitset<_Nb>& - _Unchecked_flip(size_t __pos) - { - this->_M_getword(__pos) ^= _Base::_S_maskbit(__pos); - 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; - } - - /** - * @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); - } - - /** - * @brief Sets every bit to false. - */ - bitset<_Nb>& - reset() - { - this->_M_do_reset(); - 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; - } - - /** - * @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); } - - 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,allocator >(); - * @endcode - */ - template - basic_string<_CharT, _Traits, _Alloc> - to_string() const - { - basic_string<_CharT, _Traits, _Alloc> __result; - _M_copy_to_string(__result); - return __result; - } - - // Helper functions for string operations. - template - void - _M_copy_from_string(const basic_string<_CharT,_Traits,_Alloc>& __s, - size_t, size_t); - - template - 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); } - }; // Definitions of non-inline member functions. template template - 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 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")); + } + } + } template template - 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(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'; + } // 23.3.5.3 bitset operations: //@{ @@ -1181,7 +1237,7 @@ namespace _GLIBCXX_STD } 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)