alignedallocator.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
21#ifndef EWOMS_ALIGNED_ALLOCATOR_HH
22#define EWOMS_ALIGNED_ALLOCATOR_HH
23
24#include <cassert>
25#include <cstdlib>
26#include <memory>
27#include <type_traits>
28#include <utility>
29
30namespace Opm {
31
32namespace detail {
33
34constexpr inline bool is_alignment(std::size_t value) noexcept
35{
36 return (value > 0) && ((value & (value - 1)) == 0);
37}
38
39template<std::size_t N>
41 : std::integral_constant<bool, (N > 0) && ((N & (N - 1)) == 0)>
42{};
43
44template<std::size_t A, std::size_t B>
46 : std::integral_constant<std::size_t, (A < B) ? A : B>
47{};
48
49template<class T>
50struct offset_object
51{
52 char offset;
53 T object;
54};
55
56template<class T>
57struct alignment_of
58 : min_size<sizeof(T), sizeof(offset_object<T>) - sizeof(T)>::type
59{};
60
61template<std::size_t A, std::size_t B>
62struct max_align
63 : std::integral_constant<std::size_t,(A > B) ? A : B>
64{};
65
66template<class T>
68 : std::integral_constant<std::size_t, ~static_cast<std::size_t>(0) / sizeof(T)>
69{};
70
71using std::addressof;
72
73}
74
75inline void* aligned_alloc(std::size_t alignment,
76 std::size_t size) noexcept
77{
78 assert(detail::is_alignment(alignment));
79 if (alignment < sizeof(void*)) {
80 alignment = sizeof(void*);
81 }
82 void* p;
83 if (::posix_memalign(&p, alignment, size) != 0) {
84 p = 0;
85 }
86 return p;
87}
88
89inline void aligned_free(void* ptr)
90 noexcept
91{
92 ::free(ptr);
93}
94
95template<class T, std::size_t Alignment>
97{
98 static_assert(detail::is_alignment_constant<Alignment>::value, "Alignment must be powers of two!");
99
100public:
101 using value_type = T;
102 using pointer = T*;
103 using const_pointer = const T*;
104 using void_pointer = void*;
105 using const_void_pointer = const void*;
106 using size_type = std::size_t;
107 using difference_type = std::ptrdiff_t;
108 using reference = T&;
109 using const_reference = const T&;
110
111private:
113
114public:
115 template<class U>
116 struct rebind
117 {
119 };
120
121 aligned_allocator() noexcept = default;
122
123 template<class U>
125 Alignment>&) noexcept
126 {}
127
128 pointer address(reference value) const noexcept
129 {
130 return detail::addressof(value);
131 }
132
134 {
135 return detail::addressof(value);
136 }
137
140 {
141 void* p = aligned_alloc(MaxAlign::value,
142 sizeof(T) * size);
143 if (!p && size > 0) {
144 throw std::bad_alloc();
145 }
146 return static_cast<T*>(p);
147 }
148
150 {
151 aligned_free(ptr);
152 }
153
154 constexpr size_type max_size() const noexcept
155 {
157 }
158
159 template<class U, class... Args>
160 void construct(U* ptr, Args&&... args)
161 {
162 void* p = ptr;
163 ::new(p) U(std::forward<Args>(args)...);
164 }
165
166 template<class U>
167 void construct(U* ptr)
168 {
169 void* p = ptr;
170 ::new(p) U();
171 }
172
173 template<class U>
174 void destroy(U* ptr)
175 {
176 (void)ptr;
177 ptr->~U();
178 }
179};
180
181template<std::size_t Alignment>
182class aligned_allocator<void, Alignment>
183{
185 "The specified alignment is not a power of two!");
186
187public:
188 using value_type = void;
189 using pointer = void*;
190 using const_pointer = const void*;
191
192 template<class U>
193 struct rebind
194 {
196 };
197};
198
199template<class T1, class T2, std::size_t Alignment>
200inline bool operator==(const aligned_allocator<T1,
201 Alignment>&, const aligned_allocator<T2,
202 Alignment>&) noexcept
203{
204 return true;
205}
206
207template<class T1, class T2, std::size_t Alignment>
208inline bool operator!=(const aligned_allocator<T1,
209 Alignment>&, const aligned_allocator<T2,
210 Alignment>&) noexcept
211{
212 return false;
213}
214}
215
216#endif
void * pointer
Definition: alignedallocator.hh:189
const void * const_pointer
Definition: alignedallocator.hh:190
void value_type
Definition: alignedallocator.hh:188
Definition: alignedallocator.hh:97
T value_type
Definition: alignedallocator.hh:101
std::ptrdiff_t difference_type
Definition: alignedallocator.hh:107
T & reference
Definition: alignedallocator.hh:108
constexpr size_type max_size() const noexcept
Definition: alignedallocator.hh:154
pointer address(reference value) const noexcept
Definition: alignedallocator.hh:128
T * pointer
Definition: alignedallocator.hh:102
std::size_t size_type
Definition: alignedallocator.hh:106
const void * const_void_pointer
Definition: alignedallocator.hh:105
void deallocate(pointer ptr, size_type)
Definition: alignedallocator.hh:149
void construct(U *ptr)
Definition: alignedallocator.hh:167
const T * const_pointer
Definition: alignedallocator.hh:103
aligned_allocator() noexcept=default
void construct(U *ptr, Args &&... args)
Definition: alignedallocator.hh:160
pointer allocate(size_type size, const_void_pointer=0)
Definition: alignedallocator.hh:138
void * void_pointer
Definition: alignedallocator.hh:104
const T & const_reference
Definition: alignedallocator.hh:109
void destroy(U *ptr)
Definition: alignedallocator.hh:174
const_pointer address(const_reference value) const noexcept
Definition: alignedallocator.hh:133
constexpr bool is_alignment(std::size_t value) noexcept
Definition: alignedallocator.hh:34
Definition: blackoilboundaryratevector.hh:39
void aligned_free(void *ptr) noexcept
Definition: alignedallocator.hh:89
bool operator==(const aligned_allocator< T1, Alignment > &, const aligned_allocator< T2, Alignment > &) noexcept
Definition: alignedallocator.hh:200
void * aligned_alloc(std::size_t alignment, std::size_t size) noexcept
Definition: alignedallocator.hh:75
bool operator!=(const aligned_allocator< T1, Alignment > &, const aligned_allocator< T2, Alignment > &) noexcept
Definition: alignedallocator.hh:208
Definition: alignedallocator.hh:117
Definition: alignedallocator.hh:42
Definition: alignedallocator.hh:64
Definition: alignedallocator.hh:69
Definition: alignedallocator.hh:47