1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // <tuple> 11 12 // template <class... Types> class tuple; 13 14 // template <class Alloc> 15 // tuple(allocator_arg_t, const Alloc& a); 16 17 // UNSUPPORTED: c++98, c++03 18 19 #include <tuple> 20 #include <cassert> 21 22 #include "DefaultOnly.h" 23 #include "allocators.h" 24 #include "../alloc_first.h" 25 #include "../alloc_last.h" 26 27 template <class T = void> 28 struct NonDefaultConstructible { 29 constexpr NonDefaultConstructible() { 30 static_assert(!std::is_same<T, T>::value, "Default Ctor instantiated"); 31 } 32 33 explicit constexpr NonDefaultConstructible(int) {} 34 }; 35 36 37 struct DerivedFromAllocArgT : std::allocator_arg_t {}; 38 39 int main() 40 { 41 { 42 std::tuple<> t(std::allocator_arg, A1<int>()); 43 } 44 { 45 DerivedFromAllocArgT tag; 46 std::tuple<> t(tag, A1<int>()); 47 } 48 { 49 std::tuple<int> t(std::allocator_arg, A1<int>()); 50 assert(std::get<0>(t) == 0); 51 } 52 { 53 std::tuple<DefaultOnly> t(std::allocator_arg, A1<int>()); 54 assert(std::get<0>(t) == DefaultOnly()); 55 } 56 { 57 assert(!alloc_first::allocator_constructed); 58 std::tuple<alloc_first> t(std::allocator_arg, A1<int>(5)); 59 assert(alloc_first::allocator_constructed); 60 assert(std::get<0>(t) == alloc_first()); 61 } 62 { 63 assert(!alloc_last::allocator_constructed); 64 std::tuple<alloc_last> t(std::allocator_arg, A1<int>(5)); 65 assert(alloc_last::allocator_constructed); 66 assert(std::get<0>(t) == alloc_last()); 67 } 68 { 69 alloc_first::allocator_constructed = false; 70 std::tuple<DefaultOnly, alloc_first> t(std::allocator_arg, A1<int>(5)); 71 assert(std::get<0>(t) == DefaultOnly()); 72 assert(alloc_first::allocator_constructed); 73 assert(std::get<1>(t) == alloc_first()); 74 } 75 { 76 alloc_first::allocator_constructed = false; 77 alloc_last::allocator_constructed = false; 78 std::tuple<DefaultOnly, alloc_first, alloc_last> t(std::allocator_arg, 79 A1<int>(5)); 80 assert(std::get<0>(t) == DefaultOnly()); 81 assert(alloc_first::allocator_constructed); 82 assert(std::get<1>(t) == alloc_first()); 83 assert(alloc_last::allocator_constructed); 84 assert(std::get<2>(t) == alloc_last()); 85 } 86 { 87 alloc_first::allocator_constructed = false; 88 alloc_last::allocator_constructed = false; 89 std::tuple<DefaultOnly, alloc_first, alloc_last> t(std::allocator_arg, 90 A2<int>(5)); 91 assert(std::get<0>(t) == DefaultOnly()); 92 assert(!alloc_first::allocator_constructed); 93 assert(std::get<1>(t) == alloc_first()); 94 assert(!alloc_last::allocator_constructed); 95 assert(std::get<2>(t) == alloc_last()); 96 } 97 { 98 // Test that allocator construction is selected when the user provides 99 // a custom tag type which derives from allocator_arg_t. 100 DerivedFromAllocArgT tag; 101 alloc_first::allocator_constructed = false; 102 alloc_last::allocator_constructed = false; 103 104 std::tuple<DefaultOnly, alloc_first, alloc_last> t(tag, A1<int>(5)); 105 106 assert(std::get<0>(t) == DefaultOnly()); 107 assert(alloc_first::allocator_constructed); 108 assert(std::get<1>(t) == alloc_first()); 109 assert(alloc_last::allocator_constructed); 110 assert(std::get<2>(t) == alloc_last()); 111 } 112 { 113 // Test that the uses-allocator default constructor does not evaluate 114 // it's SFINAE when it otherwise shouldn't be selected. Do this by 115 // using 'NonDefaultConstructible' which will cause a compile error 116 // if std::is_default_constructible is evaluated on it. 117 using T = NonDefaultConstructible<>; 118 T v(42); 119 std::tuple<T, T> t(v, v); 120 std::tuple<T, T> t2(42, 42); 121 } 122 } 123