opm-simulators
Toggle main menu visibility
Loading...
Searching...
No Matches
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
30
namespace
Opm
{
31
32
namespace
detail {
33
34
constexpr
inline
bool
is_alignment(std::size_t value)
noexcept
35
{
36
return
(value > 0) && ((value & (value - 1)) == 0);
37
}
38
39
template
<std::
size_t
N>
40
struct
is_alignment_constant
41
: std::integral_constant<bool, (N > 0) && ((N & (N - 1)) == 0)>
42
{};
43
44
template
<std::
size_t
A, std::
size_t
B>
45
struct
min_size
46
: std::integral_constant<std::size_t, (A < B) ? A : B>
47
{};
48
49
template<class T>
50
struct offset_object
51
{
52
char offset;
53
T object;
54
};
55
56
template<class T>
57
struct alignment_of
58
: min_size<sizeof(T), sizeof(offset_object<T>) - sizeof(T)>::type
59
{};
60
61
template<std::size_t A, std::size_t B>
62
struct max_align
63
: std::integral_constant<std::size_t,(A > B) ? A : B>
64
{};
65
66
template
<
class
T>
67
struct
max_count_of
68
: std::integral_constant<std::size_t, ~static_cast<std::size_t>(0) / sizeof(T)>
69
{};
70
71
using
std::addressof;
72
73
}
74
75
inline
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
89
inline
void
aligned_free(
void
* ptr)
90
noexcept
91
{
92
::free(ptr);
93
}
94
95
template
<
class
T, std::
size_t
Alignment>
96
class
aligned_allocator
97
{
98
static_assert
(
detail::is_alignment_constant<Alignment>::value
,
"Alignment must be powers of two!"
);
99
100
public
:
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
111
private
:
112
using
MaxAlign =
detail::max_align<Alignment, detail::alignment_of<value_type>::value
>;
113
114
public
:
115
template
<
class
U>
116
struct
rebind
117
{
118
using
other = aligned_allocator<U, Alignment>;
119
};
120
121
aligned_allocator() noexcept = default;
122
123
template<class U>
124
aligned_allocator(const aligned_allocator<U,
125
Alignment>&) noexcept
126
{}
127
128
pointer address(reference value)
const
noexcept
129
{
130
return
detail::addressof(value);
131
}
132
133
const_pointer address(const_reference value)
const
noexcept
134
{
135
return
detail::addressof(value);
136
}
137
138
pointer allocate(size_type size,
139
const_void_pointer = 0)
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
149
void
deallocate(pointer ptr, size_type)
150
{
151
aligned_free(ptr);
152
}
153
154
constexpr
size_type max_size() const noexcept
155
{
156
return
detail::max_count_of<T>::value;
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
181
template
<std::
size_t
Alignment>
182
class
aligned_allocator<void, Alignment>
183
{
184
static_assert
(
detail::is_alignment_constant<Alignment>::value
,
185
"The specified alignment is not a power of two!"
);
186
187
public
:
188
using
value_type = void;
189
using
pointer =
void
*;
190
using
const_pointer =
const
void
*;
191
192
template
<
class
U>
193
struct
rebind
194
{
195
using
other = aligned_allocator<U, Alignment>;
196
};
197
};
198
199
template
<
class
T1,
class
T2, std::
size_t
Alignment>
200
inline
bool
operator==(
const
aligned_allocator
<T1,
201
Alignment>&,
const
aligned_allocator
<T2,
202
Alignment>&) noexcept
203
{
204
return
true
;
205
}
206
207
template
<
class
T1,
class
T2, std::
size_t
Alignment>
208
inline
bool
operator!=(
const
aligned_allocator<T1,
209
Alignment>&,
const
aligned_allocator<T2,
210
Alignment>&) noexcept
211
{
212
return
false
;
213
}
214
}
215
216
#endif
Opm::aligned_allocator
Definition
alignedallocator.hh:97
Opm
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition
blackoilbioeffectsmodules.hh:43
Opm::aligned_allocator::rebind
Definition
alignedallocator.hh:117
Opm::aligned_allocator< void, Alignment >::rebind
Definition
alignedallocator.hh:194
Opm::detail::is_alignment_constant
Definition
alignedallocator.hh:42
Opm::detail::max_align
Definition
alignedallocator.hh:64
Opm::detail::max_count_of
Definition
alignedallocator.hh:69
Opm::detail::min_size
Definition
alignedallocator.hh:47
opm
models
utils
alignedallocator.hh
Generated by
1.17.0