xref: /llvm-project/libcxx/test/libcxx/utilities/tuple/tuple.tuple/tuple.assign/array.extension.pass.cpp (revision a0839b14df6de99fe29bee7cdfff182d50de665d)
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