SeqAn3  3.0.2
The Modern C++ library for sequence analysis.
seqan3::aligned_allocator< value_t, alignment_v > Class Template Reference

Allocates uninitialized storage whose memory-alignment is specified by alignment. More...

#include <seqan3/range/container/aligned_allocator.hpp>

Classes

struct  rebind
 The aligned_allocator member template class aligned_allocator::rebind provides a way to obtain an allocator for a different type. More...
 

Public Types

using difference_type = typename std::pointer_traits< pointer >::difference_type
 The difference type of the allocation.
 
using is_always_equal = std::true_type
 Are any two allocators of the same aligned_allocator type always compare equal?
 
using pointer = value_type *
 The pointer type of the allocation.
 
using size_type = std::make_unsigned_t< difference_type >
 The size type of the allocation.
 
using value_type = value_t
 The value type of the allocation.
 

Public Member Functions

pointer allocate (size_type const n) const
 Allocates sufficiently large memory to hold n many elements of value_type. More...
 
void deallocate (pointer const p, size_type const n) const noexcept
 Deallocates the storage referenced by the pointer p, which must be a pointer obtained by an earlier call to seqan3::aligned_allocator::allocate. More...
 
Constructors, destructor and assignment
 aligned_allocator ()=default
 Defaulted.
 
 aligned_allocator (aligned_allocator const &)=default
 Defaulted.
 
 aligned_allocator (aligned_allocator &&)=default
 Defaulted.
 
aligned_allocatoroperator= (aligned_allocator const &)=default
 Defaulted.
 
aligned_allocatoroperator= (aligned_allocator &&)=default
 Defaulted.
 
 ~aligned_allocator ()=default
 Defaulted.
 
template<class other_value_type , size_t other_alignment>
constexpr aligned_allocator (aligned_allocator< other_value_type, other_alignment > const &) noexcept
 Copy constructor with different value type and alignment.
 
Comparison operators
template<class value_type2 , size_t alignment2>
constexpr bool operator== (aligned_allocator< value_type2, alignment2 > const &) noexcept
 Returns true if the memory-alignment matches.
 
template<class value_type2 , size_t alignment2>
constexpr bool operator!= (aligned_allocator< value_type2, alignment2 > const &) noexcept
 Returns false if the memory-alignment mismatches.
 

Static Public Attributes

static constexpr size_t alignment = alignment_v
 The memory-alignment of the allocation.
 

Detailed Description

template<typename value_t, size_t alignment_v = __STDCPP_DEFAULT_NEW_ALIGNMENT__>
class seqan3::aligned_allocator< value_t, alignment_v >

Allocates uninitialized storage whose memory-alignment is specified by alignment.

Template Parameters
value_tThe value type of the allocation.
alignment_vThe memory-alignment of the allocation; defaults to __STDCPP_DEFAULT_NEW_ALIGNMENT__.

This class allocates memory at the given alignment_v offset. This makes sure that the allocated memory starts at a memory offset equal to some multiple of the word size. More formally, a memory address a, is said to be n-byte aligned when n is a power of two and a is a multiple of n bytes.

If the specified alignment is not supported (e.g. alignments that are not a power of two) by the used allocation method a std::bad_alloc exception will be thrown. For requested alignments larger than __STDCPP_DEFAULT_NEW_ALIGNMENT__, also called new-extended alignments, the storage will have the alignment specified by the value alignment. Otherwise, the storage is aligned for any object that does not have new-extended alignment, e.g. int or double, and is of the requested size.

#include <iostream>
#include <vector>
size_t memory_alignment(void * value, size_t alignment)
{
return (reinterpret_cast<size_t>(value) & (alignment - 1));
}
int main()
{
// 128-byte memory aligned and 16bit = 2byte address width for each element
// vector has no alignment and 16bit = 2byte address width for each element
std::vector<int16_t> vec_unaligned{1,2,3,4,5};
// 256-byte memory aligned and 32bit = 4byte address width for each element
for (auto && x: vec128)
std::cout << "Item: " << x << " (" << &x << ", 128-byte aligned offset: " << memory_alignment(&x, 128u) << ")\n";
for (auto && x: vec_unaligned)
std::cout << "Item: " << x << " (" << &x << ", unaligned start: " << memory_alignment(&x, 128u) << ")\n";
for (auto && x: vec256)
std::cout << "Item: " << x << " (" << &x << ", 256-byte aligned offset: " << memory_alignment(&x, 256u) << ")\n";
}

