]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/align/include/boost/align/aligned_allocator_adaptor.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / align / include / boost / align / aligned_allocator_adaptor.hpp
1 /*
2 (c) 2014-2016 Glen Joseph Fernandes
3 <glenjofe -at- gmail.com>
4
5 Distributed under the Boost Software
6 License, Version 1.0.
7 http://boost.org/LICENSE_1_0.txt
8 */
9 #ifndef BOOST_ALIGN_ALIGNED_ALLOCATOR_ADAPTOR_HPP
10 #define BOOST_ALIGN_ALIGNED_ALLOCATOR_ADAPTOR_HPP
11
12 #include <boost/align/detail/addressof.hpp>
13 #include <boost/align/detail/is_alignment_constant.hpp>
14 #include <boost/align/detail/max_align.hpp>
15 #include <boost/align/detail/max_size.hpp>
16 #include <boost/align/align.hpp>
17 #include <boost/align/aligned_allocator_adaptor_forward.hpp>
18 #include <boost/align/alignment_of.hpp>
19 #include <boost/static_assert.hpp>
20 #include <new>
21
22 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
23 #include <memory>
24 #endif
25
26 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
27 #include <utility>
28 #endif
29
30 namespace boost {
31 namespace alignment {
32
33 template<class Allocator, std::size_t Alignment>
34 class aligned_allocator_adaptor
35 : public Allocator {
36 BOOST_STATIC_ASSERT(detail::
37 is_alignment_constant<Alignment>::value);
38
39 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
40 typedef std::allocator_traits<Allocator> traits;
41
42 typedef typename traits::
43 template rebind_alloc<char> char_alloc;
44
45 typedef typename traits::
46 template rebind_traits<char> char_traits;
47
48 typedef typename char_traits::pointer char_ptr;
49 #else
50 typedef typename Allocator::
51 template rebind<char>::other char_alloc;
52
53 typedef typename char_alloc::pointer char_ptr;
54 #endif
55
56 public:
57 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
58 typedef typename traits::value_type value_type;
59 typedef typename traits::size_type size_type;
60 #else
61 typedef typename Allocator::value_type value_type;
62 typedef typename Allocator::size_type size_type;
63 #endif
64
65 typedef value_type* pointer;
66 typedef const value_type* const_pointer;
67 typedef void* void_pointer;
68 typedef const void* const_void_pointer;
69 typedef std::ptrdiff_t difference_type;
70
71 private:
72 enum {
73 min_align = detail::max_size<Alignment,
74 detail::max_align<value_type, char_ptr>::value>::value
75 };
76
77 public:
78 template<class U>
79 struct rebind {
80 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
81 typedef aligned_allocator_adaptor<typename traits::
82 template rebind_alloc<U>, Alignment> other;
83 #else
84 typedef aligned_allocator_adaptor<typename Allocator::
85 template rebind<U>::other, Alignment> other;
86 #endif
87 };
88
89 #if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
90 aligned_allocator_adaptor() = default;
91 #else
92 aligned_allocator_adaptor()
93 : Allocator() { }
94 #endif
95
96 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
97 template<class A>
98 explicit aligned_allocator_adaptor(A&& alloc) BOOST_NOEXCEPT
99 : Allocator(std::forward<A>(alloc)) { }
100 #else
101 template<class A>
102 explicit aligned_allocator_adaptor(const A& alloc) BOOST_NOEXCEPT
103 : Allocator(alloc) { }
104 #endif
105
106 template<class U>
107 aligned_allocator_adaptor(const aligned_allocator_adaptor<U,
108 Alignment>& other) BOOST_NOEXCEPT
109 : Allocator(other.base()) { }
110
111 Allocator& base() BOOST_NOEXCEPT {
112 return static_cast<Allocator&>(*this);
113 }
114
115 const Allocator& base() const BOOST_NOEXCEPT {
116 return static_cast<const Allocator&>(*this);
117 }
118
119 pointer allocate(size_type size) {
120 std::size_t s = size * sizeof(value_type);
121 std::size_t n = s + min_align - 1;
122 char_alloc a(base());
123 char_ptr p = a.allocate(sizeof p + n);
124 void* r = detail::addressof(*p) + sizeof p;
125 (void)align(min_align, s, r, n);
126 ::new((void*)(static_cast<char_ptr*>(r) - 1)) char_ptr(p);
127 return static_cast<pointer>(r);
128 }
129
130 pointer allocate(size_type size, const_void_pointer hint) {
131 std::size_t s = size * sizeof(value_type);
132 std::size_t n = s + min_align - 1;
133 char_ptr h = char_ptr();
134 if (hint) {
135 h = *(static_cast<const char_ptr*>(hint) - 1);
136 }
137 char_alloc a(base());
138 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
139 char_ptr p = char_traits::allocate(a, sizeof p + n, h);
140 #else
141 char_ptr p = a.allocate(sizeof p + n, h);
142 #endif
143 void* r = detail::addressof(*p) + sizeof p;
144 (void)align(min_align, s, r, n);
145 ::new((void*)(static_cast<char_ptr*>(r) - 1)) char_ptr(p);
146 return static_cast<pointer>(r);
147 }
148
149 void deallocate(pointer ptr, size_type size) {
150 char_ptr* p = (char_ptr*)ptr - 1;
151 char_ptr r = *p;
152 p->~char_ptr();
153 char_alloc a(base());
154 a.deallocate(r, sizeof r + size * sizeof(value_type) +
155 min_align - 1);
156 }
157 };
158
159 template<class A1, class A2, std::size_t Alignment>
160 inline bool operator==(const aligned_allocator_adaptor<A1,
161 Alignment>& a, const aligned_allocator_adaptor<A2,
162 Alignment>& b) BOOST_NOEXCEPT
163 {
164 return a.base() == b.base();
165 }
166
167 template<class A1, class A2, std::size_t Alignment>
168 inline bool operator!=(const aligned_allocator_adaptor<A1,
169 Alignment>& a, const aligned_allocator_adaptor<A2,
170 Alignment>& b) BOOST_NOEXCEPT
171 {
172 return !(a == b);
173 }
174
175 } /* .alignment */
176 } /* .boost */
177
178 #endif