]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/unordered/test/objects/exception.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / unordered / test / objects / exception.hpp
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
11 #include "../helpers/count.hpp"
12 #include "../helpers/fwd.hpp"
13 #include "../helpers/generators.hpp"
14 #include "../helpers/memory.hpp"
15 #include "./fwd.hpp"
16 #include <boost/limits.hpp>
17 #include <cstddef>
18 #include <new>
19
20 namespace test {
21 namespace exception {
22 class object;
23 class hash;
24 class equal_to;
25 template <class T> class allocator;
26 object generate(object const*, random_generator);
27 std::pair<object, object> generate(
28 std::pair<object, object> const*, random_generator);
29
30 struct true_type
31 {
32 enum
33 {
34 value = true
35 };
36 };
37
38 struct false_type
39 {
40 enum
41 {
42 value = false
43 };
44 };
45
46 class object : private counted_object
47 {
48 public:
49 int tag1_, tag2_;
50
51 explicit object() : tag1_(0), tag2_(0)
52 {
53 UNORDERED_SCOPE(object::object())
54 {
55 UNORDERED_EPOINT("Mock object default constructor.");
56 }
57 }
58
59 explicit object(int t1, int t2 = 0) : tag1_(t1), tag2_(t2)
60 {
61 UNORDERED_SCOPE(object::object(int))
62 {
63 UNORDERED_EPOINT("Mock object constructor by value.");
64 }
65 }
66
67 object(object const& x)
68 : counted_object(x), tag1_(x.tag1_), tag2_(x.tag2_)
69 {
70 UNORDERED_SCOPE(object::object(object))
71 {
72 UNORDERED_EPOINT("Mock object copy constructor.");
73 }
74 }
75
76 ~object()
77 {
78 tag1_ = -1;
79 tag2_ = -1;
80 }
81
82 object& operator=(object const& x)
83 {
84 UNORDERED_SCOPE(object::operator=(object))
85 {
86 tag1_ = x.tag1_;
87 UNORDERED_EPOINT("Mock object assign operator 1.");
88 tag2_ = x.tag2_;
89 // UNORDERED_EPOINT("Mock object assign operator 2.");
90 }
91 return *this;
92 }
93
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.");
99 }
100
101 return x1.tag1_ == x2.tag1_ && x1.tag2_ == x2.tag2_;
102 }
103
104 friend bool operator!=(object const& x1, object const& x2)
105 {
106 UNORDERED_SCOPE(operator!=(object, object))
107 {
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 }
132 };
133
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
143 class hash
144 {
145 int tag_;
146
147 public:
148 hash(int t = 0) : tag_(t)
149 {
150 UNORDERED_SCOPE(hash::object())
151 {
152 UNORDERED_EPOINT("Mock hash default constructor.");
153 }
154 }
155
156 hash(hash const& x) : tag_(x.tag_)
157 {
158 UNORDERED_SCOPE(hash::hash(hash))
159 {
160 UNORDERED_EPOINT("Mock hash copy constructor.");
161 }
162 }
163
164 hash& operator=(hash const& x)
165 {
166 UNORDERED_SCOPE(hash::operator=(hash))
167 {
168 UNORDERED_EPOINT("Mock hash assign operator 1.");
169 tag_ = x.tag_;
170 UNORDERED_EPOINT("Mock hash assign operator 2.");
171 }
172 return *this;
173 }
174
175 std::size_t operator()(object const& x) const
176 {
177 UNORDERED_SCOPE(hash::operator()(object))
178 {
179 UNORDERED_EPOINT("Mock hash function.");
180 }
181
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.");
216 }
217 return x1.tag_ == x2.tag_;
218 }
219
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.");
225 }
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 }
277 };
278
279 class equal_to
280 {
281 int tag_;
282
283 public:
284 equal_to(int t = 0) : tag_(t)
285 {
286 UNORDERED_SCOPE(equal_to::equal_to())
287 {
288 UNORDERED_EPOINT("Mock equal_to default constructor.");
289 }
290 }
291
292 equal_to(equal_to const& x) : tag_(x.tag_)
293 {
294 UNORDERED_SCOPE(equal_to::equal_to(equal_to))
295 {
296 UNORDERED_EPOINT("Mock equal_to copy constructor.");
297 }
298 }
299
300 equal_to& operator=(equal_to const& x)
301 {
302 UNORDERED_SCOPE(equal_to::operator=(equal_to))
303 {
304 UNORDERED_EPOINT("Mock equal_to assign operator 1.");
305 tag_ = x.tag_;
306 UNORDERED_EPOINT("Mock equal_to assign operator 2.");
307 }
308 return *this;
309 }
310
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.");
316 }
317
318 return equal_impl(x1, x2);
319 }
320
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.");
328 }
329
330 return equal_impl(x1.first, x2.first) &&
331 equal_impl(x1.second, x2.second);
332 }
333
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 }
345
346 friend bool operator==(equal_to const& x1, equal_to const& x2)
347 {
348 UNORDERED_SCOPE(operator==(equal_to, equal_to))
349 {
350 UNORDERED_EPOINT("Mock equal_to equality function.");
351 }
352 return x1.tag_ == x2.tag_;
353 }
354
355 friend bool operator!=(equal_to const& x1, equal_to const& x2)
356 {
357 UNORDERED_SCOPE(operator!=(equal_to, equal_to))
358 {
359 UNORDERED_EPOINT("Mock equal_to inequality function.");
360 }
361 return x1.tag_ != x2.tag_;
362 }
363
364 friend less create_compare(equal_to x) { return less(x.tag_); }
365 };
366
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())
387 {
388 UNORDERED_EPOINT("Mock allocator default constructor.");
389 }
390 test::detail::tracker.allocator_ref();
391 }
392
393 template <class Y> allocator(allocator<Y> const& x) : tag_(x.tag_)
394 {
395 test::detail::tracker.allocator_ref();
396 }
397
398 allocator(allocator const& x) : tag_(x.tag_)
399 {
400 test::detail::tracker.allocator_ref();
401 }
402
403 ~allocator() { test::detail::tracker.allocator_unref(); }
404
405 allocator& operator=(allocator const& x)
406 {
407 tag_ = x.tag_;
408 return *this;
409 }
410
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 }
422
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 }
430
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.");
437
438 using namespace std;
439 ptr = (T*)malloc(n * sizeof(T));
440 if (!ptr)
441 throw std::bad_alloc();
442 }
443 test::detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_);
444 return pointer(ptr);
445
446 // return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
447 }
448
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.");
455
456 using namespace std;
457 ptr = (T*)malloc(n * sizeof(T));
458 if (!ptr)
459 throw std::bad_alloc();
460 }
461 test::detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_);
462 return pointer(ptr);
463
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);
474 }
475 }
476
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);
483 }
484 test::detail::tracker.track_construct((void*)p, sizeof(T), tag_);
485 }
486
487 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
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)...);
494 }
495 test::detail::tracker.track_construct((void*)p, sizeof(T), tag_);
496 }
497 #endif
498
499 void destroy(T* p)
500 {
501 test::detail::tracker.track_destroy((void*)p, sizeof(T), tag_);
502 p->~T();
503 }
504
505 size_type max_size() const
506 {
507 UNORDERED_SCOPE(allocator::construct(pointer, T))
508 {
509 UNORDERED_EPOINT("Mock allocator max_size function.");
510 }
511 return (std::numeric_limits<std::size_t>::max)();
512 }
513
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;
517 };
518
519 template <class T> void swap(allocator<T>& x, allocator<T>& y)
520 {
521 std::swap(x.tag_, y.tag_);
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 {
530 // UNORDERED_SCOPE(operator==(allocator, allocator)) {
531 // UNORDERED_EPOINT("Mock allocator equality operator.");
532 //}
533 return x.tag_ == y.tag_;
534 }
535
536 template <class T>
537 inline bool operator!=(allocator<T> const& x, allocator<T> const& y)
538 {
539 // UNORDERED_SCOPE(operator!=(allocator, allocator)) {
540 // UNORDERED_EPOINT("Mock allocator inequality operator.");
541 //}
542 return x.tag_ != y.tag_;
543 }
544
545 template <class T> class allocator2
546 {
547 public:
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())
565 {
566 UNORDERED_EPOINT("Mock allocator2 default constructor.");
567 }
568 test::detail::tracker.allocator_ref();
569 }
570
571 allocator2(allocator<T> const& x) : tag_(x.tag_)
572 {
573 test::detail::tracker.allocator_ref();
574 }
575
576 template <class Y> allocator2(allocator2<Y> const& x) : tag_(x.tag_)
577 {
578 test::detail::tracker.allocator_ref();
579 }
580
581 allocator2(allocator2 const& x) : tag_(x.tag_)
582 {
583 test::detail::tracker.allocator_ref();
584 }
585
586 ~allocator2() { test::detail::tracker.allocator_unref(); }
587
588 allocator2& operator=(allocator2 const&) { return *this; }
589
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.
593
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 }
601
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 }
609
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.");
616
617 using namespace std;
618 ptr = (T*)malloc(n * sizeof(T));
619 if (!ptr)
620 throw std::bad_alloc();
621 }
622 test::detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_);
623 return pointer(ptr);
624
625 // return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
626 }
627
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.");
634
635 using namespace std;
636 ptr = (T*)malloc(n * sizeof(T));
637 if (!ptr)
638 throw std::bad_alloc();
639 }
640 test::detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_);
641 return pointer(ptr);
642
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);
653 }
654 }
655
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);
662 }
663 test::detail::tracker.track_construct((void*)p, sizeof(T), tag_);
664 }
665
666 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
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)...);
673 }
674 test::detail::tracker.track_construct((void*)p, sizeof(T), tag_);
675 }
676 #endif
677
678 void destroy(T* p)
679 {
680 test::detail::tracker.track_destroy((void*)p, sizeof(T), tag_);
681 p->~T();
682 }
683
684 size_type max_size() const
685 {
686 UNORDERED_SCOPE(allocator2::construct(pointer, T))
687 {
688 UNORDERED_EPOINT("Mock allocator2 max_size function.");
689 }
690 return (std::numeric_limits<std::size_t>::max)();
691 }
692
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;
696 };
697
698 template <class T> void swap(allocator2<T>& x, allocator2<T>& y)
699 {
700 std::swap(x.tag_, y.tag_);
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 {
709 // UNORDERED_SCOPE(operator==(allocator2, allocator2)) {
710 // UNORDERED_EPOINT("Mock allocator2 equality operator.");
711 //}
712 return x.tag_ == y.tag_;
713 }
714
715 template <class T>
716 inline bool operator!=(allocator2<T> const& x, allocator2<T> const& y)
717 {
718 // UNORDERED_SCOPE(operator!=(allocator2, allocator2)) {
719 // UNORDERED_EPOINT("Mock allocator2 inequality operator.");
720 //}
721 return x.tag_ != y.tag_;
722 }
723 }
724 }
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 };
732 }
733
734 // Workaround for ADL deficient compilers
735 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
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 }
749 }
750 #endif
751
752 #endif