Dune Core Modules (2.7.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#if !(DUNE_HAVE_C_ALIGNED_ALLOC || (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600))
10 #error Need either aligned_alloc() or posix_memalign() to compile AlignedAllocator
11#endif
12
13namespace Dune
14{
15
23 template<class T, int Alignment = -1>
25
26#if !DUNE_HAVE_C_ALIGNED_ALLOC
27
28 /*
29 * posix_memalign() on macOS has pretty draconian restrictions on the
30 * alignments that you may ask for: It has to be
31 *
32 * 1) a power of 2
33 * 2) at least as large as sizeof(void*)
34 *
35 * So here is a little constexpr function that calculates just that
36 * (together with the correct starting value for align fed in further down).
37 */
38 static constexpr int fixAlignment(int align)
39 {
40 return ((Alignment==-1) ? std::alignment_of<T>::value : Alignment) > align
41 ? fixAlignment(align << 1) : align;
42 }
43
44#else
45
46 /*
47 * Non-Apple platforms just have to check whether an explicit alignment was
48 * restricted or fall back to the default alignment of T.
49 */
50 static constexpr int fixAlignment(int align)
51 {
52 return (Alignment==-1) ? std::alignment_of<T>::value : Alignment;
53 }
54
55#endif
56
57 public:
58 using pointer = typename MallocAllocator<T>::pointer;
59 using size_type = typename MallocAllocator<T>::size_type;
60 template <class U> struct rebind {
62 };
63
64 static constexpr int alignment = fixAlignment(sizeof(void*));
65
67 pointer allocate(size_type n, const void* hint = 0)
68 {
69
71 if (n > this->max_size())
72 throw std::bad_alloc();
73
74#if !DUNE_HAVE_C_ALIGNED_ALLOC
75 /*
76 * Apple's standard library doesn't have aligned_alloc() - C11 is still something
77 * from the future in Cupertino. Luckily, they got around to finally implementing
78 * posix_memalign(), so let's use that instead.
79 */
80 void* ret = nullptr;
81 if (posix_memalign(&ret, alignment, n * sizeof(T)) != 0)
82 throw std::bad_alloc();
83
84 return static_cast<pointer>(ret);
85#else
86 /*
87 * Everybody else gets the standard treatment.
88 */
89 pointer ret = static_cast<pointer>(aligned_alloc(alignment, n * sizeof(T)));
90 if (!ret)
91 throw std::bad_alloc();
92
93 return ret;
94#endif
95 }
96 };
97
98}
99
100#endif // DUNE_ALIGNED_ALLOCATOR_HH
Allocators which guarantee alignment of the memory.
Definition: alignedallocator.hh:24
pointer allocate(size_type n, const void *hint=0)
allocate n objects of type T
Definition: alignedallocator.hh:67
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:14
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)