stdx.allocator.typed
This module defines TypedAllocator
, a statically-typed
allocator that
aggregates multiple untyped allocators and uses them depending on the static
properties of the types allocated. For example, distinct allocators may be used
for thread-local vs. thread-shared data, or for fixed-size data (struct
,
class
objects) vs. resizable data (arrays).
-
Declaration
enum
AllocFlag
: uint;Allocation-related flags dictated by type characteristics.
TypedAllocator
deduces these flags from the type being allocated and uses the appropriate allocator accordingly.-
Declaration
fixedSize
Fixed-size allocation (unlikely to get reallocated later). Examples:
int
,double
, anystruct
orclass
type. By default it is assumed that the allocation is variable-size, i.e. susceptible to later reallocation (for example all array types). This flag is advisory, i.e. in-place resizing may be attempted for
allocations and may succeed. The flag is just a hint to the compiler it may use allocation strategies that work well with objects of fixed size.fixedSize
-
Declaration
hasNoIndirections
The type being allocated embeds no pointers. Examples:
int
,int[]
, . The implicit conservative assumption is that the type has members with indirections so it needs to be scanned if garbage collected. Example of types with pointers:int*[]
, . -
Declaration
immutableShared
threadLocal
By default it is conservatively assumed that allocated memory may be
cast
toshared
, passed across threads, and deallocated in a different thread than the one that allocated it. If that's not the case, there are two options. First,
means the memory is allocated forimmutableShared
immutable
data and will be deallocated in the same thread it was allocated in. Second,
means the memory is not to be shared across threads at all. The two flags cannot be simultaneously present.threadLocal
-
-
Declaration
struct
TypedAllocator
(PrimaryAllocator, Policies...);
acts like a chassis on which several specialized allocators can be assembled. To let the system make a choice about a particular kind of allocation, useTypedAllocator
Default
for the respective parameters.Discussion
There is a hierarchy of allocation kinds. When an allocator is implemented for a given combination of flags, it is used. Otherwise, the next down the list is chosen.
Parameters
PrimaryAllocator
The default allocator.
Policies
Zero or more pairs consisting of an
AllocFlag
and an allocator type.Examples
import stdx.allocator.gc_allocator : GCAllocator; import stdx.allocator.mallocator : Mallocator; import stdx.allocator.mmap_allocator : MmapAllocator; alias MyAllocator = TypedAllocator!(GCAllocator, AllocFlag.fixedSize | AllocFlag.threadLocal, Mallocator, AllocFlag.fixedSize | AllocFlag.threadLocal | AllocFlag.hasNoIndirections, MmapAllocator, ); MyAllocator a; auto b = &a.allocatorFor!0(); static assert(is(typeof(*b) == shared GCAllocator)); enum f1 = AllocFlag.fixedSize | AllocFlag.threadLocal; auto c = &a.allocatorFor!f1(); static assert(is(typeof(*c) == Mallocator)); enum f2 = AllocFlag.fixedSize | AllocFlag.threadLocal; static assert(is(typeof(a.allocatorFor!f2()) == Mallocator)); // Partial match enum f3 = AllocFlag.threadLocal; static assert(is(typeof(a.allocatorFor!f3()) == Mallocator)); int* p = a.make!int; scope(exit) a.dispose(p); int[] arr = a.makeArray!int(42); scope(exit) a.dispose(arr); assert(a.expandArray(arr, 3)); assert(a.shrinkArray(arr, 4));
-
Declaration
ref auto
allocatorFor
(uint flags)();
ref autoallocatorFor
(T)();Given
flags
as a combination ofAllocFlag
values, or a typeT
, returns the allocator that's a closest fit in capabilities. -
Declaration
uint
type2flags
(T)();Given a type
T
, returns its allocation-related flags as a combination ofAllocFlag
values. -
Declaration
auto
make
(T, A...)(auto ref Aargs
);Dynamically allocates (using the appropriate allocator chosen with
allocatorFor!T
) and then creates in the memory allocated an object of typeT
, using
(if any) for its initialization. Initialization occurs in the memory allocated and is otherwise semantically the same asargs
T(
. (Note that usingargs
)
creates a pointer to an (empty) array ofmake
!(T[])T
s, not an array. To allocate and initialize an array, usemakeArray!T
described below.)Parameters
T
Type of the object being created.
A
args
Optional arguments used for initializing the created object. If not present, the object is default constructed.
Return Value
If
T
is a class type, returns a reference to the createdT
object. Otherwise, returns aT*
pointing to the created object. In all cases, returnsnull
if allocation failed.Throws
If
T
's constructor throws, deallocates the allocated memory and propagates the exception. -
Declaration
T[]
makeArray
(T)(size_tlength
);
T[]makeArray
(T)(size_tlength
, auto ref Tinit
);
T[]makeArray
(T, R)(Rrange
) if (isInputRange!R);Create an array of
T
with
elements. The array is either default-initialized, filled with copies oflength
, or initialized with values fetched frominit
.range
Parameters
T
element type of the array being created
size_t
length
length
of the newly created arrayT
init
element used for filling the array
R
range
range
used for initializing the array elementsReturn Value
The newly-created array, or
null
if either
waslength
0
or allocation failed.Throws
The first two overloads throw only if the used allocator's primitives do. The overloads that involve copy initialization deallocate memory and propagate the exception if the copy operation throws.
-
Declaration
bool
expandArray
(T)(ref T[]array
, size_tdelta
);
boolexpandArray
(T)(T[]array
, size_tdelta
, auto ref Tinit
);
boolexpandArray
(T, R)(ref T[]array
, Rrange
) if (isInputRange!R);Grows
by appendingarray
more elements. The needed memory is allocated using the same allocator that was used for thedelta
array
type. The extra elements added are either default-initialized, filled with copies of
, or initialized with values fetched frominit
.range
Parameters
T
element type of the
array
being createdT[]
array
a reference to the
array
being grownsize_t
delta
number of elements to add (upon success the new length of
is )array
T
init
element used for filling the
array
R
range
range
used for initializing thearray
elementsReturn Value
true
upon success,false
if memory could not be allocated. In the latter case
is left unaffected.array
Throws
The first two overloads throw only if the used allocator's primitives do. The overloads that involve copy initialization deallocate memory and propagate the exception if the copy operation throws.
-
Declaration
bool
shrinkArray
(T)(ref T[]arr
, size_tdelta
);Shrinks an array by
elements usingdelta
allocatorFor!(T[])
.Discussion
If , does nothing and returns
false
. Otherwise, destroys the last elements in the array and then reallocates the array's buffer. If reallocation fails, fills the array with default-initialized data.Parameters
T
element type of the array being created
T[]
arr
a reference to the array being shrunk
size_t
delta
number of elements to remove (upon success the new length of
is )arr
Return Value
true
upon success,false
if memory could not be reallocated. In the latter case is left with default-initialized elements.Throws
The first two overloads throw only if the used allocator's primitives do. The overloads that involve copy initialization deallocate memory and propagate the exception if the copy operation throws.
-
Declaration
void
dispose
(T)(T*p
);
voiddispose
(T)(Tp
) if (is(T == class) || is(T == interface));
voiddispose
(T)(T[]array
);Destroys and then deallocates (using
allocatorFor!T
) the object pointed to by a pointer, the class object referred to by aclass
orinterface
reference, or an entirearray
. It is assumed the respective entities had been allocated with the same allocator.