Chris@102
|
1 /*
|
Chris@102
|
2 (c) 2014 Glen Joseph Fernandes
|
Chris@102
|
3 glenjofe at gmail dot com
|
Chris@102
|
4
|
Chris@102
|
5 Distributed under the Boost Software
|
Chris@102
|
6 License, Version 1.0.
|
Chris@102
|
7 http://boost.org/LICENSE_1_0.txt
|
Chris@102
|
8 */
|
Chris@102
|
9 #ifndef BOOST_ALIGN_ALIGNED_ALLOCATOR_HPP
|
Chris@102
|
10 #define BOOST_ALIGN_ALIGNED_ALLOCATOR_HPP
|
Chris@102
|
11
|
Chris@102
|
12 #include <boost/config.hpp>
|
Chris@102
|
13 #include <boost/static_assert.hpp>
|
Chris@102
|
14 #include <boost/throw_exception.hpp>
|
Chris@102
|
15 #include <boost/align/aligned_alloc.hpp>
|
Chris@102
|
16 #include <boost/align/aligned_allocator_forward.hpp>
|
Chris@102
|
17 #include <boost/align/alignment_of.hpp>
|
Chris@102
|
18 #include <boost/align/detail/addressof.hpp>
|
Chris@102
|
19 #include <boost/align/detail/is_alignment_constant.hpp>
|
Chris@102
|
20 #include <boost/align/detail/max_align.hpp>
|
Chris@102
|
21 #include <boost/align/detail/max_count_of.hpp>
|
Chris@102
|
22 #include <new>
|
Chris@102
|
23
|
Chris@102
|
24 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
Chris@102
|
25 #include <utility>
|
Chris@102
|
26 #endif
|
Chris@102
|
27
|
Chris@102
|
28 namespace boost {
|
Chris@102
|
29 namespace alignment {
|
Chris@102
|
30 template<class T, std::size_t Alignment>
|
Chris@102
|
31 class aligned_allocator {
|
Chris@102
|
32 BOOST_STATIC_ASSERT(detail::
|
Chris@102
|
33 is_alignment_constant<Alignment>::value);
|
Chris@102
|
34
|
Chris@102
|
35 public:
|
Chris@102
|
36 typedef T value_type;
|
Chris@102
|
37 typedef T* pointer;
|
Chris@102
|
38 typedef const T* const_pointer;
|
Chris@102
|
39 typedef void* void_pointer;
|
Chris@102
|
40 typedef const void* const_void_pointer;
|
Chris@102
|
41 typedef std::size_t size_type;
|
Chris@102
|
42 typedef std::ptrdiff_t difference_type;
|
Chris@102
|
43 typedef T& reference;
|
Chris@102
|
44 typedef const T& const_reference;
|
Chris@102
|
45
|
Chris@102
|
46 private:
|
Chris@102
|
47 typedef detail::max_align<Alignment,
|
Chris@102
|
48 alignment_of<value_type>::value> MaxAlign;
|
Chris@102
|
49
|
Chris@102
|
50 public:
|
Chris@102
|
51 template<class U>
|
Chris@102
|
52 struct rebind {
|
Chris@102
|
53 typedef aligned_allocator<U, Alignment> other;
|
Chris@102
|
54 };
|
Chris@102
|
55
|
Chris@102
|
56 #if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
|
Chris@102
|
57 aligned_allocator()
|
Chris@102
|
58 BOOST_NOEXCEPT = default;
|
Chris@102
|
59 #else
|
Chris@102
|
60 aligned_allocator()
|
Chris@102
|
61 BOOST_NOEXCEPT {
|
Chris@102
|
62 }
|
Chris@102
|
63 #endif
|
Chris@102
|
64
|
Chris@102
|
65 template<class U>
|
Chris@102
|
66 aligned_allocator(const aligned_allocator<U,
|
Chris@102
|
67 Alignment>&) BOOST_NOEXCEPT {
|
Chris@102
|
68 }
|
Chris@102
|
69
|
Chris@102
|
70 pointer address(reference value) const
|
Chris@102
|
71 BOOST_NOEXCEPT {
|
Chris@102
|
72 return detail::addressof(value);
|
Chris@102
|
73 }
|
Chris@102
|
74
|
Chris@102
|
75 const_pointer address(const_reference value) const
|
Chris@102
|
76 BOOST_NOEXCEPT {
|
Chris@102
|
77 return detail::addressof(value);
|
Chris@102
|
78 }
|
Chris@102
|
79
|
Chris@102
|
80 pointer allocate(size_type size,
|
Chris@102
|
81 const_void_pointer = 0) {
|
Chris@102
|
82 void* p = aligned_alloc(MaxAlign::value,
|
Chris@102
|
83 sizeof(T) * size);
|
Chris@102
|
84 if (!p && size > 0) {
|
Chris@102
|
85 boost::throw_exception(std::bad_alloc());
|
Chris@102
|
86 }
|
Chris@102
|
87 return static_cast<T*>(p);
|
Chris@102
|
88 }
|
Chris@102
|
89
|
Chris@102
|
90 void deallocate(pointer ptr, size_type) {
|
Chris@102
|
91 alignment::aligned_free(ptr);
|
Chris@102
|
92 }
|
Chris@102
|
93
|
Chris@102
|
94 BOOST_CONSTEXPR size_type max_size() const
|
Chris@102
|
95 BOOST_NOEXCEPT {
|
Chris@102
|
96 return detail::max_count_of<T>::value;
|
Chris@102
|
97 }
|
Chris@102
|
98
|
Chris@102
|
99 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
Chris@102
|
100 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@102
|
101 template<class U, class... Args>
|
Chris@102
|
102 void construct(U* ptr, Args&&... args) {
|
Chris@102
|
103 void* p = ptr;
|
Chris@102
|
104 ::new(p) U(std::forward<Args>(args)...);
|
Chris@102
|
105 }
|
Chris@102
|
106 #else
|
Chris@102
|
107 template<class U, class V>
|
Chris@102
|
108 void construct(U* ptr, V&& value) {
|
Chris@102
|
109 void* p = ptr;
|
Chris@102
|
110 ::new(p) U(std::forward<V>(value));
|
Chris@102
|
111 }
|
Chris@102
|
112 #endif
|
Chris@102
|
113 #else
|
Chris@102
|
114 template<class U, class V>
|
Chris@102
|
115 void construct(U* ptr, const V& value) {
|
Chris@102
|
116 void* p = ptr;
|
Chris@102
|
117 ::new(p) U(value);
|
Chris@102
|
118 }
|
Chris@102
|
119 #endif
|
Chris@102
|
120
|
Chris@102
|
121 template<class U>
|
Chris@102
|
122 void construct(U* ptr) {
|
Chris@102
|
123 void* p = ptr;
|
Chris@102
|
124 ::new(p) U();
|
Chris@102
|
125 }
|
Chris@102
|
126
|
Chris@102
|
127 template<class U>
|
Chris@102
|
128 void destroy(U* ptr) {
|
Chris@102
|
129 (void)ptr;
|
Chris@102
|
130 ptr->~U();
|
Chris@102
|
131 }
|
Chris@102
|
132 };
|
Chris@102
|
133
|
Chris@102
|
134 template<std::size_t Alignment>
|
Chris@102
|
135 class aligned_allocator<void, Alignment> {
|
Chris@102
|
136 BOOST_STATIC_ASSERT(detail::
|
Chris@102
|
137 is_alignment_constant<Alignment>::value);
|
Chris@102
|
138
|
Chris@102
|
139 public:
|
Chris@102
|
140 typedef void value_type;
|
Chris@102
|
141 typedef void* pointer;
|
Chris@102
|
142 typedef const void* const_pointer;
|
Chris@102
|
143
|
Chris@102
|
144 template<class U>
|
Chris@102
|
145 struct rebind {
|
Chris@102
|
146 typedef aligned_allocator<U, Alignment> other;
|
Chris@102
|
147 };
|
Chris@102
|
148 };
|
Chris@102
|
149
|
Chris@102
|
150 template<class T1, class T2, std::size_t Alignment>
|
Chris@102
|
151 inline bool operator==(const aligned_allocator<T1,
|
Chris@102
|
152 Alignment>&, const aligned_allocator<T2,
|
Chris@102
|
153 Alignment>&) BOOST_NOEXCEPT
|
Chris@102
|
154 {
|
Chris@102
|
155 return true;
|
Chris@102
|
156 }
|
Chris@102
|
157
|
Chris@102
|
158 template<class T1, class T2, std::size_t Alignment>
|
Chris@102
|
159 inline bool operator!=(const aligned_allocator<T1,
|
Chris@102
|
160 Alignment>&, const aligned_allocator<T2,
|
Chris@102
|
161 Alignment>&) BOOST_NOEXCEPT
|
Chris@102
|
162 {
|
Chris@102
|
163 return false;
|
Chris@102
|
164 }
|
Chris@102
|
165 }
|
Chris@102
|
166 }
|
Chris@102
|
167
|
Chris@102
|
168 #endif
|