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 // <tuple> 12 13 // template <class... Types> class tuple; 14 15 // template <class Alloc> 16 // explicit(see-below) tuple(allocator_arg_t, const Alloc& a); 17 18 #include <tuple> 19 #include <cassert> 20 21 #include "test_macros.h" 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(int, char**) 40 { 41 { 42 std::tuple<> t(std::allocator_arg, A1<int>()); 43 } 44 { 45 std::tuple<int> t(std::allocator_arg, A1<int>()); 46 assert(std::get<0>(t) == 0); 47 } 48 { 49 std::tuple<DefaultOnly> t(std::allocator_arg, A1<int>()); 50 assert(std::get<0>(t) == DefaultOnly()); 51 } 52 { 53 assert(!alloc_first::allocator_constructed); 54 std::tuple<alloc_first> t(std::allocator_arg, A1<int>(5)); 55 assert(alloc_first::allocator_constructed); 56 assert(std::get<0>(t) == alloc_first()); 57 } 58 { 59 assert(!alloc_last::allocator_constructed); 60 std::tuple<alloc_last> t(std::allocator_arg, A1<int>(5)); 61 assert(alloc_last::allocator_constructed); 62 assert(std::get<0>(t) == alloc_last()); 63 } 64 { 65 alloc_first::allocator_constructed = false; 66 std::tuple<DefaultOnly, alloc_first> t(std::allocator_arg, A1<int>(5)); 67 assert(std::get<0>(t) == DefaultOnly()); 68 assert(alloc_first::allocator_constructed); 69 assert(std::get<1>(t) == alloc_first()); 70 } 71 { 72 alloc_first::allocator_constructed = false; 73 alloc_last::allocator_constructed = false; 74 std::tuple<DefaultOnly, alloc_first, alloc_last> t(std::allocator_arg, 75 A1<int>(5)); 76 assert(std::get<0>(t) == DefaultOnly()); 77 assert(alloc_first::allocator_constructed); 78 assert(std::get<1>(t) == alloc_first()); 79 assert(alloc_last::allocator_constructed); 80 assert(std::get<2>(t) == alloc_last()); 81 } 82 { 83 alloc_first::allocator_constructed = false; 84 alloc_last::allocator_constructed = false; 85 std::tuple<DefaultOnly, alloc_first, alloc_last> t(std::allocator_arg, 86 A2<int>(5)); 87 assert(std::get<0>(t) == DefaultOnly()); 88 assert(!alloc_first::allocator_constructed); 89 assert(std::get<1>(t) == alloc_first()); 90 assert(!alloc_last::allocator_constructed); 91 assert(std::get<2>(t) == alloc_last()); 92 } 93 { 94 // Test that we can use a tag derived from allocator_arg_t 95 struct DerivedFromAllocatorArgT : std::allocator_arg_t { }; 96 DerivedFromAllocatorArgT derived; 97 std::tuple<> t1(derived, A1<int>()); 98 std::tuple<int> t2(derived, A1<int>()); 99 std::tuple<int, int> t3(derived, A1<int>()); 100 } 101 { 102 // Test that the uses-allocator default constructor does not evaluate 103 // its SFINAE when it otherwise shouldn't be selected. Do this by 104 // using 'NonDefaultConstructible' which will cause a compile error 105 // if std::is_default_constructible is evaluated on it. 106 using T = NonDefaultConstructible<>; 107 T v(42); 108 std::tuple<T, T> t(v, v); 109 (void)t; 110 std::tuple<T, T> t2(42, 42); 111 (void)t2; 112 } 113 114 return 0; 115 } 116