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:
3/*
4 This file is part of the Open Porous Media project (OPM).
5
6 OPM is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 2 of the License, or
9 (at your option) any later version.
10
11 OPM is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with OPM. If not, see <http://www.gnu.org/licenses/>.
18
19 Consult the COPYING file in the top-level source directory of this
20 module for the precise wording of the license and the list of
21 copyright holders.
22*/
41#ifndef EWOMS_ALIGNED_ALLOCATOR_HH
42#define EWOMS_ALIGNED_ALLOCATOR_HH
43
44#include <utility>
45#include <memory>
46#include <type_traits>
47#include <cassert>
48
49namespace Opm {
50
51namespace detail {
52constexpr inline bool is_alignment(std::size_t value) noexcept
53{
54 return (value > 0) && ((value & (value - 1)) == 0);
55}
56
57template<std::size_t N>
59 : std::integral_constant<bool, (N > 0) && ((N & (N - 1)) == 0)>
60{};
61
62template<std::size_t A, std::size_t B>
64 : std::integral_constant<std::size_t, (A < B) ? A : B>
65{ };
66
67template<class T>
68struct offset_object
69{
70 char offset;
71 T object;
72};
73
74template<class T>
75struct alignment_of
76 : min_size<sizeof(T), sizeof(offset_object<T>) - sizeof(T)>::type
77{};
78
79template<std::size_t A, std::size_t B>
80struct max_align
81 : std::integral_constant<std::size_t,(A > B) ? A : B>
82{};
83
84template<class T>
86 : std::integral_constant<std::size_t, ~static_cast<std::size_t>(0) / sizeof(T)>
87{};
88
89using std::addressof;
90}
91
92inline void* aligned_alloc(std::size_t alignment,
93 std::size_t size) noexcept
94{
95 assert(detail::is_alignment(alignment));
96 if (alignment < sizeof(void*)) {
97 alignment = sizeof(void*);
98 }
99 void* p;
100 if (::posix_memalign(&p, alignment, size) != 0) {
101 p = 0;
102 }
103 return p;
104}
105
106inline void aligned_free(void* ptr)
107 noexcept
108{
109 ::free(ptr);
110}
111
112
113template<class T, std::size_t Alignment>
115 static_assert(detail::is_alignment_constant<Alignment>::value, "Alignment must be powers of two!");
116
117public:
118 using value_type = T;
119 using pointer = T*;
120 using const_pointer = const T*;
121 using void_pointer = void*;
122 using const_void_pointer = const void*;
123 using size_type = std::size_t;
124 using difference_type = std::ptrdiff_t;
125 using reference = T&;
126 using const_reference = const T&;
127
128private:
130
131public:
132 template<class U>
133 struct rebind {
135 };
136
138 noexcept = default;
139
140 template<class U>
142 Alignment>&) noexcept {
143 }
144
146 noexcept {
147 return detail::addressof(value);
148 }
149
151 noexcept {
152 return detail::addressof(value);
153 }
154
156 const_void_pointer = 0) {
157 void* p = aligned_alloc(MaxAlign::value,
158 sizeof(T) * size);
159 if (!p && size > 0) {
160 throw std::bad_alloc();
161 }
162 return static_cast<T*>(p);
163 }
164
166 aligned_free(ptr);
167 }
168
169 constexpr size_type max_size() const
170 noexcept {
172 }
173
174 template<class U, class... Args>
175 void construct(U* ptr, Args&&... args) {
176 void* p = ptr;
177 ::new(p) U(std::forward<Args>(args)...);
178 }
179
180 template<class U>
181 void construct(U* ptr) {
182 void* p = ptr;
183 ::new(p) U();
184 }
185
186 template<class U>
187 void destroy(U* ptr) {
188 (void)ptr;
189 ptr->~U();
190 }
191};
192
193template<std::size_t Alignment>
194class aligned_allocator<void, Alignment> {
196 "The specified alignment is not a power of two!");
197
198public:
199 using value_type = void;
200 using pointer = void*;
201 using const_pointer = const void*;
202
203 template<class U>
204 struct rebind {
206 };
207};
208
209template<class T1, class T2, std::size_t Alignment>
210inline bool operator==(const aligned_allocator<T1,
211 Alignment>&, const aligned_allocator<T2,
212 Alignment>&) noexcept
213{
214 return true;
215}
216
217template<class T1, class T2, std::size_t Alignment>
218inline bool operator!=(const aligned_allocator<T1,
219 Alignment>&, const aligned_allocator<T2,
220 Alignment>&) noexcept
221{
222 return false;
223}
224}
225
226#endif
void * pointer
Definition: alignedallocator.hh:200
const void * const_pointer
Definition: alignedallocator.hh:201
void value_type
Definition: alignedallocator.hh:199
Definition: alignedallocator.hh:114
T value_type
Definition: alignedallocator.hh:118
std::ptrdiff_t difference_type
Definition: alignedallocator.hh:124
T & reference
Definition: alignedallocator.hh:125
constexpr size_type max_size() const noexcept
Definition: alignedallocator.hh:169
pointer address(reference value) const noexcept
Definition: alignedallocator.hh:145
T * pointer
Definition: alignedallocator.hh:119
std::size_t size_type
Definition: alignedallocator.hh:123
const void * const_void_pointer
Definition: alignedallocator.hh:122
void deallocate(pointer ptr, size_type)
Definition: alignedallocator.hh:165
void construct(U *ptr)
Definition: alignedallocator.hh:181
const T * const_pointer
Definition: alignedallocator.hh:120
aligned_allocator() noexcept=default
void construct(U *ptr, Args &&... args)
Definition: alignedallocator.hh:175
pointer allocate(size_type size, const_void_pointer=0)
Definition: alignedallocator.hh:155
void * void_pointer
Definition: alignedallocator.hh:121
const T & const_reference
Definition: alignedallocator.hh:126
void destroy(U *ptr)
Definition: alignedallocator.hh:187
const_pointer address(const_reference value) const noexcept
Definition: alignedallocator.hh:150
constexpr bool is_alignment(std::size_t value) noexcept
Definition: alignedallocator.hh:52
Definition: blackoilboundaryratevector.hh:37
void aligned_free(void *ptr) noexcept
Definition: alignedallocator.hh:106
bool operator==(const aligned_allocator< T1, Alignment > &, const aligned_allocator< T2, Alignment > &) noexcept
Definition: alignedallocator.hh:210
void * aligned_alloc(std::size_t alignment, std::size_t size) noexcept
Definition: alignedallocator.hh:92
bool operator!=(const aligned_allocator< T1, Alignment > &, const aligned_allocator< T2, Alignment > &) noexcept
Definition: alignedallocator.hh:218
Definition: alignedallocator.hh:133
Definition: alignedallocator.hh:60
Definition: alignedallocator.hh:82
Definition: alignedallocator.hh:87
Definition: alignedallocator.hh:65