aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVille Voutilainen <ville.voutilainen@gmail.com>2016-09-21 20:25:16 +0300
committerVille Voutilainen <ville@gcc.gnu.org>2016-09-21 20:25:16 +0300
commit557867852474743abd1e6b2ca678af8a8cf18b51 (patch)
treeb4550db8a90a68c2afeea53d7398291da5409cc6
parentf524d5b34aaac95cb4b2ce7126002cd4fa9d5bae (diff)
downloadgcc-557867852474743abd1e6b2ca678af8a8cf18b51.zip
gcc-557867852474743abd1e6b2ca678af8a8cf18b51.tar.gz
gcc-557867852474743abd1e6b2ca678af8a8cf18b51.tar.bz2
Implement LWG 2729 for tuple.
* include/std/tuple (_Tuple_impl(_Tuple_impl&&)): Suppress conditionally. (_Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&&)): Likewise. (__is_tuple_impl_trait_impl, __is_tuple_impl_trait): New. (_Tuple_impl(const _Head&)): Constrain. (_Tuple_impl(_UHead&&)): Likewise. (_Tuple_impl(_Tuple_impl&&)): Suppress conditionally. (_Tuple_impl(const _Tuple_impl<_Idx, _UHead>&)): Constrain. (_Tuple_impl(_Tuple_impl<_Idx, _UHead>&&)): Likewise. (operator=(const tuple&)): Enable conditionally. (operator=(tuple&&)): Suppress conditionally. (operator=(const tuple<_UElements...>&)): Constrain. (operator=(tuple<_UElements...>&&)): Likewise. (operator=(const tuple&)): Enable conditionally (2-param tuple). (operator=(tuple&&)): Suppress conditionally (2-param tuple). (operator=(const tuple<_U1, _U2>&)): Constrain. (operator=(tuple<_U1, _U2>&&)): Likewise. (operator=(const pair<_U1, _U2>&)): Likewise. (operator=(pair<_U1, _U2>&&)): Likewise. * testsuite/20_util/tuple/element_access/get_neg.cc: Adjust. * testsuite/20_util/tuple/tuple_traits.cc: New. From-SVN: r240323
-rw-r--r--libstdc++-v3/ChangeLog25
-rw-r--r--libstdc++-v3/include/std/tuple96
-rw-r--r--libstdc++-v3/testsuite/20_util/tuple/element_access/get_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/20_util/tuple/tuple_traits.cc244
4 files changed, 349 insertions, 18 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 0c35cd7..35dc2b5 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,30 @@
2016-09-21 Ville Voutilainen <ville.voutilainen@gmail.com>
+ Implement LWG 2729 for tuple.
+ * include/std/tuple (_Tuple_impl(_Tuple_impl&&)):
+ Suppress conditionally.
+ (_Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&&)): Likewise.
+ (__is_tuple_impl_trait_impl, __is_tuple_impl_trait): New.
+ (_Tuple_impl(const _Head&)): Constrain.
+ (_Tuple_impl(_UHead&&)): Likewise.
+ (_Tuple_impl(_Tuple_impl&&)): Suppress conditionally.
+ (_Tuple_impl(const _Tuple_impl<_Idx, _UHead>&)): Constrain.
+ (_Tuple_impl(_Tuple_impl<_Idx, _UHead>&&)): Likewise.
+ (operator=(const tuple&)): Enable conditionally.
+ (operator=(tuple&&)): Suppress conditionally.
+ (operator=(const tuple<_UElements...>&)): Constrain.
+ (operator=(tuple<_UElements...>&&)): Likewise.
+ (operator=(const tuple&)): Enable conditionally (2-param tuple).
+ (operator=(tuple&&)): Suppress conditionally (2-param tuple).
+ (operator=(const tuple<_U1, _U2>&)): Constrain.
+ (operator=(tuple<_U1, _U2>&&)): Likewise.
+ (operator=(const pair<_U1, _U2>&)): Likewise.
+ (operator=(pair<_U1, _U2>&&)): Likewise.
+ * testsuite/20_util/tuple/element_access/get_neg.cc: Adjust.
+ * testsuite/20_util/tuple/tuple_traits.cc: New.
+
+2016-09-21 Ville Voutilainen <ville.voutilainen@gmail.com>
+
PR libstdc++/77537
Implement LWG 2729 for pair.
* include/bits/stl_pair.h (_PCC): New.
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index c06a040..32b932f 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -220,8 +220,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr _Tuple_impl(const _Tuple_impl&) = default;
constexpr
- _Tuple_impl(_Tuple_impl&& __in)
- noexcept(__and_<is_nothrow_move_constructible<_Head>,
+ _Tuple_impl(typename conditional<
+ __and_<is_move_constructible<_Head>,
+ is_move_constructible<_Inherited>>::value,
+ _Tuple_impl&&, __nonesuch&&>::type __in)
+ noexcept(__and_<is_nothrow_move_constructible<_Head>,
is_nothrow_move_constructible<_Inherited>>::value)
: _Inherited(std::move(_M_tail(__in))),
_Base(std::forward<_Head>(_M_head(__in))) { }
@@ -232,7 +235,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { }
template<typename _UHead, typename... _UTails>
- constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
+ constexpr _Tuple_impl(typename conditional<
+ __and_<is_move_constructible<_Head>,
+ is_move_constructible<_Inherited>>::value,
+ _Tuple_impl<_Idx, _UHead, _UTails...>&&,
+ __nonesuch&&>::type __in)
: _Inherited(std::move
(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
_Base(std::forward<_UHead>
@@ -338,6 +345,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
};
+ template<typename...>
+ struct __is_tuple_impl_trait_impl : false_type
+ { };
+
+ template<std::size_t _Idx, typename... _Tp>
+ struct __is_tuple_impl_trait_impl<_Tuple_impl<_Idx, _Tp...>> : true_type
+ { };
+
+ template<typename _Tp>
+ struct __is_tuple_impl_trait : public __is_tuple_impl_trait_impl<_Tp>
+ { };
+
// Basis case of inheritance recursion.
template<std::size_t _Idx, typename _Head>
struct _Tuple_impl<_Idx, _Head>
@@ -356,11 +375,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr _Tuple_impl()
: _Base() { }
+ template<typename _Dummy=void,
+ typename enable_if<is_constructible<_Base, const _Head&>::value,
+ bool>::type=true>
explicit
constexpr _Tuple_impl(const _Head& __head)
: _Base(__head) { }
- template<typename _UHead>
+ template<typename _UHead,
+ typename enable_if<__and_<is_constructible<_Base, _UHead&&>,
+ __not_<__is_tuple_impl_trait<
+ typename
+ remove_reference<_UHead>::type>>
+ >::value,
+ bool>::type = true>
explicit
constexpr _Tuple_impl(_UHead&& __head)
: _Base(std::forward<_UHead>(__head)) { }
@@ -368,15 +396,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr _Tuple_impl(const _Tuple_impl&) = default;
constexpr
- _Tuple_impl(_Tuple_impl&& __in)
+ _Tuple_impl(typename conditional<
+ is_move_constructible<_Head>::value,
+ _Tuple_impl&&, __nonesuch&&>::type __in)
noexcept(is_nothrow_move_constructible<_Head>::value)
: _Base(std::forward<_Head>(_M_head(__in))) { }
- template<typename _UHead>
+ template<typename _UHead,
+ typename enable_if<!is_same<_Head, _UHead>::value,
+ bool>::type = true>
constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in)
: _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
- template<typename _UHead>
+ template<typename _UHead,
+ typename enable_if<!is_same<_Head, _UHead>::value,
+ bool>::type = true>
constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in)
: _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
{ }
@@ -832,14 +866,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ }
tuple&
- operator=(const tuple& __in)
+ operator=(typename
+ conditional<__and_<is_copy_assignable<_Elements>...>::value,
+ const tuple&, const __nonesuch&>::type __in)
{
static_cast<_Inherited&>(*this) = __in;
return *this;
}
tuple&
- operator=(tuple&& __in)
+ operator=(typename
+ conditional<__and_<is_move_assignable<_Elements>...>::value,
+ tuple&&, __nonesuch&&>::type __in)
noexcept(is_nothrow_move_assignable<_Inherited>::value)
{
static_cast<_Inherited&>(*this) = std::move(__in);
@@ -848,7 +886,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename... _UElements, typename = typename
enable_if<sizeof...(_UElements)
- == sizeof...(_Elements)>::type>
+ == sizeof...(_Elements)
+ &&
+ __and_<is_assignable<_Elements&,
+ const _UElements&>...>::value>::type>
tuple&
operator=(const tuple<_UElements...>& __in)
{
@@ -858,7 +899,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename... _UElements, typename = typename
enable_if<sizeof...(_UElements)
- == sizeof...(_Elements)>::type>
+ == sizeof...(_Elements)
+ &&
+ __and_<is_assignable<_Elements&,
+ _UElements&&>...>::value>::type>
tuple&
operator=(tuple<_UElements...>&& __in)
{
@@ -1189,14 +1233,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
std::forward<_U2>(__in.second)) { }
tuple&
- operator=(const tuple& __in)
+ operator=(typename
+ conditional<__and_<is_copy_assignable<_T1>,
+ is_copy_assignable<_T2>>::value,
+ const tuple&, const __nonesuch&>::type __in)
{
static_cast<_Inherited&>(*this) = __in;
return *this;
}
tuple&
- operator=(tuple&& __in)
+ operator=(typename
+ conditional<__and_<is_move_assignable<_T1>,
+ is_move_assignable<_T2>>::value,
+ tuple&&, __nonesuch&&>::type __in)
noexcept(is_nothrow_move_assignable<_Inherited>::value)
{
static_cast<_Inherited&>(*this) = std::move(__in);
@@ -1204,7 +1254,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _U1, typename _U2>
- tuple&
+ typename
+ enable_if<__and_<is_assignable<_T1&, const _U1&>,
+ is_assignable<_T2&, const _U2&>>::value,
+ tuple&>::type
operator=(const tuple<_U1, _U2>& __in)
{
static_cast<_Inherited&>(*this) = __in;
@@ -1212,7 +1265,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _U1, typename _U2>
- tuple&
+ typename
+ enable_if<__and_<is_assignable<_T1&, _U1&&>,
+ is_assignable<_T2&, _U2&&>>::value,
+ tuple&>::type
operator=(tuple<_U1, _U2>&& __in)
{
static_cast<_Inherited&>(*this) = std::move(__in);
@@ -1220,7 +1276,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _U1, typename _U2>
- tuple&
+ typename
+ enable_if<__and_<is_assignable<_T1&, const _U1&>,
+ is_assignable<_T2&, const _U2&>>::value,
+ tuple&>::type
operator=(const pair<_U1, _U2>& __in)
{
this->_M_head(*this) = __in.first;
@@ -1229,7 +1288,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _U1, typename _U2>
- tuple&
+ typename
+ enable_if<__and_<is_assignable<_T1&, _U1&&>,
+ is_assignable<_T2&, _U2&&>>::value,
+ tuple&>::type
operator=(pair<_U1, _U2>&& __in)
{
this->_M_head(*this) = std::forward<_U1>(__in.first);
diff --git a/libstdc++-v3/testsuite/20_util/tuple/element_access/get_neg.cc b/libstdc++-v3/testsuite/20_util/tuple/element_access/get_neg.cc
index 5bcf576..1c08d45 100644
--- a/libstdc++-v3/testsuite/20_util/tuple/element_access/get_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/tuple/element_access/get_neg.cc
@@ -17,7 +17,7 @@
// { dg-options "-fno-show-column" }
// { dg-do compile { target c++14 } }
-// { dg-error "in range" "" { target *-*-* } 1280 }
+// { dg-error "in range" "" { target *-*-* } 1342 }
#include <tuple>
diff --git a/libstdc++-v3/testsuite/20_util/tuple/tuple_traits.cc b/libstdc++-v3/testsuite/20_util/tuple/tuple_traits.cc
new file mode 100644
index 0000000..b72f535
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/tuple/tuple_traits.cc
@@ -0,0 +1,244 @@
+// { dg-do compile { target c++11 } }
+
+// 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 <tuple>
+#include <type_traits>
+#include <utility>
+#include <vector>
+#include <memory>
+
+using namespace std;
+
+struct Poison
+{
+ Poison(Poison&&) = delete;
+};
+
+
+int main()
+{
+ static_assert(!is_copy_constructible<Poison>::value, "");
+ static_assert(!is_move_constructible<Poison>::value, "");
+ static_assert(!is_copy_assignable<Poison>::value, "");
+ static_assert(!is_move_assignable<Poison>::value, "");
+
+ static_assert(!is_copy_constructible<std::tuple<Poison>>::value, "");
+ static_assert(!is_move_constructible<std::tuple<Poison>>::value, "");
+ static_assert(!is_copy_assignable<std::tuple<Poison>>::value, "");
+ static_assert(!is_move_assignable<std::tuple<Poison>>::value, "");
+
+ static_assert(!is_copy_constructible<std::tuple<int, Poison>>::value,
+ "");
+ static_assert(!is_move_constructible<std::tuple<int, Poison>>::value,
+ "");
+ static_assert(!is_copy_assignable<std::tuple<int, Poison>>::value, "");
+ static_assert(!is_move_assignable<std::tuple<int, Poison>>::value, "");
+ static_assert(!is_constructible<std::tuple<int, Poison>&,
+ std::tuple<char, Poison>&>::value, "");
+ static_assert(!is_assignable<std::tuple<int, Poison>&,
+ std::tuple<char, Poison>&>::value, "");
+ static_assert(!is_constructible<std::tuple<int, Poison>&,
+ std::tuple<char, Poison>>::value, "");
+ static_assert(!is_assignable<std::tuple<int, Poison>&,
+ std::tuple<char, Poison>>::value, "");
+ static_assert(!is_constructible<std::tuple<int, Poison>&,
+ std::pair<char, Poison>&>::value, "");
+ static_assert(!is_assignable<std::tuple<int, Poison>&,
+ std::pair<char, Poison>&>::value, "");
+ static_assert(!is_constructible<std::tuple<int, Poison>&,
+ std::pair<char, Poison>>::value, "");
+ static_assert(!is_assignable<std::tuple<int, Poison>&,
+ std::pair<char, Poison>>::value, "");
+
+ static_assert(!is_copy_constructible<
+ std::tuple<int, int, Poison>>::value, "");
+ static_assert(!is_move_constructible<
+ std::tuple<int, int, Poison>>::value, "");
+ static_assert(!is_copy_assignable<
+ std::tuple<int, int, Poison>>::value, "");
+ static_assert(!is_move_assignable<
+ std::tuple<int, int, Poison>>::value, "");
+ static_assert(!is_constructible<
+ std::tuple<int, int,Poison>&,
+ std::tuple<int, char, Poison>&>::value, "");
+ static_assert(!is_assignable<
+ std::tuple<int, int, Poison>&,
+ std::tuple<int, char, Poison>&>::value, "");
+ static_assert(!is_constructible<
+ std::tuple<int, int, Poison>&,
+ std::tuple<int, char, Poison>>::value, "");
+ static_assert(!is_assignable<
+ std::tuple<int, int, Poison>&,
+ std::tuple<int, char, Poison>>::value, "");
+ static_assert(!is_constructible<
+ std::tuple<int, int, Poison>&,
+ std::pair<char, Poison>&>::value, "");
+ static_assert(!is_assignable<
+ std::tuple<int, int, Poison>&,
+ std::pair<char, Poison>&>::value, "");
+ static_assert(!is_constructible<
+ std::tuple<int, int, Poison>&,
+ std::pair<char, Poison>>::value, "");
+ static_assert(!is_assignable<
+ std::tuple<int, int, Poison>&,
+ std::pair<char, Poison>>::value, "");
+
+ static_assert(is_trivially_copy_constructible<tuple<int>>::value, "");
+ static_assert(!is_trivially_move_constructible<tuple<int>>::value, "");
+
+ static_assert(!is_trivially_copy_assignable<tuple<int>>::value, "");
+ static_assert(!is_trivially_move_assignable<tuple<int>>::value, "");
+
+ static_assert(is_copy_constructible<tuple<int>>::value, "");
+ static_assert(is_move_constructible<tuple<int>>::value, "");
+
+ static_assert(is_copy_assignable<tuple<int>>::value, "");
+ static_assert(is_move_assignable<tuple<int>>::value, "");
+
+ static_assert(!is_trivially_copy_constructible<
+ tuple<vector<int>>>::value, "");
+ static_assert(!is_trivially_move_constructible<
+ tuple<vector<int>>>::value, "");
+
+ static_assert(!is_trivially_copy_assignable<
+ tuple<vector<int>>>::value, "");
+ static_assert(!is_trivially_move_assignable<
+ tuple<vector<int>>>::value, "");
+
+ static_assert(is_copy_constructible<tuple<vector<int>>>::value, "");
+ static_assert(is_move_constructible<tuple<vector<int>>>::value, "");
+
+ static_assert(is_copy_assignable<tuple<vector<int>>>::value, "");
+ static_assert(is_move_assignable<tuple<vector<int>>>::value, "");
+
+ static_assert(!is_trivially_copy_constructible<
+ tuple<unique_ptr<int>>>::value, "");
+ static_assert(!is_trivially_move_constructible<
+ tuple<unique_ptr<int>>>::value, "");
+
+ static_assert(!is_trivially_copy_assignable<
+ tuple<unique_ptr<int>>>::value, "");
+ static_assert(!is_trivially_move_assignable<
+ tuple<unique_ptr<int>>>::value, "");
+ static_assert(!is_copy_constructible<
+ tuple<unique_ptr<int>>>::value, "");
+ static_assert(is_move_constructible<tuple<unique_ptr<int>>>::value, "");
+
+ static_assert(!is_copy_assignable<tuple<unique_ptr<int>>>::value, "");
+ static_assert(is_move_assignable<tuple<unique_ptr<int>>>::value, "");
+
+ static_assert(is_trivially_copy_constructible<
+ tuple<int, int>>::value, "");
+ static_assert(!is_trivially_move_constructible<
+ tuple<int, int>>::value, "");
+
+ static_assert(!is_trivially_copy_assignable<
+ tuple<int, int>>::value, "");
+ static_assert(!is_trivially_move_assignable<
+ tuple<int, int>>::value, "");
+
+ static_assert(is_copy_constructible<tuple<int, int>>::value, "");
+ static_assert(is_move_constructible<tuple<int, int>>::value, "");
+
+ static_assert(is_copy_assignable<tuple<int, int>>::value, "");
+ static_assert(is_move_assignable<tuple<int, int>>::value, "");
+ static_assert(!is_trivially_copy_constructible<
+ tuple<int, vector<int>>>::value, "");
+ static_assert(!is_trivially_move_constructible<
+ tuple<int, vector<int>>>::value, "");
+
+ static_assert(!is_trivially_copy_assignable<
+ tuple<int, vector<int>>>::value, "");
+ static_assert(!is_trivially_move_assignable<
+ tuple<int, vector<int>>>::value, "");
+
+ static_assert(is_copy_constructible<
+ tuple<int, vector<int>>>::value, "");
+ static_assert(is_move_constructible<
+ tuple<int, vector<int>>>::value, "");
+
+ static_assert(is_copy_assignable<tuple<int, vector<int>>>::value, "");
+ static_assert(is_move_assignable<tuple<int, vector<int>>>::value, "");
+
+ static_assert(!is_trivially_copy_constructible<
+ tuple<int, unique_ptr<int>>>::value, "");
+ static_assert(!is_trivially_move_constructible<
+ tuple<int, unique_ptr<int>>>::value, "");
+
+ static_assert(!is_trivially_copy_assignable<
+ tuple<int, unique_ptr<int>>>::value, "");
+ static_assert(!is_trivially_move_assignable<
+ tuple<int, unique_ptr<int>>>::value, "");
+
+ static_assert(!is_copy_constructible<
+ tuple<int, unique_ptr<int>>>::value, "");
+ static_assert(is_move_constructible<
+ tuple<int, unique_ptr<int>>>::value, "");
+
+ static_assert(!is_copy_assignable<
+ tuple<int, unique_ptr<int>>>::value, "");
+ static_assert(is_move_assignable<
+ tuple<int, unique_ptr<int>>>::value, "");
+
+ static_assert(is_copy_constructible<tuple<int, int, int>>::value, "");
+ static_assert(is_move_constructible<tuple<int, int, int>>::value, "");
+
+ static_assert(is_copy_assignable<tuple<int, int, int>>::value, "");
+ static_assert(is_move_assignable<tuple<int, int, int>>::value, "");
+
+ static_assert(!is_trivially_copy_constructible<
+ tuple<int, int, vector<int>>>::value, "");
+ static_assert(!is_trivially_move_constructible<
+ tuple<int, int, vector<int>>>::value, "");
+
+ static_assert(!is_trivially_copy_assignable<
+ tuple<int, int, vector<int>>>::value, "");
+ static_assert(!is_trivially_move_assignable<
+ tuple<int, int, vector<int>>>::value, "");
+
+ static_assert(is_copy_constructible<
+ tuple<int, int, vector<int>>>::value, "");
+ static_assert(is_move_constructible<
+ tuple<int, int, vector<int>>>::value, "");
+
+ static_assert(is_copy_assignable<
+ tuple<int, int, vector<int>>>::value, "");
+ static_assert(is_move_assignable<
+ tuple<int, int, vector<int>>>::value, "");
+
+ static_assert(!is_trivially_copy_constructible<
+ tuple<int, int, unique_ptr<int>>>::value, "");
+ static_assert(!is_trivially_move_constructible<
+ tuple<int, int, unique_ptr<int>>>::value, "");
+
+ static_assert(!is_trivially_copy_assignable<
+ tuple<int, int, unique_ptr<int>>>::value, "");
+ static_assert(!is_trivially_move_assignable<
+ tuple<int, int, unique_ptr<int>>>::value, "");
+
+ static_assert(!is_copy_constructible<
+ tuple<int, int, unique_ptr<int>>>::value, "");
+ static_assert(is_move_constructible<
+ tuple<int, int, unique_ptr<int>>>::value, "");
+
+ static_assert(!is_copy_assignable<
+ tuple<int, int, unique_ptr<int>>>::value, "");
+ static_assert(is_move_assignable<
+ tuple<int, int, unique_ptr<int>>>::value, "");
+}