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"
13 #include <boost/limits.hpp>
15 #include "../helpers/fwd.hpp"
16 #include "../helpers/memory.hpp"
25 template <class T> class allocator;
26 object generate(object const*, random_generator);
30 enum { value = true };
35 enum { value = false };
43 explicit object() : tag1_(0), tag2_(0)
45 UNORDERED_SCOPE(object::object()) {
46 UNORDERED_EPOINT("Mock object default constructor.");
50 explicit object(int t1, int t2 = 0) : tag1_(t1), tag2_(t2)
52 UNORDERED_SCOPE(object::object(int)) {
53 UNORDERED_EPOINT("Mock object constructor by value.");
57 object(object const& x)
58 : tag1_(x.tag1_), tag2_(x.tag2_)
60 UNORDERED_SCOPE(object::object(object)) {
61 UNORDERED_EPOINT("Mock object copy constructor.");
70 object& operator=(object const& x)
72 UNORDERED_SCOPE(object::operator=(object)) {
74 UNORDERED_EPOINT("Mock object assign operator 1.");
76 //UNORDERED_EPOINT("Mock object assign operator 2.");
81 friend bool operator==(object const& x1, object const& x2) {
82 UNORDERED_SCOPE(operator==(object, object)) {
83 UNORDERED_EPOINT("Mock object equality operator.");
86 return x1.tag1_ == x2.tag1_ && x1.tag2_ == x2.tag2_;
89 friend bool operator!=(object const& x1, object const& x2) {
90 UNORDERED_SCOPE(operator!=(object, object)) {
91 UNORDERED_EPOINT("Mock object inequality operator.");
94 return !(x1.tag1_ == x2.tag1_ && x1.tag2_ == x2.tag2_);
97 // None of the last few functions are used by the unordered associative
98 // containers - so there aren't any exception points.
99 friend bool operator<(object const& x1, object const& x2) {
100 return x1.tag1_ < x2.tag1_ ||
101 (x1.tag1_ == x2.tag1_ && x1.tag2_ < x2.tag2_);
104 friend object generate(object const*, random_generator g) {
106 return object(::test::generate(x, g), ::test::generate(x, g));
109 friend std::ostream& operator<<(std::ostream& out, object const& o)
111 return out<<"("<<o.tag1_<<","<<o.tag2_<<")";
119 hash(int t = 0) : tag_(t)
121 UNORDERED_SCOPE(hash::object()) {
122 UNORDERED_EPOINT("Mock hash default constructor.");
129 UNORDERED_SCOPE(hash::hash(hash)) {
130 UNORDERED_EPOINT("Mock hash copy constructor.");
134 hash& operator=(hash const& x)
136 UNORDERED_SCOPE(hash::operator=(hash)) {
137 UNORDERED_EPOINT("Mock hash assign operator 1.");
139 UNORDERED_EPOINT("Mock hash assign operator 2.");
144 std::size_t operator()(object const& x) const {
145 UNORDERED_SCOPE(hash::operator()(object)) {
146 UNORDERED_EPOINT("Mock hash function.");
158 result = x.tag1_ + x.tag2_;
160 return static_cast<std::size_t>(result);
163 friend bool operator==(hash const& x1, hash const& x2) {
164 UNORDERED_SCOPE(operator==(hash, hash)) {
165 UNORDERED_EPOINT("Mock hash equality function.");
167 return x1.tag_ == x2.tag_;
170 friend bool operator!=(hash const& x1, hash const& x2) {
171 UNORDERED_SCOPE(hash::operator!=(hash, hash)) {
172 UNORDERED_EPOINT("Mock hash inequality function.");
174 return x1.tag_ != x2.tag_;
182 equal_to(int t = 0) : tag_(t)
184 UNORDERED_SCOPE(equal_to::equal_to()) {
185 UNORDERED_EPOINT("Mock equal_to default constructor.");
189 equal_to(equal_to const& x)
192 UNORDERED_SCOPE(equal_to::equal_to(equal_to)) {
193 UNORDERED_EPOINT("Mock equal_to copy constructor.");
197 equal_to& operator=(equal_to const& x)
199 UNORDERED_SCOPE(equal_to::operator=(equal_to)) {
200 UNORDERED_EPOINT("Mock equal_to assign operator 1.");
202 UNORDERED_EPOINT("Mock equal_to assign operator 2.");
207 bool operator()(object const& x1, object const& x2) const {
208 UNORDERED_SCOPE(equal_to::operator()(object, object)) {
209 UNORDERED_EPOINT("Mock equal_to function.");
214 return x1.tag1_ == x2.tag1_;
216 return x1.tag2_ == x2.tag2_;
222 friend bool operator==(equal_to const& x1, equal_to const& x2) {
223 UNORDERED_SCOPE(operator==(equal_to, equal_to)) {
224 UNORDERED_EPOINT("Mock equal_to equality function.");
226 return x1.tag_ == x2.tag_;
229 friend bool operator!=(equal_to const& x1, equal_to const& x2) {
230 UNORDERED_SCOPE(operator!=(equal_to, equal_to)) {
231 UNORDERED_EPOINT("Mock equal_to inequality function.");
233 return x1.tag_ != x2.tag_;
242 typedef std::size_t size_type;
243 typedef std::ptrdiff_t difference_type;
245 typedef T const* const_pointer;
246 typedef T& reference;
247 typedef T const& const_reference;
248 typedef T value_type;
250 template <class U> struct rebind { typedef allocator<U> other; };
252 explicit allocator(int t = 0) : tag_(t)
254 UNORDERED_SCOPE(allocator::allocator()) {
255 UNORDERED_EPOINT("Mock allocator default constructor.");
257 test::detail::tracker.allocator_ref();
260 template <class Y> allocator(allocator<Y> const& x) : tag_(x.tag_)
262 UNORDERED_SCOPE(allocator::allocator()) {
263 UNORDERED_EPOINT("Mock allocator template copy constructor.");
265 test::detail::tracker.allocator_ref();
268 allocator(allocator const& x) : tag_(x.tag_)
270 UNORDERED_SCOPE(allocator::allocator()) {
271 UNORDERED_EPOINT("Mock allocator copy constructor.");
273 test::detail::tracker.allocator_ref();
277 test::detail::tracker.allocator_unref();
280 allocator& operator=(allocator const& x) {
281 UNORDERED_SCOPE(allocator::allocator()) {
282 UNORDERED_EPOINT("Mock allocator assignment operator.");
288 // If address throws, then it can't be used in erase or the
289 // destructor, which is very limiting. I need to check up on
292 pointer address(reference r) {
293 //UNORDERED_SCOPE(allocator::address(reference)) {
294 // UNORDERED_EPOINT("Mock allocator address function.");
299 const_pointer address(const_reference r) {
300 //UNORDERED_SCOPE(allocator::address(const_reference)) {
301 // UNORDERED_EPOINT("Mock allocator const address function.");
303 return const_pointer(&r);
306 pointer allocate(size_type n) {
308 UNORDERED_SCOPE(allocator::allocate(size_type)) {
309 UNORDERED_EPOINT("Mock allocator allocate function.");
312 ptr = (T*) malloc(n * sizeof(T));
313 if(!ptr) throw std::bad_alloc();
315 test::detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_);
318 //return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
321 pointer allocate(size_type n, void const*)
324 UNORDERED_SCOPE(allocator::allocate(size_type, const_pointer)) {
325 UNORDERED_EPOINT("Mock allocator allocate function.");
328 ptr = (T*) malloc(n * sizeof(T));
329 if(!ptr) throw std::bad_alloc();
331 test::detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_);
334 //return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
337 void deallocate(pointer p, size_type n)
339 //::operator delete((void*) p);
341 test::detail::tracker.track_deallocate((void*) p, n, sizeof(T), tag_);
347 void construct(pointer p, T const& t) {
348 UNORDERED_SCOPE(allocator::construct(T*, T)) {
349 UNORDERED_EPOINT("Mock allocator construct function.");
352 test::detail::tracker.track_construct((void*) p, sizeof(T), tag_);
355 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
356 template<class... Args> void construct(T* p, BOOST_FWD_REF(Args)... args) {
357 UNORDERED_SCOPE(allocator::construct(pointer, BOOST_FWD_REF(Args)...)) {
358 UNORDERED_EPOINT("Mock allocator construct function.");
359 new(p) T(boost::forward<Args>(args)...);
361 test::detail::tracker.track_construct((void*) p, sizeof(T), tag_);
366 test::detail::tracker.track_destroy((void*) p, sizeof(T), tag_);
370 size_type max_size() const {
371 UNORDERED_SCOPE(allocator::construct(pointer, T)) {
372 UNORDERED_EPOINT("Mock allocator max_size function.");
374 return (std::numeric_limits<std::size_t>::max)();
377 typedef true_type propagate_on_container_copy_assignment;
378 typedef true_type propagate_on_container_move_assignment;
379 typedef true_type propagate_on_container_swap;
383 void swap(allocator<T>& x, allocator<T>& y)
385 std::swap(x.tag_, y.tag_);
388 // It's pretty much impossible to write a compliant swap when these
389 // two can throw. So they don't.
392 inline bool operator==(allocator<T> const& x, allocator<T> const& y)
394 //UNORDERED_SCOPE(operator==(allocator, allocator)) {
395 // UNORDERED_EPOINT("Mock allocator equality operator.");
397 return x.tag_ == y.tag_;
401 inline bool operator!=(allocator<T> const& x, allocator<T> const& y)
403 //UNORDERED_SCOPE(operator!=(allocator, allocator)) {
404 // UNORDERED_EPOINT("Mock allocator inequality operator.");
406 return x.tag_ != y.tag_;
414 typedef std::size_t size_type;
415 typedef std::ptrdiff_t difference_type;
417 typedef T const* const_pointer;
418 typedef T& reference;
419 typedef T const& const_reference;
420 typedef T value_type;
422 template <class U> struct rebind { typedef allocator2<U> other; };
424 explicit allocator2(int t = 0) : tag_(t)
426 UNORDERED_SCOPE(allocator2::allocator2()) {
427 UNORDERED_EPOINT("Mock allocator2 default constructor.");
429 test::detail::tracker.allocator_ref();
432 allocator2(allocator<T> const& x) : tag_(x.tag_)
434 UNORDERED_SCOPE(allocator2::allocator2()) {
435 UNORDERED_EPOINT("Mock allocator2 constructor from allocator.");
437 test::detail::tracker.allocator_ref();
440 template <class Y> allocator2(allocator2<Y> const& x) : tag_(x.tag_)
442 UNORDERED_SCOPE(allocator2::allocator2()) {
443 UNORDERED_EPOINT("Mock allocator2 template copy constructor.");
445 test::detail::tracker.allocator_ref();
448 allocator2(allocator2 const& x) : tag_(x.tag_)
450 UNORDERED_SCOPE(allocator2::allocator2()) {
451 UNORDERED_EPOINT("Mock allocator2 copy constructor.");
453 test::detail::tracker.allocator_ref();
457 test::detail::tracker.allocator_unref();
460 allocator2& operator=(allocator2 const& x) {
461 UNORDERED_SCOPE(allocator2::allocator2()) {
462 UNORDERED_EPOINT("Mock allocator2 assignment operator.");
468 // If address throws, then it can't be used in erase or the
469 // destructor, which is very limiting. I need to check up on
472 pointer address(reference r) {
473 //UNORDERED_SCOPE(allocator2::address(reference)) {
474 // UNORDERED_EPOINT("Mock allocator2 address function.");
479 const_pointer address(const_reference r) {
480 //UNORDERED_SCOPE(allocator2::address(const_reference)) {
481 // UNORDERED_EPOINT("Mock allocator2 const address function.");
483 return const_pointer(&r);
486 pointer allocate(size_type n) {
488 UNORDERED_SCOPE(allocator2::allocate(size_type)) {
489 UNORDERED_EPOINT("Mock allocator2 allocate function.");
492 ptr = (T*) malloc(n * sizeof(T));
493 if(!ptr) throw std::bad_alloc();
495 test::detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_);
498 //return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
501 pointer allocate(size_type n, void const*)
504 UNORDERED_SCOPE(allocator2::allocate(size_type, const_pointer)) {
505 UNORDERED_EPOINT("Mock allocator2 allocate function.");
508 ptr = (T*) malloc(n * sizeof(T));
509 if(!ptr) throw std::bad_alloc();
511 test::detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_);
514 //return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
517 void deallocate(pointer p, size_type n)
519 //::operator delete((void*) p);
521 test::detail::tracker.track_deallocate((void*) p, n, sizeof(T), tag_);
527 void construct(pointer p, T const& t) {
528 UNORDERED_SCOPE(allocator2::construct(T*, T)) {
529 UNORDERED_EPOINT("Mock allocator2 construct function.");
532 test::detail::tracker.track_construct((void*) p, sizeof(T), tag_);
535 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
536 template<class... Args> void construct(T* p, BOOST_FWD_REF(Args)... args) {
537 UNORDERED_SCOPE(allocator2::construct(pointer, BOOST_FWD_REF(Args)...)) {
538 UNORDERED_EPOINT("Mock allocator2 construct function.");
539 new(p) T(boost::forward<Args>(args)...);
541 test::detail::tracker.track_construct((void*) p, sizeof(T), tag_);
546 test::detail::tracker.track_destroy((void*) p, sizeof(T), tag_);
550 size_type max_size() const {
551 UNORDERED_SCOPE(allocator2::construct(pointer, T)) {
552 UNORDERED_EPOINT("Mock allocator2 max_size function.");
554 return (std::numeric_limits<std::size_t>::max)();
557 typedef false_type propagate_on_container_copy_assignment;
558 typedef false_type propagate_on_container_move_assignment;
559 typedef false_type propagate_on_container_swap;
563 void swap(allocator2<T>& x, allocator2<T>& y)
565 std::swap(x.tag_, y.tag_);
568 // It's pretty much impossible to write a compliant swap when these
569 // two can throw. So they don't.
572 inline bool operator==(allocator2<T> const& x, allocator2<T> const& y)
574 //UNORDERED_SCOPE(operator==(allocator2, allocator2)) {
575 // UNORDERED_EPOINT("Mock allocator2 equality operator.");
577 return x.tag_ == y.tag_;
581 inline bool operator!=(allocator2<T> const& x, allocator2<T> const& y)
583 //UNORDERED_SCOPE(operator!=(allocator2, allocator2)) {
584 // UNORDERED_EPOINT("Mock allocator2 inequality operator.");
586 return x.tag_ != y.tag_;
591 // Workaround for ADL deficient compilers
592 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
595 test::exception::object generate(test::exception::object const* x,
596 random_generator g) {
597 return test::exception::generate(x, g);