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 {
NonDefaultConstructibleNonDefaultConstructible29 constexpr NonDefaultConstructible() {
30 static_assert(!std::is_same<T, T>::value, "Default Ctor instantiated");
31 }
32
NonDefaultConstructibleNonDefaultConstructible33 explicit constexpr NonDefaultConstructible(int) {}
34 };
35
36
37 struct DerivedFromAllocArgT : std::allocator_arg_t {};
38
main(int,char **)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