Compare commits
2 Commits
f2acc253b7
...
8df3f6970b
Author | SHA1 | Date | |
---|---|---|---|
8df3f6970b | |||
ced9e0be17 |
@ -16,6 +16,16 @@ namespace Aurora::Memory
|
|||||||
template <class T>
|
template <class T>
|
||||||
struct CppHeapWrapper;
|
struct CppHeapWrapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Note: The following public aliases for heap or global process heap based allocations exist:
|
||||||
|
*
|
||||||
|
* AuHUPOf_t<T> AuNewClassArrayUnique([pHeap, ]uElements, ...)
|
||||||
|
* AuSPtr<T> AuNewClassArray([pHeap, ]uElements, ...)
|
||||||
|
* AuHUPOf_t<T> AuNewClassUnique([pHeap, ] ...)
|
||||||
|
* AuSPtr<T> AuNewClass([pHeap, ] ...)
|
||||||
|
* AuHUPOf_t<T> AuNullHeapPointer<T>()
|
||||||
|
*/
|
||||||
|
|
||||||
struct Heap
|
struct Heap
|
||||||
{
|
{
|
||||||
virtual AuSPtr<Heap> AllocateDivision(AuUInt32 heap, AuUInt32 alignment = 32) = 0;
|
virtual AuSPtr<Heap> AllocateDivision(AuUInt32 heap, AuUInt32 alignment = 32) = 0;
|
||||||
@ -23,415 +33,103 @@ namespace Aurora::Memory
|
|||||||
virtual HeapStats &GetStats() = 0;
|
virtual HeapStats &GetStats() = 0;
|
||||||
virtual void WalkHeap(bool(*fCallback)(void *, void *), void *pSecondArg) = 0;
|
virtual void WalkHeap(bool(*fCallback)(void *, void *), void *pSecondArg) = 0;
|
||||||
|
|
||||||
// Potentially slower, zero allocate
|
/// Potentially slower, zero allocate
|
||||||
template<typename T = void *>
|
template<typename T = void *>
|
||||||
T ZAlloc(Types::size_t uLength)
|
T ZAlloc(Types::size_t uLength);
|
||||||
{
|
|
||||||
if constexpr (AuIsVoid_v<AuRemovePointer_t<T>>)
|
|
||||||
{
|
|
||||||
return reinterpret_cast<T>(_ZAlloc(uLength));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return reinterpret_cast<T>(_ZAlloc(uLength, alignof(AuRemovePointer_t<T>)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/// POD zero allocation
|
||||||
template<typename T = void *>
|
template<typename T = void *>
|
||||||
T ZAlloc(Types::size_t uLength, Types::size_t uAlignment)
|
T ZAlloc(Types::size_t uLength, Types::size_t uAlignment);
|
||||||
{
|
|
||||||
return reinterpret_cast<T>(_ZAlloc(uLength, uAlignment));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/// POD zero allocation
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T *ZAlloc()
|
T *ZAlloc();
|
||||||
{
|
|
||||||
return reinterpret_cast<T *>(_ZAlloc(sizeof(T), alignof(T)));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/// POD array, zero allocation
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T *NewArray(Types::size_t uLength)
|
T *NewArray(Types::size_t uLength);
|
||||||
{
|
|
||||||
return ZAlloc<T *>(uLength * sizeof(T), alignof(T));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/// POD array, zero allocation
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T *NewArray(Types::size_t uLength, Types::size_t uAlignment)
|
T *NewArray(Types::size_t uLength, Types::size_t uAlignment);
|
||||||
{
|
|
||||||
return ZAlloc<T *>(uLength * sizeof(T), uAlignment);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Fast, unsafe alloc
|
/// Fast, POD, non-zeroing allocation
|
||||||
template<typename T = void *>
|
template<typename T = void *>
|
||||||
T FAlloc(Types::size_t uLength)
|
T FAlloc(Types::size_t uLength);
|
||||||
{
|
|
||||||
if constexpr (AuIsVoid_v<AuRemovePointer_t<T>>)
|
|
||||||
{
|
|
||||||
return reinterpret_cast<T>(_FAlloc(uLength));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return reinterpret_cast<T>(_FAlloc(uLength, alignof(AuRemovePointer_t<T>)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/// Fast, POD, non-zeroing allocation
|
||||||
template<typename T = void *>
|
template<typename T = void *>
|
||||||
T FAlloc(Types::size_t uLength, Types::size_t uAlignment)
|
T FAlloc(Types::size_t uLength, Types::size_t uAlignment);
|
||||||
{
|
|
||||||
return reinterpret_cast<T>(_FAlloc(uLength, uAlignment));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/// Fast, POD, non-zeroing allocation
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T *FAlloc()
|
T *FAlloc();
|
||||||
{
|
|
||||||
return reinterpret_cast<T *>(_FAlloc(sizeof(T), alignof(T)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reallocs
|
// Reallocs
|
||||||
template<typename T>
|
|
||||||
T ZRealloc(T pHead, Types::size_t uLength)
|
|
||||||
{
|
|
||||||
if constexpr (AuIsVoid_v<AuRemovePointer_t<T>>)
|
|
||||||
{
|
|
||||||
return reinterpret_cast<T>(_ZRealloc(reinterpret_cast<void *>(pHead), uLength));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return reinterpret_cast<T>(_ZRealloc(reinterpret_cast<void *>(pHead), uLength, alignof(AuRemovePointer_t<T>)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/// POD, zero-based expansion or reallocation
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T ZRealloc(T pHead, Types::size_t uLength, Types::size_t uAlignment)
|
T ZRealloc(T pHead, Types::size_t uLength);
|
||||||
{
|
|
||||||
return reinterpret_cast<T>(_ZRealloc(reinterpret_cast<void *>(pHead), uLength, uAlignment));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/// POD, zero-based expansion or reallocation
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T FRealloc(T pHead, Types::size_t uLength)
|
T ZRealloc(T pHead, Types::size_t uLength, Types::size_t uAlignment);
|
||||||
{
|
|
||||||
if constexpr (AuIsVoid_v<AuRemovePointer_t<T>>)
|
|
||||||
{
|
|
||||||
return reinterpret_cast<T>(_FRealloc(reinterpret_cast<void *>(pHead), uLength));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return reinterpret_cast<T>(_FRealloc(reinterpret_cast<void *>(pHead), uLength, alignof(AuRemovePointer_t<T>)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/// POD, expansion or reallocation
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T FRealloc(T pHead, Types::size_t uLength, Types::size_t uAlignment)
|
T FRealloc(T pHead, Types::size_t uLength);
|
||||||
{
|
|
||||||
return reinterpret_cast<T>(_FRealloc(reinterpret_cast<void *>(pHead), uLength, uAlignment));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Free
|
/// POD, expansion or reallocation
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void Free(T pHead)
|
T FRealloc(T pHead, Types::size_t uLength, Types::size_t uAlignment);
|
||||||
{
|
|
||||||
_Free(reinterpret_cast<void *>(pHead));
|
/// Free
|
||||||
}
|
template<typename T>
|
||||||
|
void Free(T pHead);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static void DeleteThat(T *pThat)
|
static void DeleteThat(T *pThat);
|
||||||
{
|
|
||||||
static const auto kAlignment = AuMax(alignof(T), sizeof(void *));
|
|
||||||
|
|
||||||
if constexpr (AuIsClass_v<T> &&
|
|
||||||
!AuIsTriviallyDestructible_v<T>)
|
|
||||||
{
|
|
||||||
pThat->~T();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto &pHeap = *(Heap **)(((char *)pThat) - kAlignment);
|
|
||||||
pHeap->_Free(&pHeap);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static void DeleteThatArray(T *pThat)
|
static void DeleteThatArray(T *pThat);
|
||||||
{
|
|
||||||
static const auto kAlignment = AuMax(alignof(T), sizeof(void *) * 2);
|
|
||||||
|
|
||||||
auto pVoids = (void **)(((char *)pThat) - kAlignment);
|
|
||||||
auto pHeap = (Heap *)pVoids[0];
|
|
||||||
auto uLength = (AuUInt)pVoids[1];
|
|
||||||
|
|
||||||
if constexpr (AuIsClass_v<T> &&
|
|
||||||
!AuIsTriviallyDestructible_v<T>)
|
|
||||||
{
|
|
||||||
for (AU_ITERATE_N(i, uLength))
|
|
||||||
{
|
|
||||||
auto &refElement = pThat[i];
|
|
||||||
refElement.~T();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pHeap->_Free(pVoids);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename Z>
|
template <typename T, typename Z>
|
||||||
static void DeleteThatCastedOnce(T *pThat)
|
static void DeleteThatCastedOnce(T *pThat);
|
||||||
{
|
|
||||||
static const auto kAlignment = AuMax(alignof(Z), sizeof(void *));
|
|
||||||
|
|
||||||
auto pBaseClass = AuStaticCast<Z>(pThat);
|
|
||||||
|
|
||||||
if constexpr (AuIsClass_v<Z> &&
|
|
||||||
!AuIsTriviallyDestructible_v<Z>)
|
|
||||||
{
|
|
||||||
pBaseClass->~Z();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto &pHeap = *(Heap **)(((char *)pBaseClass) - kAlignment);
|
|
||||||
pHeap->_Free(&pHeap);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static void RetardedSpecWrittenByRetards(T *pThat)
|
static void RetardedSpecWrittenByRetards(T *pThat);
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
template <class T, class ...Args>
|
template <class T, class ...Args>
|
||||||
AuSPtr<T> NewClass(Args &&...args)
|
AuSPtr<T> NewClass(Args &&...args);
|
||||||
{
|
|
||||||
static const auto kAlignment = AuMax(alignof(T), sizeof(void *));
|
|
||||||
AuUInt8 *pPtr;
|
|
||||||
|
|
||||||
auto pThat = this->GetSelfReferenceRaw();
|
|
||||||
if (!pThat)
|
|
||||||
{
|
|
||||||
pThat = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
if constexpr (AuIsClass_v<T> &&
|
|
||||||
!AuIsTriviallyConstructible_v<T, Args...>)
|
|
||||||
{
|
|
||||||
pPtr = pThat->FAlloc<AuUInt8 *>(sizeof(T) + kAlignment, kAlignment);
|
|
||||||
if (pPtr)
|
|
||||||
{
|
|
||||||
new (pPtr + kAlignment) T(AuForward<Args>(args)...);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pPtr = pThat->ZAlloc<AuUInt8 *>(sizeof(T) + kAlignment, kAlignment);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pPtr)
|
|
||||||
{
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
*(void **)pPtr = pThat;
|
|
||||||
|
|
||||||
auto pTThat = (T *)(pPtr + kAlignment);
|
|
||||||
AUROXTL_COMMODITY_TRY
|
|
||||||
{
|
|
||||||
return AuSPtr<T>(pTThat, &Heap::DeleteThat<T>, CppHeapWrapper<T> { this });
|
|
||||||
}
|
|
||||||
AUROXTL_COMMODITY_CATCH
|
|
||||||
{
|
|
||||||
Heap::DeleteThat<T>(pTThat);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// note: callers can use AuHUPOf_t<Z> pUniquePointer = AuNullHeapPointer<Z>()
|
// note: callers can use AuHUPOf_t<Z> pUniquePointer = AuNullHeapPointer<Z>()
|
||||||
|
|
||||||
template <class T, class Z = T, class ...Args>
|
template <class T, class Z = T, class ...Args>
|
||||||
AuUPtr<Z, decltype(&Heap::DeleteThat<Z>)> NewClassUnique(Args &&...args)
|
AuUPtr<Z, decltype(&Heap::DeleteThat<Z>)> NewClassUnique(Args &&...args);
|
||||||
{
|
|
||||||
static const auto kAlignment = AuMax(alignof(T), sizeof(void *));
|
|
||||||
AuUInt8 *pPtr;
|
|
||||||
|
|
||||||
auto pThat = this->GetSelfReferenceRaw();
|
|
||||||
if (!pThat)
|
|
||||||
{
|
|
||||||
pThat = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
if constexpr (AuIsClass_v<T> &&
|
|
||||||
!AuIsTriviallyConstructible_v<T, Args...>)
|
|
||||||
{
|
|
||||||
pPtr = pThat->FAlloc<AuUInt8 *>(sizeof(T) + kAlignment, kAlignment);
|
|
||||||
if (pPtr)
|
|
||||||
{
|
|
||||||
new (pPtr + kAlignment) T(AuForward<Args>(args)...);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pPtr = pThat->ZAlloc<AuUInt8 *>(sizeof(T) + kAlignment, kAlignment);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pPtr)
|
|
||||||
{
|
|
||||||
return AuUPtr<Z, decltype(&Heap::DeleteThat<Z>)>(nullptr, &Heap::RetardedSpecWrittenByRetards<Z>);
|
|
||||||
}
|
|
||||||
|
|
||||||
*(void **)pPtr = pThat;
|
|
||||||
|
|
||||||
if constexpr (AuIsSame_v<T, Z>)
|
|
||||||
{
|
|
||||||
return AuUPtr<T, decltype(&Heap::DeleteThat<T>)>((T *)(pPtr + kAlignment), &Heap::DeleteThat<T>);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Heap::CastPointer<Z>(AuMove(AuUPtr<T, decltype(&Heap::DeleteThat<T>)>((T *)(pPtr + kAlignment), &Heap::DeleteThat<T>)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class ...Args>
|
template <class T, class ...Args>
|
||||||
AuSPtr<T> NewClassArray(AuUInt uElements, Args &&... fillCtr)
|
AuSPtr<T> NewClassArray(AuUInt uElements, Args &&... fillCtr);
|
||||||
{
|
|
||||||
static const auto kAlignment = AuMax(alignof(T), sizeof(void *) * 2);
|
|
||||||
AuUInt8 *pPtr;
|
|
||||||
|
|
||||||
if (!uElements)
|
template <class T, class ...Args>
|
||||||
{
|
AuSPtr<T> NewClassArray2(AuUInt uElements, AuUInt uAlignment, Args &&... fillCtr);
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
auto pThat = this->GetSelfReferenceRaw();
|
|
||||||
if (!pThat)
|
|
||||||
{
|
|
||||||
pThat = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
if constexpr (AuIsClass_v<T> &&
|
|
||||||
!AuIsTriviallyConstructible_v<T, Args...>)
|
|
||||||
{
|
|
||||||
if (bool(pPtr = pThat->FAlloc<AuUInt8 *>((sizeof(T) * uElements) + kAlignment, kAlignment)))
|
|
||||||
{
|
|
||||||
for (AU_ITERATE_N(i, uElements))
|
|
||||||
{
|
|
||||||
new (pPtr + kAlignment + (sizeof(T) * i)) T(AuForward<Args>(fillCtr)...);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (bool(pPtr = pThat->ZAlloc<AuUInt8 *>((sizeof(T) * uElements) + kAlignment, kAlignment)))
|
|
||||||
{
|
|
||||||
if constexpr (sizeof...(Args) != 0)
|
|
||||||
{
|
|
||||||
#if defined(AURT_HEAP_NO_STL)
|
|
||||||
static_assert(false);
|
|
||||||
#else
|
|
||||||
auto pElements = (T *)(pPtr + kAlignment);
|
|
||||||
std::fill(pElements, pElements + uElements, AuForward<Args>(fillCtr)...);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pPtr)
|
|
||||||
{
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
auto pVoids = (void **)pPtr;
|
|
||||||
pVoids[0] = pThat;
|
|
||||||
pVoids[1] = (void *)uElements;
|
|
||||||
|
|
||||||
auto pTThat = (T *)(pPtr + kAlignment);
|
|
||||||
AUROXTL_COMMODITY_TRY
|
|
||||||
{
|
|
||||||
return AuSPtr<T>(pTThat, &Heap::DeleteThatArray<T>, CppHeapWrapper<T> { this });
|
|
||||||
}
|
|
||||||
AUROXTL_COMMODITY_CATCH
|
|
||||||
{
|
|
||||||
Heap::DeleteThatArray<T>(pTThat);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// note: callers can use AuHUPOf_t<T> pUniquePointer = AuNullHeapPointer<T>()
|
// note: callers can use AuHUPOf_t<T> pUniquePointer = AuNullHeapPointer<T>()
|
||||||
|
|
||||||
template <class T, class ...Args>
|
template <class T, class ...Args>
|
||||||
AuUPtr<T, decltype(&Heap::DeleteThat<T>)> NewClassArrayUnique(AuUInt uElements, Args &&... fillCtr)
|
AuUPtr<T, decltype(&Heap::DeleteThat<T>)> NewClassArrayUnique(AuUInt uElements, Args &&... fillCtr);
|
||||||
{
|
|
||||||
static const auto kAlignment = AuMax(alignof(T), sizeof(void *) * 2);
|
|
||||||
AuUInt8 *pPtr;
|
|
||||||
|
|
||||||
if (!uElements)
|
template <class T, class ...Args>
|
||||||
{
|
AuUPtr<T, decltype(&Heap::DeleteThat<T>)> NewClassArray2Unique(AuUInt uElements, AuUInt uAlignment, Args &&... fillCtr);
|
||||||
return AuUPtr<T, decltype(&Heap::DeleteThat<T>)>(nullptr, &Heap::RetardedSpecWrittenByRetards<T>);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto pThat = this->GetSelfReferenceRaw();
|
|
||||||
if (!pThat)
|
|
||||||
{
|
|
||||||
pThat = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
if constexpr (AuIsClass_v<T> &&
|
|
||||||
!AuIsTriviallyConstructible_v<T, Args...>)
|
|
||||||
{
|
|
||||||
if (bool(pPtr = pThat->FAlloc<AuUInt8 *>((sizeof(T) * uElements) + kAlignment, kAlignment)))
|
|
||||||
{
|
|
||||||
for (AU_ITERATE_N(i, uElements))
|
|
||||||
{
|
|
||||||
new (pPtr + kAlignment + (sizeof(T) * i)) T(AuForward<Args>(fillCtr)...);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (bool(pPtr = pThat->ZAlloc<AuUInt8 *>((sizeof(T) * uElements) + kAlignment, kAlignment)))
|
|
||||||
{
|
|
||||||
if constexpr (sizeof...(Args) != 0)
|
|
||||||
{
|
|
||||||
#if defined(AURT_HEAP_NO_STL)
|
|
||||||
static_assert(false);
|
|
||||||
#else
|
|
||||||
auto pElements = (T *)(pPtr + kAlignment);
|
|
||||||
std::fill(pElements, pElements + uElements, AuForward<Args>(fillCtr)...);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pPtr)
|
|
||||||
{
|
|
||||||
return AuUPtr<T, decltype(&Heap::DeleteThat<T>)>(nullptr, &Heap::RetardedSpecWrittenByRetards<T>);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto pVoids = (void **)pPtr;
|
|
||||||
pVoids[0] = pThat;
|
|
||||||
pVoids[1] = (void *)uElements;
|
|
||||||
|
|
||||||
return AuUPtr<T, decltype(&Heap::DeleteThat<T>)>((T *)(pPtr + kAlignment), &Heap::DeleteThatArray<T>);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
cstatic AuUPtr<T, decltype(&Heap::DeleteThat<T>)> NullUniquePointer()
|
cstatic AuUPtr<T, decltype(&Heap::DeleteThat<T>)> NullUniquePointer();
|
||||||
{
|
|
||||||
return AuUPtr<T, decltype(&Heap::DeleteThat<T>)>(nullptr, &Heap::RetardedSpecWrittenByRetards<T>);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Z, class T>
|
template <class Z, class T>
|
||||||
cstatic AuUPtr<Z, decltype(&Heap::DeleteThat<Z>)> CastPointer(AuUPtr<T, decltype(&Heap::DeleteThat<T>)> &&pInPointer)
|
cstatic AuUPtr<Z, decltype(&Heap::DeleteThat<Z>)> CastPointer(AuUPtr<T, decltype(&Heap::DeleteThat<T>)> &&pInPointer);
|
||||||
{
|
|
||||||
if (!pInPointer)
|
|
||||||
{
|
|
||||||
return NullUniquePointer<Z>();
|
|
||||||
}
|
|
||||||
else if (pInPointer.get_deleter() == &Heap::DeleteThat<T>)
|
|
||||||
{
|
|
||||||
return AuUPtr<Z, decltype(&Heap::DeleteThat<Z>)>(AuStaticCast<Z>(pInPointer.release()), &Heap::DeleteThatCastedOnce<Z, T>);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return NullUniquePointer<Z>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using HUPOf_t = AuUPtr<T, decltype(&Heap::DeleteThat<T>)>;
|
using HUPOf_t = AuUPtr<T, decltype(&Heap::DeleteThat<T>)>;
|
||||||
|
432
Include/Aurora/Memory/Heap.inl
Normal file
432
Include/Aurora/Memory/Heap.inl
Normal file
@ -0,0 +1,432 @@
|
|||||||
|
/***
|
||||||
|
Copyright (C) 2021-2024 Jamie Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||||
|
|
||||||
|
File: Heap.inl
|
||||||
|
Date: 2024-7-14
|
||||||
|
Date: 2021-6-9
|
||||||
|
Author: Reece
|
||||||
|
***/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Aurora::Memory
|
||||||
|
{
|
||||||
|
template<typename T>
|
||||||
|
T Heap::ZAlloc(Types::size_t uLength)
|
||||||
|
{
|
||||||
|
if constexpr (AuIsVoid_v<AuRemovePointer_t<T>>)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<T>(_ZAlloc(uLength));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return reinterpret_cast<T>(_ZAlloc(uLength, alignof(AuRemovePointer_t<T>)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T Heap::ZAlloc(Types::size_t uLength, Types::size_t uAlignment)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<T>(_ZAlloc(uLength, uAlignment));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T *Heap::ZAlloc()
|
||||||
|
{
|
||||||
|
return reinterpret_cast<T *>(_ZAlloc(sizeof(T), alignof(T)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T *Heap::NewArray(Types::size_t uLength)
|
||||||
|
{
|
||||||
|
return ZAlloc<T *>(uLength * sizeof(T), alignof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T *Heap::NewArray(Types::size_t uLength, Types::size_t uAlignment)
|
||||||
|
{
|
||||||
|
return ZAlloc<T *>(uLength * sizeof(T), uAlignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T Heap::FAlloc(Types::size_t uLength)
|
||||||
|
{
|
||||||
|
if constexpr (AuIsVoid_v<AuRemovePointer_t<T>>)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<T>(_FAlloc(uLength));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return reinterpret_cast<T>(_FAlloc(uLength, alignof(AuRemovePointer_t<T>)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T Heap::FAlloc(Types::size_t uLength, Types::size_t uAlignment)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<T>(_FAlloc(uLength, uAlignment));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T *Heap::FAlloc()
|
||||||
|
{
|
||||||
|
return reinterpret_cast<T *>(_FAlloc(sizeof(T), alignof(T)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reallocs
|
||||||
|
template<typename T>
|
||||||
|
T Heap::ZRealloc(T pHead, Types::size_t uLength)
|
||||||
|
{
|
||||||
|
if constexpr (AuIsVoid_v<AuRemovePointer_t<T>>)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<T>(_ZRealloc(reinterpret_cast<void *>(pHead), uLength));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return reinterpret_cast<T>(_ZRealloc(reinterpret_cast<void *>(pHead), uLength, alignof(AuRemovePointer_t<T>)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T Heap::ZRealloc(T pHead, Types::size_t uLength, Types::size_t uAlignment)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<T>(_ZRealloc(reinterpret_cast<void *>(pHead), uLength, uAlignment));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T Heap::FRealloc(T pHead, Types::size_t uLength)
|
||||||
|
{
|
||||||
|
if constexpr (AuIsVoid_v<AuRemovePointer_t<T>>)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<T>(_FRealloc(reinterpret_cast<void *>(pHead), uLength));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return reinterpret_cast<T>(_FRealloc(reinterpret_cast<void *>(pHead), uLength, alignof(AuRemovePointer_t<T>)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T Heap::FRealloc(T pHead, Types::size_t uLength, Types::size_t uAlignment)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<T>(_FRealloc(reinterpret_cast<void *>(pHead), uLength, uAlignment));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free
|
||||||
|
template<typename T>
|
||||||
|
void Heap::Free(T pHead)
|
||||||
|
{
|
||||||
|
_Free(reinterpret_cast<void *>(pHead));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void Heap::DeleteThat(T *pThat)
|
||||||
|
{
|
||||||
|
static const auto kAlignment = AuMax(alignof(T), sizeof(void *));
|
||||||
|
|
||||||
|
if constexpr (AuIsClass_v<T> &&
|
||||||
|
!AuIsTriviallyDestructible_v<T>)
|
||||||
|
{
|
||||||
|
pThat->~T();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto &pHeap = *(Heap **)(((char *)pThat) - kAlignment);
|
||||||
|
pHeap->_Free(&pHeap);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void Heap::DeleteThatArray(T *pThat)
|
||||||
|
{
|
||||||
|
static const auto kAlignment = AuMax(alignof(T), sizeof(void *) * 2);
|
||||||
|
|
||||||
|
auto pVoids = (void **)(((char *)pThat) - kAlignment);
|
||||||
|
auto pHeap = (Heap *)pVoids[0];
|
||||||
|
auto uLength = (AuUInt)pVoids[1];
|
||||||
|
|
||||||
|
if constexpr (AuIsClass_v<T> &&
|
||||||
|
!AuIsTriviallyDestructible_v<T>)
|
||||||
|
{
|
||||||
|
for (AU_ITERATE_N(i, uLength))
|
||||||
|
{
|
||||||
|
auto &refElement = pThat[i];
|
||||||
|
refElement.~T();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pHeap->_Free(pVoids);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename Z>
|
||||||
|
void Heap::DeleteThatCastedOnce(T *pThat)
|
||||||
|
{
|
||||||
|
static const auto kAlignment = AuMax(alignof(Z), sizeof(void *));
|
||||||
|
|
||||||
|
auto pBaseClass = AuStaticCast<Z>(pThat);
|
||||||
|
|
||||||
|
if constexpr (AuIsClass_v<Z> &&
|
||||||
|
!AuIsTriviallyDestructible_v<Z>)
|
||||||
|
{
|
||||||
|
pBaseClass->~Z();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto &pHeap = *(Heap **)(((char *)pBaseClass) - kAlignment);
|
||||||
|
pHeap->_Free(&pHeap);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static void Heap::RetardedSpecWrittenByRetards(T *pThat)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class ...Args>
|
||||||
|
AuSPtr<T> Heap::NewClass(Args &&...args)
|
||||||
|
{
|
||||||
|
static const auto kAlignment = AuMax(alignof(T), sizeof(void *));
|
||||||
|
AuUInt8 *pPtr;
|
||||||
|
|
||||||
|
auto pThat = this->GetSelfReferenceRaw();
|
||||||
|
if (!pThat)
|
||||||
|
{
|
||||||
|
pThat = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
if constexpr (AuIsClass_v<T> &&
|
||||||
|
!AuIsTriviallyConstructible_v<T, Args...>)
|
||||||
|
{
|
||||||
|
pPtr = pThat->FAlloc<AuUInt8 *>(sizeof(T) + kAlignment, kAlignment);
|
||||||
|
if (pPtr)
|
||||||
|
{
|
||||||
|
new (pPtr + kAlignment) T(AuForward<Args>(args)...);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pPtr = pThat->ZAlloc<AuUInt8 *>(sizeof(T) + kAlignment, kAlignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pPtr)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
*(void **)pPtr = pThat;
|
||||||
|
|
||||||
|
auto pTThat = (T *)(pPtr + kAlignment);
|
||||||
|
AUROXTL_COMMODITY_TRY
|
||||||
|
{
|
||||||
|
return AuSPtr<T>(pTThat, &Heap::DeleteThat<T>, CppHeapWrapper<T> { this });
|
||||||
|
}
|
||||||
|
AUROXTL_COMMODITY_CATCH
|
||||||
|
{
|
||||||
|
Heap::DeleteThat<T>(pTThat);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class Z, class ...Args>
|
||||||
|
AuUPtr<Z, decltype(&Heap::DeleteThat<Z>)> Heap::NewClassUnique(Args &&...args)
|
||||||
|
{
|
||||||
|
static const auto kAlignment = AuMax(alignof(T), sizeof(void *));
|
||||||
|
AuUInt8 *pPtr;
|
||||||
|
|
||||||
|
auto pThat = this->GetSelfReferenceRaw();
|
||||||
|
if (!pThat)
|
||||||
|
{
|
||||||
|
pThat = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
if constexpr (AuIsClass_v<T> &&
|
||||||
|
!AuIsTriviallyConstructible_v<T, Args...>)
|
||||||
|
{
|
||||||
|
pPtr = pThat->FAlloc<AuUInt8 *>(sizeof(T) + kAlignment, kAlignment);
|
||||||
|
if (pPtr)
|
||||||
|
{
|
||||||
|
new (pPtr + kAlignment) T(AuForward<Args>(args)...);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pPtr = pThat->ZAlloc<AuUInt8 *>(sizeof(T) + kAlignment, kAlignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pPtr)
|
||||||
|
{
|
||||||
|
return AuUPtr<Z, decltype(&Heap::DeleteThat<Z>)>(nullptr, &Heap::RetardedSpecWrittenByRetards<Z>);
|
||||||
|
}
|
||||||
|
|
||||||
|
*(void **)pPtr = pThat;
|
||||||
|
|
||||||
|
if constexpr (AuIsSame_v<T, Z>)
|
||||||
|
{
|
||||||
|
return AuUPtr<T, decltype(&Heap::DeleteThat<T>)>((T *)(pPtr + kAlignment), &Heap::DeleteThat<T>);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Heap::CastPointer<Z>(AuMove(AuUPtr<T, decltype(&Heap::DeleteThat<T>)>((T *)(pPtr + kAlignment), &Heap::DeleteThat<T>)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class ...Args>
|
||||||
|
AuSPtr<T> Heap::NewClassArray(AuUInt uElements, Args &&... fillCtr)
|
||||||
|
{
|
||||||
|
return NewClassArray2<T, Args...>(uElements, alignof(T), AuForward<Args>(fillCtr)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class ...Args>
|
||||||
|
AuSPtr<T> Heap::NewClassArray2(AuUInt uElements, AuUInt uAlignment, Args &&... fillCtr)
|
||||||
|
{
|
||||||
|
const auto kAlignment = AuMax(uAlignment, sizeof(void *) * 2);
|
||||||
|
AuUInt8 *pPtr;
|
||||||
|
|
||||||
|
if (!uElements)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pThat = this->GetSelfReferenceRaw();
|
||||||
|
if (!pThat)
|
||||||
|
{
|
||||||
|
pThat = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
if constexpr (AuIsClass_v<T> &&
|
||||||
|
!AuIsTriviallyConstructible_v<T, Args...>)
|
||||||
|
{
|
||||||
|
if (bool(pPtr = pThat->FAlloc<AuUInt8 *>((sizeof(T) * uElements) + kAlignment, kAlignment)))
|
||||||
|
{
|
||||||
|
for (AU_ITERATE_N(i, uElements))
|
||||||
|
{
|
||||||
|
new (pPtr + kAlignment + (sizeof(T) * i)) T(AuForward<Args>(fillCtr)...);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (bool(pPtr = pThat->ZAlloc<AuUInt8 *>((sizeof(T) * uElements) + kAlignment, kAlignment)))
|
||||||
|
{
|
||||||
|
if constexpr (sizeof...(Args) != 0)
|
||||||
|
{
|
||||||
|
#if defined(AURT_HEAP_NO_STL)
|
||||||
|
static_assert(false);
|
||||||
|
#else
|
||||||
|
auto pElements = (T *)(pPtr + kAlignment);
|
||||||
|
std::fill(pElements, pElements + uElements, AuForward<Args>(fillCtr)...);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pPtr)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pVoids = (void **)pPtr;
|
||||||
|
pVoids[0] = pThat;
|
||||||
|
pVoids[1] = (void *)uElements;
|
||||||
|
|
||||||
|
auto pTThat = (T *)(pPtr + kAlignment);
|
||||||
|
AUROXTL_COMMODITY_TRY
|
||||||
|
{
|
||||||
|
return AuSPtr<T>(pTThat, &Heap::DeleteThatArray<T>, CppHeapWrapper<T> { this });
|
||||||
|
}
|
||||||
|
AUROXTL_COMMODITY_CATCH
|
||||||
|
{
|
||||||
|
Heap::DeleteThatArray<T>(pTThat);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class ...Args>
|
||||||
|
AuUPtr<T, decltype(&Heap::DeleteThat<T>)> Heap::NewClassArrayUnique(AuUInt uElements, Args &&... fillCtr)
|
||||||
|
{
|
||||||
|
return NewClassArray2Unique<T, Args...>(uElements, alignof(T), AuForward<Args>(fillCtr)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class ...Args>
|
||||||
|
AuUPtr<T, decltype(&Heap::DeleteThat<T>)> Heap::NewClassArray2Unique(AuUInt uElements, AuUInt uAlignment, Args &&... fillCtr)
|
||||||
|
{
|
||||||
|
const auto kAlignment = AuMax(uAlignment, sizeof(void *) * 2);
|
||||||
|
AuUInt8 *pPtr;
|
||||||
|
|
||||||
|
if (!uElements)
|
||||||
|
{
|
||||||
|
return AuUPtr<T, decltype(&Heap::DeleteThat<T>)>(nullptr, &Heap::RetardedSpecWrittenByRetards<T>);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pThat = this->GetSelfReferenceRaw();
|
||||||
|
if (!pThat)
|
||||||
|
{
|
||||||
|
pThat = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
if constexpr (AuIsClass_v<T> &&
|
||||||
|
!AuIsTriviallyConstructible_v<T, Args...>)
|
||||||
|
{
|
||||||
|
if (bool(pPtr = pThat->FAlloc<AuUInt8 *>((sizeof(T) * uElements) + kAlignment, kAlignment)))
|
||||||
|
{
|
||||||
|
for (AU_ITERATE_N(i, uElements))
|
||||||
|
{
|
||||||
|
new (pPtr + kAlignment + (sizeof(T) * i)) T(AuForward<Args>(fillCtr)...);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (bool(pPtr = pThat->ZAlloc<AuUInt8 *>((sizeof(T) * uElements) + kAlignment, kAlignment)))
|
||||||
|
{
|
||||||
|
if constexpr (sizeof...(Args) != 0)
|
||||||
|
{
|
||||||
|
#if defined(AURT_HEAP_NO_STL)
|
||||||
|
static_assert(false);
|
||||||
|
#else
|
||||||
|
auto pElements = (T *)(pPtr + kAlignment);
|
||||||
|
std::fill(pElements, pElements + uElements, AuForward<Args>(fillCtr)...);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pPtr)
|
||||||
|
{
|
||||||
|
return AuUPtr<T, decltype(&Heap::DeleteThat<T>)>(nullptr, &Heap::RetardedSpecWrittenByRetards<T>);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pVoids = (void **)pPtr;
|
||||||
|
pVoids[0] = pThat;
|
||||||
|
pVoids[1] = (void *)uElements;
|
||||||
|
|
||||||
|
return AuUPtr<T, decltype(&Heap::DeleteThat<T>)>((T *)(pPtr + kAlignment), &Heap::DeleteThatArray<T>);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
AuUPtr<T, decltype(&Heap::DeleteThat<T>)> Heap::NullUniquePointer()
|
||||||
|
{
|
||||||
|
return AuUPtr<T, decltype(&Heap::DeleteThat<T>)>(nullptr, &Heap::RetardedSpecWrittenByRetards<T>);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Z, class T>
|
||||||
|
AuUPtr<Z, decltype(&Heap::DeleteThat<Z>)> Heap::CastPointer(AuUPtr<T, decltype(&Heap::DeleteThat<T>)> &&pInPointer)
|
||||||
|
{
|
||||||
|
if (!pInPointer)
|
||||||
|
{
|
||||||
|
return NullUniquePointer<Z>();
|
||||||
|
}
|
||||||
|
else if (pInPointer.get_deleter() == &Heap::DeleteThat<T>)
|
||||||
|
{
|
||||||
|
return AuUPtr<Z, decltype(&Heap::DeleteThat<Z>)>(AuStaticCast<Z>(pInPointer.release()), &Heap::DeleteThatCastedOnce<Z, T>);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NullUniquePointer<Z>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
inline AuSPtr<AuUInt8> AllocateArray(Heap *pHeap, AuUInt uLength, AuUInt32 uAlignment)
|
||||||
|
{
|
||||||
|
return pHeap->NewClassArray2<AuUInt8>(uLength, uAlignment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -197,3 +197,4 @@ namespace Aurora::Memory
|
|||||||
#include "ByteBuffer.hpp"
|
#include "ByteBuffer.hpp"
|
||||||
#include "ByteBufferPushReadState.hpp"
|
#include "ByteBufferPushReadState.hpp"
|
||||||
#include "ByteBufferPushWriteState.hpp"
|
#include "ByteBufferPushWriteState.hpp"
|
||||||
|
#include "Heap.inl"
|
@ -9,6 +9,13 @@
|
|||||||
|
|
||||||
namespace Aurora::Memory
|
namespace Aurora::Memory
|
||||||
{
|
{
|
||||||
|
struct Heap;
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
inline AuSPtr<AuUInt8> AllocateArray(Heap *pHeap, AuUInt uLength, AuUInt32 uAlignment);
|
||||||
|
}
|
||||||
|
|
||||||
struct MemoryControlBlock
|
struct MemoryControlBlock
|
||||||
{
|
{
|
||||||
// Free-after-use mitigator: ensures a non-zero flag is kept whilst other memory views are present
|
// Free-after-use mitigator: ensures a non-zero flag is kept whilst other memory views are present
|
||||||
@ -392,6 +399,19 @@ namespace Aurora::Memory
|
|||||||
return MemoryView(MemoryView(pData.get(), uLength), pData);
|
return MemoryView(MemoryView(pData.get(), uLength), pData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MemoryView Clone(Heap *pHeap, AuUInt32 uAlignment = alignof(double)) const
|
||||||
|
{
|
||||||
|
auto uLength = this->uLength;
|
||||||
|
auto pData = detail::AllocateArray(uLength, uAlignment);
|
||||||
|
if (!pData)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
AuMemcpy(pData.get(), this->pBase, uLength);
|
||||||
|
return MemoryView(MemoryView(pData.get(), uLength), pData);
|
||||||
|
}
|
||||||
|
|
||||||
bool TryCloneSelf(bool bResetOnFailure = true)
|
bool TryCloneSelf(bool bResetOnFailure = true)
|
||||||
{
|
{
|
||||||
auto replacement = Clone();
|
auto replacement = Clone();
|
||||||
|
@ -142,28 +142,37 @@ auto AuNullPointer()
|
|||||||
return Aurora::Memory::Heap::NullUniquePointer<T>();
|
return Aurora::Memory::Heap::NullUniquePointer<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace __audetail
|
||||||
|
{
|
||||||
|
inline AuMemory::Heap *gDefaultDiscontiguousHeap = AuMemory::GetDefaultDiscontiguousHeap();
|
||||||
|
}
|
||||||
|
|
||||||
template <class T, class ...Args>
|
template <class T, class ...Args>
|
||||||
AuHUPOf_t<T> AuNewClassArrayUnique(AuUInt uElements, Args &&... fillCtr)
|
AuHUPOf_t<T> AuNewClassArrayUnique(AuUInt uElements, Args &&... fillCtr)
|
||||||
{
|
{
|
||||||
return Aurora::Memory::GetDefaultDiscontiguousHeap()->NewClassArrayUnique<T, Args...>(uElements, AuForward<Args>(fillCtr)...);
|
return __audetail::gDefaultDiscontiguousHeap->NewClassArrayUnique<T, Args...>(uElements, AuForward<Args>(fillCtr)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class ...Args>
|
template <class T, class ...Args>
|
||||||
AuSPtr<T> AuNewClassArray(AuUInt uElements, Args &&... fillCtr)
|
AuSPtr<T> AuNewClassArray(AuUInt uElements, Args &&... fillCtr)
|
||||||
{
|
{
|
||||||
return Aurora::Memory::GetDefaultDiscontiguousHeap()->NewClassArray<T, Args...>(uElements, AuForward<Args>(fillCtr)...);
|
return __audetail::gDefaultDiscontiguousHeap->NewClassArray<T, Args...>(uElements, AuForward<Args>(fillCtr)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class Z = T, class ...Args>
|
template <class T, class Z = T, class ...Args>
|
||||||
AuHUPOf_t<Z> AuNewClassUnique(Args &&...args)
|
AuHUPOf_t<Z> AuNewClassUnique(Args &&...args)
|
||||||
{
|
{
|
||||||
return Aurora::Memory::GetDefaultDiscontiguousHeap()->NewClassUnique<T, Z, Args...>(AuForward<Args>(args)...);
|
return __audetail::gDefaultDiscontiguousHeap->NewClassUnique<T, Z, Args...>(AuForward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class ...Args>
|
template <class T, class ...Args>
|
||||||
AuSPtr<T> AuNewClass(Args &&...args)
|
AuSPtr<T> AuNewClass(Args &&...args)
|
||||||
{
|
{
|
||||||
|
#if !defined(AURORA_RUNTIME_HEADERS_ALWAYS_LOOKUP_HEAP)
|
||||||
|
return AuMakeShared<T, Args...>(AuForward<Args>(args)...);
|
||||||
|
#else
|
||||||
return Aurora::Memory::GetDefaultDiscontiguousHeap()->NewClass<T, Args...>(AuForward<Args>(args)...);
|
return Aurora::Memory::GetDefaultDiscontiguousHeap()->NewClass<T, Args...>(AuForward<Args>(args)...);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class ...Args>
|
template <class T, class ...Args>
|
||||||
|
Loading…
Reference in New Issue
Block a user