API Reference — pma/PolyAllocator
impl::max_align_of<T, U>
A compile-time trait that resolves to whichever of two types, T or U, has the greater alignment.
Why this exists
PolyAllocator's default alignment must be at least as strict as both the element type's natural alignment and a baseline minimum (min_align_t); a raw alignof comparison on just one type could under-align the allocator's storage. This trait picks the correct type to take alignof of without requiring the caller to reason about the comparison themselves.
Fields
| Name | Type | Description |
|---|---|---|
type |
typename std::conditional<(alignof(T) > alignof(U)), T, U>::type |
The type among T/U with the larger alignment. |
Relationships
PolyAllocator— defaultAlignmentparameter isalignof(max_align_of<T, min_align_t>::type).
impl::min_align_t
An internal alias (void*) used as the minimal-alignment reference type when computing a PolyAllocator's default alignment.
Why this exists
PolyAllocator's default Alignment template parameter needs a baseline alignment to compare a type's own alignment against, and void* is a convenient stand-in for "pointer-sized minimum alignment" without depending on a specific concrete type. It exists purely to feed max_align_of inside the impl namespace.
Relationships
max_align_of— compares a type's alignment againstmin_align_tto compute the larger of the two.PolyAllocator— usesmax_align_of<T, min_align_t>as its default alignment.
template<typename T, std::size_t Alignment, class TDefaultMemoryResource> class PolyAllocator : public std::scoped_allocator_adaptor<...>
A standard-library-compatible allocator that forwards allocation and construction to a runtime-supplied MemoryResource, letting containers use arbitrary memory strategies without being templated on the allocator's concrete type.
When to use this
Use this to plug a custom MemoryResource (arena, pool, tracking allocator) into std::vector, std::map, or any other allocator-aware standard container. Construct it with a MemoryResource*; passing nullptr falls back to a default (TDefaultMemoryResource) static instance.
Method groups
| Group | Methods |
|---|---|
| Construction | PolyAllocator() (default and from MemoryResource* / nullptr / rebind-compatible allocator) |
| Raw allocation | allocateBytes, deallocateBytes |
| Object allocation | allocateObject, deallocateObject, newObject, deleteObject |
| STL allocator interface | allocate (and the deallocate/rebind machinery inherited from scoped_allocator_adaptor) |
Example
pma::MemoryResource* memRes = getArenaMemoryResource();
pma::PolyAllocator<dna::Vector3> alloc{memRes};
std::vector<dna::Vector3, pma::PolyAllocator<dna::Vector3>> joints{alloc};
joints.push_back({1.0f, 0.0f, 0.0f});
Parameters
| Name | Type | Description |
|---|---|---|
memRes |
MemoryResource* |
optional — the backing memory resource; if nullptr, falls back to a static TDefaultMemoryResource instance. |
count |
std::size_t |
required (for allocateObject/deallocateObject) — number of objects to allocate/deallocate. |
alignment |
std::size_t |
optional — defaults to the allocator's Alignment template parameter. |
Watch out for
- Two
PolyAllocatorinstances compare equal only if bothAlignmentmatches and their underlyingMemoryResourcepointers match — allocators from different memory resources are never interchangeable. - The default-constructed default memory resource is a function-local
static, guarded against clang's exit-time-destructor warning — its lifetime spans the whole program. - The default
MemoryResourceis a static local inside the default constructor, created once per<T, Alignment, TDefaultMemoryResource>instantiation. Its destructor runs at program exit. Clang's-Wexit-time-destructorswarning is explicitly suppressed here; be aware of destruction ordering if your program relies on destructor sequencing. - Passing
nullptrexplicitly is equivalent to the default constructor — it does not disable allocation; it selects the static default resource. - The outer
pma::PolyAllocatorinherits fromstd::scoped_allocator_adaptor, meaning nested containers (e.g.,std::vector<std::string>) automatically propagate the same resource to their inner allocators. If you want independent resources per nesting level, do not use the scoped adaptor directly.
Constraints
- Thread safety of allocations depends entirely on the supplied
MemoryResource. The allocator wrapper itself performs no synchronization.
TDefaultMemoryResource (template parameter)
The fallback MemoryResource type a PolyAllocator uses when constructed without an explicit memory resource (or with nullptr).
Why this exists
Requiring every PolyAllocator use site to pass a MemoryResource* would make simple cases (no custom allocator needed) verbose; this template parameter lets PolyAllocator default to DefaultMemoryResource while still allowing callers to override it for specialized allocation strategies.
Relationships
PolyAllocator— default-constructs a static instance of this type when no explicitMemoryResource*is supplied.MemoryResource—TDefaultMemoryResourcemust be a concrete subclass of this abstract base.
UDefaultMemoryResource (template parameter)
The corresponding default-memory-resource template parameter for the "other" PolyAllocator type in cross-allocator comparisons (operator==/operator!=).
Why this exists
PolyAllocator equality/inequality comparisons need to compare two possibly-differently-templated PolyAllocator instances; UDefaultMemoryResource names the second instance's default-resource type parameter symmetrically to TDefaultMemoryResource on the first, even though it plays no role in the equality check itself (only alignment and the resolved MemoryResource* do).
Relationships
PolyAllocator::operator==/operator!=— free functions comparing aPolyAllocator<T, TAlignment, TDefaultMemoryResource>against aPolyAllocator<U, UAlignment, UDefaultMemoryResource>.