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