]>
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 | { | |
1e59de90 | 197 | unsigned result; |
b32b8144 FG |
198 | switch (tag_) { |
199 | case 1: | |
1e59de90 | 200 | result = static_cast<unsigned>(x.tag1_); |
b32b8144 FG |
201 | break; |
202 | case 2: | |
1e59de90 | 203 | result = static_cast<unsigned>(x.tag2_); |
b32b8144 FG |
204 | break; |
205 | default: | |
1e59de90 TL |
206 | result = |
207 | static_cast<unsigned>(x.tag1_) + static_cast<unsigned>(x.tag2_); | |
b32b8144 | 208 | } |
1e59de90 | 209 | return result; |
b32b8144 FG |
210 | } |
211 | ||
212 | friend bool operator==(hash const& x1, hash const& x2) | |
213 | { | |
214 | UNORDERED_SCOPE(operator==(hash, hash)) | |
215 | { | |
216 | UNORDERED_EPOINT("Mock hash equality function."); | |
7c673cae | 217 | } |
b32b8144 FG |
218 | return x1.tag_ == x2.tag_; |
219 | } | |
7c673cae | 220 | |
b32b8144 FG |
221 | friend bool operator!=(hash const& x1, hash const& x2) |
222 | { | |
223 | UNORDERED_SCOPE(hash::operator!=(hash, hash)) | |
224 | { | |
225 | UNORDERED_EPOINT("Mock hash inequality function."); | |
7c673cae | 226 | } |
b32b8144 FG |
227 | return x1.tag_ != x2.tag_; |
228 | } | |
229 | }; | |
230 | ||
231 | class less | |
232 | { | |
233 | int tag_; | |
234 | ||
235 | public: | |
236 | less(int t = 0) : tag_(t) {} | |
237 | ||
238 | less(less const& x) : tag_(x.tag_) {} | |
239 | ||
240 | bool operator()(object const& x1, object const& x2) const | |
241 | { | |
242 | return less_impl(x1, x2); | |
243 | } | |
244 | ||
245 | bool operator()(std::pair<object, object> const& x1, | |
246 | std::pair<object, object> const& x2) const | |
247 | { | |
248 | if (less_impl(x1.first, x2.first)) { | |
249 | return true; | |
250 | } | |
251 | if (!less_impl(x1.first, x2.first)) { | |
252 | return false; | |
253 | } | |
254 | return less_impl(x1.second, x2.second); | |
255 | } | |
256 | ||
257 | bool less_impl(object const& x1, object const& x2) const | |
258 | { | |
259 | switch (tag_) { | |
260 | case 1: | |
261 | return x1.tag1_ < x2.tag1_; | |
262 | case 2: | |
263 | return x1.tag2_ < x2.tag2_; | |
264 | default: | |
265 | return x1 < x2; | |
266 | } | |
267 | } | |
268 | ||
269 | friend bool operator==(less const& x1, less const& x2) | |
270 | { | |
271 | return x1.tag_ == x2.tag_; | |
272 | } | |
273 | ||
274 | friend bool operator!=(less const& x1, less const& x2) | |
275 | { | |
276 | return x1.tag_ != x2.tag_; | |
277 | } | |
7c673cae FG |
278 | }; |
279 | ||
280 | class equal_to | |
281 | { | |
b32b8144 FG |
282 | int tag_; |
283 | ||
7c673cae | 284 | public: |
b32b8144 FG |
285 | equal_to(int t = 0) : tag_(t) |
286 | { | |
287 | UNORDERED_SCOPE(equal_to::equal_to()) | |
7c673cae | 288 | { |
b32b8144 | 289 | UNORDERED_EPOINT("Mock equal_to default constructor."); |
7c673cae | 290 | } |
b32b8144 | 291 | } |
7c673cae | 292 | |
b32b8144 FG |
293 | equal_to(equal_to const& x) : tag_(x.tag_) |
294 | { | |
295 | UNORDERED_SCOPE(equal_to::equal_to(equal_to)) | |
7c673cae | 296 | { |
b32b8144 | 297 | UNORDERED_EPOINT("Mock equal_to copy constructor."); |
7c673cae | 298 | } |
b32b8144 | 299 | } |
7c673cae | 300 | |
b32b8144 FG |
301 | equal_to& operator=(equal_to const& x) |
302 | { | |
303 | UNORDERED_SCOPE(equal_to::operator=(equal_to)) | |
7c673cae | 304 | { |
b32b8144 FG |
305 | UNORDERED_EPOINT("Mock equal_to assign operator 1."); |
306 | tag_ = x.tag_; | |
307 | UNORDERED_EPOINT("Mock equal_to assign operator 2."); | |
7c673cae | 308 | } |
b32b8144 FG |
309 | return *this; |
310 | } | |
7c673cae | 311 | |
b32b8144 FG |
312 | bool operator()(object const& x1, object const& x2) const |
313 | { | |
314 | UNORDERED_SCOPE(equal_to::operator()(object, object)) | |
315 | { | |
316 | UNORDERED_EPOINT("Mock equal_to function."); | |
7c673cae FG |
317 | } |
318 | ||
b32b8144 FG |
319 | return equal_impl(x1, x2); |
320 | } | |
7c673cae | 321 | |
b32b8144 FG |
322 | bool operator()(std::pair<object, object> const& x1, |
323 | std::pair<object, object> const& x2) const | |
324 | { | |
325 | UNORDERED_SCOPE(equal_to::operator()( | |
326 | std::pair<object, object>, std::pair<object, object>)) | |
327 | { | |
328 | UNORDERED_EPOINT("Mock equal_to function."); | |
7c673cae | 329 | } |
7c673cae | 330 | |
b32b8144 FG |
331 | return equal_impl(x1.first, x2.first) && |
332 | equal_impl(x1.second, x2.second); | |
333 | } | |
7c673cae | 334 | |
b32b8144 FG |
335 | bool equal_impl(object const& x1, object const& x2) const |
336 | { | |
337 | switch (tag_) { | |
338 | case 1: | |
339 | return x1.tag1_ == x2.tag1_; | |
340 | case 2: | |
341 | return x1.tag2_ == x2.tag2_; | |
342 | default: | |
343 | return x1 == x2; | |
344 | } | |
345 | } | |
7c673cae | 346 | |
b32b8144 FG |
347 | friend bool operator==(equal_to const& x1, equal_to const& x2) |
348 | { | |
349 | UNORDERED_SCOPE(operator==(equal_to, equal_to)) | |
7c673cae | 350 | { |
b32b8144 | 351 | UNORDERED_EPOINT("Mock equal_to equality function."); |
7c673cae | 352 | } |
b32b8144 FG |
353 | return x1.tag_ == x2.tag_; |
354 | } | |
7c673cae | 355 | |
b32b8144 FG |
356 | friend bool operator!=(equal_to const& x1, equal_to const& x2) |
357 | { | |
358 | UNORDERED_SCOPE(operator!=(equal_to, equal_to)) | |
7c673cae | 359 | { |
b32b8144 | 360 | UNORDERED_EPOINT("Mock equal_to inequality function."); |
7c673cae | 361 | } |
b32b8144 FG |
362 | return x1.tag_ != x2.tag_; |
363 | } | |
364 | ||
365 | friend less create_compare(equal_to x) { return less(x.tag_); } | |
366 | }; | |
7c673cae | 367 | |
b32b8144 FG |
368 | template <class T> class allocator |
369 | { | |
370 | public: | |
371 | int tag_; | |
372 | typedef std::size_t size_type; | |
373 | typedef std::ptrdiff_t difference_type; | |
374 | typedef T* pointer; | |
375 | typedef T const* const_pointer; | |
376 | typedef T& reference; | |
377 | typedef T const& const_reference; | |
378 | typedef T value_type; | |
379 | ||
380 | template <class U> struct rebind | |
381 | { | |
382 | typedef allocator<U> other; | |
383 | }; | |
384 | ||
385 | explicit allocator(int t = 0) : tag_(t) | |
386 | { | |
387 | UNORDERED_SCOPE(allocator::allocator()) | |
7c673cae | 388 | { |
b32b8144 | 389 | UNORDERED_EPOINT("Mock allocator default constructor."); |
7c673cae | 390 | } |
b32b8144 FG |
391 | test::detail::tracker.allocator_ref(); |
392 | } | |
7c673cae | 393 | |
b32b8144 FG |
394 | template <class Y> allocator(allocator<Y> const& x) : tag_(x.tag_) |
395 | { | |
396 | test::detail::tracker.allocator_ref(); | |
397 | } | |
7c673cae | 398 | |
b32b8144 FG |
399 | allocator(allocator const& x) : tag_(x.tag_) |
400 | { | |
401 | test::detail::tracker.allocator_ref(); | |
402 | } | |
7c673cae | 403 | |
b32b8144 | 404 | ~allocator() { test::detail::tracker.allocator_unref(); } |
7c673cae | 405 | |
b32b8144 FG |
406 | allocator& operator=(allocator const& x) |
407 | { | |
408 | tag_ = x.tag_; | |
409 | return *this; | |
410 | } | |
7c673cae | 411 | |
b32b8144 FG |
412 | // If address throws, then it can't be used in erase or the |
413 | // destructor, which is very limiting. I need to check up on | |
414 | // this. | |
415 | ||
416 | pointer address(reference r) | |
417 | { | |
418 | // UNORDERED_SCOPE(allocator::address(reference)) { | |
419 | // UNORDERED_EPOINT("Mock allocator address function."); | |
420 | //} | |
421 | return pointer(&r); | |
422 | } | |
7c673cae | 423 | |
b32b8144 FG |
424 | const_pointer address(const_reference r) |
425 | { | |
426 | // UNORDERED_SCOPE(allocator::address(const_reference)) { | |
427 | // UNORDERED_EPOINT("Mock allocator const address function."); | |
428 | //} | |
429 | return const_pointer(&r); | |
430 | } | |
7c673cae | 431 | |
b32b8144 FG |
432 | pointer allocate(size_type n) |
433 | { | |
434 | T* ptr = 0; | |
435 | UNORDERED_SCOPE(allocator::allocate(size_type)) | |
436 | { | |
437 | UNORDERED_EPOINT("Mock allocator allocate function."); | |
7c673cae | 438 | |
b32b8144 FG |
439 | using namespace std; |
440 | ptr = (T*)malloc(n * sizeof(T)); | |
441 | if (!ptr) | |
442 | throw std::bad_alloc(); | |
7c673cae | 443 | } |
b32b8144 FG |
444 | test::detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_); |
445 | return pointer(ptr); | |
7c673cae | 446 | |
b32b8144 FG |
447 | // return pointer(static_cast<T*>(::operator new(n * sizeof(T)))); |
448 | } | |
7c673cae | 449 | |
b32b8144 FG |
450 | pointer allocate(size_type n, void const*) |
451 | { | |
452 | T* ptr = 0; | |
453 | UNORDERED_SCOPE(allocator::allocate(size_type, const_pointer)) | |
454 | { | |
455 | UNORDERED_EPOINT("Mock allocator allocate function."); | |
7c673cae | 456 | |
b32b8144 FG |
457 | using namespace std; |
458 | ptr = (T*)malloc(n * sizeof(T)); | |
459 | if (!ptr) | |
460 | throw std::bad_alloc(); | |
7c673cae | 461 | } |
b32b8144 FG |
462 | test::detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_); |
463 | return pointer(ptr); | |
7c673cae | 464 | |
b32b8144 FG |
465 | // return pointer(static_cast<T*>(::operator new(n * sizeof(T)))); |
466 | } | |
467 | ||
468 | void deallocate(pointer p, size_type n) | |
469 | { | |
470 | //::operator delete((void*) p); | |
471 | if (p) { | |
472 | test::detail::tracker.track_deallocate((void*)p, n, sizeof(T), tag_); | |
473 | using namespace std; | |
474 | free(p); | |
7c673cae | 475 | } |
b32b8144 | 476 | } |
7c673cae | 477 | |
b32b8144 FG |
478 | void construct(pointer p, T const& t) |
479 | { | |
480 | UNORDERED_SCOPE(allocator::construct(T*, T)) | |
481 | { | |
482 | UNORDERED_EPOINT("Mock allocator construct function."); | |
483 | new (p) T(t); | |
7c673cae | 484 | } |
b32b8144 FG |
485 | test::detail::tracker.track_construct((void*)p, sizeof(T), tag_); |
486 | } | |
7c673cae FG |
487 | |
488 | #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) | |
b32b8144 FG |
489 | template <class... Args> void construct(T* p, BOOST_FWD_REF(Args)... args) |
490 | { | |
491 | UNORDERED_SCOPE(allocator::construct(pointer, BOOST_FWD_REF(Args)...)) | |
492 | { | |
493 | UNORDERED_EPOINT("Mock allocator construct function."); | |
494 | new (p) T(boost::forward<Args>(args)...); | |
7c673cae | 495 | } |
b32b8144 FG |
496 | test::detail::tracker.track_construct((void*)p, sizeof(T), tag_); |
497 | } | |
7c673cae FG |
498 | #endif |
499 | ||
b32b8144 FG |
500 | void destroy(T* p) |
501 | { | |
502 | test::detail::tracker.track_destroy((void*)p, sizeof(T), tag_); | |
503 | p->~T(); | |
504 | } | |
7c673cae | 505 | |
b32b8144 FG |
506 | size_type max_size() const |
507 | { | |
508 | UNORDERED_SCOPE(allocator::construct(pointer, T)) | |
509 | { | |
510 | UNORDERED_EPOINT("Mock allocator max_size function."); | |
7c673cae | 511 | } |
b32b8144 FG |
512 | return (std::numeric_limits<std::size_t>::max)(); |
513 | } | |
7c673cae | 514 | |
b32b8144 FG |
515 | typedef true_type propagate_on_container_copy_assignment; |
516 | typedef true_type propagate_on_container_move_assignment; | |
517 | typedef true_type propagate_on_container_swap; | |
7c673cae FG |
518 | }; |
519 | ||
b32b8144 | 520 | template <class T> void swap(allocator<T>& x, allocator<T>& y) |
7c673cae | 521 | { |
b32b8144 | 522 | std::swap(x.tag_, y.tag_); |
7c673cae FG |
523 | } |
524 | ||
525 | // It's pretty much impossible to write a compliant swap when these | |
526 | // two can throw. So they don't. | |
527 | ||
528 | template <class T> | |
529 | inline bool operator==(allocator<T> const& x, allocator<T> const& y) | |
530 | { | |
b32b8144 FG |
531 | // UNORDERED_SCOPE(operator==(allocator, allocator)) { |
532 | // UNORDERED_EPOINT("Mock allocator equality operator."); | |
533 | //} | |
534 | return x.tag_ == y.tag_; | |
7c673cae FG |
535 | } |
536 | ||
537 | template <class T> | |
538 | inline bool operator!=(allocator<T> const& x, allocator<T> const& y) | |
539 | { | |
b32b8144 FG |
540 | // UNORDERED_SCOPE(operator!=(allocator, allocator)) { |
541 | // UNORDERED_EPOINT("Mock allocator inequality operator."); | |
542 | //} | |
543 | return x.tag_ != y.tag_; | |
7c673cae FG |
544 | } |
545 | ||
b32b8144 | 546 | template <class T> class allocator2 |
7c673cae FG |
547 | { |
548 | public: | |
b32b8144 FG |
549 | int tag_; |
550 | typedef std::size_t size_type; | |
551 | typedef std::ptrdiff_t difference_type; | |
552 | typedef T* pointer; | |
553 | typedef T const* const_pointer; | |
554 | typedef T& reference; | |
555 | typedef T const& const_reference; | |
556 | typedef T value_type; | |
557 | ||
558 | template <class U> struct rebind | |
559 | { | |
560 | typedef allocator2<U> other; | |
561 | }; | |
562 | ||
563 | explicit allocator2(int t = 0) : tag_(t) | |
564 | { | |
565 | UNORDERED_SCOPE(allocator2::allocator2()) | |
7c673cae | 566 | { |
b32b8144 | 567 | UNORDERED_EPOINT("Mock allocator2 default constructor."); |
7c673cae | 568 | } |
b32b8144 FG |
569 | test::detail::tracker.allocator_ref(); |
570 | } | |
7c673cae | 571 | |
b32b8144 FG |
572 | allocator2(allocator<T> const& x) : tag_(x.tag_) |
573 | { | |
574 | test::detail::tracker.allocator_ref(); | |
575 | } | |
7c673cae | 576 | |
b32b8144 FG |
577 | template <class Y> allocator2(allocator2<Y> const& x) : tag_(x.tag_) |
578 | { | |
579 | test::detail::tracker.allocator_ref(); | |
580 | } | |
7c673cae | 581 | |
b32b8144 FG |
582 | allocator2(allocator2 const& x) : tag_(x.tag_) |
583 | { | |
584 | test::detail::tracker.allocator_ref(); | |
585 | } | |
7c673cae | 586 | |
b32b8144 | 587 | ~allocator2() { test::detail::tracker.allocator_unref(); } |
7c673cae | 588 | |
b32b8144 | 589 | allocator2& operator=(allocator2 const&) { return *this; } |
7c673cae | 590 | |
b32b8144 FG |
591 | // If address throws, then it can't be used in erase or the |
592 | // destructor, which is very limiting. I need to check up on | |
593 | // this. | |
7c673cae | 594 | |
b32b8144 FG |
595 | pointer address(reference r) |
596 | { | |
597 | // UNORDERED_SCOPE(allocator2::address(reference)) { | |
598 | // UNORDERED_EPOINT("Mock allocator2 address function."); | |
599 | //} | |
600 | return pointer(&r); | |
601 | } | |
7c673cae | 602 | |
b32b8144 FG |
603 | const_pointer address(const_reference r) |
604 | { | |
605 | // UNORDERED_SCOPE(allocator2::address(const_reference)) { | |
606 | // UNORDERED_EPOINT("Mock allocator2 const address function."); | |
607 | //} | |
608 | return const_pointer(&r); | |
609 | } | |
7c673cae | 610 | |
b32b8144 FG |
611 | pointer allocate(size_type n) |
612 | { | |
613 | T* ptr = 0; | |
614 | UNORDERED_SCOPE(allocator2::allocate(size_type)) | |
615 | { | |
616 | UNORDERED_EPOINT("Mock allocator2 allocate function."); | |
7c673cae | 617 | |
b32b8144 FG |
618 | using namespace std; |
619 | ptr = (T*)malloc(n * sizeof(T)); | |
620 | if (!ptr) | |
621 | throw std::bad_alloc(); | |
7c673cae | 622 | } |
b32b8144 FG |
623 | test::detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_); |
624 | return pointer(ptr); | |
7c673cae | 625 | |
b32b8144 FG |
626 | // return pointer(static_cast<T*>(::operator new(n * sizeof(T)))); |
627 | } | |
7c673cae | 628 | |
b32b8144 FG |
629 | pointer allocate(size_type n, void const*) |
630 | { | |
631 | T* ptr = 0; | |
632 | UNORDERED_SCOPE(allocator2::allocate(size_type, const_pointer)) | |
633 | { | |
634 | UNORDERED_EPOINT("Mock allocator2 allocate function."); | |
7c673cae | 635 | |
b32b8144 FG |
636 | using namespace std; |
637 | ptr = (T*)malloc(n * sizeof(T)); | |
638 | if (!ptr) | |
639 | throw std::bad_alloc(); | |
7c673cae | 640 | } |
b32b8144 FG |
641 | test::detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_); |
642 | return pointer(ptr); | |
7c673cae | 643 | |
b32b8144 FG |
644 | // return pointer(static_cast<T*>(::operator new(n * sizeof(T)))); |
645 | } | |
646 | ||
647 | void deallocate(pointer p, size_type n) | |
648 | { | |
649 | //::operator delete((void*) p); | |
650 | if (p) { | |
651 | test::detail::tracker.track_deallocate((void*)p, n, sizeof(T), tag_); | |
652 | using namespace std; | |
653 | free(p); | |
7c673cae | 654 | } |
b32b8144 | 655 | } |
7c673cae | 656 | |
b32b8144 FG |
657 | void construct(pointer p, T const& t) |
658 | { | |
659 | UNORDERED_SCOPE(allocator2::construct(T*, T)) | |
660 | { | |
661 | UNORDERED_EPOINT("Mock allocator2 construct function."); | |
662 | new (p) T(t); | |
7c673cae | 663 | } |
b32b8144 FG |
664 | test::detail::tracker.track_construct((void*)p, sizeof(T), tag_); |
665 | } | |
7c673cae FG |
666 | |
667 | #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) | |
b32b8144 FG |
668 | template <class... Args> void construct(T* p, BOOST_FWD_REF(Args)... args) |
669 | { | |
670 | UNORDERED_SCOPE(allocator2::construct(pointer, BOOST_FWD_REF(Args)...)) | |
671 | { | |
672 | UNORDERED_EPOINT("Mock allocator2 construct function."); | |
673 | new (p) T(boost::forward<Args>(args)...); | |
7c673cae | 674 | } |
b32b8144 FG |
675 | test::detail::tracker.track_construct((void*)p, sizeof(T), tag_); |
676 | } | |
7c673cae FG |
677 | #endif |
678 | ||
b32b8144 FG |
679 | void destroy(T* p) |
680 | { | |
681 | test::detail::tracker.track_destroy((void*)p, sizeof(T), tag_); | |
682 | p->~T(); | |
683 | } | |
7c673cae | 684 | |
b32b8144 FG |
685 | size_type max_size() const |
686 | { | |
687 | UNORDERED_SCOPE(allocator2::construct(pointer, T)) | |
688 | { | |
689 | UNORDERED_EPOINT("Mock allocator2 max_size function."); | |
7c673cae | 690 | } |
b32b8144 FG |
691 | return (std::numeric_limits<std::size_t>::max)(); |
692 | } | |
7c673cae | 693 | |
b32b8144 FG |
694 | typedef false_type propagate_on_container_copy_assignment; |
695 | typedef false_type propagate_on_container_move_assignment; | |
696 | typedef false_type propagate_on_container_swap; | |
7c673cae FG |
697 | }; |
698 | ||
b32b8144 | 699 | template <class T> void swap(allocator2<T>& x, allocator2<T>& y) |
7c673cae | 700 | { |
b32b8144 | 701 | std::swap(x.tag_, y.tag_); |
7c673cae FG |
702 | } |
703 | ||
704 | // It's pretty much impossible to write a compliant swap when these | |
705 | // two can throw. So they don't. | |
706 | ||
707 | template <class T> | |
708 | inline bool operator==(allocator2<T> const& x, allocator2<T> const& y) | |
709 | { | |
b32b8144 FG |
710 | // UNORDERED_SCOPE(operator==(allocator2, allocator2)) { |
711 | // UNORDERED_EPOINT("Mock allocator2 equality operator."); | |
712 | //} | |
713 | return x.tag_ == y.tag_; | |
7c673cae FG |
714 | } |
715 | ||
716 | template <class T> | |
717 | inline bool operator!=(allocator2<T> const& x, allocator2<T> const& y) | |
718 | { | |
b32b8144 FG |
719 | // UNORDERED_SCOPE(operator!=(allocator2, allocator2)) { |
720 | // UNORDERED_EPOINT("Mock allocator2 inequality operator."); | |
721 | //} | |
722 | return x.tag_ != y.tag_; | |
7c673cae | 723 | } |
b32b8144 | 724 | } |
7c673cae | 725 | } |
b32b8144 FG |
726 | |
727 | namespace test { | |
728 | template <typename X> struct equals_to_compare; | |
729 | template <> struct equals_to_compare<test::exception::equal_to> | |
730 | { | |
731 | typedef test::exception::less type; | |
732 | }; | |
7c673cae FG |
733 | } |
734 | ||
735 | // Workaround for ADL deficient compilers | |
736 | #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) | |
b32b8144 FG |
737 | namespace test { |
738 | test::exception::object generate( | |
739 | test::exception::object const* x, random_generator g) | |
740 | { | |
741 | return test::exception::generate(x, g); | |
742 | } | |
743 | ||
744 | std::pair<test::exception::object, test::exception::object> generate( | |
745 | std::pair<test::exception::object, test::exception::object> const* x, | |
746 | random_generator g) | |
747 | { | |
748 | return test::exception::generate(x, g); | |
749 | } | |
7c673cae FG |
750 | } |
751 | #endif | |
752 | ||
753 | #endif |