1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 // <tuple>
10
11 // template <class... Types> class tuple;
12
13 // EXTENSION
14 // template <class U, size_t N>
15 // tuple& operator=(const array<U, N>& u);
16 //
17 // template <class U, size_t N>
18 // tuple& operator=(array<U, N>&& u);
19
20 // UNSUPPORTED: c++03
21
22 #include <array>
23 #include <cassert>
24 #include <tuple>
25 #include <type_traits>
26 #include <utility>
27
28
29 template <class T>
30 struct NothrowAssignableFrom {
operator =NothrowAssignableFrom31 NothrowAssignableFrom& operator=(T) noexcept { return *this; }
32 };
33
34 template <class T>
35 struct PotentiallyThrowingAssignableFrom {
operator =PotentiallyThrowingAssignableFrom36 PotentiallyThrowingAssignableFrom& operator=(T) { return *this; }
37 };
38
main(int,char **)39 int main(int, char**) {
40 // Tests for the array const& overload
41 {
42 std::array<long, 3> array = {1l, 2l, 3l};
43 std::tuple<int, int, int> tuple;
44 tuple = array;
45 assert(std::get<0>(tuple) == 1);
46 assert(std::get<1>(tuple) == 2);
47 assert(std::get<2>(tuple) == 3);
48 }
49 {
50 typedef std::tuple<NothrowAssignableFrom<int>> Tuple;
51 typedef std::array<int, 1> Array;
52 static_assert(std::is_nothrow_assignable<Tuple&, Array const&>::value, "");
53 }
54 {
55 typedef std::tuple<PotentiallyThrowingAssignableFrom<int>> Tuple;
56 typedef std::array<int, 1> Array;
57 static_assert(std::is_assignable<Tuple&, Array const&>::value, "");
58 static_assert(!std::is_nothrow_assignable<Tuple&, Array const&>::value, "");
59 }
60
61 // Tests for the array&& overload
62 {
63 std::array<long, 3> array = {1l, 2l, 3l};
64 std::tuple<int, int, int> tuple;
65 tuple = std::move(array);
66 assert(std::get<0>(tuple) == 1);
67 assert(std::get<1>(tuple) == 2);
68 assert(std::get<2>(tuple) == 3);
69 }
70 {
71 typedef std::tuple<NothrowAssignableFrom<int>> Tuple;
72 typedef std::array<int, 1> Array;
73 static_assert(std::is_nothrow_assignable<Tuple&, Array&&>::value, "");
74 }
75 {
76 typedef std::tuple<PotentiallyThrowingAssignableFrom<int>> Tuple;
77 typedef std::array<int, 1> Array;
78 static_assert(std::is_assignable<Tuple&, Array&&>::value, "");
79 static_assert(!std::is_nothrow_assignable<Tuple&, Array&&>::value, "");
80 }
81
82 // Test lvalue-refs and const rvalue-ref
83 {
84 typedef std::tuple<NothrowAssignableFrom<int>> Tuple;
85 typedef std::array<int, 1> Array;
86 static_assert(std::is_nothrow_assignable<Tuple&, Array&>::value, "");
87 static_assert(std::is_nothrow_assignable<Tuple&, const Array&&>::value, "");
88 }
89
90 {
91 typedef std::tuple<NothrowAssignableFrom<int>> Tuple;
92 static_assert(!std::is_assignable<Tuple&, std::array<long, 2>&>::value, "");
93 static_assert(!std::is_assignable<Tuple&, std::array<long, 2>&&>::value, "");
94 static_assert(!std::is_assignable<Tuple&, const std::array<long, 2>&>::value, "");
95 static_assert(!std::is_assignable<Tuple&, const std::array<long, 2>&&>::value, "");
96
97 static_assert(!std::is_assignable<Tuple&, std::array<long, 4>&>::value, "");
98 static_assert(!std::is_assignable<Tuple&, std::array<long, 4>&&>::value, "");
99 static_assert(!std::is_assignable<Tuple&, const std::array<long, 4>&>::value, "");
100 static_assert(!std::is_assignable<Tuple&, const std::array<long, 4>&&>::value, "");
101 }
102
103 return 0;
104 }
105