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.segregator

struct Segregator(size_t threshold, SmallAllocator, LargeAllocator);

Dispatches allocations (and deallocations) between two allocators (SmallAllocator and LargeAllocator) depending on the size allocated, as
follows. All allocations smaller than or equal to threshold will be
dispatched to SmallAllocator. The others will go to LargeAllocator.

If both allocators are shared, the Segregator will also offer shared methods.

The alignment offered is the minimum of the two allocators' alignment.

static size_t goodAllocSize(size_t s);

This method is defined only if at least one of the allocators defines
it. The good allocation size is obtained from SmallAllocator if s <= threshold, or LargeAllocator otherwise. (If one of the
allocators does not define goodAllocSize, the default
implementation in this module applies.)

void[] allocate(size_t);

The memory is obtained from SmallAllocator if s <= threshold,
or LargeAllocator otherwise.

void[] alignedAllocate(size_t, uint);

This method is defined if both allocators define it, and forwards to
SmallAllocator or LargeAllocator appropriately.

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

This method is defined only if at least one of the allocators defines
it. If SmallAllocator defines expand and b.length +
delta <= threshold, the call is forwarded to SmallAllocator. If LargeAllocator defines expand and b.length > threshold, the
call is forwarded to LargeAllocator. Otherwise, the call returns
false.

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

This method is defined only if at least one of the allocators defines
it. If SmallAllocator defines reallocate and b.length <=
threshold && s <= threshold, the call is forwarded to SmallAllocator. If LargeAllocator defines expand and b.length > threshold && s > threshold, the call is forwarded to LargeAllocator. Otherwise, the call returns false.

bool alignedReallocate(ref void[] b, size_t s, uint a);

This method is defined only if at least one of the allocators defines
it, and work similarly to reallocate.

Ternary owns(void[] b);

This method is defined only if both allocators define it. The call is
forwarded to SmallAllocator if b.length <= threshold, or LargeAllocator otherwise.

bool deallocate(void[] b);

This function is defined only if both allocators define it, and forwards
appropriately depending on b.length.

bool deallocateAll();

This function is defined only if both allocators define it, and calls
deallocateAll for them in turn.

Ternary empty();

This function is defined only if both allocators define it, and returns
the conjunction of empty calls for the two.

ref auto allocatorForSize(size_t s)();

Composite allocators involving nested instantiations of Segregator make
it difficult to access individual sub-allocators stored within. allocatorForSize simplifies the task by supplying the allocator nested
inside a Segregator that is responsible for a specific size s.

A Segregator with more than three arguments expands to a composition of
elemental Segregators, as illustrated by the following example:

alias A =
Segregator!(
n1, A1,
n2, A2,
n3, A3,
A4
);

With this definition, allocation requests for n1 bytes or less are directed
to A1; requests between n1 + 1 and n2 bytes (inclusive) are
directed to A2; requests between n2 + 1 and n3 bytes (inclusive)
are directed to A3; and requests for more than n3 bytes are directed
to A4. If some particular range should not be handled, NullAllocator
may be used appropriately.