Will output something like:

Item: 1 (0x55d5d0722f00, 128-byte aligned offset: 0)
Item: 2 (0x55d5d0722f02, 128-byte aligned offset: 2)
Item: 3 (0x55d5d0722f04, 128-byte aligned offset: 4)
Item: 4 (0x55d5d0722f06, 128-byte aligned offset: 6)
Item: 5 (0x55d5d0722f08, 128-byte aligned offset: 8)
Item: 1 (0x55d5d0722f40, unaligned start: 64)
Item: 2 (0x55d5d0722f42, unaligned start: 66)
Item: 3 (0x55d5d0722f44, unaligned start: 68)
Item: 4 (0x55d5d0722f46, unaligned start: 70)
Item: 5 (0x55d5d0722f48, unaligned start: 72)
Item: 1 (0x55d5d0723000, 256-byte aligned offset: 0)
Item: 2 (0x55d5d0723004, 256-byte aligned offset: 4)
Item: 3 (0x55d5d0723008, 256-byte aligned offset: 8)
Item: 4 (0x55d5d072300c, 256-byte aligned offset: 12)
Item: 5 (0x55d5d0723010, 256-byte aligned offset: 16)

As you can see, in the case of the aligned_allocator it is guaranteed that the first element in the vector starts at offset 0.

See also
https://en.cppreference.com/w/cpp/concept/Allocator
https://en.cppreference.com/w/cpp/memory/c/aligned_alloc

Member Function Documentation

◆ allocate()

template<typename value_t , size_t alignment_v = __STDCPP_DEFAULT_NEW_ALIGNMENT__>
pointer seqan3::aligned_allocator< value_t, alignment_v >::allocate ( size_type const  n) const
inline

Allocates sufficiently large memory to hold n many elements of value_type.

Parameters
[in]nThe number of elements for which to allocate the memory.
Returns
The pointer to the first block of allocated memory.
Exceptions
Throwsstd::bad_alloc if allocation fails, i.e. either the call to the throwing version of operator new function throws or the requested memory exceeds the maximal number of elements to allocate.

Allocates n * sizeof(value_type) bytes of uninitialized storage by calling operator new. If the given alignment is bigger than STDCPP_DEFAULT_NEW_ALIGNMENT, the alignment aware operator new that takes as second argument the desired alignment of type std::align_val_t is used.

Note
We call the new operator with the semantic requirements that the c++ standard specifies/demands, but be aware that users can overload any (global) operator new that might not adhere to the standard and might cause std::bad_alloc or unaligned pointers.
See also
https://en.cppreference.com/w/cpp/memory/allocator/allocate

Thread safety

Thread-safe.

Exception

Strong exception guarantee.

◆ deallocate()

template<typename value_t , size_t alignment_v = __STDCPP_DEFAULT_NEW_ALIGNMENT__>
void seqan3::aligned_allocator< value_t, alignment_v >::deallocate ( pointer const  p,
size_type const  n 
) const
inlinenoexcept

Deallocates the storage referenced by the pointer p, which must be a pointer obtained by an earlier call to seqan3::aligned_allocator::allocate.

Parameters
[in]pThe pointer to the memory to be deallocated.
[in]nThe number of elements to be deallocated.

The argument n must be equal to the first argument of the call to seqan3::aligned_allocator::allocate that originally produced p, otherwise the behavior is undefined. This function calls operator delete to deallocate the memory of specified size. If the given alignment is bigger than STDCPP_DEFAULT_NEW_ALIGNMENT the alignment aware operator delete that takes as third argument the alignment as std::align_val_t.

See also
https://en.cppreference.com/w/cpp/memory/allocator/deallocate

Thread safety

Thread-safe.

Exception

Nothrow guarantee.


The documentation for this class was generated from the following file: