Death::Memory class

Memory-related utilities.

Public static functions

template<class T, std::size_t alignment = alignof(T)>
static auto allocateAligned(std::size_t size) -> Containers::Array<T>
Allocate aligned memory and value-initialize it.
template<class T, std::size_t alignment = alignof(T)>
static auto allocateAligned(Containers::DefaultInitT, std::size_t size) -> Containers::Array<T>
Allocate aligned memory and default-initialize it.
template<class T, std::size_t alignment = alignof(T)>
static auto allocateAligned(Containers::ValueInitT, std::size_t size) -> Containers::Array<T>
Allocate aligned memory and value-initialize it.
template<class T, std::size_t alignment = alignof(T)>
static auto allocateAligned(Containers::NoInitT, std::size_t size) -> Containers::Array<T>
Allocate aligned memory and leave it uninitialized.
template<typename T, typename std::enable_if<std::is_trivially_copyable<T>::value, int>::type = 0>
static auto loadUnaligned(const void* p) -> T constexpr noexcept
Returns a value of given size from unaligned pointer.
template<typename T, typename std::enable_if<std::is_trivially_copyable<T>::value, int>::type = 0>
static void storeUnaligned(void* p, T v) constexpr noexcept
Stores a value of given size to unaligned pointer.

Constructors, destructors, conversion operators

Memory() deleted
~Memory() deleted

Function documentation

template<class T, std::size_t alignment = alignof(T)>
static Containers::Array<T> Death::Memory::allocateAligned(std::size_t size)

Allocate aligned memory and value-initialize it.

Template parameters
T Type of the returned array
alignment Allocation alignment, in bytes
Parameters
size Count of T items to allocate. If 0, no allocation is done.

Compared to the classic C std::malloc() or C++ new that commonly aligns only to 2*sizeof(void*), this function returns "overaligned" allocations, which is mainly useful for efficient SIMD operations.

The alignment is implicitly alignof(T), but can be overridden with the alignment template parameter. When specified explicitly, it is expected to be a power-of-two value, at most 256 bytes and the total byte size being a multiple of the alignment.

The returned pointer is always aligned to at least the desired value, but the alignment can be also higher. For example, allocating a 2 MB buffer may result in it being aligned to the whole memory page, or small alignment values could get rounded up to the default 2*sizeof(void*) alignment.

Array initialization

Like with Containers::Array, the returned array is by default value-initialized, which means that trivial types are zero-initialized and the default constructor is called on other types. Different behavior can be achieved with the following tags, compared to Containers::Array the initialization is performed separately from the allocation itself with either a loop or a call to std::memset().

template<class T, std::size_t alignment = alignof(T)>
static Containers::Array<T> Death::Memory::allocateAligned(Containers::DefaultInitT, std::size_t size)

Allocate aligned memory and default-initialize it.

Compared to allocateAligned(std::size_t), trivial types are not initialized and default constructor is called otherwise. Because of the differing behavior for trivial types it's better to explicitly use either the allocateAligned(Containers::ValueInitT, std::size_t) or the allocateAligned(Containers::NoInitT, std::size_t) variant instead.

Implemented via allocateAligned(Containers::NoInitT, std::size_t) with a loop calling the constructors on the returned allocation in case of non-trivial types.

template<class T, std::size_t alignment = alignof(T)>
static Containers::Array<T> Death::Memory::allocateAligned(Containers::ValueInitT, std::size_t size)

Allocate aligned memory and value-initialize it.

Same as allocateAligned(std::size_t), just more explicit. Implemented via allocateAligned(Containers::NoInitT, std::size_t) with either a std::memset() or a loop calling the constructors on the returned allocation.

template<class T, std::size_t alignment = alignof(T)>
static Containers::Array<T> Death::Memory::allocateAligned(Containers::NoInitT, std::size_t size)

Allocate aligned memory and leave it uninitialized.

Compared to allocateAligned(std::size_t), the memory is left in an unitialized state. For trivial types is equivalent to allocateAligned(Containers::DefaultInitT, std::size_t). For non-trivial types, destruction is always done using a custom deleter that explicitly calls the destructor on all elements — which means that for non-trivial types you're expected to construct all elements using placement new (or for example std::uninitialized_copy()) in order to avoid calling destructors on uninitialized memory.