libstdc++: Fix std::common_iterator triviality [PR100823]
This fixes the remaining problem reported in the PR, that the special members should be trivial. This can be done by constraining the non-trivial versions and adding defaulted overloads that will be used when the union members are trivial. Making these members trivial alters the argument passing ABI and so isn't suitable for backporting to release branches. libstdc++-v3/ChangeLog: PR libstdc++/100823 * include/bits/stl_iterator.h (common_iterator): Define destructor, copy constructor and move constructor as trivial when the underlying types allow. * testsuite/24_iterators/common_iterator/100823.cc: Check triviality of special members.
This commit is contained in:
parent
56c999860b
commit
87a9bfe86d
2 changed files with 30 additions and 0 deletions
|
@ -1925,9 +1925,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
}
|
||||
}
|
||||
|
||||
common_iterator(const common_iterator&) = default;
|
||||
|
||||
constexpr
|
||||
common_iterator(const common_iterator& __x)
|
||||
noexcept(_S_noexcept<const _It&, const _Sent&>())
|
||||
requires (!is_trivially_copyable_v<_It> || !is_trivially_copyable_v<_Sent>)
|
||||
: _M_valueless(), _M_index(__x._M_index)
|
||||
{
|
||||
if (_M_index == 0)
|
||||
|
@ -1946,9 +1949,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
}
|
||||
}
|
||||
|
||||
common_iterator(common_iterator&&) = default;
|
||||
|
||||
constexpr
|
||||
common_iterator(common_iterator&& __x)
|
||||
noexcept(_S_noexcept<_It, _Sent>())
|
||||
requires (!is_trivially_copyable_v<_It> || !is_trivially_copyable_v<_Sent>)
|
||||
: _M_valueless(), _M_index(__x._M_index)
|
||||
{
|
||||
if (_M_index == 0)
|
||||
|
@ -2017,8 +2023,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
return *this;
|
||||
}
|
||||
|
||||
#if __cpp_concepts >= 202002L // Constrained special member functions
|
||||
~common_iterator() = default;
|
||||
|
||||
constexpr
|
||||
~common_iterator()
|
||||
requires (!is_trivially_destructible_v<_It>
|
||||
|| !is_trivially_destructible_v<_Sent>)
|
||||
#else
|
||||
constexpr
|
||||
~common_iterator()
|
||||
#endif
|
||||
{
|
||||
if (_M_index == 0)
|
||||
_M_it.~_It();
|
||||
|
|
|
@ -4,6 +4,21 @@
|
|||
#include <testsuite_iterators.h>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
void
|
||||
test_triviality()
|
||||
{
|
||||
using I = std::common_iterator<int*, const int*>;
|
||||
|
||||
// Cannot be trivial, because it has to initialize members.
|
||||
static_assert( ! std::is_trivially_default_constructible_v<I> );
|
||||
|
||||
static_assert( std::is_trivially_destructible_v<I> );
|
||||
static_assert( std::is_trivially_copy_constructible_v<I> );
|
||||
static_assert( std::is_trivially_copy_assignable_v<I> );
|
||||
static_assert( std::is_trivially_move_constructible_v<I> );
|
||||
static_assert( std::is_trivially_move_assignable_v<I> );
|
||||
}
|
||||
|
||||
void
|
||||
test_valueless_assignment()
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue