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// UNSUPPORTED: c++03
10
11// This test ensures that std::tuple is lazy when it comes to checking whether
12// the elements it is assigned from can be used to assign to the types in
13// the tuple.
14
15#include <tuple>
16#include <array>
17
18template <bool Enable, class ...Class>
19constexpr typename std::enable_if<Enable, bool>::type BlowUp() {
20 static_assert(Enable && sizeof...(Class) != sizeof...(Class), "");
21 return true;
22}
23
24template<class T>
25struct Fail {
26 static_assert(sizeof(T) != sizeof(T), "");
27 using type = void;
28};
29
30struct NoAssign {
31 NoAssign() = default;
32 NoAssign(NoAssign const&) = default;
33 template <class T, class = typename std::enable_if<sizeof(T) != sizeof(T)>::type>
34 NoAssign& operator=(T) { return *this; }
35};
36
37template <int>
38struct DieOnAssign {
39 DieOnAssign() = default;
40 template <class T, class X = typename std::enable_if<!std::is_same<T, DieOnAssign>::value>::type,
41 class = typename Fail<X>::type>
42 DieOnAssign& operator=(T) {
43 return *this;
44 }
45};
46
47void test_arity_checks() {
48 {
49 using T = std::tuple<int, DieOnAssign<0>, int>;
50 using P = std::pair<int, int>;
51 static_assert(!std::is_assignable<T&, P const&>::value, "");
52 }
53 {
54 using T = std::tuple<int, int, DieOnAssign<1> >;
55 using A = std::array<int, 1>;
56 static_assert(!std::is_assignable<T&, A const&>::value, "");
57 }
58}
59
60void test_assignability_checks() {
61 {
62 using T1 = std::tuple<int, NoAssign, DieOnAssign<2> >;
63 using T2 = std::tuple<long, long, long>;
64 static_assert(!std::is_assignable<T1&, T2 const&>::value, "");
65 }
66 {
67 using T1 = std::tuple<NoAssign, DieOnAssign<3> >;
68 using T2 = std::pair<long, double>;
69 static_assert(!std::is_assignable<T1&, T2 const&>::value, "");
70 }
71}
72
73int main(int, char**) {
74 test_arity_checks();
75 test_assignability_checks();
76 return 0;
77}
78

source code of libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/laziness.pass.cpp