]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/align/aligned_allocator_adaptor.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / align / aligned_allocator_adaptor.hpp
CommitLineData
7c673cae 1/*
b32b8144
FG
2Copyright 2014-2016 Glen Joseph Fernandes
3(glenjofe@gmail.com)
7c673cae 4
b32b8144
FG
5Distributed under the Boost Software License, Version 1.0.
6(http://www.boost.org/LICENSE_1_0.txt)
7c673cae
FG
7*/
8#ifndef BOOST_ALIGN_ALIGNED_ALLOCATOR_ADAPTOR_HPP
9#define BOOST_ALIGN_ALIGNED_ALLOCATOR_ADAPTOR_HPP
10
7c673cae
FG
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>
b32b8144 17#include <boost/core/pointer_traits.hpp>
7c673cae
FG
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
29namespace boost {
30namespace alignment {
31
32template<class Allocator, std::size_t Alignment>
33class aligned_allocator_adaptor
34 : public Allocator {
b32b8144 35 BOOST_STATIC_ASSERT(detail::is_alignment_constant<Alignment>::value);
7c673cae
FG
36
37#if !defined(BOOST_NO_CXX11_ALLOCATOR)
38 typedef std::allocator_traits<Allocator> traits;
b32b8144
FG
39 typedef typename traits::template rebind_alloc<char> char_alloc;
40 typedef typename traits::template rebind_traits<char> char_traits;
7c673cae
FG
41 typedef typename char_traits::pointer char_ptr;
42#else
b32b8144 43 typedef typename Allocator::template rebind<char>::other char_alloc;
7c673cae
FG
44 typedef typename char_alloc::pointer char_ptr;
45#endif
46
47public:
7c673cae 48 typedef typename Allocator::value_type value_type;
7c673cae
FG
49 typedef value_type* pointer;
50 typedef const value_type* const_pointer;
51 typedef void* void_pointer;
52 typedef const void* const_void_pointer;
b32b8144 53 typedef std::size_t size_type;
7c673cae
FG
54 typedef std::ptrdiff_t difference_type;
55
56private:
57 enum {
58 min_align = detail::max_size<Alignment,
59 detail::max_align<value_type, char_ptr>::value>::value
60 };
61
62public:
63 template<class U>
64 struct rebind {
65#if !defined(BOOST_NO_CXX11_ALLOCATOR)
b32b8144
FG
66 typedef aligned_allocator_adaptor<typename traits::template
67 rebind_alloc<U>, Alignment> other;
7c673cae 68#else
b32b8144
FG
69 typedef aligned_allocator_adaptor<typename Allocator::template
70 rebind<U>::other, Alignment> other;
7c673cae
FG
71#endif
72 };
73
74#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
75 aligned_allocator_adaptor() = default;
76#else
77 aligned_allocator_adaptor()
78 : Allocator() { }
79#endif
80
81#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
82 template<class A>
83 explicit aligned_allocator_adaptor(A&& alloc) BOOST_NOEXCEPT
84 : Allocator(std::forward<A>(alloc)) { }
85#else
86 template<class A>
87 explicit aligned_allocator_adaptor(const A& alloc) BOOST_NOEXCEPT
88 : Allocator(alloc) { }
89#endif
90
91 template<class U>
92 aligned_allocator_adaptor(const aligned_allocator_adaptor<U,
93 Alignment>& other) BOOST_NOEXCEPT
94 : Allocator(other.base()) { }
95
96 Allocator& base() BOOST_NOEXCEPT {
97 return static_cast<Allocator&>(*this);
98 }
99
100 const Allocator& base() const BOOST_NOEXCEPT {
101 return static_cast<const Allocator&>(*this);
102 }
103
104 pointer allocate(size_type size) {
105 std::size_t s = size * sizeof(value_type);
106 std::size_t n = s + min_align - 1;
107 char_alloc a(base());
108 char_ptr p = a.allocate(sizeof p + n);
b32b8144 109 void* r = boost::pointer_traits<char_ptr>::to_address(p) + sizeof p;
7c673cae 110 (void)align(min_align, s, r, n);
b32b8144 111 ::new(static_cast<void*>(static_cast<char_ptr*>(r) - 1)) char_ptr(p);
7c673cae
FG
112 return static_cast<pointer>(r);
113 }
114
115 pointer allocate(size_type size, const_void_pointer hint) {
116 std::size_t s = size * sizeof(value_type);
117 std::size_t n = s + min_align - 1;
118 char_ptr h = char_ptr();
119 if (hint) {
120 h = *(static_cast<const char_ptr*>(hint) - 1);
121 }
122 char_alloc a(base());
123#if !defined(BOOST_NO_CXX11_ALLOCATOR)
124 char_ptr p = char_traits::allocate(a, sizeof p + n, h);
125#else
126 char_ptr p = a.allocate(sizeof p + n, h);
127#endif
b32b8144 128 void* r = boost::pointer_traits<char_ptr>::to_address(p) + sizeof p;
7c673cae 129 (void)align(min_align, s, r, n);
b32b8144 130 ::new(static_cast<void*>(static_cast<char_ptr*>(r) - 1)) char_ptr(p);
7c673cae
FG
131 return static_cast<pointer>(r);
132 }
133
134 void deallocate(pointer ptr, size_type size) {
b32b8144 135 char_ptr* p = reinterpret_cast<char_ptr*>(ptr) - 1;
7c673cae
FG
136 char_ptr r = *p;
137 p->~char_ptr();
138 char_alloc a(base());
b32b8144 139 a.deallocate(r, sizeof r + size * sizeof(value_type) + min_align - 1);
7c673cae
FG
140 }
141};
142
b32b8144
FG
143template<class A, class B, std::size_t Alignment>
144inline bool
145operator==(const aligned_allocator_adaptor<A, Alignment>& a,
146 const aligned_allocator_adaptor<B, Alignment>& b) BOOST_NOEXCEPT
7c673cae
FG
147{
148 return a.base() == b.base();
149}
150
b32b8144
FG
151template<class A, class B, std::size_t Alignment>
152inline bool
153operator!=(const aligned_allocator_adaptor<A, Alignment>& a,
154 const aligned_allocator_adaptor<B, Alignment>& b) BOOST_NOEXCEPT
7c673cae
FG
155{
156 return !(a == b);
157}
158
b32b8144
FG
159} /* alignment */
160} /* boost */
7c673cae
FG
161
162#endif