Quickly fork, edit online, and submit a pull request for this page.
Requires a signed-in GitHub account. This works well for small changes.
If you'd like to make larger changes you may want to consider using
a local clone.

std.experimental.allocator.building_blocks.affix_allocator

struct AffixAllocator(Allocator, Prefix, Suffix = void);

Allocator that adds some extra data before (of type Prefix) and/or after
(of type Suffix) any allocation made with its parent allocator. This is
useful for uses where additional allocation-related information is needed, such
as mutexes, reference counts, or walls for debugging memory corruption errors.

If Prefix is not void, Allocator must guarantee an alignment at
least as large as Prefix.alignof.

Suffixes are slower to get at because of alignment rounding, so prefixes should
be preferred. However, small prefixes blunt the alignment so if a large
alignment with a small affix is needed, suffixes should be chosen.

The following methods are defined if Allocator defines them, and forward to it: deallocateAll, empty, owns.

If Prefix is void, the alignment is that of the parent. Otherwise, the alignment is the same as the Prefix's alignment.

Allocator _parent;

If the parent allocator Allocator is stateful, an instance of it is
stored as a member. Otherwise, AffixAllocator uses
Allocator.instance. In either case, the name parent is uniformly
used for accessing the parent allocator.

Allocator parent();

If the parent allocator Allocator is stateful, an instance of it is
stored as a member. Otherwise, AffixAllocator uses
Allocator.instance. In either case, the name parent is uniformly
used for accessing the parent allocator.

size_t goodAllocSize(size_t);

void[] allocate(size_t);

Ternary owns(void[]);

bool expand(ref void[] b, size_t delta);

bool reallocate(ref void[] b, size_t s);

bool deallocate(void[] b);

bool deallocateAll();

Ternary empty();

Standard allocator methods. Each is defined if and only if the parent
allocator defines the homonym method (except for goodAllocSize,
which may use the global default). Also, the methods will be shared if the parent allocator defines them as such.

static AffixAllocator instance;

The instance singleton is defined if and only if the parent allocator
has no state and defines its own it object.

ref auto prefix(T)(T[] b);

ref auto suffix(T)(T[] b);

Affix access functions offering references to the affixes of a
block b previously allocated with this allocator. b may not be null.
They are defined if and only if the corresponding affix is not void.

The qualifiers of the affix are not always the same as the qualifiers
of the argument. This is because the affixes are not part of the data
itself, but instead are just associated with the data and known
to the allocator. The table below documents the type of preffix(b) and
affix(b) depending on the type of b.

Result of prefix/suffix depending on argument (U is
any unqualified type, Affix is Prefix or Suffix)

Argument Type

Return

Comments

shared(U)[]

ref shared Affix

Data is shared across threads and the affix follows suit.

immutable(U)[]

ref shared Affix

Although the data is immutable, the allocator "knows" the
underlying memory is mutable, so immutable is elided for the affix
which is independent from the data itself. However, the result is
shared because immutable is implicitly shareable so multiple
threads may access and manipulate the affix for the same data.

const(shared(U))[]

ref shared Affix

The data is always shareable across threads. Even if the data
is const, the affix is modifiable by the same reasoning as for
immutable.

const(U)[]

ref const Affix

The input may have originated from U[] or immutable(U)[],
so it may be actually shared or not. Returning an unqualified affix
may result in race conditions, whereas returning a shared affix
may result in inadvertent sharing of mutable thread-local data
across multiple threads. So the returned type is conservatively
ref const.

U[]

ref Affix

Unqualified data has unqualified affixes.

Precondition:b !is null and b must have been allocated with
this allocator.