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
9namespace Dune
10{
11
19 template<class T, int Alignment = -1>
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 {
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.111.3 (Jul 15, 22:36, 2024)