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
This commit is contained in:
Jonathan Wakely 2019-10-11 16:29:55 +01:00 committed by Jonathan Wakely
parent 2bf2dacb35
commit 07758d90c7
8 changed files with 478 additions and 154 deletions

View file

@ -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.

View file

@ -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>

View file

@ -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,

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}