libstdc++: Add conditional noexcept to std::exchange
This is not required by the standard, but seems useful. Signed-off-by: Jonathan Wakely <jwakely@redhat.com> libstdc++-v3/ChangeLog: * include/std/utility (exchange): Add noexcept-specifier. * testsuite/20_util/exchange/noexcept.cc: New test.
This commit is contained in:
parent
2db38d9fca
commit
42cfa1bd6c
@ -91,6 +91,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
_GLIBCXX20_CONSTEXPR
|
||||
inline _Tp
|
||||
exchange(_Tp& __obj, _Up&& __new_val)
|
||||
noexcept(__and_<is_nothrow_move_constructible<_Tp>,
|
||||
is_nothrow_assignable<_Tp&, _Up>>::value)
|
||||
{ return std::__exchange(__obj, std::forward<_Up>(__new_val)); }
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
|
39
libstdc++-v3/testsuite/20_util/exchange/noexcept.cc
Normal file
39
libstdc++-v3/testsuite/20_util/exchange/noexcept.cc
Normal file
@ -0,0 +1,39 @@
|
||||
// { dg-options "-std=gnu++2a" }
|
||||
// { dg-do compile { target c++2a } }
|
||||
|
||||
#include <utility>
|
||||
|
||||
// This is a GCC extension. std::exchange is not required to be noexcept.
|
||||
|
||||
static_assert( noexcept( std::exchange(std::declval<int&>(), 1) ) );
|
||||
|
||||
struct X
|
||||
{
|
||||
X(const X&);
|
||||
X(X&&) noexcept;
|
||||
X& operator=(const X&);
|
||||
X& operator=(X&&) noexcept;
|
||||
X& operator=(int);
|
||||
};
|
||||
|
||||
extern X x, x2;
|
||||
static_assert( noexcept( std::exchange(x, std::move(x2)) ) );
|
||||
static_assert( ! noexcept( std::exchange(x, 1) ) );
|
||||
|
||||
struct Y
|
||||
{
|
||||
Y(Y&&) noexcept;
|
||||
Y& operator=(Y&&);
|
||||
};
|
||||
|
||||
extern Y y, y2;
|
||||
static_assert( ! noexcept( std::exchange(y, std::move(y2)) ) );
|
||||
|
||||
struct Z
|
||||
{
|
||||
Z(Z&&)noexcept;
|
||||
Z& operator=(Z&&) ;
|
||||
};
|
||||
|
||||
extern Z z, z2;
|
||||
static_assert( ! noexcept( std::exchange(z, std::move(z2)) ) );
|
Loading…
x
Reference in New Issue
Block a user