diff options
Diffstat (limited to 'libs/container/test/propagate_allocator_test.hpp')
-rw-r--r-- | libs/container/test/propagate_allocator_test.hpp | 435 |
1 files changed, 311 insertions, 124 deletions
diff --git a/libs/container/test/propagate_allocator_test.hpp b/libs/container/test/propagate_allocator_test.hpp index 67138892b..aefda7658 100644 --- a/libs/container/test/propagate_allocator_test.hpp +++ b/libs/container/test/propagate_allocator_test.hpp @@ -20,81 +20,193 @@ namespace boost{ namespace container { namespace test{ -template<template<class, class> class ContainerWrapper> -bool test_propagate_allocator() +template<class Selector> +struct alloc_propagate_base; + +template<class T, class Allocator, class Selector> +class alloc_propagate_wrapper + : public alloc_propagate_base<Selector>::template apply<T, Allocator>::type { - { - typedef propagation_test_allocator<char, true, true, true, true> AlwaysPropagate; - typedef ContainerWrapper<char, AlwaysPropagate> PropagateCont; + BOOST_COPYABLE_AND_MOVABLE(alloc_propagate_wrapper) - ////////////////////////////////////////// - //Test AlwaysPropagate allocator propagation - ////////////////////////////////////////// - AlwaysPropagate::reset_unique_id(); + public: + typedef typename alloc_propagate_base + <Selector>::template apply<T, Allocator>::type Base; - //default constructor - PropagateCont c; - BOOST_TEST (c.get_stored_allocator().id_ == 0); - BOOST_TEST (c.get_stored_allocator().ctr_copies_ == 0); - BOOST_TEST (c.get_stored_allocator().ctr_moves_ == 0); - BOOST_TEST (c.get_stored_allocator().assign_copies_ == 0); - BOOST_TEST (c.get_stored_allocator().assign_moves_ == 0); - BOOST_TEST (c.get_stored_allocator().swaps_ == 0); + typedef typename Base::allocator_type allocator_type; + typedef typename Base::value_type value_type; + typedef typename Base::size_type size_type; - //copy constructor - PropagateCont c2(c); - //propagate_on_copy_constructor produces copies, moves or RVO (depending on the compiler). - //For allocators that copy in select_on_container_copy_construction, at least we must have a copy - unsigned int ctr_copies = c2.get_stored_allocator().ctr_copies_; - unsigned int ctr_moves = c2.get_stored_allocator().ctr_moves_; - BOOST_TEST (c2.get_stored_allocator().id_ == 0); - BOOST_TEST (ctr_copies > 0); - BOOST_TEST (c2.get_stored_allocator().ctr_moves_ >= 0); - BOOST_TEST (c2.get_stored_allocator().assign_copies_ == 0); - BOOST_TEST (c2.get_stored_allocator().assign_moves_ == 0); - BOOST_TEST (c2.get_stored_allocator().swaps_ == 0); + alloc_propagate_wrapper() + : Base() + {} - //move constructor - PropagateCont c3(boost::move(c2)); - BOOST_TEST (c3.get_stored_allocator().id_ == 0); - BOOST_TEST (c3.get_stored_allocator().ctr_copies_ == ctr_copies); - BOOST_TEST (c3.get_stored_allocator().ctr_moves_ > ctr_moves); - ctr_moves = c3.get_stored_allocator().ctr_moves_; - BOOST_TEST (ctr_moves > 0); - BOOST_TEST (c3.get_stored_allocator().assign_copies_ == 0); - BOOST_TEST (c3.get_stored_allocator().assign_moves_ == 0); - BOOST_TEST (c3.get_stored_allocator().swaps_ == 0); - - //copy assign - c2 = c3; - unsigned int assign_copies = c2.get_stored_allocator().assign_copies_; - BOOST_TEST (c2.get_stored_allocator().id_ == 0); - BOOST_TEST (c2.get_stored_allocator().ctr_copies_ == ctr_copies); - BOOST_TEST (c2.get_stored_allocator().ctr_moves_ == ctr_moves); - BOOST_TEST (assign_copies == 1); - BOOST_TEST (c2.get_stored_allocator().assign_moves_ == 0); - BOOST_TEST (c2.get_stored_allocator().swaps_ == 0); + explicit alloc_propagate_wrapper(const allocator_type &a) + : Base(a) + {} +/* + //sequence containers only + explicit alloc_propagate_wrapper(size_type n, const value_type &v, const allocator_type &a) + : Base(n, v, a) + {} - //move assign - c = boost::move(c2); - unsigned int assign_moves = c.get_stored_allocator().assign_moves_; - BOOST_TEST (c.get_stored_allocator().id_ == 0); - BOOST_TEST (c.get_stored_allocator().ctr_copies_ == ctr_copies); - BOOST_TEST (c.get_stored_allocator().ctr_moves_ == ctr_moves); - BOOST_TEST (c.get_stored_allocator().assign_copies_ == assign_copies); - BOOST_TEST (assign_moves == 1); - BOOST_TEST (c.get_stored_allocator().swaps_ == 0); + alloc_propagate_wrapper(size_type n, const allocator_type &a) + : Base(n, a) + {}*/ + + template<class Iterator> + alloc_propagate_wrapper(Iterator b, Iterator e, const allocator_type &a) + : Base(b, e, a) + {} + + #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + alloc_propagate_wrapper(std::initializer_list<value_type> il, const allocator_type& a) + : Base(il, a) + {} +/* + //associative containers only + alloc_propagate_wrapper(std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a) + : Base(il, comp, a) + {}*/ + + #endif + + alloc_propagate_wrapper(const alloc_propagate_wrapper &x) + : Base(x) + {} + + alloc_propagate_wrapper(const alloc_propagate_wrapper &x, const allocator_type &a) + : Base(x, a) + {} + + alloc_propagate_wrapper(BOOST_RV_REF(alloc_propagate_wrapper) x) + : Base(boost::move(static_cast<Base&>(x))) + {} + + alloc_propagate_wrapper(BOOST_RV_REF(alloc_propagate_wrapper) x, const allocator_type &a) + : Base(boost::move(static_cast<Base&>(x)), a) + {} + + alloc_propagate_wrapper &operator=(BOOST_COPY_ASSIGN_REF(alloc_propagate_wrapper) x) + { this->Base::operator=(x); return *this; } + + alloc_propagate_wrapper &operator=(BOOST_RV_REF(alloc_propagate_wrapper) x) + { this->Base::operator=(boost::move(static_cast<Base&>(x))); return *this; } + + void swap(alloc_propagate_wrapper &x) + { this->Base::swap(x); } +}; + +template<class T> +struct get_real_stored_allocator +{ + typedef typename T::stored_allocator_type type; +}; + +template<class Container> +void test_propagate_allocator_allocator_arg(); - //swap - c.get_stored_allocator().id_ = 999; - c.swap(c2); - unsigned int swaps = c2.get_stored_allocator().swaps_; - BOOST_TEST (c2.get_stored_allocator().id_ == 999); - BOOST_TEST (c2.get_stored_allocator().ctr_copies_ == ctr_copies); - BOOST_TEST (c2.get_stored_allocator().ctr_moves_ == ctr_moves); - BOOST_TEST (c2.get_stored_allocator().assign_copies_ == assign_copies); - BOOST_TEST (c2.get_stored_allocator().assign_moves_ == assign_moves); - BOOST_TEST (swaps == 1); +template<class Selector> +bool test_propagate_allocator() +{ + { + typedef propagation_test_allocator<char, true, true, true, true> AlwaysPropagate; + typedef alloc_propagate_wrapper<char, AlwaysPropagate, Selector> PropagateCont; + typedef typename get_real_stored_allocator<typename PropagateCont::Base>::type StoredAllocator; + { + ////////////////////////////////////////// + //Test AlwaysPropagate allocator propagation + ////////////////////////////////////////// + + //default constructor + StoredAllocator::reset_unique_id(111); + PropagateCont c; //stored 112 + BOOST_TEST (c.get_stored_allocator().id_ == 112); + BOOST_TEST (c.get_stored_allocator().ctr_copies_ == 0); + BOOST_TEST (c.get_stored_allocator().ctr_moves_ == 0); + BOOST_TEST (c.get_stored_allocator().assign_copies_ == 0); + BOOST_TEST (c.get_stored_allocator().assign_moves_ == 0); + BOOST_TEST (c.get_stored_allocator().swaps_ == 0); + } + { + //copy constructor + StoredAllocator::reset_unique_id(222); + PropagateCont c; //stored 223 + BOOST_TEST (c.get_stored_allocator().id_ == 223); + //propagate_on_copy_constructor produces copies, moves or RVO (depending on the compiler). + //For allocators that copy in select_on_container_copy_construction, at least we must have a copy + PropagateCont c2(c); //should propagate 223 + BOOST_TEST (c2.get_stored_allocator().id_ == 223); + BOOST_TEST (c2.get_stored_allocator().ctr_copies_ >= 1); + BOOST_TEST (c2.get_stored_allocator().ctr_moves_ >= 0); + BOOST_TEST (c2.get_stored_allocator().assign_copies_ == 0); + BOOST_TEST (c2.get_stored_allocator().assign_moves_ == 0); + BOOST_TEST (c2.get_stored_allocator().swaps_ == 0); + } + { + //move constructor + StoredAllocator::reset_unique_id(333); + PropagateCont c; //stored 334 + BOOST_TEST (c.get_stored_allocator().id_ == 334); + PropagateCont c2(boost::move(c)); //should propagate 334 + BOOST_TEST (c2.get_stored_allocator().id_ == 334); + BOOST_TEST (c2.get_stored_allocator().ctr_copies_ == 0); + BOOST_TEST (c2.get_stored_allocator().ctr_moves_ > 0); + BOOST_TEST (c2.get_stored_allocator().assign_copies_ == 0); + BOOST_TEST (c2.get_stored_allocator().assign_moves_ == 0); + BOOST_TEST (c2.get_stored_allocator().swaps_ == 0); + } + { + //copy assign + StoredAllocator::reset_unique_id(444); + PropagateCont c; //stored 445 + BOOST_TEST (c.get_stored_allocator().id_ == 445); + PropagateCont c2; //stored 446 + BOOST_TEST (c2.get_stored_allocator().id_ == 446); + c2 = c; //should propagate 445 + BOOST_TEST (c2.get_stored_allocator().id_ == 445); + BOOST_TEST (c2.get_stored_allocator().ctr_copies_ == 0); + BOOST_TEST (c2.get_stored_allocator().ctr_moves_ == 0); + BOOST_TEST (c2.get_stored_allocator().assign_copies_ == 1); + BOOST_TEST (c2.get_stored_allocator().assign_moves_ == 0); + BOOST_TEST (c2.get_stored_allocator().swaps_ == 0); + } + { + //move assign + StoredAllocator::reset_unique_id(555); + PropagateCont c; //stored 556 + BOOST_TEST (c.get_stored_allocator().id_ == 556); + PropagateCont c2; //stored 557 + BOOST_TEST (c2.get_stored_allocator().id_ == 557); + c = boost::move(c2); //should propagate 557 + BOOST_TEST (c.get_stored_allocator().id_ == 557); + BOOST_TEST (c.get_stored_allocator().ctr_copies_ == 0); + BOOST_TEST (c.get_stored_allocator().ctr_moves_ == 0); + BOOST_TEST (c.get_stored_allocator().assign_copies_ == 0); + BOOST_TEST (c.get_stored_allocator().assign_moves_ == 1); + BOOST_TEST (c.get_stored_allocator().swaps_ == 0); + } + { + //swap + StoredAllocator::reset_unique_id(666); + PropagateCont c; //stored 667 + BOOST_TEST (c.get_stored_allocator().id_ == 667); + PropagateCont c2; //stored 668 + BOOST_TEST (c2.get_stored_allocator().id_ == 668); + c.swap(c2); + BOOST_TEST (c2.get_stored_allocator().ctr_copies_ == 0); + BOOST_TEST (c.get_stored_allocator().ctr_copies_ == 0); + BOOST_TEST (c2.get_stored_allocator().ctr_moves_ == 0); + BOOST_TEST (c.get_stored_allocator().ctr_moves_ == 0); + BOOST_TEST (c2.get_stored_allocator().assign_copies_ == 0); + BOOST_TEST (c.get_stored_allocator().assign_copies_ == 0); + BOOST_TEST (c2.get_stored_allocator().assign_moves_ == 0); + BOOST_TEST (c.get_stored_allocator().assign_moves_ == 0); + BOOST_TEST (c2.get_stored_allocator().swaps_ == 1); + BOOST_TEST (c.get_stored_allocator().swaps_ == 1); + } + //And now allocator argument constructors + test_propagate_allocator_allocator_arg<PropagateCont>(); } ////////////////////////////////////////// @@ -102,74 +214,149 @@ bool test_propagate_allocator() ////////////////////////////////////////// { typedef propagation_test_allocator<char, false, false, false, false> NeverPropagate; - typedef ContainerWrapper<char, NeverPropagate> NoPropagateCont; - NeverPropagate::reset_unique_id(); + typedef alloc_propagate_wrapper<char, NeverPropagate, Selector> NoPropagateCont; + typedef typename get_real_stored_allocator<typename NoPropagateCont::Base>::type StoredAllocator; + { + //default constructor + StoredAllocator::reset_unique_id(111); + NoPropagateCont c; //stored 112 + BOOST_TEST (c.get_stored_allocator().id_ == 112); + BOOST_TEST (c.get_stored_allocator().ctr_copies_ == 0); + BOOST_TEST (c.get_stored_allocator().ctr_moves_ == 0); + BOOST_TEST (c.get_stored_allocator().assign_copies_ == 0); + BOOST_TEST (c.get_stored_allocator().assign_moves_ == 0); + BOOST_TEST (c.get_stored_allocator().swaps_ == 0); + } + { + //copy constructor + //propagate_on_copy_constructor produces copies, moves or RVO (depending on the compiler) + //For allocators that don't copy in select_on_container_copy_construction we must have a default + //construction + StoredAllocator::reset_unique_id(222); + NoPropagateCont c; //stored 223 + BOOST_TEST (c.get_stored_allocator().id_ == 223); + NoPropagateCont c2(c); //should NOT propagate 223 + BOOST_TEST (c2.get_stored_allocator().id_ == 224); + BOOST_TEST (c2.get_stored_allocator().ctr_copies_ >= 0); + BOOST_TEST (c2.get_stored_allocator().ctr_moves_ >= 0); + BOOST_TEST (c2.get_stored_allocator().assign_copies_ == 0); + BOOST_TEST (c2.get_stored_allocator().assign_moves_ == 0); + BOOST_TEST (c2.get_stored_allocator().swaps_ == 0); + } + { + //move constructor + StoredAllocator::reset_unique_id(333); + NoPropagateCont c; //stored 334 + BOOST_TEST (c.get_stored_allocator().id_ == 334); + NoPropagateCont c2(boost::move(c)); // should NOT propagate 334 + BOOST_TEST (c2.get_stored_allocator().ctr_copies_ >= 0); + BOOST_TEST (c2.get_stored_allocator().ctr_moves_ >= 0); + BOOST_TEST (c2.get_stored_allocator().assign_copies_ == 0); + BOOST_TEST (c2.get_stored_allocator().assign_moves_ == 0); + BOOST_TEST (c2.get_stored_allocator().swaps_ == 0); + } + { + //copy assign + StoredAllocator::reset_unique_id(444); + NoPropagateCont c; //stored 445 + NoPropagateCont c2; //stored 446 + c2 = c; // should NOT propagate 445 + BOOST_TEST (c2.get_stored_allocator().id_ == 446); + BOOST_TEST (c2.get_stored_allocator().ctr_copies_ == 0); + BOOST_TEST (c2.get_stored_allocator().ctr_moves_ == 0); + BOOST_TEST (c2.get_stored_allocator().assign_copies_ == 0); + BOOST_TEST (c2.get_stored_allocator().assign_moves_ == 0); + BOOST_TEST (c2.get_stored_allocator().swaps_ == 0); + } + { + //move assign + StoredAllocator::reset_unique_id(555); + NoPropagateCont c; //stored 556 + NoPropagateCont c2; //stored 557 + c2 = c; // should NOT propagate 556 + BOOST_TEST (c2.get_stored_allocator().id_ == 557); + BOOST_TEST (c2.get_stored_allocator().ctr_copies_ == 0); + BOOST_TEST (c2.get_stored_allocator().ctr_moves_ == 0); + BOOST_TEST (c2.get_stored_allocator().assign_copies_ == 0); + BOOST_TEST (c2.get_stored_allocator().assign_moves_ == 0); + BOOST_TEST (c2.get_stored_allocator().swaps_ == 0); + } + { + //swap + StoredAllocator::reset_unique_id(666); + NoPropagateCont c; //stored 667 + BOOST_TEST (c.get_stored_allocator().id_ == 667); + NoPropagateCont c2; //stored 668 + BOOST_TEST (c2.get_stored_allocator().id_ == 668); + c2.swap(c); // should NOT swap 667 and 668 + BOOST_TEST (c2.get_stored_allocator().id_ == 668); + BOOST_TEST (c2.get_stored_allocator().ctr_copies_ == 0); + BOOST_TEST (c2.get_stored_allocator().ctr_moves_ == 0); + BOOST_TEST (c2.get_stored_allocator().assign_copies_ == 0); + BOOST_TEST (c2.get_stored_allocator().assign_moves_ == 0); + BOOST_TEST (c2.get_stored_allocator().swaps_ == 0); + BOOST_TEST (c.get_stored_allocator().id_ == 667); + BOOST_TEST (c.get_stored_allocator().ctr_copies_ == 0); + BOOST_TEST (c.get_stored_allocator().ctr_moves_ == 0); + BOOST_TEST (c.get_stored_allocator().assign_copies_ == 0); + BOOST_TEST (c.get_stored_allocator().assign_moves_ == 0); + BOOST_TEST (c.get_stored_allocator().swaps_ == 0); + } + //And now allocator argument constructors + test_propagate_allocator_allocator_arg<NoPropagateCont>(); + } - //default constructor - NoPropagateCont c; - BOOST_TEST (c.get_stored_allocator().id_ == 0); - BOOST_TEST (c.get_stored_allocator().ctr_copies_ == 0); + return report_errors() == 0; +} + +template<class Container> +void test_propagate_allocator_allocator_arg() +{ + typedef typename Container::allocator_type allocator_type; + typedef typename get_real_stored_allocator<typename Container::Base>::type StoredAllocator; + + { //The allocator must be always propagated + //allocator constructor + allocator_type::reset_unique_id(111); + const allocator_type & a = allocator_type(); //stored 112 + Container c(a); //should propagate 112 + BOOST_TEST (c.get_stored_allocator().id_ == 112); + BOOST_TEST (c.get_stored_allocator().ctr_copies_ > 0); BOOST_TEST (c.get_stored_allocator().ctr_moves_ == 0); BOOST_TEST (c.get_stored_allocator().assign_copies_ == 0); BOOST_TEST (c.get_stored_allocator().assign_moves_ == 0); BOOST_TEST (c.get_stored_allocator().swaps_ == 0); - - //copy constructor - //propagate_on_copy_constructor produces copies, moves or RVO (depending on the compiler) - //For allocators that don't copy in select_on_container_copy_construction we must have a default - //construction - NoPropagateCont c2(c); - unsigned int ctr_copies = c2.get_stored_allocator().ctr_copies_; - unsigned int ctr_moves = c2.get_stored_allocator().ctr_moves_; - BOOST_TEST (c2.get_stored_allocator().id_ == 1); - BOOST_TEST (ctr_copies >= 0); - BOOST_TEST (ctr_moves >= 0); - BOOST_TEST (c2.get_stored_allocator().assign_copies_ == 0); - BOOST_TEST (c2.get_stored_allocator().assign_moves_ == 0); - BOOST_TEST (c2.get_stored_allocator().swaps_ == 0); - - //move constructor - NoPropagateCont c3(boost::move(c2)); - BOOST_TEST (c3.get_stored_allocator().id_ == 1); - BOOST_TEST (c3.get_stored_allocator().ctr_copies_ == ctr_copies); - BOOST_TEST (c3.get_stored_allocator().ctr_moves_ > ctr_moves); - unsigned int ctr_moves2 = ctr_moves; - ctr_moves = c3.get_stored_allocator().ctr_moves_; - BOOST_TEST (c3.get_stored_allocator().assign_copies_ == 0); - BOOST_TEST (c3.get_stored_allocator().assign_moves_ == 0); - BOOST_TEST (c3.get_stored_allocator().swaps_ == 0); - - //copy assign - c2 = c3; - BOOST_TEST (c2.get_stored_allocator().id_ == 1); - BOOST_TEST (c2.get_stored_allocator().ctr_copies_ == ctr_copies); - BOOST_TEST (c2.get_stored_allocator().ctr_moves_ == ctr_moves2); + } + { + //copy allocator constructor + StoredAllocator::reset_unique_id(999); + Container c; + //stored_allocator_type could be the same type as allocator_type + //so reset it again to get a predictable result + allocator_type::reset_unique_id(222); + Container c2(c, allocator_type()); //should propagate 223 + BOOST_TEST (c2.get_stored_allocator().id_ == 223); + BOOST_TEST (c2.get_stored_allocator().ctr_copies_ > 0); + BOOST_TEST (c2.get_stored_allocator().ctr_moves_ == 0); BOOST_TEST (c2.get_stored_allocator().assign_copies_ == 0); BOOST_TEST (c2.get_stored_allocator().assign_moves_ == 0); BOOST_TEST (c2.get_stored_allocator().swaps_ == 0); - - //move assign - c = boost::move(c2); - BOOST_TEST (c.get_stored_allocator().id_ == 0); - BOOST_TEST (c.get_stored_allocator().ctr_copies_ == 0); - BOOST_TEST (c.get_stored_allocator().ctr_moves_ == 0); - BOOST_TEST (c.get_stored_allocator().assign_copies_ == 0); - BOOST_TEST (c.get_stored_allocator().assign_moves_ == 0); - BOOST_TEST (c.get_stored_allocator().swaps_ == 0); - - //swap - c.get_stored_allocator().id_ = 999; - c2.swap(c); - BOOST_TEST (c2.get_stored_allocator().id_ == 1); - BOOST_TEST (c.get_stored_allocator().id_ == 999); - BOOST_TEST (c2.get_stored_allocator().ctr_copies_ == ctr_copies); - BOOST_TEST (c2.get_stored_allocator().ctr_moves_ == ctr_moves2); + } + { + //move allocator constructor + StoredAllocator::reset_unique_id(999); + Container c; + //stored_allocator_type could be the same type as allocator_type + //so reset it again to get a predictable result + allocator_type::reset_unique_id(333); + Container c2(boost::move(c), allocator_type()); //should propagate 334 + BOOST_TEST (c2.get_stored_allocator().id_ == 334); + BOOST_TEST (c2.get_stored_allocator().ctr_copies_ > 0); + BOOST_TEST (c2.get_stored_allocator().ctr_moves_ == 0); BOOST_TEST (c2.get_stored_allocator().assign_copies_ == 0); BOOST_TEST (c2.get_stored_allocator().assign_moves_ == 0); BOOST_TEST (c2.get_stored_allocator().swaps_ == 0); } - - return report_errors() == 0; } } //namespace test{ |