/* (c) 2014 Glen Joseph Fernandes glenjofe at gmail dot com Distributed under the Boost Software License, Version 1.0. http://boost.org/LICENSE_1_0.txt */ #ifndef BOOST_ALIGN_ALIGNED_ALLOCATOR_ADAPTOR_HPP #define BOOST_ALIGN_ALIGNED_ALLOCATOR_ADAPTOR_HPP #include #include #include #include #include #include #include #include #include #if !defined(BOOST_NO_CXX11_ALLOCATOR) #include #endif #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) #include #endif namespace boost { namespace alignment { template class aligned_allocator_adaptor : public Allocator { BOOST_STATIC_ASSERT(detail:: is_alignment_constant::value); #if !defined(BOOST_NO_CXX11_ALLOCATOR) typedef std::allocator_traits Traits; typedef typename Traits:: template rebind_alloc CharAlloc; typedef typename Traits:: template rebind_traits CharTraits; typedef typename CharTraits::pointer CharPtr; #else typedef typename Allocator:: template rebind::other CharAlloc; typedef typename CharAlloc::pointer CharPtr; #endif public: #if !defined(BOOST_NO_CXX11_ALLOCATOR) typedef typename Traits::value_type value_type; typedef typename Traits::size_type size_type; #else typedef typename Allocator::value_type value_type; typedef typename Allocator::size_type size_type; #endif typedef value_type* pointer; typedef const value_type* const_pointer; typedef void* void_pointer; typedef const void* const_void_pointer; typedef std::ptrdiff_t difference_type; private: typedef detail::max_align::value, alignment_of::value>::value> MaxAlign; public: template struct rebind { #if !defined(BOOST_NO_CXX11_ALLOCATOR) typedef aligned_allocator_adaptor, Alignment> other; #else typedef aligned_allocator_adaptor::other, Alignment> other; #endif }; #if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) aligned_allocator_adaptor() = default; #else aligned_allocator_adaptor() : Allocator() { } #endif #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) template explicit aligned_allocator_adaptor(A&& alloc) BOOST_NOEXCEPT : Allocator(std::forward(alloc)) { } #else template explicit aligned_allocator_adaptor(const A& alloc) BOOST_NOEXCEPT : Allocator(alloc) { } #endif template aligned_allocator_adaptor(const aligned_allocator_adaptor& other) BOOST_NOEXCEPT : Allocator(other.base()) { } Allocator& base() BOOST_NOEXCEPT { return static_cast(*this); } const Allocator& base() const BOOST_NOEXCEPT { return static_cast(*this); } pointer allocate(size_type size) { std::size_t n1 = size * sizeof(value_type); std::size_t n2 = n1 + MaxAlign::value - 1; CharAlloc a(base()); CharPtr p1 = a.allocate(sizeof p1 + n2); void* p2 = detail::addressof(*p1) + sizeof p1; (void)align(MaxAlign::value, n1, p2, n2); void* p3 = static_cast(p2) - 1; ::new(p3) CharPtr(p1); return static_cast(p2); } pointer allocate(size_type size, const_void_pointer hint) { std::size_t n1 = size * sizeof(value_type); std::size_t n2 = n1 + MaxAlign::value - 1; CharPtr h = CharPtr(); if (hint) { h = *(static_cast(hint) - 1); } CharAlloc a(base()); #if !defined(BOOST_NO_CXX11_ALLOCATOR) CharPtr p1 = CharTraits::allocate(a, sizeof p1 + n2, h); #else CharPtr p1 = a.allocate(sizeof p1 + n2, h); #endif void* p2 = detail::addressof(*p1) + sizeof p1; (void)align(MaxAlign::value, n1, p2, n2); void* p3 = static_cast(p2) - 1; ::new(p3) CharPtr(p1); return static_cast(p2); } void deallocate(pointer ptr, size_type size) { CharPtr* p1 = reinterpret_cast(ptr) - 1; CharPtr p2 = *p1; p1->~CharPtr(); CharAlloc a(base()); a.deallocate(p2, size * sizeof(value_type) + MaxAlign::value + sizeof p2); } }; template inline bool operator==(const aligned_allocator_adaptor& a, const aligned_allocator_adaptor& b) BOOST_NOEXCEPT { return a.base() == b.base(); } template inline bool operator!=(const aligned_allocator_adaptor& a, const aligned_allocator_adaptor& b) BOOST_NOEXCEPT { return !(a == b); } } } #endif