2 (c) 2014-2015 Glen Joseph Fernandes
3 glenjofe at gmail dot com
5 Distributed under the Boost Software
7 http://boost.org/LICENSE_1_0.txt
9 #ifndef BOOST_ALIGN_ALIGNED_ALLOCATOR_ADAPTOR_HPP
10 #define BOOST_ALIGN_ALIGNED_ALLOCATOR_ADAPTOR_HPP
12 #include <boost/config.hpp>
13 #include <boost/static_assert.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/align/detail/addressof.hpp>
18 #include <boost/align/detail/is_alignment_constant.hpp>
19 #include <boost/align/detail/max_align.hpp>
22 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
26 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
33 template<class Allocator, std::size_t Alignment>
34 class aligned_allocator_adaptor
36 BOOST_STATIC_ASSERT(detail::
37 is_alignment_constant<Alignment>::value);
39 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
40 typedef std::allocator_traits<Allocator> traits;
42 typedef typename traits::
43 template rebind_alloc<char> char_alloc;
45 typedef typename traits::
46 template rebind_traits<char> char_traits;
48 typedef typename char_traits::pointer char_ptr;
50 typedef typename Allocator::
51 template rebind<char>::other char_alloc;
53 typedef typename char_alloc::pointer char_ptr;
57 ptr_align = alignment_of<char_ptr>::value
61 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
62 typedef typename traits::value_type value_type;
63 typedef typename traits::size_type size_type;
65 typedef typename Allocator::value_type value_type;
66 typedef typename Allocator::size_type size_type;
69 typedef value_type* pointer;
70 typedef const value_type* const_pointer;
71 typedef void* void_pointer;
72 typedef const void* const_void_pointer;
73 typedef std::ptrdiff_t difference_type;
77 min_align = detail::max_align<Alignment,
78 detail::max_align<alignment_of<value_type>::value,
79 alignment_of<char_ptr>::value>::value>::value
85 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
86 typedef aligned_allocator_adaptor<typename traits::
87 template rebind_alloc<U>, Alignment> other;
89 typedef aligned_allocator_adaptor<typename Allocator::
90 template rebind<U>::other, Alignment> other;
94 #if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
95 aligned_allocator_adaptor() = default;
97 aligned_allocator_adaptor()
102 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
104 explicit aligned_allocator_adaptor(A&& alloc) BOOST_NOEXCEPT
105 : Allocator(std::forward<A>(alloc)) {
109 explicit aligned_allocator_adaptor(const A& alloc)
116 aligned_allocator_adaptor(const aligned_allocator_adaptor<U,
117 Alignment>& other) BOOST_NOEXCEPT
118 : Allocator(other.base()) {
121 Allocator& base() BOOST_NOEXCEPT {
122 return static_cast<Allocator&>(*this);
125 const Allocator& base() const BOOST_NOEXCEPT {
126 return static_cast<const Allocator&>(*this);
129 pointer allocate(size_type size) {
130 std::size_t n1 = size * sizeof(value_type);
131 std::size_t n2 = n1 + min_align - ptr_align;
132 char_alloc a(base());
133 char_ptr p1 = a.allocate(sizeof p1 + n2);
134 void* p2 = detail::addressof(*p1) + sizeof p1;
135 (void)align(min_align, n1, p2, n2);
136 void* p3 = static_cast<char_ptr*>(p2) - 1;
137 ::new(p3) char_ptr(p1);
138 return static_cast<pointer>(p2);
141 pointer allocate(size_type size, const_void_pointer hint) {
142 std::size_t n1 = size * sizeof(value_type);
143 std::size_t n2 = n1 + min_align - ptr_align;
144 char_ptr h = char_ptr();
146 h = *(static_cast<const char_ptr*>(hint) - 1);
148 char_alloc a(base());
149 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
150 char_ptr p1 = char_traits::allocate(a, sizeof p1 + n2, h);
152 char_ptr p1 = a.allocate(sizeof p1 + n2, h);
154 void* p2 = detail::addressof(*p1) + sizeof p1;
155 (void)align(min_align, n1, p2, n2);
156 void* p3 = static_cast<char_ptr*>(p2) - 1;
157 ::new(p3) char_ptr(p1);
158 return static_cast<pointer>(p2);
161 void deallocate(pointer ptr, size_type size) {
162 char_ptr* p1 = reinterpret_cast<char_ptr*>(ptr) - 1;
165 char_alloc a(base());
166 a.deallocate(p2, size * sizeof(value_type) +
167 min_align - ptr_align + sizeof p2);
171 template<class A1, class A2, std::size_t Alignment>
172 inline bool operator==(const aligned_allocator_adaptor<A1,
173 Alignment>& a, const aligned_allocator_adaptor<A2,
174 Alignment>& b) BOOST_NOEXCEPT
176 return a.base() == b.base();
179 template<class A1, class A2, std::size_t Alignment>
180 inline bool operator!=(const aligned_allocator_adaptor<A1,
181 Alignment>& a, const aligned_allocator_adaptor<A2,
182 Alignment>& b) BOOST_NOEXCEPT