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 // <memory>
10
11 // template <class Alloc>
12 // struct allocator_traits
13 // {
14 // template <class Ptr, class... Args>
15 // static constexpr void construct(allocator_type& a, Ptr p, Args&&... args);
16 // ...
17 // };
18
19 #include <memory>
20 #include <new>
21 #include <type_traits>
22 #include <cassert>
23 #include <utility>
24
25 #include "test_macros.h"
26 #include "incomplete_type_helper.h"
27
28 template <class T>
29 struct A
30 {
31 typedef T value_type;
32
33 };
34
35 template <class T>
36 struct B
37 {
38 typedef T value_type;
39
BB40 TEST_CONSTEXPR_CXX20 B(int& count) : count_(count) {}
41
42 #if TEST_STD_VER >= 11
43 template <class U, class ...Args>
constructB44 TEST_CONSTEXPR_CXX20 void construct(U* p, Args&& ...args)
45 {
46 ++count_;
47 #if TEST_STD_VER > 17
48 std::construct_at(p, std::forward<Args>(args)...);
49 #else
50 ::new ((void*)p) U(std::forward<Args>(args)...);
51 #endif
52 }
53 #endif
54
55 int& count_;
56 };
57
58 struct A0
59 {
A0A060 TEST_CONSTEXPR_CXX20 A0(int* count) {++*count;}
61 };
62
63 struct A1
64 {
A1A165 TEST_CONSTEXPR_CXX20 A1(int* count, char c)
66 {
67 assert(c == 'c');
68 ++*count;
69 }
70 };
71
72 struct A2
73 {
A2A274 TEST_CONSTEXPR_CXX20 A2(int* count, char c, int i)
75 {
76 assert(c == 'd');
77 assert(i == 5);
78 ++*count;
79 }
80 };
81
test()82 TEST_CONSTEXPR_CXX20 bool test()
83 {
84 {
85 int A0_count = 0;
86 A<A0> a;
87 std::allocator<A0> alloc;
88 A0* a0 = alloc.allocate(1);
89 assert(A0_count == 0);
90 std::allocator_traits<A<A0> >::construct(a, a0, &A0_count);
91 assert(A0_count == 1);
92 alloc.deallocate(a0, 1);
93 }
94 {
95 int A1_count = 0;
96 A<A1> a;
97 std::allocator<A1> alloc;
98 A1* a1 = alloc.allocate(1);
99 assert(A1_count == 0);
100 std::allocator_traits<A<A1> >::construct(a, a1, &A1_count, 'c');
101 assert(A1_count == 1);
102 alloc.deallocate(a1, 1);
103 }
104 {
105 int A2_count = 0;
106 A<A2> a;
107 std::allocator<A2> alloc;
108 A2* a2 = alloc.allocate(1);
109 assert(A2_count == 0);
110 std::allocator_traits<A<A2> >::construct(a, a2, &A2_count, 'd', 5);
111 assert(A2_count == 1);
112 alloc.deallocate(a2, 1);
113 }
114 {
115 typedef IncompleteHolder* VT;
116 typedef A<VT> Alloc;
117 Alloc a;
118 std::allocator<VT> alloc;
119 VT* vt = alloc.allocate(1);
120 std::allocator_traits<Alloc>::construct(a, vt, nullptr);
121 alloc.deallocate(vt, 1);
122 }
123
124 #if TEST_STD_VER >= 11
125 {
126 int A0_count = 0;
127 int b_construct = 0;
128 B<A0> b(b_construct);
129 std::allocator<A0> alloc;
130 A0* a0 = alloc.allocate(1);
131 assert(A0_count == 0);
132 assert(b_construct == 0);
133 std::allocator_traits<B<A0> >::construct(b, a0, &A0_count);
134 assert(A0_count == 1);
135 assert(b_construct == 1);
136 alloc.deallocate(a0, 1);
137 }
138 {
139 int A1_count = 0;
140 int b_construct = 0;
141 B<A1> b(b_construct);
142 std::allocator<A1> alloc;
143 A1* a1 = alloc.allocate(1);
144 assert(A1_count == 0);
145 assert(b_construct == 0);
146 std::allocator_traits<B<A1> >::construct(b, a1, &A1_count, 'c');
147 assert(A1_count == 1);
148 assert(b_construct == 1);
149 alloc.deallocate(a1, 1);
150 }
151 {
152 int A2_count = 0;
153 int b_construct = 0;
154 B<A2> b(b_construct);
155 std::allocator<A2> alloc;
156 A2* a2 = alloc.allocate(1);
157 assert(A2_count == 0);
158 assert(b_construct == 0);
159 std::allocator_traits<B<A2> >::construct(b, a2, &A2_count, 'd', 5);
160 assert(A2_count == 1);
161 assert(b_construct == 1);
162 alloc.deallocate(a2, 1);
163 }
164 #endif
165
166 return true;
167 }
168
main(int,char **)169 int main(int, char**)
170 {
171 test();
172
173 #if TEST_STD_VER > 17
174 static_assert(test());
175 #endif
176
177 return 0;
178 }
179