diff options
author | Edward Smith-Rowland <3dw4rd@verizon.net> | 2013-10-19 01:31:19 +0000 |
---|---|---|
committer | Edward Smith-Rowland <emsr@gcc.gnu.org> | 2013-10-19 01:31:19 +0000 |
commit | 6b8fe121affbf6fcfe19fca582c56cb9baf9b600 (patch) | |
tree | 6c13387d2b1e6d35e2d97616603d95b65a65a270 | |
parent | d979bbbb845ada9bee20db91fe057f2357dc1b3e (diff) | |
download | gcc-6b8fe121affbf6fcfe19fca582c56cb9baf9b600.zip gcc-6b8fe121affbf6fcfe19fca582c56cb9baf9b600.tar.gz gcc-6b8fe121affbf6fcfe19fca582c56cb9baf9b600.tar.bz2 |
re PR libstdc++/58729 (tr2::dynamic_bitset::resize fails)
2013-10-18 Edward Smith-Rowland <3dw4rd@verizon.net>
PR libstdc++/58729
* include/tr2/dynamic_bitset (_M_resize, resize): Use input value
to set bits; (_M_do_left_shift, _M_do_right_shift, _M_do_to_ulong,
_M_do_to_ullong, _M_do_find_first, _M_do_find_next, _M_copy_from_ptr,
operator>>): Move long methods outline to...
* include/tr2/dynamic_bitset.tcc: New.
* include/Makefile.am: Add dynamic_bitset.tcc.
* include/Makefile.in: Add dynamic_bitset.tcc.
* testsuite/tr2/dynamic_bitset/pr58729.cc: New.
From-SVN: r203841
-rw-r--r-- | libstdc++-v3/ChangeLog | 12 | ||||
-rw-r--r-- | libstdc++-v3/include/Makefile.am | 1 | ||||
-rw-r--r-- | libstdc++-v3/include/Makefile.in | 1 | ||||
-rw-r--r-- | libstdc++-v3/include/tr2/dynamic_bitset | 298 | ||||
-rw-r--r-- | libstdc++-v3/include/tr2/dynamic_bitset.tcc | 286 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/tr2/dynamic_bitset/pr58729.cc | 64 |
6 files changed, 408 insertions, 254 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index b37fdb6..c3fa989 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,15 @@ +2013-10-18 Edward Smith-Rowland <3dw4rd@verizon.net> + + PR libstdc++/58729 + * include/tr2/dynamic_bitset (_M_resize, resize): Use input value + to set bits; (_M_do_left_shift, _M_do_right_shift, _M_do_to_ulong, + _M_do_to_ullong, _M_do_find_first, _M_do_find_next, _M_copy_from_ptr, + operator>>): Move long methods outline to... + * include/tr2/dynamic_bitset.tcc: New. + * include/Makefile.am: Add dynamic_bitset.tcc. + * include/Makefile.in: Add dynamic_bitset.tcc. + * testsuite/tr2/dynamic_bitset/pr58729.cc: New. + 2013-10-18 Tim Shen <timshen91@gmail.com> * include/bits/regex_scanner.tcc: (_Scanner<>::_M_scan_normal, diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index 1a4fd6f..0ddc8b5 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -623,6 +623,7 @@ tr2_headers = \ ${tr2_srcdir}/bool_set \ ${tr2_srcdir}/bool_set.tcc \ ${tr2_srcdir}/dynamic_bitset \ + ${tr2_srcdir}/dynamic_bitset.tcc \ ${tr2_srcdir}/ratio \ ${tr2_srcdir}/type_traits diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index 87a9f1b..a1fd1d3 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -888,6 +888,7 @@ tr2_headers = \ ${tr2_srcdir}/bool_set \ ${tr2_srcdir}/bool_set.tcc \ ${tr2_srcdir}/dynamic_bitset \ + ${tr2_srcdir}/dynamic_bitset.tcc \ ${tr2_srcdir}/ratio \ ${tr2_srcdir}/type_traits diff --git a/libstdc++-v3/include/tr2/dynamic_bitset b/libstdc++-v3/include/tr2/dynamic_bitset index ebe9dc2..5cd05f5 100644 --- a/libstdc++-v3/include/tr2/dynamic_bitset +++ b/libstdc++-v3/include/tr2/dynamic_bitset @@ -137,7 +137,12 @@ public: if (__nbits % _S_bits_per_block > 0) ++__sz; if (__sz != this->_M_w.size()) - this->_M_w.resize(__sz); + { + block_type __val = 0; + if (__value) + __val = std::numeric_limits<block_type>::max(); + this->_M_w.resize(__sz, __val); + } } allocator_type @@ -246,7 +251,7 @@ public: bool _M_is_equal(const __dynamic_bitset_base& __x) const { - if (__x.size() == this->size()) + if (__x._M_w.size() == this->_M_w.size()) { for (size_t __i = 0; __i < this->_M_w.size(); ++__i) if (this->_M_w[__i] != __x._M_w[__i]) @@ -260,7 +265,7 @@ public: bool _M_is_less(const __dynamic_bitset_base& __x) const { - if (__x.size() == this->size()) + if (__x._M_w.size() == this->_M_w.size()) { for (size_t __i = this->_M_w.size(); __i > 0; --__i) { @@ -297,9 +302,9 @@ public: bool _M_is_subset_of(const __dynamic_bitset_base& __b) { - if (__b.size() == this->size()) + if (__b._M_w.size() == this->_M_w.size()) { - for (size_t __i = 0; __i < _M_w.size(); ++__i) + for (size_t __i = 0; __i < this->_M_w.size(); ++__i) if (this->_M_w[__i] != (this->_M_w[__i] | __b._M_w[__i])) return false; return true; @@ -364,140 +369,6 @@ public: } }; - // Definitions of non-inline functions from __dynamic_bitset_base. - template<typename _WordT, typename _Alloc> - void - __dynamic_bitset_base<_WordT, _Alloc>::_M_do_left_shift(size_t __shift) - { - if (__builtin_expect(__shift != 0, 1)) - { - const size_t __wshift = __shift / _S_bits_per_block; - const size_t __offset = __shift % _S_bits_per_block; - - if (__offset == 0) - for (size_t __n = this->_M_w.size() - 1; __n >= __wshift; --__n) - this->_M_w[__n] = this->_M_w[__n - __wshift]; - else - { - const size_t __sub_offset = _S_bits_per_block - __offset; - for (size_t __n = _M_w.size() - 1; __n > __wshift; --__n) - this->_M_w[__n] = ((this->_M_w[__n - __wshift] << __offset) - | (this->_M_w[__n - __wshift - 1] >> __sub_offset)); - this->_M_w[__wshift] = this->_M_w[0] << __offset; - } - - //// std::fill(this->_M_w.begin(), this->_M_w.begin() + __wshift, - //// static_cast<_WordT>(0)); - } - } - - template<typename _WordT, typename _Alloc> - void - __dynamic_bitset_base<_WordT, _Alloc>::_M_do_right_shift(size_t __shift) - { - if (__builtin_expect(__shift != 0, 1)) - { - const size_t __wshift = __shift / _S_bits_per_block; - const size_t __offset = __shift % _S_bits_per_block; - const size_t __limit = this->_M_w.size() - __wshift - 1; - - if (__offset == 0) - for (size_t __n = 0; __n <= __limit; ++__n) - this->_M_w[__n] = this->_M_w[__n + __wshift]; - else - { - const size_t __sub_offset = (_S_bits_per_block - - __offset); - for (size_t __n = 0; __n < __limit; ++__n) - this->_M_w[__n] = ((this->_M_w[__n + __wshift] >> __offset) - | (this->_M_w[__n + __wshift + 1] << __sub_offset)); - this->_M_w[__limit] = this->_M_w[_M_w.size()-1] >> __offset; - } - - ////std::fill(this->_M_w.begin() + __limit + 1, this->_M_w.end(), - //// static_cast<_WordT>(0)); - } - } - - template<typename _WordT, typename _Alloc> - unsigned long - __dynamic_bitset_base<_WordT, _Alloc>::_M_do_to_ulong() const - { - size_t __n = sizeof(unsigned long) / sizeof(block_type); - for (size_t __i = __n; __i < this->_M_w.size(); ++__i) - if (this->_M_w[__i]) - __throw_overflow_error(__N("__dynamic_bitset_base::_M_do_to_ulong")); - unsigned long __res = 0UL; - for (size_t __i = 0; __i < __n && __i < this->_M_w.size(); ++__i) - __res += this->_M_w[__i] << (__i * _S_bits_per_block); - return __res; - } - - template<typename _WordT, typename _Alloc> - unsigned long long - __dynamic_bitset_base<_WordT, _Alloc>::_M_do_to_ullong() const - { - size_t __n = sizeof(unsigned long long) / sizeof(block_type); - for (size_t __i = __n; __i < this->_M_w.size(); ++__i) - if (this->_M_w[__i]) - __throw_overflow_error(__N("__dynamic_bitset_base::_M_do_to_ullong")); - unsigned long long __res = 0ULL; - for (size_t __i = 0; __i < __n && __i < this->_M_w.size(); ++__i) - __res += this->_M_w[__i] << (__i * _S_bits_per_block); - return __res; - } - - template<typename _WordT, typename _Alloc> - size_t - __dynamic_bitset_base<_WordT, _Alloc> - ::_M_do_find_first(size_t __not_found) const - { - for (size_t __i = 0; __i < this->_M_w.size(); ++__i) - { - _WordT __thisword = this->_M_w[__i]; - if (__thisword != static_cast<_WordT>(0)) - return (__i * _S_bits_per_block - + __builtin_ctzl(__thisword)); - } - // not found, so return an indication of failure. - return __not_found; - } - - template<typename _WordT, typename _Alloc> - size_t - __dynamic_bitset_base<_WordT, _Alloc> - ::_M_do_find_next(size_t __prev, size_t __not_found) const - { - // make bound inclusive - ++__prev; - - // check out of bounds - if (__prev >= this->_M_w.size() * _S_bits_per_block) - return __not_found; - - // search first word - size_t __i = _S_whichword(__prev); - _WordT __thisword = this->_M_w[__i]; - - // mask off bits below bound - __thisword &= (~static_cast<_WordT>(0)) << _S_whichbit(__prev); - - if (__thisword != static_cast<_WordT>(0)) - return (__i * _S_bits_per_block - + __builtin_ctzl(__thisword)); - - // check subsequent words - for (++__i; __i < this->_M_w.size(); ++__i) - { - __thisword = this->_M_w[__i]; - if (__thisword != static_cast<_WordT>(0)) - return (__i * _S_bits_per_block - + __builtin_ctzl(__thisword)); - } - // not found, so return an indication of failure. - return __not_found; - } // end _M_do_find_next - /** * @brief The %dynamic_bitset class represents a sequence of bits. * @@ -594,6 +465,15 @@ public: this->_M_hiword() &= ~((~static_cast<block_type>(0)) << __shift); } + // Set the unused bits in the uppermost word. + void + _M_do_fill() + { + size_type __shift = this->_M_Nb % bits_per_block; + if (__shift > 0) + this->_M_hiword() |= ((~static_cast<block_type>(0)) << __shift); + } + /** * These versions of single-bit set, reset, flip, and test * do no range checking. @@ -847,6 +727,8 @@ public: void resize(size_type __nbits, bool __value = false) { + if (__value) + this->_M_do_fill(); this->_M_resize(__nbits, __value); this->_M_Nb = __nbits; this->_M_do_sanitize(); @@ -1240,33 +1122,21 @@ public: bool is_proper_subset_of(const dynamic_bitset& __b) const { return this->_M_is_proper_subset_of(__b); } - }; - // Definitions of non-inline member functions. - template<typename _WordT, typename _Alloc> - template<typename _CharT, typename _Traits> - void - dynamic_bitset<_WordT, _Alloc>:: - _M_copy_from_ptr(const _CharT* __str, size_t __len, - size_t __pos, size_t __n, _CharT __zero, _CharT __one) - { - reset(); - const size_t __nbits = std::min(_M_Nb, std::min(__n, __len - __pos)); - for (size_t __i = __nbits; __i > 0; --__i) - { - const _CharT __c = __str[__pos + __nbits - __i]; - if (_Traits::eq(__c, __zero)) - ; - else if (_Traits::eq(__c, __one)) - _M_unchecked_set(__i - 1); - else - __throw_invalid_argument(__N("dynamic_bitset::_M_copy_from_ptr")); - } - } + friend bool + operator==(const dynamic_bitset<_WordT, _Alloc>& __lhs, + const dynamic_bitset<_WordT, _Alloc>& __rhs) + { return __lhs._M_is_equal(__rhs); } + + friend bool + operator<(const dynamic_bitset<_WordT, _Alloc>& __lhs, + const dynamic_bitset<_WordT, _Alloc>& __rhs) + { return __lhs._M_is_less(__rhs); } + }; template<typename _WordT, typename _Alloc> template<typename _CharT, typename _Traits, typename _Alloc1> - void + inline void dynamic_bitset<_WordT, _Alloc>:: _M_copy_to_string(std::basic_string<_CharT, _Traits, _Alloc1>& __str, _CharT __zero, _CharT __one) const @@ -1280,38 +1150,27 @@ public: //@{ /// These comparisons for equality/inequality are, well, @e bitwise. - template<typename _WordT, typename _Alloc> - bool - operator==(const dynamic_bitset<_WordT, _Alloc>& __lhs, - const dynamic_bitset<_WordT, _Alloc>& __rhs) - { return __lhs._M_is_equal(__rhs); } template<typename _WordT, typename _Alloc> - bool + inline bool operator!=(const dynamic_bitset<_WordT, _Alloc>& __lhs, const dynamic_bitset<_WordT, _Alloc>& __rhs) - { return !__lhs._M_is_equal(__rhs); } - - template<typename _WordT, typename _Alloc> - bool - operator<(const dynamic_bitset<_WordT, _Alloc>& __lhs, - const dynamic_bitset<_WordT, _Alloc>& __rhs) - { return __lhs._M_is_less(__rhs); } + { return !(__lhs == __rhs); } template<typename _WordT, typename _Alloc> - bool + inline bool operator<=(const dynamic_bitset<_WordT, _Alloc>& __lhs, const dynamic_bitset<_WordT, _Alloc>& __rhs) { return !(__lhs > __rhs); } template<typename _WordT, typename _Alloc> - bool + inline bool operator>(const dynamic_bitset<_WordT, _Alloc>& __lhs, const dynamic_bitset<_WordT, _Alloc>& __rhs) { return __rhs < __lhs; } template<typename _WordT, typename _Alloc> - bool + inline bool operator>=(const dynamic_bitset<_WordT, _Alloc>& __lhs, const dynamic_bitset<_WordT, _Alloc>& __rhs) { return !(__lhs < __rhs); } @@ -1368,8 +1227,9 @@ public: } //@} - //@{ /** + * @defgroup Global I/O operators for bitsets. + * @{ * @brief Global I/O operators for bitsets. * * Direct I/O between streams and bitsets is supported. Output is @@ -1377,81 +1237,9 @@ public: * and '1' characters. The %dynamic_bitset will grow as necessary * to hold the string of bits. */ - template<typename _CharT, typename _Traits, - typename _WordT, typename _Alloc> - std::basic_istream<_CharT, _Traits>& - operator>>(std::basic_istream<_CharT, _Traits>& __is, - dynamic_bitset<_WordT, _Alloc>& __x) - { - typedef typename _Traits::char_type char_type; - typedef std::basic_istream<_CharT, _Traits> __istream_type; - typedef typename __istream_type::ios_base __ios_base; - - std::basic_string<_CharT, _Traits> __tmp; - __tmp.reserve(__x.size()); - - const char_type __zero = __is.widen('0'); - const char_type __one = __is.widen('1'); - - typename __ios_base::iostate __state = __ios_base::goodbit; - typename __istream_type::sentry __sentry(__is); - if (__sentry) - { - __try - { - while (1) - { - static typename _Traits::int_type __eof = _Traits::eof(); - - typename _Traits::int_type __c1 = __is.rdbuf()->sbumpc(); - if (_Traits::eq_int_type(__c1, __eof)) - { - __state |= __ios_base::eofbit; - break; - } - else - { - const char_type __c2 = _Traits::to_char_type(__c1); - if (_Traits::eq(__c2, __zero)) - __tmp.push_back(__zero); - else if (_Traits::eq(__c2, __one)) - __tmp.push_back(__one); - else if (_Traits:: - eq_int_type(__is.rdbuf()->sputbackc(__c2), - __eof)) - { - __state |= __ios_base::failbit; - break; - } - else - break; - } - } - } - __catch(__cxxabiv1::__forced_unwind&) - { - __is._M_setstate(__ios_base::badbit); - __throw_exception_again; - } - __catch(...) - { __is._M_setstate(__ios_base::badbit); } - } - - __x.resize(__tmp.size()); - - if (__tmp.empty() && __x.size()) - __state |= __ios_base::failbit; - else - __x._M_copy_from_string(__tmp, static_cast<size_t>(0), __x.size(), - __zero, __one); - if (__state) - __is.setstate(__state); - return __is; - } - template <typename _CharT, typename _Traits, typename _WordT, typename _Alloc> - std::basic_ostream<_CharT, _Traits>& + inline std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const dynamic_bitset<_WordT, _Alloc>& __x) { @@ -1461,12 +1249,14 @@ public: __x._M_copy_to_string(__tmp, __ct.widen('0'), __ct.widen('1')); return __os << __tmp; } - //@} + /** + * @} + */ _GLIBCXX_END_NAMESPACE_VERSION } // tr2 } // std -#undef _GLIBCXX_BITSET_BITS_PER_WORD +#include <tr2/dynamic_bitset.tcc> #endif /* _GLIBCXX_TR2_DYNAMIC_BITSET */ diff --git a/libstdc++-v3/include/tr2/dynamic_bitset.tcc b/libstdc++-v3/include/tr2/dynamic_bitset.tcc new file mode 100644 index 0000000..016fdf0 --- /dev/null +++ b/libstdc++-v3/include/tr2/dynamic_bitset.tcc @@ -0,0 +1,286 @@ +// TR2 <dynamic_bitset> -*- C++ -*- + +// Copyright (C) 2009-2013 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr2/dynamic_bitset.tcc + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{tr2/dynamic_bitset} + */ + +#ifndef _GLIBCXX_TR2_DYNAMIC_BITSET_TCC +#define _GLIBCXX_TR2_DYNAMIC_BITSET_TCC 1 + +#pragma GCC system_header + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr2 +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + // Definitions of non-inline functions from __dynamic_bitset_base. + template<typename _WordT, typename _Alloc> + void + __dynamic_bitset_base<_WordT, _Alloc>::_M_do_left_shift(size_t __shift) + { + if (__builtin_expect(__shift != 0, 1)) + { + const size_t __wshift = __shift / _S_bits_per_block; + const size_t __offset = __shift % _S_bits_per_block; + + if (__offset == 0) + for (size_t __n = this->_M_w.size() - 1; __n >= __wshift; --__n) + this->_M_w[__n] = this->_M_w[__n - __wshift]; + else + { + const size_t __sub_offset = _S_bits_per_block - __offset; + for (size_t __n = _M_w.size() - 1; __n > __wshift; --__n) + this->_M_w[__n] = ((this->_M_w[__n - __wshift] << __offset) + | (this->_M_w[__n - __wshift - 1] >> __sub_offset)); + this->_M_w[__wshift] = this->_M_w[0] << __offset; + } + + //// std::fill(this->_M_w.begin(), this->_M_w.begin() + __wshift, + //// static_cast<_WordT>(0)); + } + } + + template<typename _WordT, typename _Alloc> + void + __dynamic_bitset_base<_WordT, _Alloc>::_M_do_right_shift(size_t __shift) + { + if (__builtin_expect(__shift != 0, 1)) + { + const size_t __wshift = __shift / _S_bits_per_block; + const size_t __offset = __shift % _S_bits_per_block; + const size_t __limit = this->_M_w.size() - __wshift - 1; + + if (__offset == 0) + for (size_t __n = 0; __n <= __limit; ++__n) + this->_M_w[__n] = this->_M_w[__n + __wshift]; + else + { + const size_t __sub_offset = (_S_bits_per_block + - __offset); + for (size_t __n = 0; __n < __limit; ++__n) + this->_M_w[__n] = ((this->_M_w[__n + __wshift] >> __offset) + | (this->_M_w[__n + __wshift + 1] << __sub_offset)); + this->_M_w[__limit] = this->_M_w[_M_w.size()-1] >> __offset; + } + + ////std::fill(this->_M_w.begin() + __limit + 1, this->_M_w.end(), + //// static_cast<_WordT>(0)); + } + } + + template<typename _WordT, typename _Alloc> + unsigned long + __dynamic_bitset_base<_WordT, _Alloc>::_M_do_to_ulong() const + { + size_t __n = sizeof(unsigned long) / sizeof(block_type); + for (size_t __i = __n; __i < this->_M_w.size(); ++__i) + if (this->_M_w[__i]) + __throw_overflow_error(__N("__dynamic_bitset_base::_M_do_to_ulong")); + unsigned long __res = 0UL; + for (size_t __i = 0; __i < __n && __i < this->_M_w.size(); ++__i) + __res += this->_M_w[__i] << (__i * _S_bits_per_block); + return __res; + } + + template<typename _WordT, typename _Alloc> + unsigned long long + __dynamic_bitset_base<_WordT, _Alloc>::_M_do_to_ullong() const + { + size_t __n = sizeof(unsigned long long) / sizeof(block_type); + for (size_t __i = __n; __i < this->_M_w.size(); ++__i) + if (this->_M_w[__i]) + __throw_overflow_error(__N("__dynamic_bitset_base::_M_do_to_ullong")); + unsigned long long __res = 0ULL; + for (size_t __i = 0; __i < __n && __i < this->_M_w.size(); ++__i) + __res += this->_M_w[__i] << (__i * _S_bits_per_block); + return __res; + } + + template<typename _WordT, typename _Alloc> + size_t + __dynamic_bitset_base<_WordT, _Alloc> + ::_M_do_find_first(size_t __not_found) const + { + for (size_t __i = 0; __i < this->_M_w.size(); ++__i) + { + _WordT __thisword = this->_M_w[__i]; + if (__thisword != static_cast<_WordT>(0)) + return (__i * _S_bits_per_block + + __builtin_ctzl(__thisword)); + } + // not found, so return an indication of failure. + return __not_found; + } + + template<typename _WordT, typename _Alloc> + size_t + __dynamic_bitset_base<_WordT, _Alloc> + ::_M_do_find_next(size_t __prev, size_t __not_found) const + { + // make bound inclusive + ++__prev; + + // check out of bounds + if (__prev >= this->_M_w.size() * _S_bits_per_block) + return __not_found; + + // search first word + size_t __i = _S_whichword(__prev); + _WordT __thisword = this->_M_w[__i]; + + // mask off bits below bound + __thisword &= (~static_cast<_WordT>(0)) << _S_whichbit(__prev); + + if (__thisword != static_cast<_WordT>(0)) + return (__i * _S_bits_per_block + + __builtin_ctzl(__thisword)); + + // check subsequent words + for (++__i; __i < this->_M_w.size(); ++__i) + { + __thisword = this->_M_w[__i]; + if (__thisword != static_cast<_WordT>(0)) + return (__i * _S_bits_per_block + + __builtin_ctzl(__thisword)); + } + // not found, so return an indication of failure. + return __not_found; + } // end _M_do_find_next + + // Definitions of non-inline member functions. + template<typename _WordT, typename _Alloc> + template<typename _CharT, typename _Traits> + void + dynamic_bitset<_WordT, _Alloc>:: + _M_copy_from_ptr(const _CharT* __str, size_t __len, + size_t __pos, size_t __n, _CharT __zero, _CharT __one) + { + reset(); + const size_t __nbits = std::min(_M_Nb, std::min(__n, __len - __pos)); + for (size_t __i = __nbits; __i > 0; --__i) + { + const _CharT __c = __str[__pos + __nbits - __i]; + if (_Traits::eq(__c, __zero)) + ; + else if (_Traits::eq(__c, __one)) + _M_unchecked_set(__i - 1); + else + __throw_invalid_argument(__N("dynamic_bitset::_M_copy_from_ptr")); + } + } + + /** + * @defgroup Global I/O operators for bitsets. + * @{ + * @brief Global I/O operators for bitsets. + * + * Direct I/O between streams and bitsets is supported. Output is + * straightforward. Input will skip whitespace and only accept '0' + * and '1' characters. The %dynamic_bitset will grow as necessary + * to hold the string of bits. + */ + template<typename _CharT, typename _Traits, + typename _WordT, typename _Alloc> + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + dynamic_bitset<_WordT, _Alloc>& __x) + { + typedef typename _Traits::char_type char_type; + typedef std::basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::ios_base __ios_base; + + std::basic_string<_CharT, _Traits> __tmp; + __tmp.reserve(__x.size()); + + const char_type __zero = __is.widen('0'); + const char_type __one = __is.widen('1'); + + typename __ios_base::iostate __state = __ios_base::goodbit; + typename __istream_type::sentry __sentry(__is); + if (__sentry) + { + __try + { + while (1) + { + static typename _Traits::int_type __eof = _Traits::eof(); + + typename _Traits::int_type __c1 = __is.rdbuf()->sbumpc(); + if (_Traits::eq_int_type(__c1, __eof)) + { + __state |= __ios_base::eofbit; + break; + } + else + { + const char_type __c2 = _Traits::to_char_type(__c1); + if (_Traits::eq(__c2, __zero)) + __tmp.push_back(__zero); + else if (_Traits::eq(__c2, __one)) + __tmp.push_back(__one); + else if (_Traits:: + eq_int_type(__is.rdbuf()->sputbackc(__c2), + __eof)) + { + __state |= __ios_base::failbit; + break; + } + else + break; + } + } + } + __catch(__cxxabiv1::__forced_unwind&) + { + __is._M_setstate(__ios_base::badbit); + __throw_exception_again; + } + __catch(...) + { __is._M_setstate(__ios_base::badbit); } + } + + __x.resize(__tmp.size()); + + if (__tmp.empty() && __x.size()) + __state |= __ios_base::failbit; + else + __x._M_copy_from_string(__tmp, static_cast<size_t>(0), __x.size(), + __zero, __one); + if (__state) + __is.setstate(__state); + return __is; + } + /** + * @} + */ + +_GLIBCXX_END_NAMESPACE_VERSION +} // tr2 +} // std + +#endif /* _GLIBCXX_TR2_DYNAMIC_BITSET_TCC */ diff --git a/libstdc++-v3/testsuite/tr2/dynamic_bitset/pr58729.cc b/libstdc++-v3/testsuite/tr2/dynamic_bitset/pr58729.cc new file mode 100644 index 0000000..7607e3f --- /dev/null +++ b/libstdc++-v3/testsuite/tr2/dynamic_bitset/pr58729.cc @@ -0,0 +1,64 @@ +// { dg-options "-std=gnu++11" } + +// 2013-10-15 Edward M. Smith-Rowland <3dw4rd@verizon.net> +// +// Copyright (C) 2013 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// libstdc++/58729 + +#include <tr2/dynamic_bitset> +#include <testsuite_hooks.h> + +void +test01() +{ + std::tr2::dynamic_bitset<> pdb2{}; + + pdb2.resize(10, true); + VERIFY (pdb2 == std::tr2::dynamic_bitset<>{"1111111111"}); + + pdb2.resize(15); + VERIFY (pdb2 == std::tr2::dynamic_bitset<>{"000001111111111"}); + + pdb2.flip(); + VERIFY (pdb2 == std::tr2::dynamic_bitset<>{"111110000000000"}); + + VERIFY (pdb2.size() == 15); + VERIFY (pdb2.count() == 5); + + pdb2.resize(20, false); + VERIFY (pdb2 == std::tr2::dynamic_bitset<>{"00000111110000000000"}); + + pdb2.resize(25, true); + VERIFY (pdb2 == std::tr2::dynamic_bitset<>{"1111100000111110000000000"}); + + pdb2.resize(75, true); + VERIFY (pdb2 == std::tr2::dynamic_bitset<>{"1111111111111111111111111" + "1111111111111111111111111" + "1111100000111110000000000"}); + + VERIFY (pdb2.size() == 75); + VERIFY (pdb2.count() == 60); +} + +int +main() +{ + test01(); + return 0; +} |