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