]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR libstdc++/58729 (tr2::dynamic_bitset::resize fails)
authorEdward Smith-Rowland <3dw4rd@verizon.net>
Sat, 19 Oct 2013 01:31:19 +0000 (01:31 +0000)
committerEdward Smith-Rowland <emsr@gcc.gnu.org>
Sat, 19 Oct 2013 01:31:19 +0000 (01:31 +0000)
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

libstdc++-v3/ChangeLog
libstdc++-v3/include/Makefile.am
libstdc++-v3/include/Makefile.in
libstdc++-v3/include/tr2/dynamic_bitset
libstdc++-v3/include/tr2/dynamic_bitset.tcc [new file with mode: 0644]
libstdc++-v3/testsuite/tr2/dynamic_bitset/pr58729.cc [new file with mode: 0644]

index b37fdb64aa7935c6ea9ad1d7edfc5a1a2f803793..c3fa989b86713c88684f0d2efcaff3d41df7cc63 100644 (file)
@@ -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,
index 1a4fd6f9bc2f7ca8abe0e8c0550984772ec5beae..0ddc8b51419f57ee7780f06786ec131ce2b0a098 100644 (file)
@@ -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
 
index 87a9f1b80cfb36c6597d2cd8f79f6ff279e41db4..a1fd1d39982da8520c33fae9cbcc752e4c5b0efe 100644 (file)
@@ -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
 
index ebe9dc2809584b741605f154147c2f994c2579f5..5cd05f53c54f8a0929b664f38e7f5c419632b29d 100644 (file)
@@ -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 (file)
index 0000000..016fdf0
--- /dev/null
@@ -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 (file)
index 0000000..7607e3f
--- /dev/null
@@ -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;
+}