]>
Commit | Line | Data |
---|---|---|
b32b8144 | 1 | // |
92f5a8d4 | 2 | // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com) |
b32b8144 FG |
3 | // |
4 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
5 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
6 | // | |
7 | // Official repository: https://github.com/boostorg/beast | |
8 | // | |
9 | ||
10 | #ifndef BOOST_BEAST_TEST_TEST_ALLOCATOR_HPP | |
11 | #define BOOST_BEAST_TEST_TEST_ALLOCATOR_HPP | |
12 | ||
13 | #include <atomic> | |
14 | #include <cstddef> | |
92f5a8d4 | 15 | #include <cstdint> |
b32b8144 FG |
16 | #include <memory> |
17 | ||
18 | namespace boost { | |
19 | namespace beast { | |
20 | namespace test { | |
21 | ||
22 | struct test_allocator_info | |
23 | { | |
24 | std::size_t id; | |
25 | std::size_t ncopy = 0; | |
26 | std::size_t nmove = 0; | |
27 | std::size_t nmassign = 0; | |
28 | std::size_t ncpassign = 0; | |
29 | std::size_t nselect = 0; | |
92f5a8d4 TL |
30 | std::size_t max_size = ( |
31 | std::numeric_limits<std::size_t>::max)(); | |
b32b8144 FG |
32 | |
33 | test_allocator_info() | |
34 | : id([] | |
35 | { | |
36 | static std::atomic<std::size_t> sid(0); | |
37 | return ++sid; | |
38 | }()) | |
39 | { | |
40 | } | |
41 | }; | |
42 | ||
92f5a8d4 TL |
43 | template< |
44 | class T, | |
45 | bool Equal, | |
46 | bool Assign, | |
47 | bool Move, | |
48 | bool Swap, | |
49 | bool Select> | |
b32b8144 FG |
50 | class test_allocator; |
51 | ||
92f5a8d4 TL |
52 | template< |
53 | class T, | |
54 | bool Equal, | |
55 | bool Assign, | |
56 | bool Move, | |
57 | bool Swap, | |
58 | bool Select> | |
b32b8144 FG |
59 | struct test_allocator_base |
60 | { | |
61 | }; | |
62 | ||
92f5a8d4 TL |
63 | // Select == true |
64 | template< | |
65 | class T, | |
66 | bool Equal, | |
67 | bool Assign, | |
68 | bool Move, | |
69 | bool Swap> | |
70 | struct test_allocator_base< | |
71 | T, Equal, Assign, Move, Swap, true> | |
b32b8144 FG |
72 | { |
73 | static | |
74 | test_allocator<T, Equal, Assign, Move, Swap, true> | |
75 | select_on_container_copy_construction(test_allocator< | |
92f5a8d4 | 76 | T, Equal, Assign, Move, Swap, true> const&) |
b32b8144 | 77 | { |
92f5a8d4 TL |
78 | return test_allocator<T, |
79 | Equal, Assign, Move, Swap, true>{}; | |
b32b8144 FG |
80 | } |
81 | }; | |
82 | ||
92f5a8d4 TL |
83 | template< |
84 | class T, | |
85 | bool Equal, | |
86 | bool Assign, | |
87 | bool Move, | |
88 | bool Swap, | |
89 | bool Select> | |
90 | class test_allocator | |
91 | : public test_allocator_base< | |
b32b8144 FG |
92 | T, Equal, Assign, Move, Swap, Select> |
93 | { | |
94 | std::shared_ptr<test_allocator_info> info_; | |
95 | ||
96 | template<class, bool, bool, bool, bool, bool> | |
97 | friend class test_allocator; | |
98 | ||
99 | public: | |
100 | using value_type = T; | |
101 | ||
102 | using propagate_on_container_copy_assignment = | |
103 | std::integral_constant<bool, Assign>; | |
104 | ||
105 | using propagate_on_container_move_assignment = | |
106 | std::integral_constant<bool, Move>; | |
107 | ||
108 | using propagate_on_container_swap = | |
109 | std::integral_constant<bool, Swap>; | |
110 | ||
111 | template<class U> | |
112 | struct rebind | |
113 | { | |
114 | using other = test_allocator<U, Equal, Assign, Move, Swap, Select>; | |
115 | }; | |
116 | ||
117 | test_allocator() | |
92f5a8d4 TL |
118 | : info_(std::make_shared< |
119 | test_allocator_info>()) | |
b32b8144 FG |
120 | { |
121 | } | |
122 | ||
123 | test_allocator(test_allocator const& u) noexcept | |
124 | : info_(u.info_) | |
125 | { | |
126 | ++info_->ncopy; | |
127 | } | |
128 | ||
129 | template<class U> | |
130 | test_allocator(test_allocator<U, | |
131 | Equal, Assign, Move, Swap, Select> const& u) noexcept | |
132 | : info_(u.info_) | |
133 | { | |
134 | ++info_->ncopy; | |
135 | } | |
136 | ||
137 | test_allocator(test_allocator&& t) | |
138 | : info_(t.info_) | |
139 | { | |
140 | ++info_->nmove; | |
141 | } | |
142 | ||
143 | test_allocator& | |
144 | operator=(test_allocator const& u) noexcept | |
145 | { | |
146 | info_ = u.info_; | |
147 | ++info_->ncpassign; | |
148 | return *this; | |
149 | } | |
150 | ||
151 | test_allocator& | |
152 | operator=(test_allocator&& u) noexcept | |
153 | { | |
154 | info_ = u.info_; | |
155 | ++info_->nmassign; | |
156 | return *this; | |
157 | } | |
158 | ||
159 | value_type* | |
160 | allocate(std::size_t n) | |
161 | { | |
162 | return static_cast<value_type*>( | |
163 | ::operator new (n*sizeof(value_type))); | |
164 | } | |
165 | ||
166 | void | |
167 | deallocate(value_type* p, std::size_t) noexcept | |
168 | { | |
169 | ::operator delete(p); | |
170 | } | |
171 | ||
92f5a8d4 TL |
172 | std::size_t |
173 | max_size() const | |
174 | { | |
175 | return info_->max_size; | |
176 | } | |
177 | ||
178 | void | |
179 | max_size(std::size_t n) | |
180 | { | |
181 | info_->max_size = n; | |
182 | } | |
183 | ||
b32b8144 FG |
184 | bool |
185 | operator==(test_allocator const& other) const | |
186 | { | |
187 | return id() == other.id() || Equal; | |
188 | } | |
189 | ||
190 | bool | |
191 | operator!=(test_allocator const& other) const | |
192 | { | |
193 | return ! this->operator==(other); | |
194 | } | |
195 | ||
196 | std::size_t | |
197 | id() const | |
198 | { | |
199 | return info_->id; | |
200 | } | |
201 | ||
92f5a8d4 | 202 | test_allocator_info* |
b32b8144 FG |
203 | operator->() const |
204 | { | |
205 | return info_.get(); | |
206 | } | |
207 | }; | |
208 | ||
92f5a8d4 TL |
209 | //------------------------------------------------------------------------------ |
210 | ||
211 | #if 0 | |
212 | struct allocator_info | |
213 | { | |
214 | std::size_t const id; | |
215 | ||
216 | allocator_info() | |
217 | : id([] | |
218 | { | |
219 | static std::atomic<std::size_t> sid(0); | |
220 | return ++sid; | |
221 | }()) | |
222 | { | |
223 | } | |
224 | }; | |
225 | ||
226 | struct allocator_defaults | |
227 | { | |
228 | static std::size_t constexpr max_size = | |
229 | (std::numeric_limits<std::size_t>::max)(); | |
230 | }; | |
231 | ||
232 | template< | |
233 | class T, | |
234 | class Traits = allocator_defaults> | |
235 | struct allocator | |
236 | { | |
237 | public: | |
238 | using value_type = T; | |
239 | ||
240 | #if 0 | |
241 | template<class U> | |
242 | struct rebind | |
243 | { | |
244 | using other = | |
245 | test_allocator<U, Traits>; | |
246 | }; | |
247 | #endif | |
248 | ||
249 | allocator() = default; | |
250 | allocator(allocator&& t) = default; | |
251 | allocator(allocator const& u) = default; | |
252 | ||
253 | template< | |
254 | class U, | |
255 | class = typename std::enable_if< | |
256 | ! std::is_same<U, T>::value>::type> | |
257 | allocator( | |
258 | allocator<U, Traits> const& u) noexcept | |
259 | { | |
260 | } | |
261 | ||
262 | allocator& | |
263 | operator=(allocator&& u) noexcept | |
264 | { | |
265 | return *this; | |
266 | } | |
267 | ||
268 | allocator& | |
269 | operator=(allocator const& u) noexcept | |
270 | { | |
271 | return *this; | |
272 | } | |
273 | ||
274 | value_type* | |
275 | allocate(std::size_t n) | |
276 | { | |
277 | return static_cast<value_type*>( | |
278 | ::operator new(n * sizeof(value_type))); | |
279 | } | |
280 | ||
281 | void | |
282 | deallocate(value_type* p, std::size_t) noexcept | |
283 | { | |
284 | ::operator delete(p); | |
285 | } | |
286 | ||
287 | std::size_t | |
288 | max_size() const | |
289 | { | |
290 | } | |
291 | ||
292 | bool | |
293 | operator==(test_allocator const& other) const | |
294 | { | |
295 | return id() == other.id() || Equal; | |
296 | } | |
297 | ||
298 | bool | |
299 | operator!=(test_allocator const& other) const | |
300 | { | |
301 | return ! this->operator==(other); | |
302 | } | |
303 | }; | |
304 | #endif | |
305 | ||
b32b8144 FG |
306 | } // test |
307 | } // beast | |
308 | } // boost | |
309 | ||
310 | #endif |