Loading...
Searching...
No Matches
alignedallocator.hh
Go to the documentation of this file.
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
// SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
#ifndef DUNE_ALIGNED_ALLOCATOR_HH
#define DUNE_ALIGNED_ALLOCATOR_HH
#include "mallocallocator.hh"
#include <cstdlib>
#include <type_traits>
namespace Dune
{
template<class T, int Alignment = -1>
class AlignedAllocator : public MallocAllocator<T> {
#if __APPLE__
/*
* macOS has pretty draconian restrictions on the
* alignments that you may ask for: It has to be
*
* 1) a power of 2
* 2) at least as large as sizeof(void*)
*
* So here is a little constexpr function that calculates just that
* (together with the correct starting value for align fed in further down).
*/
static constexpr int fixAlignment(int align)
{
return ((Alignment==-1) ? std::alignment_of<T>::value : Alignment) > align
? fixAlignment(align << 1) : align;
}
#else
/*
* Non-Apple platforms we just have to check whether an explicit alignment was
* restricted or fall back to the default alignment of T.
*/
static constexpr int fixAlignment(int align)
{
return (Alignment==-1) ? std::alignment_of<T>::value : Alignment;
}
#endif
public:
using pointer = typename MallocAllocator<T>::pointer;
using size_type = typename MallocAllocator<T>::size_type;
template <class U> struct rebind {
typedef AlignedAllocator<U,Alignment> other;
};
static constexpr int alignment = fixAlignment(sizeof(void*));
pointer allocate(size_type n, [[maybe_unused]] const void* hint = 0)
{
if (n > this->max_size())
throw std::bad_alloc();
#if __APPLE__
// Apple is also restrictive regarding the allocation size.
// size must be at least the alignment size.
size_type size = n * sizeof(T) >= alignment ? n * sizeof(T) : alignment;
#else
size_type size = n * sizeof(T);
#endif
/*
* Everybody else gets the standard treatment.
*/
#if defined(_MSC_VER)
pointer ret = static_cast<pointer>(_aligned_malloc(alignment, size));
#else
pointer ret = static_cast<pointer>(std::aligned_alloc(alignment, size));
#endif
if (!ret)
throw std::bad_alloc();
return ret;
}
#if defined(_MSC_VER)
void deallocate(pointer p, [[maybe_unused]] size_type n)
{
_aligned_free(p);
}
#endif
};
}
#endif // DUNE_ALIGNED_ALLOCATOR_HH
mallocallocator.hh
Allocators that use malloc/free.
Dune
Dune namespace
Definition alignedallocator.hh:13
Dune::size
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition integersequence.hh:75
Dune::AlignedAllocator
Allocators which guarantee alignment of the memory.
Definition alignedallocator.hh:23
Dune::AlignedAllocator::size_type
typename MallocAllocator< T >::size_type size_type
Definition alignedallocator.hh:58
Dune::AlignedAllocator::allocate
pointer allocate(size_type n, const void *hint=0)
allocate n objects of type T
Definition alignedallocator.hh:66
Dune::AlignedAllocator::pointer
typename MallocAllocator< T >::pointer pointer
Definition alignedallocator.hh:57
Dune::AlignedAllocator< U, Alignment >::alignment
static constexpr int alignment
Definition alignedallocator.hh:63
Dune::AlignedAllocator::rebind
Definition alignedallocator.hh:59
Dune::AlignedAllocator::rebind::other
AlignedAllocator< U, Alignment > other
Definition alignedallocator.hh:60
Dune::MallocAllocator::pointer
T * pointer
Definition mallocallocator.hh:28
Dune::MallocAllocator::MallocAllocator
MallocAllocator() noexcept
create a new MallocAllocator
Definition mallocallocator.hh:38
Dune::MallocAllocator::size_type
std::size_t size_type
Definition mallocallocator.hh:26
Dune::MallocAllocator::deallocate
void deallocate(pointer p, size_type n)
deallocate n objects of type T at address p
Definition mallocallocator.hh:68
Dune::MallocAllocator::max_size
size_type max_size() const noexcept
max size for allocate
Definition mallocallocator.hh:74