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
27template <class T = void>
28struct 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
37struct DerivedFromAllocArgT : std::allocator_arg_t {};
38
39int 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

source code of libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc.pass.cpp