]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/experimental/type_erased_allocator/2.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / experimental / type_erased_allocator / 2.cc
1 // { dg-do run { target c++14 } }
2 // { dg-require-thread-fence "" }
3
4 // Copyright (C) 2015-2017 Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library. This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 3, or (at your option)
10 // any later version.
11
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING3. If not see
19 // <http://www.gnu.org/licenses/>.
20
21 #include <experimental/memory_resource>
22 #include <experimental/utility>
23 #include <memory>
24 #include <testsuite_hooks.h>
25 #include <testsuite_allocator.h>
26
27 using std::experimental::pmr::polymorphic_allocator;
28 using std::experimental::pmr::memory_resource;
29 using std::experimental::pmr::new_delete_resource;
30 using std::experimental::pmr::get_default_resource;
31 using std::allocator_arg_t;
32
33 enum CtorType { Default, Copy, Move, Other, Tuple, Piecewise_Default, Piecewise_Copy};
34
35 // type that takes a memory_resource before other ctor args
36 struct A
37 {
38 using allocator_type = std::experimental::erased_type;
39
40 CtorType type;
41 memory_resource* alloc = nullptr;
42
43 A() : type(Default) { }
44 A(allocator_arg_t, memory_resource* a) : type(Default), alloc(a) { }
45 A(const A&) : type(Copy) { }
46 A(allocator_arg_t, memory_resource* a, const A&) : type(Copy), alloc(a) { }
47 A(A&&) : type (Move) { }
48 A(allocator_arg_t, memory_resource* a, A&&) : type (Move), alloc(a) { }
49 A(int) : type(Other) { }
50 A(allocator_arg_t, memory_resource* a, int) : type(Other), alloc(a) { }
51 };
52
53 // type that takes a memory_resource after other ctor args
54 struct B
55 {
56 using allocator_type = std::experimental::erased_type;
57
58 CtorType type;
59 memory_resource* alloc = nullptr;
60
61 B() : type(Default) { }
62 B(memory_resource* a) : type(Default), alloc(a) { }
63 B(const B&) : type(Copy) { }
64 B(const B&, memory_resource* a) : type(Copy), alloc(a) { }
65 B(B&&) : type (Move) { }
66 B(B&&, memory_resource* a) : type(Move), alloc(a) { }
67 B(int) : type(Other) { }
68 B(int, memory_resource* a) : type(Other), alloc(a) { }
69 };
70
71 // type that takes no memory_resource
72 struct C
73 {
74 CtorType type;
75 C() : type(Default) { }
76 C(const C&) : type(Copy) { }
77 C(C&&) : type(Move) { }
78 C(int) : type(Other) { }
79 };
80
81 // test construct for type that
82 // uses memory_resource* as allocator
83 template<typename A>
84 void test_uses_alloc() {
85 polymorphic_allocator<A> pa;
86 A* p = pa.allocate(1);
87 A a;
88
89 pa.construct(p);
90 VERIFY(p->alloc == get_default_resource());
91 VERIFY(p->type == Default);
92 pa.destroy(p);
93
94 pa.construct(p, a);
95 VERIFY(p->type == Copy);
96 pa.destroy(p);
97
98 pa.construct(p, A());
99 VERIFY(p->type == Move);
100 pa.destroy(p);
101
102 pa.construct(p, 1);
103 VERIFY(p->type == Other);
104 pa.destroy(p);
105
106 pa.deallocate(p, 1);
107 }
108
109 // test construct for type that not using allocator
110 template <typename C>
111 void test_non_alloc() {
112 polymorphic_allocator<C> pa;
113 C* p = pa.allocate(1);
114 C b;
115
116 pa.construct(p);
117 VERIFY(p->type == Default);
118 pa.destroy(p);
119
120 pa.construct(p, b);
121 VERIFY(p->type == Copy);
122 pa.destroy(p);
123
124 pa.construct(p, C());
125 VERIFY(p->type == Move);
126 pa.destroy(p);
127
128 pa.construct(p, 1);
129 VERIFY(p->type == Other);
130 pa.destroy(p);
131
132 pa.deallocate(p, 1);
133 }
134
135 // test piecewise_construct
136 template <typename A, typename B>
137 void test_pair() {
138 polymorphic_allocator<std::pair<A, B>> pa;
139 std::pair<A, B>* p = pa.allocate(1);
140 std::tuple<> t;
141
142 // construct(pair<T1, T2>* p, piecewise_construct_t, tuple<...>, tuple<...>)
143 pa.construct(p, std::piecewise_construct, t, t);
144 VERIFY(p->first.type == Default);
145 VERIFY(p->second.type == Default);
146 pa.destroy(p);
147
148 // construct(pair<T1, T2>* __p)
149 pa.construct(p);
150 VERIFY(p->first.type == Default);
151 VERIFY(p->second.type == Default);
152 pa.destroy(p);
153
154 // construct(pair<T1, T2>* p, U&& x, V&& y)
155 A a; B b;
156 pa.construct(p, a, b);
157 VERIFY(p->first.type == Copy);
158 VERIFY(p->second.type == Copy);
159 pa.destroy(p);
160
161 pa.construct(p, A(), B());
162 VERIFY(p->first.type == Move);
163 VERIFY(p->second.type == Move);
164 auto pp = *p;
165 pa.destroy(p);
166
167 // construct(pair<T1, T2>* p, const pair<U, V>& x)
168 pa.construct(p, pp);
169 VERIFY(p->first.type == Copy);
170 VERIFY(p->second.type == Copy);
171 pa.destroy(p);
172
173 // construct(pair<T1, T2>* p, pair<U, V>&& x)
174 pa.construct(p, std::move(pp));
175 VERIFY(p->first.type == Move);
176 VERIFY(p->second.type == Move);
177 pa.destroy(p);
178 pa.deallocate(p, 1);
179 }
180
181 void test01() {
182 test_uses_alloc<A>();
183 test_uses_alloc<B>();
184 test_non_alloc<C>();
185 }
186
187 void test02() {
188 test_pair<A, A>();
189 test_pair<A, B>();
190 test_pair<A, C>();
191 test_pair<B, B>();
192 test_pair<B, A>();
193 test_pair<B, C>();
194 test_pair<C, C>();
195 }
196
197
198 int main() {
199 test01();
200 test02();
201 }