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 18 template <bool Enable, class ...Class> 19 constexpr typename std::enable_if<Enable, bool>::type BlowUp() { 20 static_assert(Enable && sizeof...(Class) != sizeof...(Class), ""); 21 return true; 22 } 23 24 template<class T> 25 struct Fail { 26 static_assert(sizeof(T) != sizeof(T), ""); 27 using type = void; 28 }; 29 30 struct 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 37 template <int> 38 struct 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 47 void 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 60 void 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 73 int main(int, char**) { 74 test_arity_checks(); 75 test_assignability_checks(); 76 return 0; 77 } 78