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 // 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 "test_macros.h" 26 #include "DefaultOnly.h" 27 #include "allocators.h" 28 #include "../alloc_first.h" 29 #include "../alloc_last.h" 30 31 template <class T = void> 32 struct NonDefaultConstructible { 33 constexpr NonDefaultConstructible() { 34 static_assert(!std::is_same<T, T>::value, "Default Ctor instantiated"); 35 } 36 37 explicit constexpr NonDefaultConstructible(int) {} 38 }; 39 40 41 struct DerivedFromAllocArgT : std::allocator_arg_t {}; 42 43 int main(int, char**) 44 { 45 { 46 std::tuple<> t(std::allocator_arg, 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 the uses-allocator default constructor does not evaluate 99 // its SFINAE when it otherwise shouldn't be selected. Do this by 100 // using 'NonDefaultConstructible' which will cause a compile error 101 // if std::is_default_constructible is evaluated on it. 102 using T = NonDefaultConstructible<>; 103 T v(42); 104 std::tuple<T, T> t(v, v); 105 (void)t; 106 std::tuple<T, T> t2(42, 42); 107 (void)t2; 108 } 109 110 return 0; 111 } 112