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