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++98, c++03 10 11 // <tuple> 12 13 // template <class... Types> class tuple; 14 15 // template <class Alloc> 16 // tuple(allocator_arg_t, const Alloc& a); 17 18 // NOTE: this constructor does not currently support tags derived from 19 // allocator_arg_t because libc++ has to deduce the parameter as a template 20 // argument. See PR27684 (https://bugs.llvm.org/show_bug.cgi?id=27684) 21 22 #include <tuple> 23 #include <cassert> 24 25 #include "DefaultOnly.h" 26 #include "allocators.h" 27 #include "../alloc_first.h" 28 #include "../alloc_last.h" 29 30 template <class T = void> 31 struct NonDefaultConstructible { 32 constexpr NonDefaultConstructible() { 33 static_assert(!std::is_same<T, T>::value, "Default Ctor instantiated"); 34 } 35 36 explicit constexpr NonDefaultConstructible(int) {} 37 }; 38 39 40 struct DerivedFromAllocArgT : std::allocator_arg_t {}; 41 42 int main(int, char**) 43 { 44 { 45 std::tuple<> t(std::allocator_arg, A1<int>()); 46 } 47 { 48 std::tuple<int> t(std::allocator_arg, A1<int>()); 49 assert(std::get<0>(t) == 0); 50 } 51 { 52 std::tuple<DefaultOnly> t(std::allocator_arg, A1<int>()); 53 assert(std::get<0>(t) == DefaultOnly()); 54 } 55 { 56 assert(!alloc_first::allocator_constructed); 57 std::tuple<alloc_first> t(std::allocator_arg, A1<int>(5)); 58 assert(alloc_first::allocator_constructed); 59 assert(std::get<0>(t) == alloc_first()); 60 } 61 { 62 assert(!alloc_last::allocator_constructed); 63 std::tuple<alloc_last> t(std::allocator_arg, A1<int>(5)); 64 assert(alloc_last::allocator_constructed); 65 assert(std::get<0>(t) == alloc_last()); 66 } 67 { 68 alloc_first::allocator_constructed = false; 69 std::tuple<DefaultOnly, alloc_first> t(std::allocator_arg, A1<int>(5)); 70 assert(std::get<0>(t) == DefaultOnly()); 71 assert(alloc_first::allocator_constructed); 72 assert(std::get<1>(t) == alloc_first()); 73 } 74 { 75 alloc_first::allocator_constructed = false; 76 alloc_last::allocator_constructed = false; 77 std::tuple<DefaultOnly, alloc_first, alloc_last> t(std::allocator_arg, 78 A1<int>(5)); 79 assert(std::get<0>(t) == DefaultOnly()); 80 assert(alloc_first::allocator_constructed); 81 assert(std::get<1>(t) == alloc_first()); 82 assert(alloc_last::allocator_constructed); 83 assert(std::get<2>(t) == alloc_last()); 84 } 85 { 86 alloc_first::allocator_constructed = false; 87 alloc_last::allocator_constructed = false; 88 std::tuple<DefaultOnly, alloc_first, alloc_last> t(std::allocator_arg, 89 A2<int>(5)); 90 assert(std::get<0>(t) == DefaultOnly()); 91 assert(!alloc_first::allocator_constructed); 92 assert(std::get<1>(t) == alloc_first()); 93 assert(!alloc_last::allocator_constructed); 94 assert(std::get<2>(t) == alloc_last()); 95 } 96 { 97 // Test that the uses-allocator default constructor does not evaluate 98 // its SFINAE when it otherwise shouldn't be selected. Do this by 99 // using 'NonDefaultConstructible' which will cause a compile error 100 // if std::is_default_constructible is evaluated on it. 101 using T = NonDefaultConstructible<>; 102 T v(42); 103 std::tuple<T, T> t(v, v); 104 (void)t; 105 std::tuple<T, T> t2(42, 42); 106 (void)t2; 107 } 108 109 return 0; 110 } 111