123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447 |
- //////////////////////////////////////////////////////////////////////////////
- //
- // (C) Copyright Ion Gaztanaga 2011-2013. Distributed under the Boost
- // Software License, Version 1.0. (See accompanying file
- // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- //
- // See http://www.boost.org/libs/container for documentation.
- //
- //////////////////////////////////////////////////////////////////////////////
- #include <boost/container/detail/config_begin.hpp>
- #include <cstddef>
- #include <boost/container/allocator_traits.hpp>
- #include <boost/static_assert.hpp>
- #include <boost/container/detail/type_traits.hpp>
- #include <boost/container/detail/function_detector.hpp>
- #include <boost/move/utility_core.hpp>
- #include <memory>
- #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
- #include <boost/move/detail/fwd_macros.hpp>
- #endif
- #include <boost/core/lightweight_test.hpp>
- template<class T>
- class SimpleAllocator
- {
- public:
- bool allocate_called_;
- bool deallocate_called_;
- typedef boost::container::dtl::
- true_type is_always_equal;
- typedef T value_type;
- template <class U>
- SimpleAllocator(SimpleAllocator<U>)
- : allocate_called_(false)
- , deallocate_called_(false)
- {}
- SimpleAllocator()
- : allocate_called_(false)
- , deallocate_called_(false)
- {}
- T* allocate(std::size_t)
- { allocate_called_ = true; return 0; }
- void deallocate(T*, std::size_t)
- { deallocate_called_ = true; }
- bool allocate_called() const
- { return allocate_called_; }
- bool deallocate_called() const
- { return deallocate_called_; }
- friend bool operator==(const SimpleAllocator &, const SimpleAllocator &)
- { return true; }
- friend bool operator!=(const SimpleAllocator &, const SimpleAllocator &)
- { return false; }
- };
- template<class T>
- class SimpleSmartPtr
- {
- void unspecified_bool_type_func() const {}
- typedef void (SimpleSmartPtr::*unspecified_bool_type)() const;
- public:
- typedef T* pointer;
- explicit SimpleSmartPtr(pointer p = 0)
- : ptr_(p)
- {}
- SimpleSmartPtr(const SimpleSmartPtr &c)
- { this->ptr_ = c.ptr_; }
- SimpleSmartPtr & operator=(const SimpleSmartPtr &c)
- { this->ptr_ = c.ptr_; }
- operator unspecified_bool_type() const
- { return ptr_? &SimpleSmartPtr::unspecified_bool_type_func : 0; }
- private:
- T *ptr_;
- };
- template<class T>
- class ComplexAllocator
- {
- public:
- bool allocate_called_;
- bool deallocate_called_;
- bool allocate_hint_called_;
- bool destroy_called_;
- mutable bool max_size_called_;
- mutable bool select_on_container_copy_construction_called_;
- bool construct_called_;
- mutable bool storage_is_unpropagable_;
- typedef T value_type;
- typedef SimpleSmartPtr<T> pointer;
- typedef SimpleSmartPtr<const T> const_pointer;
- typedef typename ::boost::container::
- dtl::unvoid_ref<T>::type reference;
- typedef typename ::boost::container::
- dtl::unvoid_ref<const T>::type const_reference;
- typedef SimpleSmartPtr<void> void_pointer;
- typedef SimpleSmartPtr<const void> const_void_pointer;
- typedef signed short difference_type;
- typedef unsigned short size_type;
- typedef boost::container::dtl::
- true_type propagate_on_container_copy_assignment;
- typedef boost::container::dtl::
- true_type propagate_on_container_move_assignment;
- typedef boost::container::dtl::
- true_type propagate_on_container_swap;
- typedef boost::container::dtl::
- true_type is_partially_propagable;
- ComplexAllocator()
- : allocate_called_(false)
- , deallocate_called_(false)
- , allocate_hint_called_(false)
- , destroy_called_(false)
- , max_size_called_(false)
- , select_on_container_copy_construction_called_(false)
- , construct_called_(false)
- {}
- pointer allocate(size_type)
- { allocate_called_ = true; return pointer(); }
- void deallocate(pointer, size_type)
- { deallocate_called_ = true; }
- //optional
- ComplexAllocator select_on_container_copy_construction() const
- { select_on_container_copy_construction_called_ = true; return *this; }
- pointer allocate(size_type n, const const_void_pointer &)
- { allocate_hint_called_ = true; return allocate(n); }
- template<class U>
- void destroy(U*)
- { destroy_called_ = true; }
- size_type max_size() const
- { max_size_called_ = true; return size_type(size_type(0)-1); }
- #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
- #define BOOST_CONTAINER_COMPLEXALLOCATOR_CONSTRUCT_IMPL(N)\
- \
- template< class U BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \
- void construct(U *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N) \
- { construct_called_ = true; ::new(p) U ( BOOST_MOVE_FWD##N ); }\
- //
- BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_COMPLEXALLOCATOR_CONSTRUCT_IMPL)
- #undef BOOST_CONTAINER_COMPLEXALLOCATOR_CONSTRUCT_IMPL
- #else
- template< class U, class ...Args>
- void construct(U *p, BOOST_FWD_REF(Args) ...args)
- { construct_called_ = true; ::new(p) U( ::boost::forward<Args>(args)...); }
- #endif
- template<class U>
- void construct(U *p, boost::container::default_init_t)
- { construct_called_ = true; ::new(p)U; }
- bool storage_is_unpropagable(pointer p) const
- { storage_is_unpropagable_ = true; return !p; }
- //getters
- bool allocate_called() const
- { return allocate_called_; }
- bool deallocate_called() const
- { return deallocate_called_; }
- bool allocate_hint_called() const
- { return allocate_hint_called_; }
- bool destroy_called() const
- { return destroy_called_; }
- bool max_size_called() const
- { return max_size_called_; }
- bool select_on_container_copy_construction_called() const
- { return select_on_container_copy_construction_called_; }
- bool construct_called() const
- { return construct_called_; }
- bool storage_is_unpropagable_called() const
- { return storage_is_unpropagable_; }
- };
- class copymovable
- {
- BOOST_COPYABLE_AND_MOVABLE(copymovable)
- public:
- bool copymoveconstructed_;
- bool moved_;
- copymovable(int, int, int)
- : copymoveconstructed_(false), moved_(false)
- {}
- copymovable()
- : copymoveconstructed_(false), moved_(false)
- {}
- copymovable(const copymovable &)
- : copymoveconstructed_(true), moved_(false)
- {}
- copymovable(BOOST_RV_REF(copymovable))
- : copymoveconstructed_(true), moved_(true)
- {}
- copymovable & operator=(BOOST_COPY_ASSIGN_REF(copymovable) ){ return *this; }
- copymovable & operator=(BOOST_RV_REF(copymovable) ){ return *this; }
- bool copymoveconstructed() const
- { return copymoveconstructed_; }
- bool moved() const
- { return moved_; }
- };
- void test_void_allocator()
- {
- boost::container::allocator_traits<std::allocator<void> > stdtraits; (void)stdtraits;
- boost::container::allocator_traits<SimpleAllocator<void> > simtraits; (void)simtraits;
- boost::container::allocator_traits<ComplexAllocator<void> > comtraits; (void)comtraits;
- }
- int main()
- {
- using namespace boost::container::dtl;
- test_void_allocator();
- //SimpleAllocator
- BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
- < SimpleAllocator<int> >::value_type, int>::value ));
- BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
- < SimpleAllocator<int> >::pointer, int*>::value ));
- BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
- < SimpleAllocator<int> >::const_pointer, const int*>::value ));
- BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
- < SimpleAllocator<int> >::void_pointer, void*>::value ));
- BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
- < SimpleAllocator<int> >::const_void_pointer, const void*>::value ));
- BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
- < SimpleAllocator<int> >::difference_type, std::ptrdiff_t>::value ));
- BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
- < SimpleAllocator<int> >::size_type, std::size_t>::value ));
- BOOST_STATIC_ASSERT(( boost::container::allocator_traits
- < SimpleAllocator<int> >::propagate_on_container_copy_assignment::value == false ));
- BOOST_STATIC_ASSERT(( boost::container::allocator_traits
- < SimpleAllocator<int> >::propagate_on_container_move_assignment::value == false ));
- BOOST_STATIC_ASSERT(( boost::container::allocator_traits
- < SimpleAllocator<int> >::propagate_on_container_swap::value == false ));
- BOOST_STATIC_ASSERT(( boost::container::allocator_traits
- < SimpleAllocator<int> >::is_always_equal::value == true ));
- BOOST_STATIC_ASSERT(( boost::container::allocator_traits
- < SimpleAllocator<int> >::is_partially_propagable::value == false ));
- BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
- < SimpleAllocator<int> >::rebind_traits<double>::allocator_type
- , SimpleAllocator<double> >::value ));
- BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
- < SimpleAllocator<int> >::rebind_alloc<double>::value_type
- , double >::value ));
- //ComplexAllocator
- BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
- < ComplexAllocator<int> >::value_type, int>::value ));
- BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
- < ComplexAllocator<int> >::pointer, SimpleSmartPtr<int> >::value ));
- BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
- < ComplexAllocator<int> >::const_pointer, SimpleSmartPtr<const int> >::value ));
- BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
- < ComplexAllocator<int> >::void_pointer, SimpleSmartPtr<void> >::value ));
- BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
- < ComplexAllocator<int> >::const_void_pointer, SimpleSmartPtr<const void> >::value ));
- BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
- < ComplexAllocator<int> >::difference_type, signed short>::value ));
- BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
- < ComplexAllocator<int> >::size_type, unsigned short>::value ));
- BOOST_STATIC_ASSERT(( boost::container::allocator_traits
- < ComplexAllocator<int> >::propagate_on_container_copy_assignment::value == true ));
- BOOST_STATIC_ASSERT(( boost::container::allocator_traits
- < ComplexAllocator<int> >::propagate_on_container_move_assignment::value == true ));
- BOOST_STATIC_ASSERT(( boost::container::allocator_traits
- < ComplexAllocator<int> >::propagate_on_container_swap::value == true ));
- BOOST_STATIC_ASSERT(( boost::container::allocator_traits
- < ComplexAllocator<int> >::is_always_equal::value == false ));
- BOOST_STATIC_ASSERT(( boost::container::allocator_traits
- < ComplexAllocator<int> >::is_partially_propagable::value == true ));
- BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
- < ComplexAllocator<int> >::rebind_traits<double>::allocator_type
- , ComplexAllocator<double> >::value ));
- BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
- < ComplexAllocator<int> >::rebind_alloc<double>::value_type
- , double >::value ));
- typedef ComplexAllocator<int> CAlloc;
- typedef SimpleAllocator<int> SAlloc;
- typedef boost::container::allocator_traits<CAlloc> CAllocTraits;
- typedef boost::container::allocator_traits<SAlloc> SAllocTraits;
- CAlloc c_alloc;
- SAlloc s_alloc;
- //allocate
- CAllocTraits::allocate(c_alloc, 1);
- BOOST_TEST(c_alloc.allocate_called());
- SAllocTraits::allocate(s_alloc, 1);
- BOOST_TEST(s_alloc.allocate_called());
- //deallocate
- CAllocTraits::deallocate(c_alloc, CAllocTraits::pointer(), 1);
- BOOST_TEST(c_alloc.deallocate_called());
- SAllocTraits::deallocate(s_alloc, SAllocTraits::pointer(), 1);
- BOOST_TEST(s_alloc.deallocate_called());
- //allocate with hint
- CAllocTraits::allocate(c_alloc, 1, CAllocTraits::const_void_pointer());
- BOOST_TEST(c_alloc.allocate_hint_called());
- s_alloc.allocate_called_ = false;
- SAllocTraits::allocate(s_alloc, 1, SAllocTraits::const_void_pointer());
- BOOST_TEST(s_alloc.allocate_called());
- //destroy
- float dummy;
- CAllocTraits::destroy(c_alloc, &dummy);
- BOOST_TEST(c_alloc.destroy_called());
- SAllocTraits::destroy(s_alloc, &dummy);
- //max_size
- CAllocTraits::max_size(c_alloc);
- BOOST_TEST(c_alloc.max_size_called());
- BOOST_TEST(SAllocTraits::size_type(-1)/sizeof(SAllocTraits::value_type) == SAllocTraits::max_size(s_alloc));
- //select_on_container_copy_construction
- CAllocTraits::select_on_container_copy_construction(c_alloc);
- BOOST_TEST(c_alloc.select_on_container_copy_construction_called());
- SAllocTraits::select_on_container_copy_construction(s_alloc);
- //construct
- {
- copymovable c;
- c.copymoveconstructed_ = true;
- c.copymoveconstructed_ = true;
- CAllocTraits::construct(c_alloc, &c);
- BOOST_TEST(c_alloc.construct_called() && !c.copymoveconstructed() && !c.moved());
- }
- {
- int i = 5;
- CAllocTraits::construct(c_alloc, &i, boost::container::default_init);
- BOOST_TEST(c_alloc.construct_called() && i == 5);
- }
- {
- copymovable c;
- copymovable c2;
- CAllocTraits::construct(c_alloc, &c, c2);
- BOOST_TEST(c_alloc.construct_called() && c.copymoveconstructed() && !c.moved());
- }
- {
- copymovable c;
- copymovable c2;
- CAllocTraits::construct(c_alloc, &c, ::boost::move(c2));
- BOOST_TEST(c_alloc.construct_called() && c.copymoveconstructed() && c.moved());
- }
- {
- copymovable c;
- c.copymoveconstructed_ = true;
- c.copymoveconstructed_ = true;
- SAllocTraits::construct(s_alloc, &c);
- BOOST_TEST(!c.copymoveconstructed() && !c.moved());
- }
- {
- int i = 4;
- SAllocTraits::construct(s_alloc, &i, boost::container::default_init);
- BOOST_TEST(i == 4);
- }
- {
- copymovable c;
- copymovable c2;
- SAllocTraits::construct(s_alloc, &c, c2);
- BOOST_TEST(c.copymoveconstructed() && !c.moved());
- }
- {
- copymovable c;
- copymovable c2;
- SAllocTraits::construct(s_alloc, &c, ::boost::move(c2));
- BOOST_TEST(c.copymoveconstructed() && c.moved());
- }
- {
- copymovable c;
- CAllocTraits::construct(c_alloc, &c, 0, 1, 2);
- BOOST_TEST(c_alloc.construct_called() && !c.copymoveconstructed() && !c.moved());
- }
- {
- copymovable c;
- copymovable c2;
- SAllocTraits::construct(s_alloc, &c, 0, 1, 2);
- BOOST_TEST(!c.copymoveconstructed() && !c.moved());
- }
- //storage_is_unpropagable
- {
- SAlloc s_alloc2;
- BOOST_TEST(!SAllocTraits::storage_is_unpropagable(s_alloc, SAllocTraits::pointer()));
- }
- {
- {
- CAlloc c_alloc2;
- CAlloc::value_type v;
- BOOST_TEST(!CAllocTraits::storage_is_unpropagable(c_alloc, CAllocTraits::pointer(&v)));
- BOOST_TEST(c_alloc.storage_is_unpropagable_called());
- }
- {
- CAlloc c_alloc2;
- BOOST_TEST( CAllocTraits::storage_is_unpropagable(c_alloc2, CAllocTraits::pointer()));
- BOOST_TEST(c_alloc2.storage_is_unpropagable_called());
- }
- }
- return ::boost::report_errors();
- }
- #include <boost/container/detail/config_end.hpp>
|