opm-simulators
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>
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>
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>
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:
113 
114 public:
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 
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 {
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  {
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
Definition: alignedallocator.hh:116
Definition: alignedallocator.hh:40
Definition: alignedallocator.hh:45
Definition: alignedallocator.hh:67
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: blackoilbioeffectsmodules.hh:45
Definition: alignedallocator.hh:62
Definition: alignedallocator.hh:96