This patch bootstraps and tests clean on x86-64-linux.
Truthfully, dynamic_bitset needs some more love wrt C++11 and a testsuite. It got put in before it was baked really. That will be later.
2013-10-16 Edward Smith-Rowland <3dw...@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.
Index: include/tr2/dynamic_bitset =================================================================== --- include/tr2/dynamic_bitset (revision 203739) +++ include/tr2/dynamic_bitset (working copy) @@ -137,7 +137,12 @@ 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 @@ 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 @@ 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 @@ 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 @@ } }; - // 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 @@ 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 @@ 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 @@ bool is_proper_subset_of(const dynamic_bitset& __b) const { return this->_M_is_proper_subset_of(__b); } + + 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); } }; - // 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")); - } - } - - 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 @@ //@{ /// 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); } + { return !(__lhs == __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); } - - 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 @@ } //@} - //@{ /** + * @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 @@ * 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 @@ __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 */ Index: include/tr2/dynamic_bitset.tcc =================================================================== --- include/tr2/dynamic_bitset.tcc (revision 0) +++ include/tr2/dynamic_bitset.tcc (working copy) @@ -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 */ Index: include/Makefile.am =================================================================== --- include/Makefile.am (revision 203739) +++ include/Makefile.am (working copy) @@ -623,6 +623,7 @@ ${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: include/Makefile.in =================================================================== --- include/Makefile.in (revision 203739) +++ include/Makefile.in (working copy) @@ -888,6 +888,7 @@ ${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: testsuite/tr2/dynamic_bitset/pr58729.cc =================================================================== --- testsuite/tr2/dynamic_bitset/pr58729.cc (revision 0) +++ testsuite/tr2/dynamic_bitset/pr58729.cc (working copy) @@ -0,0 +1,64 @@ +// { dg-options "-std=gnu++11" } + +// 2013-10-15 Edward M. Smith-Rowland <3dw...@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; +}