Constrain swap overload for std::optional (LWG 2748)
* doc/xml/manual/intro.xml: Document LWG 2748 status. * include/std/optional (optional<T>::swap): Use is_nothrow_swappable_v for exception specification. (swap(optional<T>&, optional<T>&)): Disable when T is not swappable. * testsuite/20_util/optional/swap/2.cc: New test. From-SVN: r242415
This commit is contained in:
parent
b229ab2a71
commit
8b99f005cb
|
@ -1,3 +1,11 @@
|
|||
2016-11-15 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
* doc/xml/manual/intro.xml: Document LWG 2748 status.
|
||||
* include/std/optional (optional<T>::swap): Use is_nothrow_swappable_v
|
||||
for exception specification.
|
||||
(swap(optional<T>&, optional<T>&)): Disable when T is not swappable.
|
||||
* testsuite/20_util/optional/swap/2.cc: New test.
|
||||
|
||||
2016-11-14 Ville Voutilainen <ville.voutilainen@gmail.com>
|
||||
|
||||
Implement P0513R0, Poisoning the Hash.
|
||||
|
|
|
@ -1094,7 +1094,7 @@ requirements of the license of GCC.
|
|||
</para></listitem></varlistentry>
|
||||
|
||||
<varlistentry><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="../ext/lwg-defects.html#2583">2583</link>:
|
||||
<emphasis>There is no way to supply an allocator for <code> basic_string(str, pos)</code>
|
||||
<emphasis>There is no way to supply an allocator for <code>basic_string(str, pos)</code>
|
||||
</emphasis>
|
||||
</term>
|
||||
<listitem><para>Add new constructor
|
||||
|
@ -1107,6 +1107,14 @@ requirements of the license of GCC.
|
|||
<listitem><para>Define the <code>value_compare</code> typedef.
|
||||
</para></listitem></varlistentry>
|
||||
|
||||
<varlistentry><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="../ext/lwg-defects.html#2748">2748</link>:
|
||||
<emphasis>swappable traits for optionals
|
||||
</emphasis>
|
||||
</term>
|
||||
<listitem><para>Disable the non-member <code>swap</code> overload when
|
||||
the contained object is not swappable.
|
||||
</para></listitem></varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
</section>
|
||||
|
|
|
@ -613,7 +613,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
void
|
||||
swap(optional& __other)
|
||||
noexcept(is_nothrow_move_constructible<_Tp>()
|
||||
&& noexcept(swap(declval<_Tp&>(), declval<_Tp&>())))
|
||||
&& is_nothrow_swappable_v<_Tp>)
|
||||
{
|
||||
using std::swap;
|
||||
|
||||
|
@ -920,8 +920,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
{ return !__rhs || __lhs >= *__rhs; }
|
||||
|
||||
// Swap and creation functions.
|
||||
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 2748. swappable traits for optionals
|
||||
template<typename _Tp>
|
||||
inline void
|
||||
inline enable_if_t<is_move_constructible_v<_Tp> && is_swappable_v<_Tp>>
|
||||
swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs)
|
||||
noexcept(noexcept(__lhs.swap(__rhs)))
|
||||
{ __lhs.swap(__rhs); }
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
// { dg-options "-std=gnu++17" }
|
||||
// { dg-do compile }
|
||||
|
||||
// Copyright (C) 2016 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/>.
|
||||
|
||||
#include <optional>
|
||||
|
||||
// Swappable.
|
||||
struct A { };
|
||||
|
||||
static_assert( std::is_nothrow_swappable_v<A> );
|
||||
static_assert( std::is_nothrow_swappable_v<std::optional<A>> );
|
||||
|
||||
// Swappable, but might throw.
|
||||
struct B { };
|
||||
void swap(B&, B&) noexcept(false);
|
||||
|
||||
static_assert( std::is_swappable_v<std::optional<B>> );
|
||||
static_assert( !std::is_nothrow_swappable_v<std::optional<B>> );
|
||||
|
||||
// Not swappable, but optional<C> is swappable via the generic std::swap.
|
||||
struct C { };
|
||||
void swap(C&, C&) = delete;
|
||||
|
||||
static_assert( std::is_swappable_v<std::optional<C>> );
|
||||
|
||||
// Not swappable, and optional<D> not swappable via the generic std::swap.
|
||||
struct D { D(D&&) = delete; };
|
||||
|
||||
static_assert( !std::is_swappable_v<std::optional<D>> );
|
Loading…
Reference in New Issue