[+] Heap::NewClassUnique

[+] Heap::NewClassArrayUnique
This commit is contained in:
Reece Wilson 2024-01-18 12:17:01 +00:00
parent dbdfceb97f
commit d1ab8377bc

View File

@ -90,6 +90,59 @@ namespace Aurora::Memory
_Free(reinterpret_cast<void *>(pHead));
}
protected:
template <typename T>
static void DeleteThat(T *pThat)
{
static const auto kAlignment = AuMax(alignof(T), sizeof(void *));
if constexpr (AuIsClass_v<T>
#if !defined(AURT_HEAP_NO_STL)
&& !std::is_trivially_destructible_v<T>
#endif
)
{
pThat->~T();
}
auto &pHeap = *(Heap **)(((char *)pThat) - kAlignment);
pHeap->_Free(&pHeap);
}
template <typename T>
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 uCount = (AuUInt)pVoids[1];
if constexpr (AuIsClass_v<T>
#if !defined(AURT_HEAP_NO_STL)
&& !std::is_trivially_destructible_v<T>
#endif
)
{
for (AU_ITERATE_N(i, uCount))
{
auto &refElement = pThat[i];
refElement.~T();
}
}
pHeap->_Free(pVoids);
}
template <typename T>
static void RetardedSpecWrittenByRetards(T *pThat)
{
}
public:
template <class T, class ...Args>
AuSPtr<T> NewClass(Args &&...args)
{
@ -128,6 +181,45 @@ namespace Aurora::Memory
return AuSPtr<T>((T *)(pPtr + kAlignment), &Heap::DeleteThat<T>);
}
template <class T, class ...Args>
AuUPtr<T, decltype(&Heap::DeleteThat<T>)> 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>
#if !defined(AURT_HEAP_NO_STL)
&& !std::is_trivially_constructible_v<T>
#endif
)
{
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<T, decltype(&Heap::DeleteThat<T>)>(nullptr, &Heap::RetardedSpecWrittenByRetards<T>);
}
*(void **)pPtr = pThat;
return AuUPtr<T, decltype(&Heap::DeleteThat<T>)>((T *)(pPtr + kAlignment), &Heap::DeleteThat<T>);
}
template <class T, class ...Args>
AuSPtr<T> NewClassArray(AuUInt uElements, Args &&... fillCtr)
{
@ -187,6 +279,65 @@ namespace Aurora::Memory
return AuSPtr<T>((T *)(pPtr + kAlignment), &Heap::DeleteThatArray<T>);
}
template <class T, class ...Args>
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)
{
return AuUPtr<T, decltype(&Heap::DeleteThat<T>)>(nullptr, &Heap::RetardedSpecWrittenByRetards<T>);
}
auto pThat = this->GetSelfReferenceRaw();
if (!pThat)
{
pThat = this;
}
if constexpr (AuIsClass_v<T>
#if !defined(AURT_HEAP_NO_STL)
&& !std::is_trivially_constructible_v<T>
#endif
)
{
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<typename T>
static AuSPtr<T> ToSmartPointer(AuSPtr<Heap> heap,
T *pHead,
@ -213,49 +364,6 @@ namespace Aurora::Memory
}
protected:
template <typename T>
static void DeleteThat(T *pThat)
{
static const auto kAlignment = AuMax(alignof(T), sizeof(void *));
if constexpr (AuIsClass_v<T>
#if !defined(AURT_HEAP_NO_STL)
&& !std::is_trivially_destructible_v<T>
#endif
)
{
pThat->~T();
}
auto &pHeap = *(Heap **)(((char *)pThat) - kAlignment);
pHeap->_Free(&pHeap);
}
template <typename T>
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 uCount = (AuUInt)pVoids[1];
if constexpr (AuIsClass_v<T>
#if !defined(AURT_HEAP_NO_STL)
&& !std::is_trivially_destructible_v<T>
#endif
)
{
for (AU_ITERATE_N(i, uCount))
{
auto &refElement = pThat[i];
refElement.~T();
}
}
pHeap->_Free(pVoids);
}
friend struct ProxyHeap;
virtual AuSPtr<Heap> GetSelfReference() = 0; // may return empty/default. not all heaps are sharable.