Orrery
A GPU-accelerated N-body gravitational simulator
Toggle main menu visibility
Loading...
Searching...
No Matches
aligned_allocator.hpp
Go to the documentation of this file.
1
#pragma once
2
26
27
#include <cstddef>
28
#include <limits>
29
#include <new>
30
#include <type_traits>
31
32
namespace
orrery::core {
33
41
inline
constexpr
std::size_t
kCacheLineBytes
= 64;
42
51
template
<
typename
T>
class
AlignedAllocator {
52
public
:
53
using
value_type = T;
54
57
using
propagate_on_container_move_assignment
= std::true_type;
58
61
using
is_always_equal
= std::true_type;
62
63
static
constexpr
std::size_t kAlignment =
kCacheLineBytes
;
64
65
static_assert
(kAlignment >=
alignof
(T),
66
"The requested alignment is weaker than the type's own requirement"
);
67
68
AlignedAllocator() noexcept = default;
69
72
template<typename U>
73
constexpr AlignedAllocator(const AlignedAllocator<U>&
/*other*/
) noexcept {}
74
81
[[nodiscard]]
static
T*
allocate
(std::size_t count) {
82
if
(count >
max_size
()) {
83
// The multiplication below would wrap, and a wrapped byte count
84
// allocates a small block that is then handed back as though it
85
// were large. That is a silent buffer overflow rather than a failed
86
// allocation, so the overflow is turned into the failure it is.
87
throw
std::bad_array_new_length{};
88
}
89
90
// The aligned form of operator new rather than a hand-rolled
91
// over-allocate-and-offset scheme: it is the standard's own answer to
92
// this question, it is available on all three supported compilers, and
93
// it needs no bookkeeping to recover the original pointer.
94
return
static_cast<
T*
>
(::operator
new
(count *
sizeof
(T), std::align_val_t{kAlignment}));
95
}
96
97
static
void
deallocate(T* pointer, std::size_t
/*count*/
)
noexcept
{
98
// The aligned form, matching the allocation above. An ordinary operator
99
// delete would be undefined behaviour here, since the storage did not
100
// come from an ordinary operator new.
101
//
102
// The sized overload is deliberately not used, although the count is to
103
// hand. It saves the allocator a size lookup, but it is only declared
104
// by compilers built with sized deallocation enabled, which is not the
105
// default in every release this project supports. A hint worth that
106
// little is not worth a portability condition.
107
::operator
delete
(pointer, std::align_val_t{kAlignment});
108
}
109
111
[[nodiscard]]
static
constexpr
std::size_t
max_size
() noexcept {
112
return
std::numeric_limits<std::size_t>::max() /
sizeof
(T);
113
}
114
};
115
118
template
<
typename
T,
typename
U>
119
[[nodiscard]]
constexpr
bool
operator==
(
const
AlignedAllocator<T>
&
/*lhs*/
,
120
const
AlignedAllocator<U>
&
/*rhs*/
)
noexcept
{
121
return
true
;
122
}
123
124
}
// namespace orrery::core
orrery::core::operator==
constexpr bool operator==(const AlignedAllocator< T > &, const AlignedAllocator< U > &) noexcept
All instances are interchangeable, whatever their value type, because the allocator holds nothing tha...
Definition
aligned_allocator.hpp:119
orrery::core::kCacheLineBytes
constexpr std::size_t kCacheLineBytes
The cache line length on the target machine, in bytes.
Definition
aligned_allocator.hpp:41
orrery::core::AlignedAllocator
A standard allocator that returns cache-line-aligned storage.
Definition
aligned_allocator.hpp:51
orrery::core::AlignedAllocator::max_size
static constexpr std::size_t max_size() noexcept
The largest count that can be expressed in bytes without wrapping.
Definition
aligned_allocator.hpp:111
orrery::core::AlignedAllocator::propagate_on_container_move_assignment
std::true_type propagate_on_container_move_assignment
Moving a container moves its storage rather than copying its elements, which is the behaviour the con...
Definition
aligned_allocator.hpp:57
orrery::core::AlignedAllocator::is_always_equal
std::true_type is_always_equal
The allocator holds no state, so any instance can free memory that any other instance allocated.
Definition
aligned_allocator.hpp:61
orrery::core::AlignedAllocator::allocate
static T * allocate(std::size_t count)
Allocate storage for count objects.
Definition
aligned_allocator.hpp:81
orrery
core
aligned_allocator.hpp
Generated by
1.17.0