Dune Core Modules (2.6.0)

alignedallocator.hh
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 #ifndef DUNE_ALIGNED_ALLOCATOR_HH
4 #define DUNE_ALIGNED_ALLOCATOR_HH
5 
6 #include "mallocallocator.hh"
7 #include <cstdlib>
8 
9 namespace Dune
10 {
11 
19  template<class T, int Alignment = -1>
20  class AlignedAllocator : public MallocAllocator<T> {
21 
22 #if __APPLE__
23 
24  /*
25  * posix_memalign() on macOS has pretty draconian restrictions on the
26  * alignments that you may ask for: It has to be
27  *
28  * 1) a power of 2
29  * 2) at least as large as sizeof(void*)
30  *
31  * So here is a little constexpr function that calculates just that
32  * (together with the correct starting value for align fed in further down).
33  */
34  static constexpr int fixAlignment(int align)
35  {
36  return ((Alignment==-1) ? std::alignment_of<T>::value : Alignment) > align
37  ? fixAlignment(align << 1) : align;
38  }
39 
40 #else
41 
42  /*
43  * Non-Apple platforms just have to check whether an explicit alignment was
44  * restricted or fall back to the default alignment of T.
45  */
46  static constexpr int fixAlignment(int align)
47  {
48  return (Alignment==-1) ? std::alignment_of<T>::value : Alignment;
49  }
50 
51 #endif
52 
53  public:
54  using pointer = typename MallocAllocator<T>::pointer;
55  using size_type = typename MallocAllocator<T>::size_type;
56  template <class U> struct rebind {
57  typedef AlignedAllocator<U,Alignment> other;
58  };
59 
60  static constexpr int alignment = fixAlignment(sizeof(void*));
61 
63  pointer allocate(size_type n, const void* hint = 0)
64  {
65 
67  if (n > this->max_size())
68  throw std::bad_alloc();
69 
70 #if __APPLE__
71  /*
72  * Apple's standard library doesn't have aligned_alloc() - C11 is still something
73  * from the future in Cupertino. Luckily, they got around to finally implementing
74  * posix_memalign(), so let's use that instead.
75  */
76  void* ret = nullptr;
77  if (posix_memalign(&ret, alignment, n * sizeof(T)) != 0)
78  throw std::bad_alloc();
79 
80  return static_cast<pointer>(ret);
81 #else
82  /*
83  * Everybody else gets the standard treatment.
84  */
85  pointer ret = static_cast<pointer>(aligned_alloc(alignment, n * sizeof(T)));
86  if (!ret)
87  throw std::bad_alloc();
88 
89  return ret;
90 #endif
91  }
92  };
93 
94 }
95 
96 #endif // DUNE_ALIGNED_ALLOCATOR_HH
Allocators which guarantee alignment of the memory.
Definition: alignedallocator.hh:20
pointer allocate(size_type n, const void *hint=0)
allocate n objects of type T
Definition: alignedallocator.hh:63
Allocators implementation which simply calls malloc/free.
Definition: mallocallocator.hh:23
size_type max_size() const noexcept
max size for allocate
Definition: mallocallocator.hh:75
#define DUNE_UNUSED_PARAMETER(parm)
A macro to mark intentionally unused function parameters with.
Definition: unused.hh:25
Allocators that use malloc/free.
Dune namespace.
Definition: alignedallocator.hh:10
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 2, 22:35, 2024)