]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/align/aligned_allocator_adaptor.hpp
bump version to 18.2.4-pve3
[ceph.git] / ceph / src / boost / boost / align / aligned_allocator_adaptor.hpp
1 /*
2 Copyright 2014-2016 Glen Joseph Fernandes
3 (glenjofe@gmail.com)
4
5 Distributed under the Boost Software License, Version 1.0.
6 (http://www.boost.org/LICENSE_1_0.txt)
7 */
8 #ifndef BOOST_ALIGN_ALIGNED_ALLOCATOR_ADAPTOR_HPP
9 #define BOOST_ALIGN_ALIGNED_ALLOCATOR_ADAPTOR_HPP
10
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>
19 #include <new>
20
21 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
22 #include <memory>
23 #endif
24
25 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
26 #include <utility>
27 #endif
28
29 namespace boost {
30 namespace alignment {
31
32 template<class Allocator, std::size_t Alignment>
33 class aligned_allocator_adaptor
34 : public Allocator {
35 BOOST_STATIC_ASSERT(detail::is_alignment_constant<Alignment>::value);
36
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;
42 #else
43 typedef typename Allocator::template rebind<char>::other char_alloc;
44 typedef typename char_alloc::pointer char_ptr;
45 #endif
46
47 public:
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;
55
56 private:
57 template<class U>
58 struct min_align {
59 enum {
60 value = detail::max_size<Alignment,
61 detail::max_align<U, char_ptr>::value>::value
62 };
63 };
64
65 public:
66 template<class U>
67 struct rebind {
68 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
69 typedef aligned_allocator_adaptor<typename traits::template
70 rebind_alloc<U>, Alignment> other;
71 #else
72 typedef aligned_allocator_adaptor<typename Allocator::template
73 rebind<U>::other, Alignment> other;
74 #endif
75 };
76
77 aligned_allocator_adaptor()
78 : Allocator() { }
79
80 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
81 template<class A>
82 explicit aligned_allocator_adaptor(A&& alloc) BOOST_NOEXCEPT
83 : Allocator(std::forward<A>(alloc)) { }
84 #else
85 template<class A>
86 explicit aligned_allocator_adaptor(const A& alloc) BOOST_NOEXCEPT
87 : Allocator(alloc) { }
88 #endif
89
90 template<class U>
91 aligned_allocator_adaptor(const aligned_allocator_adaptor<U,
92 Alignment>& other) BOOST_NOEXCEPT
93 : Allocator(other.base()) { }
94
95 Allocator& base() BOOST_NOEXCEPT {
96 return static_cast<Allocator&>(*this);
97 }
98
99 const Allocator& base() const BOOST_NOEXCEPT {
100 return static_cast<const Allocator&>(*this);
101 }
102
103 pointer allocate(size_type size) {
104 enum {
105 m = min_align<value_type>::value
106 };
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);
115 }
116
117 pointer allocate(size_type size, const_void_pointer hint) {
118 enum {
119 m = min_align<value_type>::value
120 };
121 std::size_t s = size * sizeof(value_type);
122 std::size_t n = s + m - 1;
123 char_ptr h = char_ptr();
124 if (hint) {
125 h = *(static_cast<const char_ptr*>(hint) - 1);
126 }
127 char_alloc a(base());
128 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
129 char_ptr p = char_traits::allocate(a, sizeof p + n, h);
130 #else
131 char_ptr p = a.allocate(sizeof p + n, h);
132 #endif
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);
137 }
138
139 void deallocate(pointer ptr, size_type size) {
140 enum {
141 m = min_align<value_type>::value
142 };
143 char_ptr* p = reinterpret_cast<char_ptr*>(ptr) - 1;
144 char_ptr r = *p;
145 p->~char_ptr();
146 char_alloc a(base());
147 a.deallocate(r, sizeof r + size * sizeof(value_type) + m - 1);
148 }
149 };
150
151 template<class A, class B, std::size_t Alignment>
152 inline bool
153 operator==(const aligned_allocator_adaptor<A, Alignment>& a,
154 const aligned_allocator_adaptor<B, Alignment>& b) BOOST_NOEXCEPT
155 {
156 return a.base() == b.base();
157 }
158
159 template<class A, class B, std::size_t Alignment>
160 inline bool
161 operator!=(const aligned_allocator_adaptor<A, Alignment>& a,
162 const aligned_allocator_adaptor<B, Alignment>& b) BOOST_NOEXCEPT
163 {
164 return !(a == b);
165 }
166
167 } /* alignment */
168 } /* boost */
169
170 #endif