aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Smith-Rowland <3dw4rd@verizon.net>2013-10-19 01:31:19 +0000
committerEdward Smith-Rowland <emsr@gcc.gnu.org>2013-10-19 01:31:19 +0000
commit6b8fe121affbf6fcfe19fca582c56cb9baf9b600 (patch)
tree6c13387d2b1e6d35e2d97616603d95b65a65a270
parentd979bbbb845ada9bee20db91fe057f2357dc1b3e (diff)
downloadgcc-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/ChangeLog12
-rw-r--r--libstdc++-v3/include/Makefile.am1
-rw-r--r--libstdc++-v3/include/Makefile.in1
-rw-r--r--libstdc++-v3/include/tr2/dynamic_bitset298
-rw-r--r--libstdc++-v3/include/tr2/dynamic_bitset.tcc286
-rw-r--r--libstdc++-v3/testsuite/tr2/dynamic_bitset/pr58729.cc64
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;
+}