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