]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | |
2 | // Copyright 2006-2009 Daniel James. | |
3 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
4 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
5 | ||
6 | #if !defined(BOOST_UNORDERED_EXCEPTION_TEST_OBJECTS_HEADER) | |
7 | #define BOOST_UNORDERED_EXCEPTION_TEST_OBJECTS_HEADER | |
8 | ||
9 | #include "../helpers/exception_test.hpp" | |
10 | ||
b32b8144 | 11 | #include "../helpers/count.hpp" |
7c673cae | 12 | #include "../helpers/fwd.hpp" |
b32b8144 | 13 | #include "../helpers/generators.hpp" |
7c673cae | 14 | #include "../helpers/memory.hpp" |
b32b8144 FG |
15 | #include "./fwd.hpp" |
16 | #include <boost/limits.hpp> | |
17 | #include <cstddef> | |
18 | #include <new> | |
7c673cae | 19 | |
b32b8144 FG |
20 | namespace test { |
21 | namespace exception { | |
7c673cae FG |
22 | class object; |
23 | class hash; | |
24 | class equal_to; | |
25 | template <class T> class allocator; | |
26 | object generate(object const*, random_generator); | |
b32b8144 FG |
27 | std::pair<object, object> generate( |
28 | std::pair<object, object> const*, random_generator); | |
7c673cae FG |
29 | |
30 | struct true_type | |
31 | { | |
b32b8144 FG |
32 | enum |
33 | { | |
34 | value = true | |
35 | }; | |
7c673cae FG |
36 | }; |
37 | ||
38 | struct false_type | |
39 | { | |
b32b8144 FG |
40 | enum |
41 | { | |
42 | value = false | |
43 | }; | |
7c673cae FG |
44 | }; |
45 | ||
b32b8144 | 46 | class object : private counted_object |
7c673cae FG |
47 | { |
48 | public: | |
b32b8144 | 49 | int tag1_, tag2_; |
7c673cae | 50 | |
b32b8144 FG |
51 | explicit object() : tag1_(0), tag2_(0) |
52 | { | |
53 | UNORDERED_SCOPE(object::object()) | |
7c673cae | 54 | { |
b32b8144 | 55 | UNORDERED_EPOINT("Mock object default constructor."); |
7c673cae | 56 | } |
b32b8144 | 57 | } |
7c673cae | 58 | |
b32b8144 FG |
59 | explicit object(int t1, int t2 = 0) : tag1_(t1), tag2_(t2) |
60 | { | |
61 | UNORDERED_SCOPE(object::object(int)) | |
7c673cae | 62 | { |
b32b8144 | 63 | UNORDERED_EPOINT("Mock object constructor by value."); |
7c673cae | 64 | } |
b32b8144 | 65 | } |
7c673cae | 66 | |
b32b8144 FG |
67 | object(object const& x) |
68 | : counted_object(x), tag1_(x.tag1_), tag2_(x.tag2_) | |
69 | { | |
70 | UNORDERED_SCOPE(object::object(object)) | |
7c673cae | 71 | { |
b32b8144 | 72 | UNORDERED_EPOINT("Mock object copy constructor."); |
7c673cae | 73 | } |
b32b8144 | 74 | } |
7c673cae | 75 | |
b32b8144 FG |
76 | ~object() |
77 | { | |
78 | tag1_ = -1; | |
79 | tag2_ = -1; | |
80 | } | |
7c673cae | 81 | |
b32b8144 FG |
82 | object& operator=(object const& x) |
83 | { | |
84 | UNORDERED_SCOPE(object::operator=(object)) | |
7c673cae | 85 | { |
b32b8144 FG |
86 | tag1_ = x.tag1_; |
87 | UNORDERED_EPOINT("Mock object assign operator 1."); | |
88 | tag2_ = x.tag2_; | |
89 | // UNORDERED_EPOINT("Mock object assign operator 2."); | |
7c673cae | 90 | } |
b32b8144 FG |
91 | return *this; |
92 | } | |
7c673cae | 93 | |
b32b8144 FG |
94 | friend bool operator==(object const& x1, object const& x2) |
95 | { | |
96 | UNORDERED_SCOPE(operator==(object, object)) | |
97 | { | |
98 | UNORDERED_EPOINT("Mock object equality operator."); | |
7c673cae FG |
99 | } |
100 | ||
b32b8144 FG |
101 | return x1.tag1_ == x2.tag1_ && x1.tag2_ == x2.tag2_; |
102 | } | |
7c673cae | 103 | |
b32b8144 FG |
104 | friend bool operator!=(object const& x1, object const& x2) |
105 | { | |
106 | UNORDERED_SCOPE(operator!=(object, object)) | |
7c673cae | 107 | { |
b32b8144 FG |
108 | UNORDERED_EPOINT("Mock object inequality operator."); |
109 | } | |
110 | ||
111 | return !(x1.tag1_ == x2.tag1_ && x1.tag2_ == x2.tag2_); | |
112 | } | |
113 | ||
114 | // None of the last few functions are used by the unordered associative | |
115 | // containers - so there aren't any exception points. | |
116 | friend bool operator<(object const& x1, object const& x2) | |
117 | { | |
118 | return x1.tag1_ < x2.tag1_ || | |
119 | (x1.tag1_ == x2.tag1_ && x1.tag2_ < x2.tag2_); | |
120 | } | |
121 | ||
122 | friend object generate(object const*, random_generator g) | |
123 | { | |
124 | int* x = 0; | |
125 | return object(::test::generate(x, g), ::test::generate(x, g)); | |
126 | } | |
127 | ||
128 | friend std::ostream& operator<<(std::ostream& out, object const& o) | |
129 | { | |
130 | return out << "(" << o.tag1_ << "," << o.tag2_ << ")"; | |
131 | } | |
7c673cae FG |
132 | }; |
133 | ||
b32b8144 FG |
134 | std::pair<object, object> generate( |
135 | std::pair<object, object> const*, random_generator g) | |
136 | { | |
137 | int* x = 0; | |
138 | return std::make_pair( | |
139 | object(::test::generate(x, g), ::test::generate(x, g)), | |
140 | object(::test::generate(x, g), ::test::generate(x, g))); | |
141 | } | |
142 | ||
7c673cae FG |
143 | class hash |
144 | { | |
b32b8144 FG |
145 | int tag_; |
146 | ||
7c673cae | 147 | public: |
b32b8144 FG |
148 | hash(int t = 0) : tag_(t) |
149 | { | |
150 | UNORDERED_SCOPE(hash::object()) | |
7c673cae | 151 | { |
b32b8144 | 152 | UNORDERED_EPOINT("Mock hash default constructor."); |
7c673cae | 153 | } |
b32b8144 | 154 | } |
7c673cae | 155 | |
b32b8144 FG |
156 | hash(hash const& x) : tag_(x.tag_) |
157 | { | |
158 | UNORDERED_SCOPE(hash::hash(hash)) | |
7c673cae | 159 | { |
b32b8144 | 160 | UNORDERED_EPOINT("Mock hash copy constructor."); |
7c673cae | 161 | } |
b32b8144 | 162 | } |
7c673cae | 163 | |
b32b8144 FG |
164 | hash& operator=(hash const& x) |
165 | { | |
166 | UNORDERED_SCOPE(hash::operator=(hash)) | |
7c673cae | 167 | { |
b32b8144 FG |
168 | UNORDERED_EPOINT("Mock hash assign operator 1."); |
169 | tag_ = x.tag_; | |
170 | UNORDERED_EPOINT("Mock hash assign operator 2."); | |
7c673cae | 171 | } |
b32b8144 FG |
172 | return *this; |
173 | } | |
7c673cae | 174 | |
b32b8144 FG |
175 | std::size_t operator()(object const& x) const |
176 | { | |
177 | UNORDERED_SCOPE(hash::operator()(object)) | |
178 | { | |
179 | UNORDERED_EPOINT("Mock hash function."); | |
7c673cae FG |
180 | } |
181 | ||
b32b8144 FG |
182 | return hash_impl(x); |
183 | } | |
184 | ||
185 | std::size_t operator()(std::pair<object, object> const& x) const | |
186 | { | |
187 | UNORDERED_SCOPE(hash::operator()(std::pair<object, object>)) | |
188 | { | |
189 | UNORDERED_EPOINT("Mock hash pair function."); | |
190 | } | |
191 | ||
192 | return hash_impl(x.first) * 193ul + hash_impl(x.second) * 97ul + 29ul; | |
193 | } | |
194 | ||
195 | std::size_t hash_impl(object const& x) const | |
196 | { | |
197 | int result; | |
198 | switch (tag_) { | |
199 | case 1: | |
200 | result = x.tag1_; | |
201 | break; | |
202 | case 2: | |
203 | result = x.tag2_; | |
204 | break; | |
205 | default: | |
206 | result = x.tag1_ + x.tag2_; | |
207 | } | |
208 | return static_cast<std::size_t>(result); | |
209 | } | |
210 | ||
211 | friend bool operator==(hash const& x1, hash const& x2) | |
212 | { | |
213 | UNORDERED_SCOPE(operator==(hash, hash)) | |
214 | { | |
215 | UNORDERED_EPOINT("Mock hash equality function."); | |
7c673cae | 216 | } |
b32b8144 FG |
217 | return x1.tag_ == x2.tag_; |
218 | } | |
7c673cae | 219 | |
b32b8144 FG |
220 | friend bool operator!=(hash const& x1, hash const& x2) |
221 | { | |
222 | UNORDERED_SCOPE(hash::operator!=(hash, hash)) | |
223 | { | |
224 | UNORDERED_EPOINT("Mock hash inequality function."); | |
7c673cae | 225 | } |
b32b8144 FG |
226 | return x1.tag_ != x2.tag_; |
227 | } | |
228 | }; | |
229 | ||
230 | class less | |
231 | { | |
232 | int tag_; | |
233 | ||
234 | public: | |
235 | less(int t = 0) : tag_(t) {} | |
236 | ||
237 | less(less const& x) : tag_(x.tag_) {} | |
238 | ||
239 | bool operator()(object const& x1, object const& x2) const | |
240 | { | |
241 | return less_impl(x1, x2); | |
242 | } | |
243 | ||
244 | bool operator()(std::pair<object, object> const& x1, | |
245 | std::pair<object, object> const& x2) const | |
246 | { | |
247 | if (less_impl(x1.first, x2.first)) { | |
248 | return true; | |
249 | } | |
250 | if (!less_impl(x1.first, x2.first)) { | |
251 | return false; | |
252 | } | |
253 | return less_impl(x1.second, x2.second); | |
254 | } | |
255 | ||
256 | bool less_impl(object const& x1, object const& x2) const | |
257 | { | |
258 | switch (tag_) { | |
259 | case 1: | |
260 | return x1.tag1_ < x2.tag1_; | |
261 | case 2: | |
262 | return x1.tag2_ < x2.tag2_; | |
263 | default: | |
264 | return x1 < x2; | |
265 | } | |
266 | } | |
267 | ||
268 | friend bool operator==(less const& x1, less const& x2) | |
269 | { | |
270 | return x1.tag_ == x2.tag_; | |
271 | } | |
272 | ||
273 | friend bool operator!=(less const& x1, less const& x2) | |
274 | { | |
275 | return x1.tag_ != x2.tag_; | |
276 | } | |
7c673cae FG |
277 | }; |
278 | ||
279 | class equal_to | |
280 | { | |
b32b8144 FG |
281 | int tag_; |
282 | ||
7c673cae | 283 | public: |
b32b8144 FG |
284 | equal_to(int t = 0) : tag_(t) |
285 | { | |
286 | UNORDERED_SCOPE(equal_to::equal_to()) | |
7c673cae | 287 | { |
b32b8144 | 288 | UNORDERED_EPOINT("Mock equal_to default constructor."); |
7c673cae | 289 | } |
b32b8144 | 290 | } |
7c673cae | 291 | |
b32b8144 FG |
292 | equal_to(equal_to const& x) : tag_(x.tag_) |
293 | { | |
294 | UNORDERED_SCOPE(equal_to::equal_to(equal_to)) | |
7c673cae | 295 | { |
b32b8144 | 296 | UNORDERED_EPOINT("Mock equal_to copy constructor."); |
7c673cae | 297 | } |
b32b8144 | 298 | } |
7c673cae | 299 | |
b32b8144 FG |
300 | equal_to& operator=(equal_to const& x) |
301 | { | |
302 | UNORDERED_SCOPE(equal_to::operator=(equal_to)) | |
7c673cae | 303 | { |
b32b8144 FG |
304 | UNORDERED_EPOINT("Mock equal_to assign operator 1."); |
305 | tag_ = x.tag_; | |
306 | UNORDERED_EPOINT("Mock equal_to assign operator 2."); | |
7c673cae | 307 | } |
b32b8144 FG |
308 | return *this; |
309 | } | |
7c673cae | 310 | |
b32b8144 FG |
311 | bool operator()(object const& x1, object const& x2) const |
312 | { | |
313 | UNORDERED_SCOPE(equal_to::operator()(object, object)) | |
314 | { | |
315 | UNORDERED_EPOINT("Mock equal_to function."); | |
7c673cae FG |
316 | } |
317 | ||
b32b8144 FG |
318 | return equal_impl(x1, x2); |
319 | } | |
7c673cae | 320 | |
b32b8144 FG |
321 | bool operator()(std::pair<object, object> const& x1, |
322 | std::pair<object, object> const& x2) const | |
323 | { | |
324 | UNORDERED_SCOPE(equal_to::operator()( | |
325 | std::pair<object, object>, std::pair<object, object>)) | |
326 | { | |
327 | UNORDERED_EPOINT("Mock equal_to function."); | |
7c673cae | 328 | } |
7c673cae | 329 | |
b32b8144 FG |
330 | return equal_impl(x1.first, x2.first) && |
331 | equal_impl(x1.second, x2.second); | |
332 | } | |
7c673cae | 333 | |
b32b8144 FG |
334 | bool equal_impl(object const& x1, object const& x2) const |
335 | { | |
336 | switch (tag_) { | |
337 | case 1: | |
338 | return x1.tag1_ == x2.tag1_; | |
339 | case 2: | |
340 | return x1.tag2_ == x2.tag2_; | |
341 | default: | |
342 | return x1 == x2; | |
343 | } | |
344 | } | |
7c673cae | 345 | |
b32b8144 FG |
346 | friend bool operator==(equal_to const& x1, equal_to const& x2) |
347 | { | |
348 | UNORDERED_SCOPE(operator==(equal_to, equal_to)) | |
7c673cae | 349 | { |
b32b8144 | 350 | UNORDERED_EPOINT("Mock equal_to equality function."); |
7c673cae | 351 | } |
b32b8144 FG |
352 | return x1.tag_ == x2.tag_; |
353 | } | |
7c673cae | 354 | |
b32b8144 FG |
355 | friend bool operator!=(equal_to const& x1, equal_to const& x2) |
356 | { | |
357 | UNORDERED_SCOPE(operator!=(equal_to, equal_to)) | |
7c673cae | 358 | { |
b32b8144 | 359 | UNORDERED_EPOINT("Mock equal_to inequality function."); |
7c673cae | 360 | } |
b32b8144 FG |
361 | return x1.tag_ != x2.tag_; |
362 | } | |
363 | ||
364 | friend less create_compare(equal_to x) { return less(x.tag_); } | |
365 | }; | |
7c673cae | 366 | |
b32b8144 FG |
367 | template <class T> class allocator |
368 | { | |
369 | public: | |
370 | int tag_; | |
371 | typedef std::size_t size_type; | |
372 | typedef std::ptrdiff_t difference_type; | |
373 | typedef T* pointer; | |
374 | typedef T const* const_pointer; | |
375 | typedef T& reference; | |
376 | typedef T const& const_reference; | |
377 | typedef T value_type; | |
378 | ||
379 | template <class U> struct rebind | |
380 | { | |
381 | typedef allocator<U> other; | |
382 | }; | |
383 | ||
384 | explicit allocator(int t = 0) : tag_(t) | |
385 | { | |
386 | UNORDERED_SCOPE(allocator::allocator()) | |
7c673cae | 387 | { |
b32b8144 | 388 | UNORDERED_EPOINT("Mock allocator default constructor."); |
7c673cae | 389 | } |
b32b8144 FG |
390 | test::detail::tracker.allocator_ref(); |
391 | } | |
7c673cae | 392 | |
b32b8144 FG |
393 | template <class Y> allocator(allocator<Y> const& x) : tag_(x.tag_) |
394 | { | |
395 | test::detail::tracker.allocator_ref(); | |
396 | } | |
7c673cae | 397 | |
b32b8144 FG |
398 | allocator(allocator const& x) : tag_(x.tag_) |
399 | { | |
400 | test::detail::tracker.allocator_ref(); | |
401 | } | |
7c673cae | 402 | |
b32b8144 | 403 | ~allocator() { test::detail::tracker.allocator_unref(); } |
7c673cae | 404 | |
b32b8144 FG |
405 | allocator& operator=(allocator const& x) |
406 | { | |
407 | tag_ = x.tag_; | |
408 | return *this; | |
409 | } | |
7c673cae | 410 | |
b32b8144 FG |
411 | // If address throws, then it can't be used in erase or the |
412 | // destructor, which is very limiting. I need to check up on | |
413 | // this. | |
414 | ||
415 | pointer address(reference r) | |
416 | { | |
417 | // UNORDERED_SCOPE(allocator::address(reference)) { | |
418 | // UNORDERED_EPOINT("Mock allocator address function."); | |
419 | //} | |
420 | return pointer(&r); | |
421 | } | |
7c673cae | 422 | |
b32b8144 FG |
423 | const_pointer address(const_reference r) |
424 | { | |
425 | // UNORDERED_SCOPE(allocator::address(const_reference)) { | |
426 | // UNORDERED_EPOINT("Mock allocator const address function."); | |
427 | //} | |
428 | return const_pointer(&r); | |
429 | } | |
7c673cae | 430 | |
b32b8144 FG |
431 | pointer allocate(size_type n) |
432 | { | |
433 | T* ptr = 0; | |
434 | UNORDERED_SCOPE(allocator::allocate(size_type)) | |
435 | { | |
436 | UNORDERED_EPOINT("Mock allocator allocate function."); | |
7c673cae | 437 | |
b32b8144 FG |
438 | using namespace std; |
439 | ptr = (T*)malloc(n * sizeof(T)); | |
440 | if (!ptr) | |
441 | throw std::bad_alloc(); | |
7c673cae | 442 | } |
b32b8144 FG |
443 | test::detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_); |
444 | return pointer(ptr); | |
7c673cae | 445 | |
b32b8144 FG |
446 | // return pointer(static_cast<T*>(::operator new(n * sizeof(T)))); |
447 | } | |
7c673cae | 448 | |
b32b8144 FG |
449 | pointer allocate(size_type n, void const*) |
450 | { | |
451 | T* ptr = 0; | |
452 | UNORDERED_SCOPE(allocator::allocate(size_type, const_pointer)) | |
453 | { | |
454 | UNORDERED_EPOINT("Mock allocator allocate function."); | |
7c673cae | 455 | |
b32b8144 FG |
456 | using namespace std; |
457 | ptr = (T*)malloc(n * sizeof(T)); | |
458 | if (!ptr) | |
459 | throw std::bad_alloc(); | |
7c673cae | 460 | } |
b32b8144 FG |
461 | test::detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_); |
462 | return pointer(ptr); | |
7c673cae | 463 | |
b32b8144 FG |
464 | // return pointer(static_cast<T*>(::operator new(n * sizeof(T)))); |
465 | } | |
466 | ||
467 | void deallocate(pointer p, size_type n) | |
468 | { | |
469 | //::operator delete((void*) p); | |
470 | if (p) { | |
471 | test::detail::tracker.track_deallocate((void*)p, n, sizeof(T), tag_); | |
472 | using namespace std; | |
473 | free(p); | |
7c673cae | 474 | } |
b32b8144 | 475 | } |
7c673cae | 476 | |
b32b8144 FG |
477 | void construct(pointer p, T const& t) |
478 | { | |
479 | UNORDERED_SCOPE(allocator::construct(T*, T)) | |
480 | { | |
481 | UNORDERED_EPOINT("Mock allocator construct function."); | |
482 | new (p) T(t); | |
7c673cae | 483 | } |
b32b8144 FG |
484 | test::detail::tracker.track_construct((void*)p, sizeof(T), tag_); |
485 | } | |
7c673cae FG |
486 | |
487 | #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) | |
b32b8144 FG |
488 | template <class... Args> void construct(T* p, BOOST_FWD_REF(Args)... args) |
489 | { | |
490 | UNORDERED_SCOPE(allocator::construct(pointer, BOOST_FWD_REF(Args)...)) | |
491 | { | |
492 | UNORDERED_EPOINT("Mock allocator construct function."); | |
493 | new (p) T(boost::forward<Args>(args)...); | |
7c673cae | 494 | } |
b32b8144 FG |
495 | test::detail::tracker.track_construct((void*)p, sizeof(T), tag_); |
496 | } | |
7c673cae FG |
497 | #endif |
498 | ||
b32b8144 FG |
499 | void destroy(T* p) |
500 | { | |
501 | test::detail::tracker.track_destroy((void*)p, sizeof(T), tag_); | |
502 | p->~T(); | |
503 | } | |
7c673cae | 504 | |
b32b8144 FG |
505 | size_type max_size() const |
506 | { | |
507 | UNORDERED_SCOPE(allocator::construct(pointer, T)) | |
508 | { | |
509 | UNORDERED_EPOINT("Mock allocator max_size function."); | |
7c673cae | 510 | } |
b32b8144 FG |
511 | return (std::numeric_limits<std::size_t>::max)(); |
512 | } | |
7c673cae | 513 | |
b32b8144 FG |
514 | typedef true_type propagate_on_container_copy_assignment; |
515 | typedef true_type propagate_on_container_move_assignment; | |
516 | typedef true_type propagate_on_container_swap; | |
7c673cae FG |
517 | }; |
518 | ||
b32b8144 | 519 | template <class T> void swap(allocator<T>& x, allocator<T>& y) |
7c673cae | 520 | { |
b32b8144 | 521 | std::swap(x.tag_, y.tag_); |
7c673cae FG |
522 | } |
523 | ||
524 | // It's pretty much impossible to write a compliant swap when these | |
525 | // two can throw. So they don't. | |
526 | ||
527 | template <class T> | |
528 | inline bool operator==(allocator<T> const& x, allocator<T> const& y) | |
529 | { | |
b32b8144 FG |
530 | // UNORDERED_SCOPE(operator==(allocator, allocator)) { |
531 | // UNORDERED_EPOINT("Mock allocator equality operator."); | |
532 | //} | |
533 | return x.tag_ == y.tag_; | |
7c673cae FG |
534 | } |
535 | ||
536 | template <class T> | |
537 | inline bool operator!=(allocator<T> const& x, allocator<T> const& y) | |
538 | { | |
b32b8144 FG |
539 | // UNORDERED_SCOPE(operator!=(allocator, allocator)) { |
540 | // UNORDERED_EPOINT("Mock allocator inequality operator."); | |
541 | //} | |
542 | return x.tag_ != y.tag_; | |
7c673cae FG |
543 | } |
544 | ||
b32b8144 | 545 | template <class T> class allocator2 |
7c673cae FG |
546 | { |
547 | public: | |
b32b8144 FG |
548 | int tag_; |
549 | typedef std::size_t size_type; | |
550 | typedef std::ptrdiff_t difference_type; | |
551 | typedef T* pointer; | |
552 | typedef T const* const_pointer; | |
553 | typedef T& reference; | |
554 | typedef T const& const_reference; | |
555 | typedef T value_type; | |
556 | ||
557 | template <class U> struct rebind | |
558 | { | |
559 | typedef allocator2<U> other; | |
560 | }; | |
561 | ||
562 | explicit allocator2(int t = 0) : tag_(t) | |
563 | { | |
564 | UNORDERED_SCOPE(allocator2::allocator2()) | |
7c673cae | 565 | { |
b32b8144 | 566 | UNORDERED_EPOINT("Mock allocator2 default constructor."); |
7c673cae | 567 | } |
b32b8144 FG |
568 | test::detail::tracker.allocator_ref(); |
569 | } | |
7c673cae | 570 | |
b32b8144 FG |
571 | allocator2(allocator<T> const& x) : tag_(x.tag_) |
572 | { | |
573 | test::detail::tracker.allocator_ref(); | |
574 | } | |
7c673cae | 575 | |
b32b8144 FG |
576 | template <class Y> allocator2(allocator2<Y> const& x) : tag_(x.tag_) |
577 | { | |
578 | test::detail::tracker.allocator_ref(); | |
579 | } | |
7c673cae | 580 | |
b32b8144 FG |
581 | allocator2(allocator2 const& x) : tag_(x.tag_) |
582 | { | |
583 | test::detail::tracker.allocator_ref(); | |
584 | } | |
7c673cae | 585 | |
b32b8144 | 586 | ~allocator2() { test::detail::tracker.allocator_unref(); } |
7c673cae | 587 | |
b32b8144 | 588 | allocator2& operator=(allocator2 const&) { return *this; } |
7c673cae | 589 | |
b32b8144 FG |
590 | // If address throws, then it can't be used in erase or the |
591 | // destructor, which is very limiting. I need to check up on | |
592 | // this. | |
7c673cae | 593 | |
b32b8144 FG |
594 | pointer address(reference r) |
595 | { | |
596 | // UNORDERED_SCOPE(allocator2::address(reference)) { | |
597 | // UNORDERED_EPOINT("Mock allocator2 address function."); | |
598 | //} | |
599 | return pointer(&r); | |
600 | } | |
7c673cae | 601 | |
b32b8144 FG |
602 | const_pointer address(const_reference r) |
603 | { | |
604 | // UNORDERED_SCOPE(allocator2::address(const_reference)) { | |
605 | // UNORDERED_EPOINT("Mock allocator2 const address function."); | |
606 | //} | |
607 | return const_pointer(&r); | |
608 | } | |
7c673cae | 609 | |
b32b8144 FG |
610 | pointer allocate(size_type n) |
611 | { | |
612 | T* ptr = 0; | |
613 | UNORDERED_SCOPE(allocator2::allocate(size_type)) | |
614 | { | |
615 | UNORDERED_EPOINT("Mock allocator2 allocate function."); | |
7c673cae | 616 | |
b32b8144 FG |
617 | using namespace std; |
618 | ptr = (T*)malloc(n * sizeof(T)); | |
619 | if (!ptr) | |
620 | throw std::bad_alloc(); | |
7c673cae | 621 | } |
b32b8144 FG |
622 | test::detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_); |
623 | return pointer(ptr); | |
7c673cae | 624 | |
b32b8144 FG |
625 | // return pointer(static_cast<T*>(::operator new(n * sizeof(T)))); |
626 | } | |
7c673cae | 627 | |
b32b8144 FG |
628 | pointer allocate(size_type n, void const*) |
629 | { | |
630 | T* ptr = 0; | |
631 | UNORDERED_SCOPE(allocator2::allocate(size_type, const_pointer)) | |
632 | { | |
633 | UNORDERED_EPOINT("Mock allocator2 allocate function."); | |
7c673cae | 634 | |
b32b8144 FG |
635 | using namespace std; |
636 | ptr = (T*)malloc(n * sizeof(T)); | |
637 | if (!ptr) | |
638 | throw std::bad_alloc(); | |
7c673cae | 639 | } |
b32b8144 FG |
640 | test::detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_); |
641 | return pointer(ptr); | |
7c673cae | 642 | |
b32b8144 FG |
643 | // return pointer(static_cast<T*>(::operator new(n * sizeof(T)))); |
644 | } | |
645 | ||
646 | void deallocate(pointer p, size_type n) | |
647 | { | |
648 | //::operator delete((void*) p); | |
649 | if (p) { | |
650 | test::detail::tracker.track_deallocate((void*)p, n, sizeof(T), tag_); | |
651 | using namespace std; | |
652 | free(p); | |
7c673cae | 653 | } |
b32b8144 | 654 | } |
7c673cae | 655 | |
b32b8144 FG |
656 | void construct(pointer p, T const& t) |
657 | { | |
658 | UNORDERED_SCOPE(allocator2::construct(T*, T)) | |
659 | { | |
660 | UNORDERED_EPOINT("Mock allocator2 construct function."); | |
661 | new (p) T(t); | |
7c673cae | 662 | } |
b32b8144 FG |
663 | test::detail::tracker.track_construct((void*)p, sizeof(T), tag_); |
664 | } | |
7c673cae FG |
665 | |
666 | #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) | |
b32b8144 FG |
667 | template <class... Args> void construct(T* p, BOOST_FWD_REF(Args)... args) |
668 | { | |
669 | UNORDERED_SCOPE(allocator2::construct(pointer, BOOST_FWD_REF(Args)...)) | |
670 | { | |
671 | UNORDERED_EPOINT("Mock allocator2 construct function."); | |
672 | new (p) T(boost::forward<Args>(args)...); | |
7c673cae | 673 | } |
b32b8144 FG |
674 | test::detail::tracker.track_construct((void*)p, sizeof(T), tag_); |
675 | } | |
7c673cae FG |
676 | #endif |
677 | ||
b32b8144 FG |
678 | void destroy(T* p) |
679 | { | |
680 | test::detail::tracker.track_destroy((void*)p, sizeof(T), tag_); | |
681 | p->~T(); | |
682 | } | |
7c673cae | 683 | |
b32b8144 FG |
684 | size_type max_size() const |
685 | { | |
686 | UNORDERED_SCOPE(allocator2::construct(pointer, T)) | |
687 | { | |
688 | UNORDERED_EPOINT("Mock allocator2 max_size function."); | |
7c673cae | 689 | } |
b32b8144 FG |
690 | return (std::numeric_limits<std::size_t>::max)(); |
691 | } | |
7c673cae | 692 | |
b32b8144 FG |
693 | typedef false_type propagate_on_container_copy_assignment; |
694 | typedef false_type propagate_on_container_move_assignment; | |
695 | typedef false_type propagate_on_container_swap; | |
7c673cae FG |
696 | }; |
697 | ||
b32b8144 | 698 | template <class T> void swap(allocator2<T>& x, allocator2<T>& y) |
7c673cae | 699 | { |
b32b8144 | 700 | std::swap(x.tag_, y.tag_); |
7c673cae FG |
701 | } |
702 | ||
703 | // It's pretty much impossible to write a compliant swap when these | |
704 | // two can throw. So they don't. | |
705 | ||
706 | template <class T> | |
707 | inline bool operator==(allocator2<T> const& x, allocator2<T> const& y) | |
708 | { | |
b32b8144 FG |
709 | // UNORDERED_SCOPE(operator==(allocator2, allocator2)) { |
710 | // UNORDERED_EPOINT("Mock allocator2 equality operator."); | |
711 | //} | |
712 | return x.tag_ == y.tag_; | |
7c673cae FG |
713 | } |
714 | ||
715 | template <class T> | |
716 | inline bool operator!=(allocator2<T> const& x, allocator2<T> const& y) | |
717 | { | |
b32b8144 FG |
718 | // UNORDERED_SCOPE(operator!=(allocator2, allocator2)) { |
719 | // UNORDERED_EPOINT("Mock allocator2 inequality operator."); | |
720 | //} | |
721 | return x.tag_ != y.tag_; | |
7c673cae | 722 | } |
b32b8144 | 723 | } |
7c673cae | 724 | } |
b32b8144 FG |
725 | |
726 | namespace test { | |
727 | template <typename X> struct equals_to_compare; | |
728 | template <> struct equals_to_compare<test::exception::equal_to> | |
729 | { | |
730 | typedef test::exception::less type; | |
731 | }; | |
7c673cae FG |
732 | } |
733 | ||
734 | // Workaround for ADL deficient compilers | |
735 | #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) | |
b32b8144 FG |
736 | namespace test { |
737 | test::exception::object generate( | |
738 | test::exception::object const* x, random_generator g) | |
739 | { | |
740 | return test::exception::generate(x, g); | |
741 | } | |
742 | ||
743 | std::pair<test::exception::object, test::exception::object> generate( | |
744 | std::pair<test::exception::object, test::exception::object> const* x, | |
745 | random_generator g) | |
746 | { | |
747 | return test::exception::generate(x, g); | |
748 | } | |
7c673cae FG |
749 | } |
750 | #endif | |
751 | ||
752 | #endif |