API Reference — pma/utils/ManagedInstance
template<class TPointer, class TTarget, class TBase = TTarget> class ManagedInstance { static ManagedInstance with(MemoryResource* memRes); PointerType create(Args&&... args); }
Build a smart pointer (unique_ptr or shared_ptr) whose object was allocated from a specific pma::MemoryResource, with a deleter that knows how to free it back to that same resource.
When to use this
Use ManagedInstance::with(memRes).create(...) instead of std::make_unique/std::make_shared whenever the object must be allocated through a particular MemoryResource — the deleter captures the allocator so the object is freed correctly even though the caller only holds a generic smart pointer.
Example
pma::MemoryResource* memRes = getArenaMemoryResource();
auto instance = pma::impl::ManagedInstance<std::unique_ptr<Base, std::function<void(Base*)>>, Derived, Base>::with(memRes)
.create(constructorArg1, constructorArg2);
// instance is a std::unique_ptr<Base, ...> whose deleter frees Derived via memRes
Parameters
| Name | Type | Description |
|---|---|---|
memRes |
MemoryResource* |
required — the memory resource the constructed object is allocated from and later freed to. |
args |
Args&&... |
required — forwarded to TTarget's constructor. |
Returns
PointerType — a unique_ptr/shared_ptr (per the TPointer alias used) holding the newly constructed TTarget, deleted through memRes.
Watch out for
- The deleter lambda captures
PolyAllocator<TTarget>by value. The underlyingMemoryResource*is stored inside that allocator copy. If theMemoryResourceis destroyed before the last smart pointer goes out of scope, the deleter accesses a dangling pointer and produces undefined behavior. ManagedInstancelives innamespace pma::impl— use theUniqueInstanceandSharedInstancepublic aliases rather than naming this template directly. The template parameters are order-sensitive and error-prone to spell manually.
class MemoryResource;
Forward declaration of the MemoryResource interface used by ManagedInstance to allocate and free the objects it manages.
Why this exists
ManagedInstance only needs a pointer to MemoryResource, so a forward declaration here avoids pulling in the full MemoryResource header just for this utility.
Relationships
ManagedInstance— usesMemoryResource*to create and destroy managed objects.
using PointerType = TPointer;
Public member typedef of ManagedInstance naming the smart-pointer type it produces from create().
Why this exists
Exposing PointerType lets UniqueInstance/SharedInstance (and callers) refer to the exact return type of create() without repeating the full std::unique_ptr<...>/std::shared_ptr<...> spelling.
SharedInstance
A managed-instance alias that wraps a target type in a std::shared_ptr, giving multiple owners a reference-counted handle to the same instance.
Why this exists
Constructing and destroying pma types can require routing through custom allocators and factory/destroy functions rather than plain new/delete. SharedInstance packages that lifecycle management behind the familiar std::shared_ptr interface so callers get reference-counted shared ownership without hand-rolling a custom deleter each time. It pairs with UniqueInstance, which provides the same guarantee for single-owner (std::unique_ptr) lifetimes.
Relationships
UniqueInstance— sibling alias usingstd::unique_ptrwith a custom deleter for single ownership.ManagedInstance— the underlyingimpl::ManagedInstancetemplate that both aliases specialize.
Constraints
- The
MemoryResource*supplied towith()must outlive all copies of the returnedshared_ptr. The deleter embedded in the control block references that pointer at destruction time.
template<class TTarget, class TBase = TTarget> using UniqueInstance = impl::ManagedInstance<std::unique_ptr<TBase, std::function<void(TBase*)>>, TTarget, TBase>;
Convenience alias for building ManagedInstances that hand back a std::unique_ptr with a memory-resource-aware deleter.
Why this exists
Spelling out impl::ManagedInstance<std::unique_ptr<TBase, std::function<void(TBase*)>>, TTarget, TBase> at every call site is verbose and easy to get wrong; UniqueInstance<TTarget, TBase> gives the same behavior with just the two types that matter to the caller.
Construction
auto ptr = pma::UniqueInstance<Derived, Base>::with(memRes).create(args...);
Relationships
ManagedInstance— the underlying implementationUniqueInstancealiases.SharedInstance— sibling alias producing ashared_ptrinstead.
Constraints
- The
MemoryResource*supplied towith()must outlive the returnedunique_ptr. The deleter holds a copy of thePolyAllocatorwhich references that pointer.