+2011-05-19 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * include/std/tuple (tuple<>::operator=(tuple&&)): Specify as
+ noexcept.
+ (__get_helper): Likewise.
+ (_Head_base<>::_M_head, _Tuple_impl<>::_M_head, _M_tail): Likewise.
+ * include/bits/move.h (swap): Likewise.
+ * include/bits/algorithmfwd.h (swap): Adjust.
+ * include/bits/stl_pair.h (pair<>::operator=(pair&&)): Spec noexcept.
+ * testsuite/util/testsuite_allocator.h (uneq_allocator): In C++0x
+ mode, prefer delete to access control to make the type not copy
+ assignable.
+ * testsuite/util/testsuite_tr1.h: Add test classes.
+ * testsuite/20_util/tuple/noexcept_swap.cc: New.
+ * testsuite/20_util/tuple/noexcept_move_assign.cc: Likewise.
+ * testsuite/25_algorithms/reverse/moveable.cc: Likewise, prefer
+ delete to access control.
+ * testsuite/25_algorithms/swap_ranges/moveable.cc: Likewise.
+ * testsuite/20_util/weak_ptr/comparison/cmp_neg.cc: Adjust dg-warning
+ line numbers.
+
2011-05-19 Daniel Krugler <daniel.kruegler@googlemail.com>
* testsuite/util/testsuite_tr1.h: Add test classes.
template<typename _Tp>
void
- swap(_Tp&, _Tp&);
+ swap(_Tp&, _Tp&)
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ noexcept(is_nothrow_move_constructible<_Tp>::value
+ && is_nothrow_move_assignable<_Tp>::value)
+#endif
+ ;
template<typename _Tp, size_t _Nm>
void
template<typename _Tp>
inline void
swap(_Tp& __a, _Tp& __b)
- // noexcept has to wait is_nothrow_move_assignable
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ noexcept(is_nothrow_move_constructible<_Tp>::value
+ && is_nothrow_move_assignable<_Tp>::value)
+#endif
{
// concept requirements
__glibcxx_function_requires(_SGIAssignableConcept<_Tp>)
pair&
operator=(pair&& __p)
- // noexcept has to wait is_nothrow_move_assignable
+ noexcept(is_nothrow_move_assignable<_T1>::value
+ && is_nothrow_move_assignable<_T2>::value)
{
first = std::move(__p.first);
second = std::move(__p.second);
_Head_base(_UHead&& __h)
: _Head(std::forward<_UHead>(__h)) { }
- _Head& _M_head() { return *this; }
- const _Head& _M_head() const { return *this; }
+ _Head& _M_head() noexcept { return *this; }
+ const _Head& _M_head() const noexcept { return *this; }
};
template<std::size_t _Idx, typename _Head>
_Head_base(_UHead&& __h)
: _M_head_impl(std::forward<_UHead>(__h)) { }
- _Head& _M_head() { return _M_head_impl; }
- const _Head& _M_head() const { return _M_head_impl; }
+ _Head& _M_head() noexcept { return _M_head_impl; }
+ const _Head& _M_head() const noexcept { return _M_head_impl; }
_Head _M_head_impl;
};
typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
typedef _Head_base<_Idx, _Head, std::is_empty<_Head>::value> _Base;
- _Head& _M_head() { return _Base::_M_head(); }
- const _Head& _M_head() const { return _Base::_M_head(); }
+ _Head& _M_head() noexcept { return _Base::_M_head(); }
+ const _Head& _M_head() const noexcept { return _Base::_M_head(); }
- _Inherited& _M_tail() { return *this; }
- const _Inherited& _M_tail() const { return *this; }
+ _Inherited& _M_tail() noexcept { return *this; }
+ const _Inherited& _M_tail() const noexcept { return *this; }
constexpr _Tuple_impl()
: _Inherited(), _Base() { }
_Tuple_impl&
operator=(_Tuple_impl&& __in)
+ noexcept(is_nothrow_move_assignable<_Head>::value
+ && is_nothrow_move_assignable<_Inherited>::value)
{
_M_head() = std::forward<_Head>(__in._M_head());
_M_tail() = std::move(__in._M_tail());
tuple&
operator=(tuple&& __in)
+ noexcept(is_nothrow_move_assignable<_Inherited>::value)
{
static_cast<_Inherited&>(*this) = std::move(__in);
return *this;
tuple&
operator=(tuple&& __in)
- // noexcept has to wait is_nothrow_move_assignable
+ noexcept(is_nothrow_move_assignable<_Inherited>::value)
{
static_cast<_Inherited&>(*this) = std::move(__in);
return *this;
template<typename _U1, typename _U2>
tuple&
- operator=(pair<_U1, _U2>&& __in) noexcept
+ operator=(pair<_U1, _U2>&& __in)
{
this->_M_head() = std::forward<_U1>(__in.first);
this->_M_tail()._M_head() = std::forward<_U2>(__in.second);
tuple&
operator=(tuple&& __in)
+ noexcept(is_nothrow_move_assignable<_Inherited>::value)
{
static_cast<_Inherited&>(*this) = std::move(__in);
return *this;
template<std::size_t __i, typename _Head, typename... _Tail>
inline typename __add_ref<_Head>::type
- __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t)
+ __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
{ return __t._M_head(); }
template<std::size_t __i, typename _Head, typename... _Tail>
inline typename __add_c_ref<_Head>::type
- __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t)
+ __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
{ return __t._M_head(); }
// Return a reference (const reference, rvalue reference) to the ith element
--- /dev/null
+// { dg-do compile }
+// { dg-options "-std=gnu++0x" }
+
+// 2011-05-19 Paolo Carlini <paolo.carlini@oracle.com>
+//
+// Copyright (C) 2011 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 <tuple>
+#include <testsuite_tr1.h>
+
+using namespace __gnu_test;
+
+typedef std::tuple<int> tt1;
+typedef std::tuple<int, double> tt2;
+typedef std::tuple<short, double, int> tt3;
+typedef std::tuple<short, NoexceptMoveAssignClass, double> tt4;
+typedef std::tuple<NoexceptMoveAssignClass,
+ NoexceptMoveAssignClass, double> tt5;
+typedef std::tuple<NoexceptMoveAssignClass,
+ NoexceptMoveAssignClass,
+ NoexceptMoveAssignClass> tt6;
+typedef std::tuple<ExceptMoveAssignClass> tt7;
+typedef std::tuple<ExceptMoveAssignClass, double> tt8;
+typedef std::tuple<short, double, ExceptMoveAssignClass> tt9;
+typedef std::tuple<ExceptMoveAssignClass, double,
+ ExceptMoveAssignClass> tt10;
+typedef std::tuple<NoexceptMoveAssignClass,
+ ExceptMoveAssignClass> tt11;
+typedef std::tuple<int,
+ NoexceptMoveAssignClass,
+ ExceptMoveAssignClass> tt12;
+
+static_assert(std::is_nothrow_move_assignable<tt1>::value, "Error");
+static_assert(std::is_nothrow_move_assignable<tt2>::value, "Error");
+static_assert(std::is_nothrow_move_assignable<tt3>::value, "Error");
+static_assert(std::is_nothrow_move_assignable<tt4>::value, "Error");
+static_assert(std::is_nothrow_move_assignable<tt5>::value, "Error");
+static_assert(std::is_nothrow_move_assignable<tt6>::value, "Error");
+static_assert(!std::is_nothrow_move_assignable<tt7>::value, "Error");
+static_assert(!std::is_nothrow_move_assignable<tt8>::value, "Error");
+static_assert(!std::is_nothrow_move_assignable<tt9>::value, "Error");
+static_assert(!std::is_nothrow_move_assignable<tt10>::value, "Error");
+static_assert(!std::is_nothrow_move_assignable<tt11>::value, "Error");
+static_assert(!std::is_nothrow_move_assignable<tt12>::value, "Error");
--- /dev/null
+// { dg-do compile }
+// { dg-options "-std=gnu++0x" }
+
+// 2011-05-19 Paolo Carlini <paolo.carlini@oracle.com>
+//
+// Copyright (C) 2011 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 <tuple>
+#include <testsuite_tr1.h>
+
+using namespace __gnu_test;
+
+typedef std::tuple<int> tt1;
+typedef std::tuple<int, double> tt2;
+typedef std::tuple<short, double, int> tt3;
+typedef std::tuple<short, NoexceptMoveAssignClass, double> tt4;
+typedef std::tuple<ExceptMoveAssignClass> tt5;
+typedef std::tuple<ExceptMoveAssignClass, double> tt6;
+typedef std::tuple<short, double, ExceptMoveAssignClass> tt7;
+typedef std::tuple<ExceptMoveConsClass> tt8;
+typedef std::tuple<int, ExceptMoveConsClass> tt9;
+typedef std::tuple<ExceptMoveConsClass, short, double> tt10;
+typedef std::tuple<short, NoexceptMoveConsClass, double> tt11;
+typedef std::tuple<NoexceptMoveConsClass> tt12;
+typedef std::tuple<NoexceptMoveConsNoexceptMoveAssignClass> tt13;
+typedef std::tuple<ExceptMoveConsNoexceptMoveAssignClass> tt14;
+typedef std::tuple<NoexceptMoveConsExceptMoveAssignClass> tt15;
+typedef std::tuple<ExceptMoveConsExceptMoveAssignClass> tt16;
+typedef std::tuple<NoexceptMoveConsNoexceptMoveAssignClass,
+ double> tt17;
+typedef std::tuple<double,
+ NoexceptMoveConsNoexceptMoveAssignClass,
+ short> tt18;
+typedef std::tuple<NoexceptMoveConsNoexceptMoveAssignClass,
+ NoexceptMoveConsNoexceptMoveAssignClass,
+ char> tt19;
+typedef std::tuple<NoexceptMoveConsNoexceptMoveAssignClass,
+ NoexceptMoveConsNoexceptMoveAssignClass,
+ NoexceptMoveConsNoexceptMoveAssignClass> tt20;
+typedef std::tuple<NoexceptMoveConsNoexceptMoveAssignClass,
+ ExceptMoveConsNoexceptMoveAssignClass,
+ NoexceptMoveConsNoexceptMoveAssignClass> tt21;
+typedef std::tuple<NoexceptMoveConsNoexceptMoveAssignClass,
+ ExceptMoveConsNoexceptMoveAssignClass,
+ NoexceptMoveConsExceptMoveAssignClass> tt22;
+typedef std::tuple<NoexceptMoveConsNoexceptMoveAssignClass,
+ NoexceptMoveConsNoexceptMoveAssignClass,
+ ExceptMoveConsExceptMoveAssignClass> tt23;
+typedef std::tuple<NoexceptMoveConsNoexceptMoveAssignClass,
+ short, ExceptMoveConsExceptMoveAssignClass> tt24;
+typedef std::tuple<NoexceptMoveConsNoexceptMoveAssignClass,
+ short, ExceptMoveConsExceptMoveAssignClass> tt25;
+
+static_assert(noexcept(std::declval<tt1&>().swap(std::declval<tt1&>())),
+ "Error");
+static_assert(noexcept(std::declval<tt2&>().swap(std::declval<tt2&>())),
+ "Error");
+static_assert(noexcept(std::declval<tt3&>().swap(std::declval<tt3&>())),
+ "Error");
+static_assert(noexcept(std::declval<tt4&>().swap(std::declval<tt4&>())),
+ "Error");
+static_assert(!noexcept(std::declval<tt5&>().swap(std::declval<tt5&>())),
+ "Error");
+static_assert(!noexcept(std::declval<tt6&>().swap(std::declval<tt6&>())),
+ "Error");
+static_assert(!noexcept(std::declval<tt7&>().swap(std::declval<tt7&>())),
+ "Error");
+static_assert(!noexcept(std::declval<tt8&>().swap(std::declval<tt8&>())),
+ "Error");
+static_assert(!noexcept(std::declval<tt9&>().swap(std::declval<tt9&>())),
+ "Error");
+static_assert(!noexcept(std::declval<tt10&>().swap(std::declval<tt10&>())),
+ "Error");
+static_assert(noexcept(std::declval<tt11&>().swap(std::declval<tt11&>())),
+ "Error");
+static_assert(noexcept(std::declval<tt12&>().swap(std::declval<tt12&>())),
+ "Error");
+static_assert(noexcept(std::declval<tt13&>().swap(std::declval<tt13&>())),
+ "Error");
+static_assert(!noexcept(std::declval<tt14&>().swap(std::declval<tt14&>())),
+ "Error");
+static_assert(!noexcept(std::declval<tt15&>().swap(std::declval<tt15&>())),
+ "Error");
+static_assert(!noexcept(std::declval<tt16&>().swap(std::declval<tt16&>())),
+ "Error");
+static_assert(noexcept(std::declval<tt17&>().swap(std::declval<tt17&>())),
+ "Error");
+static_assert(noexcept(std::declval<tt18&>().swap(std::declval<tt18&>())),
+ "Error");
+static_assert(noexcept(std::declval<tt19&>().swap(std::declval<tt19&>())),
+ "Error");
+static_assert(noexcept(std::declval<tt20&>().swap(std::declval<tt20&>())),
+ "Error");
+static_assert(!noexcept(std::declval<tt21&>().swap(std::declval<tt21&>())),
+ "Error");
+static_assert(!noexcept(std::declval<tt22&>().swap(std::declval<tt22&>())),
+ "Error");
+static_assert(!noexcept(std::declval<tt23&>().swap(std::declval<tt23&>())),
+ "Error");
+static_assert(!noexcept(std::declval<tt24&>().swap(std::declval<tt24&>())),
+ "Error");
// { dg-warning "note" "" { target *-*-* } 485 }
// { dg-warning "note" "" { target *-*-* } 479 }
// { dg-warning "note" "" { target *-*-* } 469 }
-// { dg-warning "note" "" { target *-*-* } 599 }
+// { dg-warning "note" "" { target *-*-* } 603 }
// { dg-warning "note" "" { target *-*-* } 1056 }
// { dg-warning "note" "" { target *-*-* } 1050 }
// { dg-warning "note" "" { target *-*-* } 342 }
// { dg-warning "note" "" { target *-*-* } 292 }
-// { dg-warning "note" "" { target *-*-* } 211 }
+// { dg-warning "note" "" { target *-*-* } 212 }
// { dg-do compile }
// { dg-options "-std=gnu++0x" }
-// Copyright (C) 2005, 2007, 2009 Free Software Foundation, Inc.
+// Copyright (C) 2005, 2007, 2009, 2011 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
using __gnu_test::bidirectional_iterator_wrapper;
-class X
-{
- X();
- X(const X&);
- void operator=(const X&);
+struct X
+{
+ X() = delete;
+ X(const X&) = delete;
+ void operator=(const X&) = delete;
};
void
// { dg-do compile }
// { dg-options "-std=gnu++0x" }
-// Copyright (C) 2005, 2007, 2009 Free Software Foundation, Inc.
+// Copyright (C) 2005, 2007, 2009, 2011 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
using __gnu_test::forward_iterator_wrapper;
-class X
+struct X
{
- X();
- X(const X&);
- void operator=(const X&);
+ X() = delete;
+ X(const X&) = delete;
+ void operator=(const X&) = delete;
};
void
void
destroy(pointer p) { p->~Tp(); }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ // Not copy assignable...
+ uneq_allocator&
+ operator=(const uneq_allocator&) = delete;
+#endif
+
private:
+
+#ifndef __GXX_EXPERIMENTAL_CXX0X__
// Not assignable...
uneq_allocator&
operator=(const uneq_allocator&);
+#endif
// ... yet swappable!
friend inline void
DeletedMoveAssignClass&
operator=(DeletedMoveAssignClass&&) = delete;
};
+
+ struct NoexceptMoveConsNoexceptMoveAssignClass
+ {
+ NoexceptMoveConsNoexceptMoveAssignClass
+ (NoexceptMoveConsNoexceptMoveAssignClass&&) noexcept(true);
+
+ NoexceptMoveConsNoexceptMoveAssignClass&
+ operator=(NoexceptMoveConsNoexceptMoveAssignClass&&) noexcept(true);
+ };
+
+ struct ExceptMoveConsNoexceptMoveAssignClass
+ {
+ ExceptMoveConsNoexceptMoveAssignClass
+ (ExceptMoveConsNoexceptMoveAssignClass&&) noexcept(false);
+
+ ExceptMoveConsNoexceptMoveAssignClass&
+ operator=(ExceptMoveConsNoexceptMoveAssignClass&&) noexcept(true);
+ };
+
+ struct NoexceptMoveConsExceptMoveAssignClass
+ {
+ NoexceptMoveConsExceptMoveAssignClass
+ (NoexceptMoveConsExceptMoveAssignClass&&) noexcept(true);
+
+ NoexceptMoveConsExceptMoveAssignClass&
+ operator=(NoexceptMoveConsExceptMoveAssignClass&&) noexcept(false);
+ };
+
+ struct ExceptMoveConsExceptMoveAssignClass
+ {
+ ExceptMoveConsExceptMoveAssignClass
+ (ExceptMoveConsExceptMoveAssignClass&&) noexcept(false);
+
+ ExceptMoveConsExceptMoveAssignClass&
+ operator=(ExceptMoveConsExceptMoveAssignClass&&) noexcept(false);
+ };
#endif
struct NType // neither trivial nor standard-layout