From 9f77b1a1de8a57e6bd21c52f9c48e0f4d8ebac25 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Tue, 11 Dec 2018 14:22:28 +0000 Subject: [PATCH] [pair] Mark constructors as conditionally noexcept Summary: std::tuple marks its constructors as noexcept when the corresponding memberwise constructors are noexcept too -- this commit improves std::pair so that it behaves the same. This is a re-application of r348824, which broke the build in C++03 mode because a test was marked as supported in C++03 when it shouldn't be. Note: I did not add support in the explicit and non-explicit `pair(_Tuple&& __p)` constructors because those are non-standard extensions, and supporting them properly is tedious (we have to copy the rvalue-referenceness of the deduced _Tuple&& onto the result of tuple_element). Reviewers: mclow.lists, EricWF Subscribers: christof, llvm-commits Differential Revision: https://reviews.llvm.org/D48669 llvm-svn: 348847 --- libcxx/include/utility | 22 ++++- .../utility/pairs/pairs.pair/U_V.pass.cpp | 54 ++++++++++++ .../const_first_const_second.pass.cpp | 62 +++++++++++++ .../pairs/pairs.pair/const_pair_U_V.pass.cpp | 64 ++++++++++++++ .../utility/pairs/pairs.pair/default.pass.cpp | 31 +++++++ .../pairs/pairs.pair/piecewise.pass.cpp | 38 ++++++++ .../pairs/pairs.pair/rv_pair_U_V.pass.cpp | 63 ++++++++++++++ .../pairs/pairs.pair/piecewise.pass.cpp | 5 +- libcxx/test/support/archetypes.hpp | 9 +- libcxx/test/support/archetypes.ipp | 86 ++++++++++--------- 10 files changed, 388 insertions(+), 46 deletions(-) create mode 100644 libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/U_V.pass.cpp create mode 100644 libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/const_first_const_second.pass.cpp create mode 100644 libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/const_pair_U_V.pass.cpp create mode 100644 libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/default.pass.cpp create mode 100644 libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp create mode 100644 libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/rv_pair_U_V.pass.cpp diff --git a/libcxx/include/utility b/libcxx/include/utility index ddfa27e22232..fb7f4470507a 100644 --- a/libcxx/include/utility +++ b/libcxx/include/utility @@ -409,13 +409,17 @@ struct _LIBCPP_TEMPLATE_VIS pair _CheckArgsDep<_Dummy>::template __enable_default<_T1, _T2>() > = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - pair() : first(), second() {} + pair() _NOEXCEPT_(is_nothrow_default_constructible::value && + is_nothrow_default_constructible::value) + : first(), second() {} template ::template __enable_explicit<_T1 const&, _T2 const&>() > = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit pair(_T1 const& __t1, _T2 const& __t2) + _NOEXCEPT_(is_nothrow_copy_constructible::value && + is_nothrow_copy_constructible::value) : first(__t1), second(__t2) {} template = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 pair(_T1 const& __t1, _T2 const& __t2) + _NOEXCEPT_(is_nothrow_copy_constructible::value && + is_nothrow_copy_constructible::value) : first(__t1), second(__t2) {} template = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit pair(_U1&& __u1, _U2&& __u2) + _NOEXCEPT_((is_nothrow_constructible::value && + is_nothrow_constructible::value)) : first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {} template = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 pair(_U1&& __u1, _U2&& __u2) + _NOEXCEPT_((is_nothrow_constructible::value && + is_nothrow_constructible::value)) : first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {} template = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit pair(pair<_U1, _U2> const& __p) + _NOEXCEPT_((is_nothrow_constructible::value && + is_nothrow_constructible::value)) : first(__p.first), second(__p.second) {} template = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 pair(pair<_U1, _U2> const& __p) + _NOEXCEPT_((is_nothrow_constructible::value && + is_nothrow_constructible::value)) : first(__p.first), second(__p.second) {} template = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit pair(pair<_U1, _U2>&&__p) + _NOEXCEPT_((is_nothrow_constructible::value && + is_nothrow_constructible::value)) : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {} template = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 pair(pair<_U1, _U2>&& __p) + _NOEXCEPT_((is_nothrow_constructible::value && + is_nothrow_constructible::value)) : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {} template __first_args, tuple<_Args2...> __second_args) + _NOEXCEPT_((is_nothrow_constructible::value && + is_nothrow_constructible::value)) : pair(__pc, __first_args, __second_args, typename __make_tuple_indices::type(), typename __make_tuple_indices::type()) {} diff --git a/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/U_V.pass.cpp b/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/U_V.pass.cpp new file mode 100644 index 000000000000..6a3e613e9dcb --- /dev/null +++ b/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/U_V.pass.cpp @@ -0,0 +1,54 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// + +// template struct pair + +// template pair(U&& x, V&& y); + +#include + + +struct ExplicitT { + constexpr explicit ExplicitT(int x) : value(x) {} + int value; +}; + +struct ImplicitT { + constexpr ImplicitT(int x) : value(x) {} + int value; +}; + +struct ExplicitNothrowT { + explicit ExplicitNothrowT(int x) noexcept : value(x) {} + int value; +}; + +struct ImplicitNothrowT { + ImplicitNothrowT(int x) noexcept : value(x) {} + int value; +}; + +int main() { + { // explicit noexcept test + static_assert(!std::is_nothrow_constructible, int, int>::value, ""); + static_assert(!std::is_nothrow_constructible, int, int>::value, ""); + static_assert(!std::is_nothrow_constructible, int, int>::value, ""); + static_assert( std::is_nothrow_constructible, int, int>::value, ""); + } + { // implicit noexcept test + static_assert(!std::is_nothrow_constructible, int, int>::value, ""); + static_assert(!std::is_nothrow_constructible, int, int>::value, ""); + static_assert(!std::is_nothrow_constructible, int, int>::value, ""); + static_assert( std::is_nothrow_constructible, int, int>::value, ""); + } +} diff --git a/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/const_first_const_second.pass.cpp b/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/const_first_const_second.pass.cpp new file mode 100644 index 000000000000..6a2401223755 --- /dev/null +++ b/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/const_first_const_second.pass.cpp @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// + +// template struct pair + +// pair(const T1& x, const T2& y); + +#include + + +struct ExplicitT { + constexpr explicit ExplicitT(int x) : value(x) {} + constexpr explicit ExplicitT(ExplicitT const& o) : value(o.value) {} + int value; +}; + +struct ImplicitT { + constexpr ImplicitT(int x) : value(x) {} + constexpr ImplicitT(ImplicitT const& o) : value(o.value) {} + int value; +}; + +struct ExplicitNothrowT { + explicit ExplicitNothrowT(ExplicitNothrowT const&) noexcept {} +}; + +struct ImplicitNothrowT { + ImplicitNothrowT(ImplicitNothrowT const&) noexcept {} +}; + +int main() { + { // explicit noexcept test + static_assert(!std::is_nothrow_constructible, + ExplicitT const&, ExplicitT const&>::value, ""); + static_assert(!std::is_nothrow_constructible, + ExplicitNothrowT const&, ExplicitT const&>::value, ""); + static_assert(!std::is_nothrow_constructible, + ExplicitT const&, ExplicitNothrowT const&>::value, ""); + static_assert( std::is_nothrow_constructible, + ExplicitNothrowT const&, ExplicitNothrowT const&>::value, ""); + } + { // implicit noexcept test + static_assert(!std::is_nothrow_constructible, + ImplicitT const&, ImplicitT const&>::value, ""); + static_assert(!std::is_nothrow_constructible, + ImplicitNothrowT const&, ImplicitT const&>::value, ""); + static_assert(!std::is_nothrow_constructible, + ImplicitT const&, ImplicitNothrowT const&>::value, ""); + static_assert( std::is_nothrow_constructible, + ImplicitNothrowT const&, ImplicitNothrowT const&>::value, ""); + } +} diff --git a/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/const_pair_U_V.pass.cpp b/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/const_pair_U_V.pass.cpp new file mode 100644 index 000000000000..edb3bbf64afb --- /dev/null +++ b/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/const_pair_U_V.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// + +// template struct pair + +// template EXPLICIT constexpr pair(const pair& p); + +#include + + +struct ExplicitT { + constexpr explicit ExplicitT(int x) : value(x) {} + constexpr explicit ExplicitT(ExplicitT const& o) : value(o.value) {} + int value; +}; + +struct ImplicitT { + constexpr ImplicitT(int x) : value(x) {} + constexpr ImplicitT(ImplicitT const& o) : value(o.value) {} + int value; +}; + +struct ExplicitNothrowT { + explicit ExplicitNothrowT(int x) noexcept : value(x) {} + int value; +}; + +struct ImplicitNothrowT { + ImplicitNothrowT(int x) noexcept : value(x) {} + int value; +}; + +int main() { + { // explicit noexcept test + static_assert(!std::is_nothrow_constructible, + std::pair const&>::value, ""); + static_assert(!std::is_nothrow_constructible, + std::pair const&>::value, ""); + static_assert(!std::is_nothrow_constructible, + std::pair const&>::value, ""); + static_assert( std::is_nothrow_constructible, + std::pair const&>::value, ""); + } + { // implicit noexcept test + static_assert(!std::is_nothrow_constructible, + std::pair const&>::value, ""); + static_assert(!std::is_nothrow_constructible, + std::pair const&>::value, ""); + static_assert(!std::is_nothrow_constructible, + std::pair const&>::value, ""); + static_assert( std::is_nothrow_constructible, + std::pair const&>::value, ""); + } +} diff --git a/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/default.pass.cpp b/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/default.pass.cpp new file mode 100644 index 000000000000..07425cff10d1 --- /dev/null +++ b/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/default.pass.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// + +// template struct pair + +// constexpr pair(); + +#include +#include + +#include "archetypes.hpp" + + +int main() { + using NonThrowingDefault = NonThrowingTypes::DefaultOnly; + using ThrowingDefault = NonTrivialTypes::DefaultOnly; + static_assert(!std::is_nothrow_default_constructible>::value, ""); + static_assert(!std::is_nothrow_default_constructible>::value, ""); + static_assert(!std::is_nothrow_default_constructible>::value, ""); + static_assert( std::is_nothrow_default_constructible>::value, ""); +} diff --git a/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp b/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp new file mode 100644 index 000000000000..81dad3bc2ffa --- /dev/null +++ b/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// + +// template struct pair + +// template +// pair(piecewise_construct_t, tuple first_args, +// tuple second_args); + +#include +#include +#include + +#include "archetypes.hpp" + + +int main() { + using NonThrowingConvert = NonThrowingTypes::ConvertingType; + using ThrowingConvert = NonTrivialTypes::ConvertingType; + static_assert(!std::is_nothrow_constructible, + std::piecewise_construct_t, std::tuple, std::tuple>::value, ""); + static_assert(!std::is_nothrow_constructible, + std::piecewise_construct_t, std::tuple, std::tuple>::value, ""); + static_assert(!std::is_nothrow_constructible, + std::piecewise_construct_t, std::tuple, std::tuple>::value, ""); + static_assert( std::is_nothrow_constructible, + std::piecewise_construct_t, std::tuple, std::tuple>::value, ""); +} diff --git a/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/rv_pair_U_V.pass.cpp b/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/rv_pair_U_V.pass.cpp new file mode 100644 index 000000000000..5d8d36262f17 --- /dev/null +++ b/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/rv_pair_U_V.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// + +// template struct pair + +// template pair(pair&& p); + +#include +#include + + +struct ExplicitT { + constexpr explicit ExplicitT(int x) : value(x) {} + int value; +}; + +struct ImplicitT { + constexpr ImplicitT(int x) : value(x) {} + int value; +}; + +struct ExplicitNothrowT { + explicit ExplicitNothrowT(int x) noexcept : value(x) {} + int value; +}; + +struct ImplicitNothrowT { + ImplicitNothrowT(int x) noexcept : value(x) {} + int value; +}; + +int main() { + { // explicit noexcept test + static_assert(!std::is_nothrow_constructible, + std::pair&&>::value, ""); + static_assert(!std::is_nothrow_constructible, + std::pair&&>::value, ""); + static_assert(!std::is_nothrow_constructible, + std::pair&&>::value, ""); + static_assert( std::is_nothrow_constructible, + std::pair&&>::value, ""); + } + { // implicit noexcept test + static_assert(!std::is_nothrow_constructible, + std::pair&&>::value, ""); + static_assert(!std::is_nothrow_constructible, + std::pair&&>::value, ""); + static_assert(!std::is_nothrow_constructible, + std::pair&&>::value, ""); + static_assert( std::is_nothrow_constructible, + std::pair&&>::value, ""); + } +} diff --git a/libcxx/test/std/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp b/libcxx/test/std/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp index c738adad7d79..aa86949dd5b3 100644 --- a/libcxx/test/std/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp +++ b/libcxx/test/std/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp @@ -17,9 +17,10 @@ // pair(piecewise_construct_t, tuple first_args, // tuple second_args); -#include -#include #include +#include +#include + int main() { diff --git a/libcxx/test/support/archetypes.hpp b/libcxx/test/support/archetypes.hpp index 1695a6fc686c..a0ea7c3ce8e1 100644 --- a/libcxx/test/support/archetypes.hpp +++ b/libcxx/test/support/archetypes.hpp @@ -225,7 +225,6 @@ namespace ExplicitTypes { #include "archetypes.ipp" } - //============================================================================// // namespace NonConstexprTypes { @@ -241,12 +240,18 @@ namespace NonLiteralTypes { #include "archetypes.ipp" } +//============================================================================// +// Non-throwing implicit test types +namespace NonThrowingTypes { +#define DEFINE_NOEXCEPT noexcept +#include "archetypes.ipp" +} + //============================================================================// // Non-Trivially Copyable Implicit Test Types namespace NonTrivialTypes { #define DEFINE_CTOR {} #define DEFINE_ASSIGN { return *this; } -#define DEFINE_DEFAULT_CTOR = default #include "archetypes.ipp" } diff --git a/libcxx/test/support/archetypes.ipp b/libcxx/test/support/archetypes.ipp index 36045017907f..943dcf9f5d8a 100644 --- a/libcxx/test/support/archetypes.ipp +++ b/libcxx/test/support/archetypes.ipp @@ -5,6 +5,9 @@ #ifndef DEFINE_EXPLICIT #define DEFINE_EXPLICIT #endif +#ifndef DEFINE_NOEXCEPT +#define DEFINE_NOEXCEPT +#endif #ifndef DEFINE_CONSTEXPR #ifdef TEST_WORKAROUND_EDG_EXPLICIT_CONSTEXPR #define DEFINE_CONSTEXPR @@ -36,114 +39,114 @@ struct AllCtors : DEFINE_BASE(AllCtors) { using Base = DEFINE_BASE(AllCtors); using Base::Base; using Base::operator=; - DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors() DEFINE_DEFAULT_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors(AllCtors const&) DEFINE_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors(AllCtors &&) DEFINE_CTOR; - DEFINE_ASSIGN_CONSTEXPR AllCtors& operator=(AllCtors const&) DEFINE_ASSIGN; - DEFINE_ASSIGN_CONSTEXPR AllCtors& operator=(AllCtors &&) DEFINE_ASSIGN; + DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors(AllCtors const&) DEFINE_NOEXCEPT DEFINE_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors(AllCtors &&) DEFINE_NOEXCEPT DEFINE_CTOR; + DEFINE_ASSIGN_CONSTEXPR AllCtors& operator=(AllCtors const&) DEFINE_NOEXCEPT DEFINE_ASSIGN; + DEFINE_ASSIGN_CONSTEXPR AllCtors& operator=(AllCtors &&) DEFINE_NOEXCEPT DEFINE_ASSIGN; DEFINE_DTOR(AllCtors) }; struct NoCtors : DEFINE_BASE(NoCtors) { using Base = DEFINE_BASE(NoCtors); - DEFINE_EXPLICIT NoCtors() = delete; - DEFINE_EXPLICIT NoCtors(NoCtors const&) = delete; - NoCtors& operator=(NoCtors const&) = delete; + DEFINE_EXPLICIT NoCtors() DEFINE_NOEXCEPT = delete; + DEFINE_EXPLICIT NoCtors(NoCtors const&) DEFINE_NOEXCEPT = delete; + NoCtors& operator=(NoCtors const&) DEFINE_NOEXCEPT = delete; DEFINE_DTOR(NoCtors) }; struct NoDefault : DEFINE_BASE(NoDefault) { using Base = DEFINE_BASE(NoDefault); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR NoDefault() = delete; + DEFINE_EXPLICIT DEFINE_CONSTEXPR NoDefault() DEFINE_NOEXCEPT = delete; DEFINE_DTOR(NoDefault) }; struct DefaultOnly : DEFINE_BASE(DefaultOnly) { using Base = DEFINE_BASE(DefaultOnly); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR DefaultOnly() DEFINE_DEFAULT_CTOR; - DefaultOnly(DefaultOnly const&) = delete; - DefaultOnly& operator=(DefaultOnly const&) = delete; + DEFINE_EXPLICIT DEFINE_CONSTEXPR DefaultOnly() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; + DefaultOnly(DefaultOnly const&) DEFINE_NOEXCEPT = delete; + DefaultOnly& operator=(DefaultOnly const&) DEFINE_NOEXCEPT = delete; DEFINE_DTOR(DefaultOnly) }; struct Copyable : DEFINE_BASE(Copyable) { using Base = DEFINE_BASE(Copyable); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR Copyable() DEFINE_DEFAULT_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR Copyable(Copyable const &) DEFINE_CTOR; - Copyable &operator=(Copyable const &) DEFINE_ASSIGN; + DEFINE_EXPLICIT DEFINE_CONSTEXPR Copyable() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR Copyable(Copyable const &) DEFINE_NOEXCEPT DEFINE_CTOR; + Copyable &operator=(Copyable const &) DEFINE_NOEXCEPT DEFINE_ASSIGN; DEFINE_DTOR(Copyable) }; struct CopyOnly : DEFINE_BASE(CopyOnly) { using Base = DEFINE_BASE(CopyOnly); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly() DEFINE_DEFAULT_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly(CopyOnly const &) DEFINE_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly(CopyOnly &&) = delete; - CopyOnly &operator=(CopyOnly const &) DEFINE_ASSIGN; - CopyOnly &operator=(CopyOnly &&) = delete; + DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly(CopyOnly const &) DEFINE_NOEXCEPT DEFINE_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly(CopyOnly &&) DEFINE_NOEXCEPT = delete; + CopyOnly &operator=(CopyOnly const &) DEFINE_NOEXCEPT DEFINE_ASSIGN; + CopyOnly &operator=(CopyOnly &&) DEFINE_NOEXCEPT = delete; DEFINE_DTOR(CopyOnly) }; struct NonCopyable : DEFINE_BASE(NonCopyable) { using Base = DEFINE_BASE(NonCopyable); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR NonCopyable() DEFINE_DEFAULT_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR NonCopyable(NonCopyable const &) = delete; - NonCopyable &operator=(NonCopyable const &) = delete; + DEFINE_EXPLICIT DEFINE_CONSTEXPR NonCopyable() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR NonCopyable(NonCopyable const &) DEFINE_NOEXCEPT = delete; + NonCopyable &operator=(NonCopyable const &) DEFINE_NOEXCEPT = delete; DEFINE_DTOR(NonCopyable) }; struct MoveOnly : DEFINE_BASE(MoveOnly) { using Base = DEFINE_BASE(MoveOnly); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveOnly() DEFINE_DEFAULT_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveOnly(MoveOnly &&) DEFINE_CTOR; - MoveOnly &operator=(MoveOnly &&) DEFINE_ASSIGN; + DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveOnly() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveOnly(MoveOnly &&) DEFINE_NOEXCEPT DEFINE_CTOR; + MoveOnly &operator=(MoveOnly &&) DEFINE_NOEXCEPT DEFINE_ASSIGN; DEFINE_DTOR(MoveOnly) }; struct CopyAssignable : DEFINE_BASE(CopyAssignable) { using Base = DEFINE_BASE(CopyAssignable); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyAssignable() = delete; - CopyAssignable& operator=(CopyAssignable const&) DEFINE_ASSIGN; + DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyAssignable() DEFINE_NOEXCEPT = delete; + CopyAssignable& operator=(CopyAssignable const&) DEFINE_NOEXCEPT DEFINE_ASSIGN; DEFINE_DTOR(CopyAssignable) }; struct CopyAssignOnly : DEFINE_BASE(CopyAssignOnly) { using Base = DEFINE_BASE(CopyAssignOnly); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyAssignOnly() = delete; - CopyAssignOnly& operator=(CopyAssignOnly const&) DEFINE_ASSIGN; - CopyAssignOnly& operator=(CopyAssignOnly &&) = delete; + DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyAssignOnly() DEFINE_NOEXCEPT = delete; + CopyAssignOnly& operator=(CopyAssignOnly const&) DEFINE_NOEXCEPT DEFINE_ASSIGN; + CopyAssignOnly& operator=(CopyAssignOnly &&) DEFINE_NOEXCEPT = delete; DEFINE_DTOR(CopyAssignOnly) }; struct MoveAssignOnly : DEFINE_BASE(MoveAssignOnly) { using Base = DEFINE_BASE(MoveAssignOnly); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveAssignOnly() = delete; - MoveAssignOnly& operator=(MoveAssignOnly const&) = delete; - MoveAssignOnly& operator=(MoveAssignOnly &&) DEFINE_ASSIGN; + DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveAssignOnly() DEFINE_NOEXCEPT = delete; + MoveAssignOnly& operator=(MoveAssignOnly const&) DEFINE_NOEXCEPT = delete; + MoveAssignOnly& operator=(MoveAssignOnly &&) DEFINE_NOEXCEPT DEFINE_ASSIGN; DEFINE_DTOR(MoveAssignOnly) }; struct ConvertingType : DEFINE_BASE(ConvertingType) { using Base = DEFINE_BASE(ConvertingType); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType() DEFINE_DEFAULT_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(ConvertingType const&) DEFINE_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(ConvertingType &&) DEFINE_CTOR; - ConvertingType& operator=(ConvertingType const&) DEFINE_ASSIGN; - ConvertingType& operator=(ConvertingType &&) DEFINE_ASSIGN; + DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(ConvertingType const&) DEFINE_NOEXCEPT DEFINE_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(ConvertingType &&) DEFINE_NOEXCEPT DEFINE_CTOR; + ConvertingType& operator=(ConvertingType const&) DEFINE_NOEXCEPT DEFINE_ASSIGN; + ConvertingType& operator=(ConvertingType &&) DEFINE_NOEXCEPT DEFINE_ASSIGN; template - DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(Args&&...) {} + DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(Args&&...) DEFINE_NOEXCEPT {} template - ConvertingType& operator=(Arg&&) { return *this; } + ConvertingType& operator=(Arg&&) DEFINE_NOEXCEPT { return *this; } DEFINE_DTOR(ConvertingType) }; @@ -165,6 +168,7 @@ using ApplyTypes = List< #undef DEFINE_BASE #undef DEFINE_EXPLICIT +#undef DEFINE_NOEXCEPT #undef DEFINE_CONSTEXPR #undef DEFINE_ASSIGN_CONSTEXPR #undef DEFINE_CTOR