2 Copyright 2014-2016 Glen Joseph Fernandes
5 Distributed under the Boost Software License, Version 1.0.
6 (http://www.boost.org/LICENSE_1_0.txt)
8 #ifndef BOOST_ALIGN_ALIGNED_ALLOCATOR_ADAPTOR_HPP
9 #define BOOST_ALIGN_ALIGNED_ALLOCATOR_ADAPTOR_HPP
11 #include <boost/align/detail/is_alignment_constant.hpp>
12 #include <boost/align/detail/max_align.hpp>
13 #include <boost/align/detail/max_size.hpp>
14 #include <boost/align/align.hpp>
15 #include <boost/align/aligned_allocator_adaptor_forward.hpp>
16 #include <boost/align/alignment_of.hpp>
17 #include <boost/core/pointer_traits.hpp>
18 #include <boost/static_assert.hpp>
21 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
25 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
32 template<class Allocator, std::size_t Alignment>
33 class aligned_allocator_adaptor
35 BOOST_STATIC_ASSERT(detail::is_alignment_constant<Alignment>::value);
37 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
38 typedef std::allocator_traits<Allocator> traits;
39 typedef typename traits::template rebind_alloc<char> char_alloc;
40 typedef typename traits::template rebind_traits<char> char_traits;
41 typedef typename char_traits::pointer char_ptr;
43 typedef typename Allocator::template rebind<char>::other char_alloc;
44 typedef typename char_alloc::pointer char_ptr;
48 typedef typename Allocator::value_type value_type;
49 typedef value_type* pointer;
50 typedef const value_type* const_pointer;
51 typedef void* void_pointer;
52 typedef const void* const_void_pointer;
53 typedef std::size_t size_type;
54 typedef std::ptrdiff_t difference_type;
60 value = detail::max_size<Alignment,
61 detail::max_align<U, char_ptr>::value>::value
68 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
69 typedef aligned_allocator_adaptor<typename traits::template
70 rebind_alloc<U>, Alignment> other;
72 typedef aligned_allocator_adaptor<typename Allocator::template
73 rebind<U>::other, Alignment> other;
77 aligned_allocator_adaptor()
80 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
82 explicit aligned_allocator_adaptor(A&& alloc) BOOST_NOEXCEPT
83 : Allocator(std::forward<A>(alloc)) { }
86 explicit aligned_allocator_adaptor(const A& alloc) BOOST_NOEXCEPT
87 : Allocator(alloc) { }
91 aligned_allocator_adaptor(const aligned_allocator_adaptor<U,
92 Alignment>& other) BOOST_NOEXCEPT
93 : Allocator(other.base()) { }
95 Allocator& base() BOOST_NOEXCEPT {
96 return static_cast<Allocator&>(*this);
99 const Allocator& base() const BOOST_NOEXCEPT {
100 return static_cast<const Allocator&>(*this);
103 pointer allocate(size_type size) {
105 m = min_align<value_type>::value
107 std::size_t s = size * sizeof(value_type);
108 std::size_t n = s + m - 1;
109 char_alloc a(base());
110 char_ptr p = a.allocate(sizeof p + n);
111 void* r = boost::to_address(p) + sizeof p;
112 (void)boost::alignment::align(m, s, r, n);
113 ::new(static_cast<void*>(static_cast<char_ptr*>(r) - 1)) char_ptr(p);
114 return static_cast<pointer>(r);
117 pointer allocate(size_type size, const_void_pointer hint) {
119 m = min_align<value_type>::value
121 std::size_t s = size * sizeof(value_type);
122 std::size_t n = s + m - 1;
123 char_ptr h = char_ptr();
125 h = *(static_cast<const char_ptr*>(hint) - 1);
127 char_alloc a(base());
128 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
129 char_ptr p = char_traits::allocate(a, sizeof p + n, h);
131 char_ptr p = a.allocate(sizeof p + n, h);
133 void* r = boost::to_address(p) + sizeof p;
134 (void)boost::alignment::align(m, s, r, n);
135 ::new(static_cast<void*>(static_cast<char_ptr*>(r) - 1)) char_ptr(p);
136 return static_cast<pointer>(r);
139 void deallocate(pointer ptr, size_type size) {
141 m = min_align<value_type>::value
143 char_ptr* p = reinterpret_cast<char_ptr*>(ptr) - 1;
146 char_alloc a(base());
147 a.deallocate(r, sizeof r + size * sizeof(value_type) + m - 1);
151 template<class A, class B, std::size_t Alignment>
153 operator==(const aligned_allocator_adaptor<A, Alignment>& a,
154 const aligned_allocator_adaptor<B, Alignment>& b) BOOST_NOEXCEPT
156 return a.base() == b.base();
159 template<class A, class B, std::size_t Alignment>
161 operator!=(const aligned_allocator_adaptor<A, Alignment>& a,
162 const aligned_allocator_adaptor<B, Alignment>& b) BOOST_NOEXCEPT