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)
6 #if !defined(BOOST_UNORDERED_EXCEPTION_TEST_OBJECTS_HEADER)
7 #define BOOST_UNORDERED_EXCEPTION_TEST_OBJECTS_HEADER
9 #include "../helpers/exception_test.hpp"
11 #include "../helpers/count.hpp"
12 #include "../helpers/fwd.hpp"
13 #include "../helpers/generators.hpp"
14 #include "../helpers/memory.hpp"
16 #include <boost/limits.hpp>
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);
46 class object : private counted_object
51 explicit object() : tag1_(0), tag2_(0)
53 UNORDERED_SCOPE(object::object())
55 UNORDERED_EPOINT("Mock object default constructor.");
59 explicit object(int t1, int t2 = 0) : tag1_(t1), tag2_(t2)
61 UNORDERED_SCOPE(object::object(int))
63 UNORDERED_EPOINT("Mock object constructor by value.");
67 object(object const& x)
68 : counted_object(x), tag1_(x.tag1_), tag2_(x.tag2_)
70 UNORDERED_SCOPE(object::object(object))
72 UNORDERED_EPOINT("Mock object copy constructor.");
82 object& operator=(object const& x)
84 UNORDERED_SCOPE(object::operator=(object))
87 UNORDERED_EPOINT("Mock object assign operator 1.");
89 // UNORDERED_EPOINT("Mock object assign operator 2.");
94 friend bool operator==(object const& x1, object const& x2)
96 UNORDERED_SCOPE(operator==(object, object))
98 UNORDERED_EPOINT("Mock object equality operator.");
101 return x1.tag1_ == x2.tag1_ && x1.tag2_ == x2.tag2_;
104 friend bool operator!=(object const& x1, object const& x2)
106 UNORDERED_SCOPE(operator!=(object, object))
108 UNORDERED_EPOINT("Mock object inequality operator.");
111 return !(x1.tag1_ == x2.tag1_ && x1.tag2_ == x2.tag2_);
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)
118 return x1.tag1_ < x2.tag1_ ||
119 (x1.tag1_ == x2.tag1_ && x1.tag2_ < x2.tag2_);
122 friend object generate(object const*, random_generator g)
125 return object(::test::generate(x, g), ::test::generate(x, g));
128 friend std::ostream& operator<<(std::ostream& out, object const& o)
130 return out << "(" << o.tag1_ << "," << o.tag2_ << ")";
134 std::pair<object, object> generate(
135 std::pair<object, object> const*, random_generator g)
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)));
148 hash(int t = 0) : tag_(t)
150 UNORDERED_SCOPE(hash::object())
152 UNORDERED_EPOINT("Mock hash default constructor.");
156 hash(hash const& x) : tag_(x.tag_)
158 UNORDERED_SCOPE(hash::hash(hash))
160 UNORDERED_EPOINT("Mock hash copy constructor.");
164 hash& operator=(hash const& x)
166 UNORDERED_SCOPE(hash::operator=(hash))
168 UNORDERED_EPOINT("Mock hash assign operator 1.");
170 UNORDERED_EPOINT("Mock hash assign operator 2.");
175 std::size_t operator()(object const& x) const
177 UNORDERED_SCOPE(hash::operator()(object))
179 UNORDERED_EPOINT("Mock hash function.");
185 std::size_t operator()(std::pair<object, object> const& x) const
187 UNORDERED_SCOPE(hash::operator()(std::pair<object, object>))
189 UNORDERED_EPOINT("Mock hash pair function.");
192 return hash_impl(x.first) * 193ul + hash_impl(x.second) * 97ul + 29ul;
195 std::size_t hash_impl(object const& x) const
206 result = x.tag1_ + x.tag2_;
208 return static_cast<std::size_t>(result);
211 friend bool operator==(hash const& x1, hash const& x2)
213 UNORDERED_SCOPE(operator==(hash, hash))
215 UNORDERED_EPOINT("Mock hash equality function.");
217 return x1.tag_ == x2.tag_;
220 friend bool operator!=(hash const& x1, hash const& x2)
222 UNORDERED_SCOPE(hash::operator!=(hash, hash))
224 UNORDERED_EPOINT("Mock hash inequality function.");
226 return x1.tag_ != x2.tag_;
235 less(int t = 0) : tag_(t) {}
237 less(less const& x) : tag_(x.tag_) {}
239 bool operator()(object const& x1, object const& x2) const
241 return less_impl(x1, x2);
244 bool operator()(std::pair<object, object> const& x1,
245 std::pair<object, object> const& x2) const
247 if (less_impl(x1.first, x2.first)) {
250 if (!less_impl(x1.first, x2.first)) {
253 return less_impl(x1.second, x2.second);
256 bool less_impl(object const& x1, object const& x2) const
260 return x1.tag1_ < x2.tag1_;
262 return x1.tag2_ < x2.tag2_;
268 friend bool operator==(less const& x1, less const& x2)
270 return x1.tag_ == x2.tag_;
273 friend bool operator!=(less const& x1, less const& x2)
275 return x1.tag_ != x2.tag_;
284 equal_to(int t = 0) : tag_(t)
286 UNORDERED_SCOPE(equal_to::equal_to())
288 UNORDERED_EPOINT("Mock equal_to default constructor.");
292 equal_to(equal_to const& x) : tag_(x.tag_)
294 UNORDERED_SCOPE(equal_to::equal_to(equal_to))
296 UNORDERED_EPOINT("Mock equal_to copy constructor.");
300 equal_to& operator=(equal_to const& x)
302 UNORDERED_SCOPE(equal_to::operator=(equal_to))
304 UNORDERED_EPOINT("Mock equal_to assign operator 1.");
306 UNORDERED_EPOINT("Mock equal_to assign operator 2.");
311 bool operator()(object const& x1, object const& x2) const
313 UNORDERED_SCOPE(equal_to::operator()(object, object))
315 UNORDERED_EPOINT("Mock equal_to function.");
318 return equal_impl(x1, x2);
321 bool operator()(std::pair<object, object> const& x1,
322 std::pair<object, object> const& x2) const
324 UNORDERED_SCOPE(equal_to::operator()(
325 std::pair<object, object>, std::pair<object, object>))
327 UNORDERED_EPOINT("Mock equal_to function.");
330 return equal_impl(x1.first, x2.first) &&
331 equal_impl(x1.second, x2.second);
334 bool equal_impl(object const& x1, object const& x2) const
338 return x1.tag1_ == x2.tag1_;
340 return x1.tag2_ == x2.tag2_;
346 friend bool operator==(equal_to const& x1, equal_to const& x2)
348 UNORDERED_SCOPE(operator==(equal_to, equal_to))
350 UNORDERED_EPOINT("Mock equal_to equality function.");
352 return x1.tag_ == x2.tag_;
355 friend bool operator!=(equal_to const& x1, equal_to const& x2)
357 UNORDERED_SCOPE(operator!=(equal_to, equal_to))
359 UNORDERED_EPOINT("Mock equal_to inequality function.");
361 return x1.tag_ != x2.tag_;
364 friend less create_compare(equal_to x) { return less(x.tag_); }
367 template <class T> class allocator
371 typedef std::size_t size_type;
372 typedef std::ptrdiff_t difference_type;
374 typedef T const* const_pointer;
375 typedef T& reference;
376 typedef T const& const_reference;
377 typedef T value_type;
379 template <class U> struct rebind
381 typedef allocator<U> other;
384 explicit allocator(int t = 0) : tag_(t)
386 UNORDERED_SCOPE(allocator::allocator())
388 UNORDERED_EPOINT("Mock allocator default constructor.");
390 test::detail::tracker.allocator_ref();
393 template <class Y> allocator(allocator<Y> const& x) : tag_(x.tag_)
395 test::detail::tracker.allocator_ref();
398 allocator(allocator const& x) : tag_(x.tag_)
400 test::detail::tracker.allocator_ref();
403 ~allocator() { test::detail::tracker.allocator_unref(); }
405 allocator& operator=(allocator const& x)
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
415 pointer address(reference r)
417 // UNORDERED_SCOPE(allocator::address(reference)) {
418 // UNORDERED_EPOINT("Mock allocator address function.");
423 const_pointer address(const_reference r)
425 // UNORDERED_SCOPE(allocator::address(const_reference)) {
426 // UNORDERED_EPOINT("Mock allocator const address function.");
428 return const_pointer(&r);
431 pointer allocate(size_type n)
434 UNORDERED_SCOPE(allocator::allocate(size_type))
436 UNORDERED_EPOINT("Mock allocator allocate function.");
439 ptr = (T*)malloc(n * sizeof(T));
441 throw std::bad_alloc();
443 test::detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_);
446 // return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
449 pointer allocate(size_type n, void const*)
452 UNORDERED_SCOPE(allocator::allocate(size_type, const_pointer))
454 UNORDERED_EPOINT("Mock allocator allocate function.");
457 ptr = (T*)malloc(n * sizeof(T));
459 throw std::bad_alloc();
461 test::detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_);
464 // return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
467 void deallocate(pointer p, size_type n)
469 //::operator delete((void*) p);
471 test::detail::tracker.track_deallocate((void*)p, n, sizeof(T), tag_);
477 void construct(pointer p, T const& t)
479 UNORDERED_SCOPE(allocator::construct(T*, T))
481 UNORDERED_EPOINT("Mock allocator construct function.");
484 test::detail::tracker.track_construct((void*)p, sizeof(T), tag_);
487 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
488 template <class... Args> void construct(T* p, BOOST_FWD_REF(Args)... args)
490 UNORDERED_SCOPE(allocator::construct(pointer, BOOST_FWD_REF(Args)...))
492 UNORDERED_EPOINT("Mock allocator construct function.");
493 new (p) T(boost::forward<Args>(args)...);
495 test::detail::tracker.track_construct((void*)p, sizeof(T), tag_);
501 test::detail::tracker.track_destroy((void*)p, sizeof(T), tag_);
505 size_type max_size() const
507 UNORDERED_SCOPE(allocator::construct(pointer, T))
509 UNORDERED_EPOINT("Mock allocator max_size function.");
511 return (std::numeric_limits<std::size_t>::max)();
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;
519 template <class T> void swap(allocator<T>& x, allocator<T>& y)
521 std::swap(x.tag_, y.tag_);
524 // It's pretty much impossible to write a compliant swap when these
525 // two can throw. So they don't.
528 inline bool operator==(allocator<T> const& x, allocator<T> const& y)
530 // UNORDERED_SCOPE(operator==(allocator, allocator)) {
531 // UNORDERED_EPOINT("Mock allocator equality operator.");
533 return x.tag_ == y.tag_;
537 inline bool operator!=(allocator<T> const& x, allocator<T> const& y)
539 // UNORDERED_SCOPE(operator!=(allocator, allocator)) {
540 // UNORDERED_EPOINT("Mock allocator inequality operator.");
542 return x.tag_ != y.tag_;
545 template <class T> class allocator2
549 typedef std::size_t size_type;
550 typedef std::ptrdiff_t difference_type;
552 typedef T const* const_pointer;
553 typedef T& reference;
554 typedef T const& const_reference;
555 typedef T value_type;
557 template <class U> struct rebind
559 typedef allocator2<U> other;
562 explicit allocator2(int t = 0) : tag_(t)
564 UNORDERED_SCOPE(allocator2::allocator2())
566 UNORDERED_EPOINT("Mock allocator2 default constructor.");
568 test::detail::tracker.allocator_ref();
571 allocator2(allocator<T> const& x) : tag_(x.tag_)
573 test::detail::tracker.allocator_ref();
576 template <class Y> allocator2(allocator2<Y> const& x) : tag_(x.tag_)
578 test::detail::tracker.allocator_ref();
581 allocator2(allocator2 const& x) : tag_(x.tag_)
583 test::detail::tracker.allocator_ref();
586 ~allocator2() { test::detail::tracker.allocator_unref(); }
588 allocator2& operator=(allocator2 const&) { return *this; }
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
594 pointer address(reference r)
596 // UNORDERED_SCOPE(allocator2::address(reference)) {
597 // UNORDERED_EPOINT("Mock allocator2 address function.");
602 const_pointer address(const_reference r)
604 // UNORDERED_SCOPE(allocator2::address(const_reference)) {
605 // UNORDERED_EPOINT("Mock allocator2 const address function.");
607 return const_pointer(&r);
610 pointer allocate(size_type n)
613 UNORDERED_SCOPE(allocator2::allocate(size_type))
615 UNORDERED_EPOINT("Mock allocator2 allocate function.");
618 ptr = (T*)malloc(n * sizeof(T));
620 throw std::bad_alloc();
622 test::detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_);
625 // return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
628 pointer allocate(size_type n, void const*)
631 UNORDERED_SCOPE(allocator2::allocate(size_type, const_pointer))
633 UNORDERED_EPOINT("Mock allocator2 allocate function.");
636 ptr = (T*)malloc(n * sizeof(T));
638 throw std::bad_alloc();
640 test::detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_);
643 // return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
646 void deallocate(pointer p, size_type n)
648 //::operator delete((void*) p);
650 test::detail::tracker.track_deallocate((void*)p, n, sizeof(T), tag_);
656 void construct(pointer p, T const& t)
658 UNORDERED_SCOPE(allocator2::construct(T*, T))
660 UNORDERED_EPOINT("Mock allocator2 construct function.");
663 test::detail::tracker.track_construct((void*)p, sizeof(T), tag_);
666 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
667 template <class... Args> void construct(T* p, BOOST_FWD_REF(Args)... args)
669 UNORDERED_SCOPE(allocator2::construct(pointer, BOOST_FWD_REF(Args)...))
671 UNORDERED_EPOINT("Mock allocator2 construct function.");
672 new (p) T(boost::forward<Args>(args)...);
674 test::detail::tracker.track_construct((void*)p, sizeof(T), tag_);
680 test::detail::tracker.track_destroy((void*)p, sizeof(T), tag_);
684 size_type max_size() const
686 UNORDERED_SCOPE(allocator2::construct(pointer, T))
688 UNORDERED_EPOINT("Mock allocator2 max_size function.");
690 return (std::numeric_limits<std::size_t>::max)();
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;
698 template <class T> void swap(allocator2<T>& x, allocator2<T>& y)
700 std::swap(x.tag_, y.tag_);
703 // It's pretty much impossible to write a compliant swap when these
704 // two can throw. So they don't.
707 inline bool operator==(allocator2<T> const& x, allocator2<T> const& y)
709 // UNORDERED_SCOPE(operator==(allocator2, allocator2)) {
710 // UNORDERED_EPOINT("Mock allocator2 equality operator.");
712 return x.tag_ == y.tag_;
716 inline bool operator!=(allocator2<T> const& x, allocator2<T> const& y)
718 // UNORDERED_SCOPE(operator!=(allocator2, allocator2)) {
719 // UNORDERED_EPOINT("Mock allocator2 inequality operator.");
721 return x.tag_ != y.tag_;
727 template <typename X> struct equals_to_compare;
728 template <> struct equals_to_compare<test::exception::equal_to>
730 typedef test::exception::less type;
734 // Workaround for ADL deficient compilers
735 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
737 test::exception::object generate(
738 test::exception::object const* x, random_generator g)
740 return test::exception::generate(x, g);
743 std::pair<test::exception::object, test::exception::object> generate(
744 std::pair<test::exception::object, test::exception::object> const* x,
747 return test::exception::generate(x, g);