From aefea862c28f3b9d7e390dc02b2989b22ba034ef Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sat, 25 Aug 2012 21:54:50 +0000 Subject: [PATCH] Unordered: Two exception testing allocators. For different C++11 properties. [SVN r80225] --- test/exception/containers.hpp | 4 +- test/exception/swap_exception_tests.cpp | 5 +- test/objects/exception.hpp | 180 ++++++++++++++++++++++++ 3 files changed, 186 insertions(+), 3 deletions(-) diff --git a/test/exception/containers.hpp b/test/exception/containers.hpp index b3a326b8..1e379645 100644 --- a/test/exception/containers.hpp +++ b/test/exception/containers.hpp @@ -18,13 +18,13 @@ typedef boost::unordered_multiset< test::exception::object, test::exception::hash, test::exception::equal_to, - test::exception::allocator > test_multiset; + test::exception::allocator2 > test_multiset; typedef boost::unordered_map< test::exception::object, test::exception::object, test::exception::hash, test::exception::equal_to, - test::exception::allocator > test_map; + test::exception::allocator2 > test_map; typedef boost::unordered_multimap< test::exception::object, test::exception::object, diff --git a/test/exception/swap_exception_tests.cpp b/test/exception/swap_exception_tests.cpp index 23f12476..39e59494 100644 --- a/test/exception/swap_exception_tests.cpp +++ b/test/exception/swap_exception_tests.cpp @@ -60,7 +60,9 @@ struct swap_base : public test::exception_base initial_x(x_values.begin(), x_values.end(), 0, hasher(tag1), key_equal(tag1), allocator_type(tag1)), initial_y(y_values.begin(), y_values.end(), 0, hasher(tag2), - key_equal(tag2), allocator_type(tag2)) + key_equal(tag2), allocator_type( + T::allocator_type::propagate_on_container_swap::value ? + tag2 : tag1)) {} struct data_type { @@ -71,6 +73,7 @@ struct swap_base : public test::exception_base }; data_type init() const { return data_type(initial_x, initial_y); } + void run(data_type& d) const { try { d.x.swap(d.y); diff --git a/test/objects/exception.hpp b/test/objects/exception.hpp index 9ff13005..2fba92c1 100644 --- a/test/objects/exception.hpp +++ b/test/objects/exception.hpp @@ -401,6 +401,186 @@ namespace exception //} return x.tag_ != y.tag_; } + + template + class allocator2 + { + public: + int tag_; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef T* pointer; + typedef T const* const_pointer; + typedef T& reference; + typedef T const& const_reference; + typedef T value_type; + + template struct rebind { typedef allocator2 other; }; + + explicit allocator2(int t = 0) : tag_(t) + { + UNORDERED_SCOPE(allocator2::allocator2()) { + UNORDERED_EPOINT("Mock allocator2 default constructor."); + } + test::detail::tracker.allocator_ref(); + } + + template allocator2(allocator const& x) : tag_(x.tag_) + { + UNORDERED_SCOPE(allocator2::allocator2()) { + UNORDERED_EPOINT("Mock allocator2 copy constructor from allocator."); + } + test::detail::tracker.allocator_ref(); + } + + template allocator2(allocator2 const& x) : tag_(x.tag_) + { + UNORDERED_SCOPE(allocator2::allocator2()) { + UNORDERED_EPOINT("Mock allocator2 template copy constructor."); + } + test::detail::tracker.allocator_ref(); + } + + allocator2(allocator2 const& x) : tag_(x.tag_) + { + UNORDERED_SCOPE(allocator2::allocator2()) { + UNORDERED_EPOINT("Mock allocator2 copy constructor."); + } + test::detail::tracker.allocator_ref(); + } + + ~allocator2() { + test::detail::tracker.allocator_unref(); + } + + allocator2& operator=(allocator2 const& x) { + UNORDERED_SCOPE(allocator2::allocator2()) { + UNORDERED_EPOINT("Mock allocator2 assignment operator."); + tag_ = x.tag_; + } + return *this; + } + + // If address throws, then it can't be used in erase or the + // destructor, which is very limiting. I need to check up on + // this. + + pointer address(reference r) { + //UNORDERED_SCOPE(allocator2::address(reference)) { + // UNORDERED_EPOINT("Mock allocator2 address function."); + //} + return pointer(&r); + } + + const_pointer address(const_reference r) { + //UNORDERED_SCOPE(allocator2::address(const_reference)) { + // UNORDERED_EPOINT("Mock allocator2 const address function."); + //} + return const_pointer(&r); + } + + pointer allocate(size_type n) { + T* ptr = 0; + UNORDERED_SCOPE(allocator2::allocate(size_type)) { + UNORDERED_EPOINT("Mock allocator2 allocate function."); + + using namespace std; + ptr = (T*) malloc(n * sizeof(T)); + if(!ptr) throw std::bad_alloc(); + } + test::detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_); + return pointer(ptr); + + //return pointer(static_cast(::operator new(n * sizeof(T)))); + } + + pointer allocate(size_type n, void const* u) + { + T* ptr = 0; + UNORDERED_SCOPE(allocator2::allocate(size_type, const_pointer)) { + UNORDERED_EPOINT("Mock allocator2 allocate function."); + + using namespace std; + ptr = (T*) malloc(n * sizeof(T)); + if(!ptr) throw std::bad_alloc(); + } + test::detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_); + return pointer(ptr); + + //return pointer(static_cast(::operator new(n * sizeof(T)))); + } + + void deallocate(pointer p, size_type n) + { + //::operator delete((void*) p); + if(p) { + test::detail::tracker.track_deallocate((void*) p, n, sizeof(T), tag_); + using namespace std; + free(p); + } + } + + void construct(pointer p, T const& t) { + UNORDERED_SCOPE(allocator2::construct(T*, T)) { + UNORDERED_EPOINT("Mock allocator2 construct function."); + new(p) T(t); + } + test::detail::tracker.track_construct((void*) p, sizeof(T), tag_); + } + +#if !defined(BOOST_NO_VARIADIC_TEMPLATES) + template void construct(T* p, BOOST_FWD_REF(Args)... args) { + UNORDERED_SCOPE(allocator2::construct(pointer, BOOST_FWD_REF(Args)...)) { + UNORDERED_EPOINT("Mock allocator2 construct function."); + new(p) T(boost::forward(args)...); + } + test::detail::tracker.track_construct((void*) p, sizeof(T), tag_); + } +#endif + + void destroy(T* p) { + test::detail::tracker.track_destroy((void*) p, sizeof(T), tag_); + p->~T(); + } + + size_type max_size() const { + UNORDERED_SCOPE(allocator2::construct(pointer, T)) { + UNORDERED_EPOINT("Mock allocator2 max_size function."); + } + return (std::numeric_limits::max)(); + } + + typedef false_type propagate_on_container_copy_assignment; + typedef false_type propagate_on_container_move_assignment; + typedef false_type propagate_on_container_swap; + }; + + template + void swap(allocator2& x, allocator2& y) + { + std::swap(x.tag_, y.tag_); + } + + // It's pretty much impossible to write a compliant swap when these + // two can throw. So they don't. + + template + inline bool operator==(allocator2 const& x, allocator2 const& y) + { + //UNORDERED_SCOPE(operator==(allocator2, allocator2)) { + // UNORDERED_EPOINT("Mock allocator2 equality operator."); + //} + return x.tag_ == y.tag_; + } + + template + inline bool operator!=(allocator2 const& x, allocator2 const& y) + { + //UNORDERED_SCOPE(operator!=(allocator2, allocator2)) { + // UNORDERED_EPOINT("Mock allocator2 inequality operator."); + //} + return x.tag_ != y.tag_; + } } }