aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2019-10-11 16:29:55 +0100
committerJonathan Wakely <redi@gcc.gnu.org>2019-10-11 16:29:55 +0100
commit07758d90c7bc6b80b10a83bac52f9ab9e394131d (patch)
tree471b8a23cc4ad0e7c100d147ad0f5b63bc744864
parent2bf2dacb355af3632fd98b2f9e920f1e03722049 (diff)
downloadgcc-07758d90c7bc6b80b10a83bac52f9ab9e394131d.zip
gcc-07758d90c7bc6b80b10a83bac52f9ab9e394131d.tar.gz
gcc-07758d90c7bc6b80b10a83bac52f9ab9e394131d.tar.bz2
PR libstdc++/92059 fix several bugs in tr2::dynamic_bitset
PR libstdc++/92059 * include/tr2/dynamic_bitset (__dynamic_bitset_base): Define all special member functions as defaulted. Add noexcept to most members. (__dynamic_bitset_base(size_t, unsigned long long, const _Alloc&)): Mask off unwanted bits in the __val parameter. Avoid undefined left shifts. (__dynamic_bitset_base::_M_assign): Remove. (__dynamic_bitset_base::_M_do_reset): Use std::fill. (__dynamic_bitset_base::_M_are_all_aux): Avoid integer promotion when block_type has lower rank than int. (dynamic_bitset): Add noexcept to most members. Use injected-class-name in return types and parameter types. (dynamic_bitset::_M_Nb): Add default member initializer. (dynamic_bitset(), dynamic_bitset(const dynamic_bitset&)): Define as defaulted. (dynamic_bitset(dynamic_bitset&&)): Clear source object after move. (dynamic_bitset::operator=(const dynamic_bitset&)): Define as defaulted. (dynamic_bitset::operator=(dynamic_bitset&&)): Add noexcept-specifier. Define without using swap, to propagate allocator correctly. (dynamic_bitset(const char*, const _Alloc&)): Use strlen. (dynamic_bitset::_M_do_sanitize, dynamic_bitset::_M_do_fill): Use casts to avoid unwanted integer promotions. (dynamic_bitset::_M_copy_from_ptr): Rearrange template parameters and add default template arguments and default argument to simplify usage. (dynamic_bitset::_M_copy_from_string): Adjust call to _M_copy_from_ptr. (operator==(const dynamic_bitset&, const dynamic_bitset&)) (operator<(const dynamic_bitset&, const dynamic_bitset&)): Use _M_Nb. * include/tr2/dynamic_bitset.tcc (dynamic_bitset::_M_copy_from_ptr): Adjust template parameters to match declaration. * testsuite/tr2/dynamic_bitset/cmp.cc: New test. * testsuite/tr2/dynamic_bitset/cons.cc: New test. * testsuite/tr2/dynamic_bitset/copy.cc: New test. * testsuite/tr2/dynamic_bitset/move.cc: New test. * testsuite/tr2/dynamic_bitset/pr92059.cc: New test. From-SVN: r276890
-rw-r--r--libstdc++-v3/ChangeLog36
-rw-r--r--libstdc++-v3/include/tr2/dynamic_bitset295
-rw-r--r--libstdc++-v3/include/tr2/dynamic_bitset.tcc2
-rw-r--r--libstdc++-v3/testsuite/tr2/dynamic_bitset/cmp.cc50
-rw-r--r--libstdc++-v3/testsuite/tr2/dynamic_bitset/cons.cc105
-rw-r--r--libstdc++-v3/testsuite/tr2/dynamic_bitset/copy.cc55
-rw-r--r--libstdc++-v3/testsuite/tr2/dynamic_bitset/move.cc53
-rw-r--r--libstdc++-v3/testsuite/tr2/dynamic_bitset/pr92059.cc36
8 files changed, 478 insertions, 154 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 1459185..3e6a7dd 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,41 @@
2019-10-11 Jonathan Wakely <jwakely@redhat.com>
+ PR libstdc++/92059
+ * include/tr2/dynamic_bitset (__dynamic_bitset_base): Define all
+ special member functions as defaulted. Add noexcept to most members.
+ (__dynamic_bitset_base(size_t, unsigned long long, const _Alloc&)):
+ Mask off unwanted bits in the __val parameter. Avoid undefined left
+ shifts.
+ (__dynamic_bitset_base::_M_assign): Remove.
+ (__dynamic_bitset_base::_M_do_reset): Use std::fill.
+ (__dynamic_bitset_base::_M_are_all_aux): Avoid integer promotion when
+ block_type has lower rank than int.
+ (dynamic_bitset): Add noexcept to most members. Use injected-class-name
+ in return types and parameter types.
+ (dynamic_bitset::_M_Nb): Add default member initializer.
+ (dynamic_bitset(), dynamic_bitset(const dynamic_bitset&)): Define as
+ defaulted.
+ (dynamic_bitset(dynamic_bitset&&)): Clear source object after move.
+ (dynamic_bitset::operator=(const dynamic_bitset&)): Define as
+ defaulted.
+ (dynamic_bitset::operator=(dynamic_bitset&&)): Add noexcept-specifier.
+ Define without using swap, to propagate allocator correctly.
+ (dynamic_bitset(const char*, const _Alloc&)): Use strlen.
+ (dynamic_bitset::_M_do_sanitize, dynamic_bitset::_M_do_fill): Use
+ casts to avoid unwanted integer promotions.
+ (dynamic_bitset::_M_copy_from_ptr): Rearrange template parameters and
+ add default template arguments and default argument to simplify usage.
+ (dynamic_bitset::_M_copy_from_string): Adjust call to _M_copy_from_ptr.
+ (operator==(const dynamic_bitset&, const dynamic_bitset&))
+ (operator<(const dynamic_bitset&, const dynamic_bitset&)): Use _M_Nb.
+ * include/tr2/dynamic_bitset.tcc (dynamic_bitset::_M_copy_from_ptr):
+ Adjust template parameters to match declaration.
+ * testsuite/tr2/dynamic_bitset/cmp.cc: New test.
+ * testsuite/tr2/dynamic_bitset/cons.cc: New test.
+ * testsuite/tr2/dynamic_bitset/copy.cc: New test.
+ * testsuite/tr2/dynamic_bitset/move.cc: New test.
+ * testsuite/tr2/dynamic_bitset/pr92059.cc: New test.
+
* include/bits/charconv.h (__to_chars_len): Avoid -Wsign-compare
warnings.
diff --git a/libstdc++-v3/include/tr2/dynamic_bitset b/libstdc++-v3/include/tr2/dynamic_bitset
index 434a4cc..28c877c 100644
--- a/libstdc++-v3/include/tr2/dynamic_bitset
+++ b/libstdc++-v3/include/tr2/dynamic_bitset
@@ -34,10 +34,9 @@
#include <limits>
#include <vector>
#include <string>
-#include <memory> // For std::allocator
-#include <bits/functexcept.h> // For invalid_argument, out_of_range,
- // overflow_error
-#include <iosfwd>
+#include <istream>
+#include <bits/functexcept.h>
+#include <bits/stl_algo.h> // For fill
#include <bits/cxxabi_forced.h>
namespace std _GLIBCXX_VISIBILITY(default)
@@ -76,41 +75,48 @@ namespace tr2
std::vector<block_type, allocator_type> _M_w;
explicit
- __dynamic_bitset_base(const allocator_type& __alloc = allocator_type())
+ __dynamic_bitset_base(const allocator_type& __alloc)
: _M_w(__alloc)
{ }
- explicit
- __dynamic_bitset_base(__dynamic_bitset_base&& __b)
- { this->_M_w.swap(__b._M_w); }
+ __dynamic_bitset_base() = default;
+ __dynamic_bitset_base(const __dynamic_bitset_base&) = default;
+ __dynamic_bitset_base(__dynamic_bitset_base&& __b) = default;
+ __dynamic_bitset_base& operator=(const __dynamic_bitset_base&) = default;
+ __dynamic_bitset_base& operator=(__dynamic_bitset_base&&) = default;
+ ~__dynamic_bitset_base() = default;
explicit
__dynamic_bitset_base(size_type __nbits, unsigned long long __val = 0ULL,
const allocator_type& __alloc = allocator_type())
- : _M_w(__nbits / _S_bits_per_block
- + (__nbits % _S_bits_per_block > 0),
- __val, __alloc)
+ : _M_w(__nbits / _S_bits_per_block + (__nbits % _S_bits_per_block > 0),
+ block_type(0), __alloc)
{
- unsigned long long __mask = ~static_cast<block_type>(0);
- size_t __n = std::min(this->_M_w.size(),
- sizeof(unsigned long long) / sizeof(block_type));
- for (size_t __i = 0; __i < __n; ++__i)
+ if (__nbits < std::numeric_limits<decltype(__val)>::digits)
+ __val &= ~(-1ULL << __nbits);
+ if (__val == 0)
+ return;
+
+ if _GLIBCXX17_CONSTEXPR (sizeof(__val) == sizeof(block_type))
+ _M_w[0] = __val;
+ else
{
- this->_M_w[__i] = (__val & __mask) >> (__i * _S_bits_per_block);
- __mask <<= _S_bits_per_block;
+ const size_t __n
+ = std::min(_M_w.size(), sizeof(__val) / sizeof(block_type));
+ for (size_t __i = 0; __val && __i < __n; ++__i)
+ {
+ _M_w[__i] = static_cast<block_type>(__val);
+ __val >>= _S_bits_per_block;
+ }
}
}
void
- _M_assign(const __dynamic_bitset_base& __b)
- { this->_M_w = __b._M_w; }
-
- void
- _M_swap(__dynamic_bitset_base& __b)
+ _M_swap(__dynamic_bitset_base& __b) noexcept
{ this->_M_w.swap(__b._M_w); }
void
- _M_clear()
+ _M_clear() noexcept
{ this->_M_w.clear(); }
void
@@ -129,7 +135,7 @@ namespace tr2
}
allocator_type
- _M_get_allocator() const
+ _M_get_allocator() const noexcept
{ return this->_M_w.get_allocator(); }
static size_type
@@ -149,23 +155,23 @@ namespace tr2
{ return (static_cast<block_type>(1)) << _S_whichbit(__pos); }
block_type&
- _M_getword(size_type __pos)
+ _M_getword(size_type __pos) noexcept
{ return this->_M_w[_S_whichword(__pos)]; }
block_type
- _M_getword(size_type __pos) const
+ _M_getword(size_type __pos) const noexcept
{ return this->_M_w[_S_whichword(__pos)]; }
block_type&
- _M_hiword()
+ _M_hiword() noexcept
{ return this->_M_w[_M_w.size() - 1]; }
block_type
- _M_hiword() const
+ _M_hiword() const noexcept
{ return this->_M_w[_M_w.size() - 1]; }
void
- _M_do_and(const __dynamic_bitset_base& __x)
+ _M_do_and(const __dynamic_bitset_base& __x) noexcept
{
if (__x._M_w.size() == this->_M_w.size())
for (size_t __i = 0; __i < this->_M_w.size(); ++__i)
@@ -175,7 +181,7 @@ namespace tr2
}
void
- _M_do_or(const __dynamic_bitset_base& __x)
+ _M_do_or(const __dynamic_bitset_base& __x) noexcept
{
if (__x._M_w.size() == this->_M_w.size())
for (size_t __i = 0; __i < this->_M_w.size(); ++__i)
@@ -185,7 +191,7 @@ namespace tr2
}
void
- _M_do_xor(const __dynamic_bitset_base& __x)
+ _M_do_xor(const __dynamic_bitset_base& __x) noexcept
{
if (__x._M_w.size() == this->_M_w.size())
for (size_t __i = 0; __i < this->_M_w.size(); ++__i)
@@ -195,7 +201,7 @@ namespace tr2
}
void
- _M_do_dif(const __dynamic_bitset_base& __x)
+ _M_do_dif(const __dynamic_bitset_base& __x) noexcept
{
if (__x._M_w.size() == this->_M_w.size())
for (size_t __i = 0; __i < this->_M_w.size(); ++__i)
@@ -211,28 +217,27 @@ namespace tr2
_M_do_right_shift(size_t __shift);
void
- _M_do_flip()
+ _M_do_flip() noexcept
{
for (size_t __i = 0; __i < this->_M_w.size(); ++__i)
this->_M_w[__i] = ~this->_M_w[__i];
}
void
- _M_do_set()
+ _M_do_set() noexcept
{
for (size_t __i = 0; __i < this->_M_w.size(); ++__i)
- this->_M_w[__i] = ~static_cast<block_type>(0);
+ this->_M_w[__i] = static_cast<block_type>(-1);
}
void
- _M_do_reset()
+ _M_do_reset() noexcept
{
- for (size_t __i = 0; __i < this->_M_w.size(); ++__i)
- this->_M_w[__i] = static_cast<block_type>(0);
+ std::fill(_M_w.begin(), _M_w.end(), static_cast<block_type>(0));
}
bool
- _M_is_equal(const __dynamic_bitset_base& __x) const
+ _M_is_equal(const __dynamic_bitset_base& __x) const noexcept
{
if (__x._M_w.size() == this->_M_w.size())
{
@@ -246,7 +251,7 @@ namespace tr2
}
bool
- _M_is_less(const __dynamic_bitset_base& __x) const
+ _M_is_less(const __dynamic_bitset_base& __x) const noexcept
{
if (__x._M_w.size() == this->_M_w.size())
{
@@ -264,17 +269,17 @@ namespace tr2
}
size_t
- _M_are_all_aux() const
+ _M_are_all_aux() const noexcept
{
for (size_t __i = 0; __i < this->_M_w.size() - 1; ++__i)
- if (_M_w[__i] != ~static_cast<block_type>(0))
+ if (_M_w[__i] != static_cast<block_type>(-1))
return 0;
return ((this->_M_w.size() - 1) * _S_bits_per_block
+ __builtin_popcountll(this->_M_hiword()));
}
bool
- _M_is_any() const
+ _M_is_any() const noexcept
{
for (size_t __i = 0; __i < this->_M_w.size(); ++__i)
if (this->_M_w[__i] != static_cast<block_type>(0))
@@ -283,7 +288,7 @@ namespace tr2
}
bool
- _M_is_subset_of(const __dynamic_bitset_base& __b)
+ _M_is_subset_of(const __dynamic_bitset_base& __b) noexcept
{
if (__b._M_w.size() == this->_M_w.size())
{
@@ -297,7 +302,7 @@ namespace tr2
}
bool
- _M_is_proper_subset_of(const __dynamic_bitset_base& __b) const
+ _M_is_proper_subset_of(const __dynamic_bitset_base& __b) const noexcept
{
if (this->is_subset_of(__b))
{
@@ -311,7 +316,7 @@ namespace tr2
}
size_t
- _M_do_count() const
+ _M_do_count() const noexcept
{
size_t __result = 0;
for (size_t __i = 0; __i < this->_M_w.size(); ++__i)
@@ -357,6 +362,7 @@ namespace tr2
*
* See N2050,
* Proposal to Add a Dynamically Sizeable Bitset to the Standard Library.
+ * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2050.pdf
*
* In the general unoptimized case, storage is allocated in
* word-sized blocks. Let B be the number of bits in a word, then
@@ -435,7 +441,7 @@ namespace tr2
{
size_type __shift = this->_M_Nb % bits_per_block;
if (__shift > 0)
- this->_M_hiword() &= ~((~static_cast<block_type>(0)) << __shift);
+ this->_M_hiword() &= block_type(~(block_type(-1) << __shift));
}
// Set the unused bits in the uppermost word.
@@ -444,22 +450,22 @@ namespace tr2
{
size_type __shift = this->_M_Nb % bits_per_block;
if (__shift > 0)
- this->_M_hiword() |= ((~static_cast<block_type>(0)) << __shift);
+ this->_M_hiword() |= block_type(block_type(-1) << __shift);
}
/**
* These versions of single-bit set, reset, flip, and test
* do no range checking.
*/
- dynamic_bitset<_WordT, _Alloc>&
- _M_unchecked_set(size_type __pos)
+ dynamic_bitset&
+ _M_unchecked_set(size_type __pos) noexcept
{
this->_M_getword(__pos) |= _Base::_S_maskbit(__pos);
return *this;
}
- dynamic_bitset<_WordT, _Alloc>&
- _M_unchecked_set(size_type __pos, int __val)
+ dynamic_bitset&
+ _M_unchecked_set(size_type __pos, int __val) noexcept
{
if (__val)
this->_M_getword(__pos) |= _Base::_S_maskbit(__pos);
@@ -468,26 +474,26 @@ namespace tr2
return *this;
}
- dynamic_bitset<_WordT, _Alloc>&
- _M_unchecked_reset(size_type __pos)
+ dynamic_bitset&
+ _M_unchecked_reset(size_type __pos) noexcept
{
this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos);
return *this;
}
- dynamic_bitset<_WordT, _Alloc>&
- _M_unchecked_flip(size_type __pos)
+ dynamic_bitset&
+ _M_unchecked_flip(size_type __pos) noexcept
{
this->_M_getword(__pos) ^= _Base::_S_maskbit(__pos);
return *this;
}
bool
- _M_unchecked_test(size_type __pos) const
+ _M_unchecked_test(size_type __pos) const noexcept
{ return ((this->_M_getword(__pos) & _Base::_S_maskbit(__pos))
!= static_cast<_WordT>(0)); }
- size_type _M_Nb;
+ size_type _M_Nb = 0;
public:
/**
@@ -511,22 +517,16 @@ namespace tr2
block_type *_M_wp;
size_type _M_bpos;
- // left undefined
- reference();
-
public:
- reference(dynamic_bitset& __b, size_type __pos)
+ reference(dynamic_bitset& __b, size_type __pos) noexcept
{
this->_M_wp = &__b._M_getword(__pos);
this->_M_bpos = _Base::_S_whichbit(__pos);
}
- ~reference()
- { }
-
// For b[i] = __x;
reference&
- operator=(bool __x)
+ operator=(bool __x) noexcept
{
if (__x)
*this->_M_wp |= _Base::_S_maskbit(this->_M_bpos);
@@ -537,7 +537,7 @@ namespace tr2
// For b[i] = b[__j];
reference&
- operator=(const reference& __j)
+ operator=(const reference& __j) noexcept
{
if ((*(__j._M_wp) & _Base::_S_maskbit(__j._M_bpos)))
*this->_M_wp |= _Base::_S_maskbit(this->_M_bpos);
@@ -548,16 +548,16 @@ namespace tr2
// Flips the bit
bool
- operator~() const
+ operator~() const noexcept
{ return (*(_M_wp) & _Base::_S_maskbit(this->_M_bpos)) == 0; }
// For __x = b[i];
- operator bool() const
+ operator bool() const noexcept
{ return (*(this->_M_wp) & _Base::_S_maskbit(this->_M_bpos)) != 0; }
// For b[i].flip();
reference&
- flip()
+ flip() noexcept
{
*this->_M_wp ^= _Base::_S_maskbit(this->_M_bpos);
return *this;
@@ -569,10 +569,14 @@ namespace tr2
typedef bool const_reference;
// 23.3.5.1 constructors:
+
+ /// All bits set to zero.
+ dynamic_bitset() = default;
+
/// All bits set to zero.
explicit
- dynamic_bitset(const allocator_type& __alloc = allocator_type())
- : _Base(__alloc), _M_Nb(0)
+ dynamic_bitset(const allocator_type& __alloc)
+ : _Base(__alloc)
{ }
/// Initial bits bitwise-copied from a single word (others set to zero).
@@ -585,7 +589,7 @@ namespace tr2
dynamic_bitset(initializer_list<block_type> __il,
const allocator_type& __alloc = allocator_type())
- : _Base(__alloc), _M_Nb(0)
+ : _Base(__alloc)
{ this->append(__il); }
/**
@@ -609,8 +613,7 @@ namespace tr2
__n = std::basic_string<_CharT, _Traits, _Alloc1>::npos,
_CharT __zero = _CharT('0'), _CharT __one = _CharT('1'),
const allocator_type& __alloc = allocator_type())
- : _Base(__alloc),
- _M_Nb(0) // Watch for npos.
+ : _Base(__alloc)
{
if (__pos > __str.size())
__throw_out_of_range(__N("dynamic_bitset::bitset initial position "
@@ -619,8 +622,7 @@ namespace tr2
// Watch for npos.
this->_M_Nb = (__n > __str.size() ? __str.size() - __pos : __n);
this->resize(this->_M_Nb);
- this->_M_copy_from_string(__str, __pos, __n,
- _CharT('0'), _CharT('1'));
+ this->_M_copy_from_string(__str, __pos, __n);
}
/**
@@ -633,61 +635,42 @@ namespace tr2
explicit
dynamic_bitset(const char* __str,
const allocator_type& __alloc = allocator_type())
- : _Base(__alloc)
+ : _Base(__builtin_strlen(__str), 0ULL, __alloc),
+ _M_Nb(__builtin_strlen(__str))
{
- size_t __len = 0;
- if (__str)
- while (__str[__len] != '\0')
- ++__len;
- this->resize(__len);
- this->_M_copy_from_ptr<char,std::char_traits<char>>
- (__str, __len, 0, __len, '0', '1');
+ this->_M_copy_from_ptr(__str, _M_Nb, 0, _M_Nb);
}
- /**
- * @brief Copy constructor.
- */
- dynamic_bitset(const dynamic_bitset& __b)
- : _Base(__b), _M_Nb(__b.size())
- { }
+ /// Copy constructor.
+ dynamic_bitset(const dynamic_bitset&) = default;
- /**
- * @brief Move constructor.
- */
- dynamic_bitset(dynamic_bitset&& __b)
- : _Base(std::forward<_Base>(__b)), _M_Nb(__b.size())
- { }
+ /// Move constructor.
+ dynamic_bitset(dynamic_bitset&& __b) noexcept
+ : _Base(std::move(__b)), _M_Nb(__b._M_Nb)
+ { __b.clear(); }
- /**
- * @brief Swap with another bitset.
- */
+ /// Swap with another bitset.
void
- swap(dynamic_bitset& __b)
+ swap(dynamic_bitset& __b) noexcept
{
this->_M_swap(__b);
std::swap(this->_M_Nb, __b._M_Nb);
}
- /**
- * @brief Assignment.
- */
- dynamic_bitset&
- operator=(const dynamic_bitset& __b)
- {
- if (&__b != this)
- {
- this->_M_assign(__b);
- this->_M_Nb = __b._M_Nb;
- }
- }
+ /// Copy assignment operator.
+ dynamic_bitset& operator=(const dynamic_bitset&) = default;
- /**
- * @brief Move assignment.
- */
+ /// Move assignment operator.
dynamic_bitset&
operator=(dynamic_bitset&& __b)
+ noexcept(std::is_nothrow_move_assignable<_Base>::value)
{
- this->swap(__b);
+ static_cast<_Base&>(*this) = static_cast<_Base&&>(__b);
+ _M_Nb = __b._M_Nb;
+ if _GLIBCXX17_CONSTEXPR (std::is_nothrow_move_assignable<_Base>::value)
+ __b._M_Nb = 0;
+ else if (get_allocator() == __b.get_allocator())
+ __b._M_Nb = 0;
return *this;
}
@@ -695,7 +678,7 @@ namespace tr2
* @brief Return the allocator for the bitset.
*/
allocator_type
- get_allocator() const
+ get_allocator() const noexcept
{ return this->_M_get_allocator(); }
/**
@@ -734,6 +717,8 @@ namespace tr2
++this->_M_Nb;
}
+ // XXX why is there no pop_back() member in the proposal?
+
/**
* @brief Append a block.
*/
@@ -770,36 +755,36 @@ namespace tr2
*
* These should be self-explanatory.
*/
- dynamic_bitset<_WordT, _Alloc>&
- operator&=(const dynamic_bitset<_WordT, _Alloc>& __rhs)
+ dynamic_bitset&
+ operator&=(const dynamic_bitset& __rhs)
{
this->_M_do_and(__rhs);
return *this;
}
- dynamic_bitset<_WordT, _Alloc>&
- operator&=(dynamic_bitset<_WordT, _Alloc>&& __rhs)
+ dynamic_bitset&
+ operator&=(dynamic_bitset&& __rhs)
{
this->_M_do_and(std::move(__rhs));
return *this;
}
- dynamic_bitset<_WordT, _Alloc>&
- operator|=(const dynamic_bitset<_WordT, _Alloc>& __rhs)
+ dynamic_bitset&
+ operator|=(const dynamic_bitset& __rhs)
{
this->_M_do_or(__rhs);
return *this;
}
- dynamic_bitset<_WordT, _Alloc>&
- operator^=(const dynamic_bitset<_WordT, _Alloc>& __rhs)
+ dynamic_bitset&
+ operator^=(const dynamic_bitset& __rhs)
{
this->_M_do_xor(__rhs);
return *this;
}
- dynamic_bitset<_WordT, _Alloc>&
- operator-=(const dynamic_bitset<_WordT, _Alloc>& __rhs)
+ dynamic_bitset&
+ operator-=(const dynamic_bitset& __rhs)
{
this->_M_do_dif(__rhs);
return *this;
@@ -813,7 +798,7 @@ namespace tr2
*
* These should be self-explanatory.
*/
- dynamic_bitset<_WordT, _Alloc>&
+ dynamic_bitset&
operator<<=(size_type __pos)
{
if (__builtin_expect(__pos < this->_M_Nb, 1))
@@ -826,7 +811,7 @@ namespace tr2
return *this;
}
- dynamic_bitset<_WordT, _Alloc>&
+ dynamic_bitset&
operator>>=(size_type __pos)
{
if (__builtin_expect(__pos < this->_M_Nb, 1))
@@ -844,7 +829,7 @@ namespace tr2
/**
* @brief Sets every bit to true.
*/
- dynamic_bitset<_WordT, _Alloc>&
+ dynamic_bitset&
set()
{
this->_M_do_set();
@@ -858,7 +843,7 @@ namespace tr2
* @param __val Either true or false, defaults to true.
* @throw std::out_of_range If @a __pos is bigger the size of the %set.
*/
- dynamic_bitset<_WordT, _Alloc>&
+ dynamic_bitset&
set(size_type __pos, bool __val = true)
{
if (__pos >= _M_Nb)
@@ -869,7 +854,7 @@ namespace tr2
/**
* @brief Sets every bit to false.
*/
- dynamic_bitset<_WordT, _Alloc>&
+ dynamic_bitset&
reset()
{
this->_M_do_reset();
@@ -883,7 +868,7 @@ namespace tr2
*
* Same as writing @c set(__pos, false).
*/
- dynamic_bitset<_WordT, _Alloc>&
+ dynamic_bitset&
reset(size_type __pos)
{
if (__pos >= _M_Nb)
@@ -894,7 +879,7 @@ namespace tr2
/**
* @brief Toggles every bit to its opposite value.
*/
- dynamic_bitset<_WordT, _Alloc>&
+ dynamic_bitset&
flip()
{
this->_M_do_flip();
@@ -907,7 +892,7 @@ namespace tr2
* @param __pos The index of the bit.
* @throw std::out_of_range If @a __pos is bigger the size of the %set.
*/
- dynamic_bitset<_WordT, _Alloc>&
+ dynamic_bitset&
flip(size_type __pos)
{
if (__pos >= _M_Nb)
@@ -916,7 +901,7 @@ namespace tr2
}
/// See the no-argument flip().
- dynamic_bitset<_WordT, _Alloc>
+ dynamic_bitset
operator~() const
{ return dynamic_bitset<_WordT, _Alloc>(*this).flip(); }
@@ -978,19 +963,23 @@ namespace tr2
}
// Helper functions for string operations.
- template<typename _CharT, typename _Traits>
+ template<typename _Traits = std::char_traits<char>,
+ typename _CharT = typename _Traits::char_type>
void
_M_copy_from_ptr(const _CharT*, size_t, size_t, size_t,
- _CharT, _CharT);
+ _CharT __zero = _CharT('0'),
+ _CharT __one = _CharT('1'));
template<typename _CharT, typename _Traits, typename _Alloc1>
void
- _M_copy_from_string(const std::basic_string<_CharT,
- _Traits, _Alloc1>& __str, size_t __pos, size_t __n,
+ _M_copy_from_string(const basic_string<_CharT, _Traits, _Alloc1>& __str,
+ size_t __pos, size_t __n,
_CharT __zero = _CharT('0'),
_CharT __one = _CharT('1'))
- { _M_copy_from_ptr<_CharT, _Traits>(__str.data(), __str.size(),
- __pos, __n, __zero, __one); }
+ {
+ _M_copy_from_ptr<_Traits>(__str.data(), __str.size(), __pos, __n,
+ __zero, __one);
+ }
template<typename _CharT, typename _Traits, typename _Alloc1>
void
@@ -1065,13 +1054,13 @@ namespace tr2
//@{
/// Self-explanatory.
- dynamic_bitset<_WordT, _Alloc>
+ dynamic_bitset
operator<<(size_type __pos) const
- { return dynamic_bitset<_WordT, _Alloc>(*this) <<= __pos; }
+ { return dynamic_bitset(*this) <<= __pos; }
- dynamic_bitset<_WordT, _Alloc>
+ dynamic_bitset
operator>>(size_type __pos) const
- { return dynamic_bitset<_WordT, _Alloc>(*this) >>= __pos; }
+ { return dynamic_bitset(*this) >>= __pos; }
//@}
/**
@@ -1102,14 +1091,14 @@ namespace tr2
{ 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); }
+ operator==(const dynamic_bitset& __lhs,
+ const dynamic_bitset& __rhs) noexcept
+ { return __lhs._M_Nb == __rhs._M_Nb && __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); }
+ operator<(const dynamic_bitset& __lhs,
+ const dynamic_bitset& __rhs) noexcept
+ { return __lhs._M_is_less(__rhs) || __lhs._M_Nb < __rhs._M_Nb; }
};
template<typename _WordT, typename _Alloc>
diff --git a/libstdc++-v3/include/tr2/dynamic_bitset.tcc b/libstdc++-v3/include/tr2/dynamic_bitset.tcc
index 8228d7b..bbd2cb3 100644
--- a/libstdc++-v3/include/tr2/dynamic_bitset.tcc
+++ b/libstdc++-v3/include/tr2/dynamic_bitset.tcc
@@ -174,7 +174,7 @@ namespace tr2
// Definitions of non-inline member functions.
template<typename _WordT, typename _Alloc>
- template<typename _CharT, typename _Traits>
+ template<typename _Traits, typename _CharT>
void
dynamic_bitset<_WordT, _Alloc>::
_M_copy_from_ptr(const _CharT* __str, size_t __len,
diff --git a/libstdc++-v3/testsuite/tr2/dynamic_bitset/cmp.cc b/libstdc++-v3/testsuite/tr2/dynamic_bitset/cmp.cc
new file mode 100644
index 0000000..a811307
--- /dev/null
+++ b/libstdc++-v3/testsuite/tr2/dynamic_bitset/cmp.cc
@@ -0,0 +1,50 @@
+// Copyright (C) 2019 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/>.
+
+// { dg-do run { target c++11 } }
+
+#include <tr2/dynamic_bitset>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ std::tr2::dynamic_bitset<> a(100);
+ std::tr2::dynamic_bitset<> b = a;
+ VERIFY( a == b );
+ b.resize(99);
+ VERIFY( a != b );
+}
+
+void
+test02()
+{
+ std::tr2::dynamic_bitset<> a(100);
+ std::tr2::dynamic_bitset<> b = a;
+ VERIFY( !(a < b) );
+ VERIFY( !(b < a) );
+ b.resize(99);
+ VERIFY( !(a < b) );
+ VERIFY( b < a );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+}
diff --git a/libstdc++-v3/testsuite/tr2/dynamic_bitset/cons.cc b/libstdc++-v3/testsuite/tr2/dynamic_bitset/cons.cc
new file mode 100644
index 0000000..9e21a91
--- /dev/null
+++ b/libstdc++-v3/testsuite/tr2/dynamic_bitset/cons.cc
@@ -0,0 +1,105 @@
+// Copyright (C) 2019 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/>.
+
+// { dg-do run { target c++11 } }
+
+#include <tr2/dynamic_bitset>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ std::tr2::dynamic_bitset<> a;
+ VERIFY( a.size() == 0 );
+ VERIFY( a.empty() );
+ std::tr2::dynamic_bitset<> b(1);
+ VERIFY( b.size() == 1 );
+ VERIFY( !b.empty() );
+ VERIFY( a != b );
+}
+
+void
+test02()
+{
+ std::tr2::dynamic_bitset<> a(1, 0); // { 0 }
+ std::tr2::dynamic_bitset<> b(2, 2); // { 0, 1 }
+ VERIFY( a != b );
+}
+
+void
+test03()
+{
+ std::tr2::dynamic_bitset<> a;
+ a.resize(1); // { 0 }
+ std::tr2::dynamic_bitset<> b(2, 2); // { 0, 1 }
+ VERIFY( a != b );
+}
+
+void
+test04()
+{
+ std::tr2::dynamic_bitset<> a(3, 2); // { 0, 1, 0 }
+ std::tr2::dynamic_bitset<> b(2, 2); // { 0, 1 }
+ VERIFY( a != b );
+}
+
+void
+test05()
+{
+ std::tr2::dynamic_bitset<unsigned short> a(1, 0); // { 0 }
+ std::tr2::dynamic_bitset<unsigned short> b(2, 2); // { 0, 1 }
+ VERIFY( a != b );
+}
+
+void
+test06()
+{
+ std::tr2::dynamic_bitset<unsigned short> a;
+ a.resize(1); // { 0 }
+ std::tr2::dynamic_bitset<unsigned short> b(2, 2); // { 0, 1 }
+ VERIFY( a != b );
+}
+
+void
+test07()
+{
+ std::tr2::dynamic_bitset<unsigned short> a(3, 2); // { 0, 1, 0 }
+ std::tr2::dynamic_bitset<unsigned short> b(2, 2); // { 0, 1 }
+ VERIFY( a != b );
+}
+
+void
+test08()
+{
+ std::tr2::dynamic_bitset<> a(65, -1ULL);
+ std::tr2::dynamic_bitset<> b(64, -1ULL);
+ b.push_back(0);
+ VERIFY( a == b );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+ test05();
+ test06();
+ test07();
+ test08();
+}
diff --git a/libstdc++-v3/testsuite/tr2/dynamic_bitset/copy.cc b/libstdc++-v3/testsuite/tr2/dynamic_bitset/copy.cc
new file mode 100644
index 0000000..06bc115
--- /dev/null
+++ b/libstdc++-v3/testsuite/tr2/dynamic_bitset/copy.cc
@@ -0,0 +1,55 @@
+// Copyright (C) 2019 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/>.
+
+// { dg-do run { target c++11 } }
+
+#include <tr2/dynamic_bitset>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ std::tr2::dynamic_bitset<> a(100);
+ const auto n = a.num_blocks();
+ std::tr2::dynamic_bitset<> b = a;
+ VERIFY(b.num_blocks() == n);
+ VERIFY(b.size() == 100);
+ VERIFY(a.num_blocks() == n);
+ VERIFY(a.size() == 100);
+ VERIFY(b == a);
+}
+
+void
+test02()
+{
+ std::tr2::dynamic_bitset<> a(100);
+ const auto n = a.num_blocks();
+ std::tr2::dynamic_bitset<> b;
+ b = a;
+ VERIFY(b.num_blocks() == n);
+ VERIFY(b.size() == 100);
+ VERIFY(a.num_blocks() == n);
+ VERIFY(a.size() == 100);
+ VERIFY(b == a);
+}
+
+int
+main()
+{
+ test01();
+ test02();
+}
diff --git a/libstdc++-v3/testsuite/tr2/dynamic_bitset/move.cc b/libstdc++-v3/testsuite/tr2/dynamic_bitset/move.cc
new file mode 100644
index 0000000..ed320db
--- /dev/null
+++ b/libstdc++-v3/testsuite/tr2/dynamic_bitset/move.cc
@@ -0,0 +1,53 @@
+// Copyright (C) 2019 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/>.
+
+// { dg-do run { target c++11 } }
+
+#include <tr2/dynamic_bitset>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ std::tr2::dynamic_bitset<> a(100);
+ const auto n = a.num_blocks();
+ std::tr2::dynamic_bitset<> b = std::move(a);
+ VERIFY(b.num_blocks() == n);
+ VERIFY(b.size() == 100);
+ VERIFY(a.num_blocks() == 0);
+ VERIFY(a.size() == 0);
+}
+
+void
+test02()
+{
+ std::tr2::dynamic_bitset<> a(100);
+ const auto n = a.num_blocks();
+ std::tr2::dynamic_bitset<> b;
+ b = std::move(a);
+ VERIFY(b.num_blocks() == n);
+ VERIFY(b.size() == 100);
+ VERIFY(a.num_blocks() == 0);
+ VERIFY(a.size() == 0);
+}
+
+int
+main()
+{
+ test01();
+ test02();
+}
diff --git a/libstdc++-v3/testsuite/tr2/dynamic_bitset/pr92059.cc b/libstdc++-v3/testsuite/tr2/dynamic_bitset/pr92059.cc
new file mode 100644
index 0000000..0aec1ad
--- /dev/null
+++ b/libstdc++-v3/testsuite/tr2/dynamic_bitset/pr92059.cc
@@ -0,0 +1,36 @@
+// Copyright (C) 2019 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/>.
+
+// { dg-do run { target c++11 } }
+
+#include <tr2/dynamic_bitset>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ // PR libstdc++/92059
+ std::tr2::dynamic_bitset<> b1(10000), b2(10000);
+ b2 = b1; // crashed on missing return
+ VERIFY( b2 == b1);
+}
+
+int
+main()
+{
+ test01();
+}