[*] Move assets from Runtime to ROXTL
[+] AuMemoryViewRead [+] AuMemoryViewWrite [+] AuMemoryViewStreamXXX [+] SOO UniqueOnHeap [+] SOO SharedOnHeap [+] AuHeap [+] AuHeapStats [+] New implementation of AuUPtr<T>
This commit is contained in:
parent
0b8fbafdca
commit
11bb77f129
@ -62,18 +62,18 @@
|
||||
\
|
||||
struct CppDeleter ## name \
|
||||
{ \
|
||||
inline void operator()(type *t) \
|
||||
inline void operator()(type *t) const \
|
||||
{ \
|
||||
if (!t) return; \
|
||||
name ## Release(t); \
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
using name ## Unique_t = AURORA_RUNTIME_AU_UNIQUE_PTR<type, CppDeleter ## name>; \
|
||||
using name ## Unique_t = AuUPtr<type>; \
|
||||
template <class ... T> \
|
||||
name ## Unique_t name ## Unique(T &&... args) \
|
||||
{ \
|
||||
return name ## Unique_t(name ## New(AuForward<T &&>(args)...)); \
|
||||
return name ## Unique_t(name ## New(AuForward<T &&>(args)...), name ## Release); \
|
||||
} \
|
||||
\
|
||||
using name ## Shared_t = AuSPtr<type>; \
|
||||
|
@ -90,5 +90,15 @@
|
||||
#define _AURORA_AVOID_EXTREMLY_DUMB_STL_TYPES
|
||||
// TODO:
|
||||
#if !defined(_AURORA_NULLEXPT_BRANCH)
|
||||
#define _AURORA_NULLEXPT_BRANCH
|
||||
//#define _AURORA_NULLEXPT_BRANCH
|
||||
#endif
|
||||
|
||||
#if !defined(AURORA_ROXTL_HAS_RUNTIME)
|
||||
// AURORA_ENGINE_KERNEL - static or local translation unit
|
||||
// _AUHAS_AURORARUNTIME - standard pipeline macro for including a product by the name AuroraRuntime
|
||||
#if defined(AURORA_ENGINE_KERNEL) || (defined(_AUHAS_AURORARUNTIME) && _AUHAS_AURORARUNTIME == 1)
|
||||
#define AURORA_ROXTL_HAS_RUNTIME 1
|
||||
#else
|
||||
#define AURORA_ROXTL_HAS_RUNTIME 0
|
||||
#endif
|
||||
#endif
|
1
Include/auROXTL/MemoryModel/auDummyHeap.hpp
Executable file
1
Include/auROXTL/MemoryModel/auDummyHeap.hpp
Executable file
@ -0,0 +1 @@
|
||||
// TODO:
|
1
Include/auROXTL/MemoryModel/auDummyHeap.ipp
Executable file
1
Include/auROXTL/MemoryModel/auDummyHeap.ipp
Executable file
@ -0,0 +1 @@
|
||||
// TODO:
|
158
Include/auROXTL/MemoryModel/auHeap.hpp
Executable file
158
Include/auROXTL/MemoryModel/auHeap.hpp
Executable file
@ -0,0 +1,158 @@
|
||||
/***
|
||||
Copyright (C) 2021-2024 Jamie Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: auHeap.hpp
|
||||
File: Heap.hpp
|
||||
Date: 2021-6-9
|
||||
Author: Reece
|
||||
Note: Moved from Runtime to ROXTL
|
||||
Note: The intention is that the runtime will still implement all the relevant heaps.
|
||||
However, we should provide one AuDummyHeap that proxies the intrin memory allocations (AuMemory::__FAlloc, AuMemory::__Free, AuMemory::__SizeOf).
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* Note: The following public global aliases exists for heap and/or global process heap based allocations:
|
||||
*
|
||||
* 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 AuHeap
|
||||
{
|
||||
virtual AuSPtr<AuHeap> AllocateDivision(AuUInt32 heap, AuUInt32 alignment = 32) = 0;
|
||||
virtual AuUInt GetChunkSize(const void *pHead) = 0;
|
||||
virtual AuHeapStats & GetStats() = 0;
|
||||
|
||||
virtual void WalkHeap(bool(*fCallback)(void *, void *), void *pSecondArg) = 0;
|
||||
|
||||
/// Potentially slower, zero allocate
|
||||
template<typename T = void *>
|
||||
T ZAlloc(AuUInt uLength);
|
||||
|
||||
/// POD zero allocation
|
||||
template<typename T = void *>
|
||||
T ZAlloc(AuUInt uLength, AuUInt uAlignment);
|
||||
|
||||
/// POD zero allocation
|
||||
template<typename T>
|
||||
T *ZAlloc();
|
||||
|
||||
/// POD array, zero allocation
|
||||
template<typename T>
|
||||
T *NewArray(AuUInt uLength);
|
||||
|
||||
/// POD array, zero allocation
|
||||
template<typename T>
|
||||
T *NewArray(AuUInt uLength, AuUInt uAlignment);
|
||||
|
||||
/// Fast, POD, non-zeroing allocation
|
||||
template<typename T = void *>
|
||||
T FAlloc(AuUInt uLength);
|
||||
|
||||
/// Fast, POD, non-zeroing allocation
|
||||
template<typename T = void *>
|
||||
T FAlloc(AuUInt uLength, AuUInt uAlignment);
|
||||
|
||||
/// Fast, POD, non-zeroing allocation
|
||||
template<typename T>
|
||||
T *FAlloc();
|
||||
|
||||
// Reallocs
|
||||
|
||||
/// POD, zero-based expansion or reallocation
|
||||
template<typename T>
|
||||
T ZRealloc(T pHead, AuUInt uLength);
|
||||
|
||||
/// POD, zero-based expansion or reallocation
|
||||
template<typename T>
|
||||
T ZRealloc(T pHead, AuUInt uLength, AuUInt uAlignment);
|
||||
|
||||
/// POD, expansion or reallocation
|
||||
template<typename T>
|
||||
T FRealloc(T pHead, AuUInt uLength);
|
||||
|
||||
/// POD, expansion or reallocation
|
||||
template<typename T>
|
||||
T FRealloc(T pHead, AuUInt uLength, AuUInt uAlignment);
|
||||
|
||||
/// Free
|
||||
template<typename T>
|
||||
void Free(T pHead);
|
||||
|
||||
protected:
|
||||
|
||||
template <typename T>
|
||||
static void DeleteThat(T *pThat);
|
||||
|
||||
template <typename T>
|
||||
static void DeleteThatArray(T *pThat);
|
||||
|
||||
template <typename T>
|
||||
static void DeleteThatArray2(T *pThat);
|
||||
|
||||
template <typename T, typename Z>
|
||||
static void DeleteThatCastedOnce(T *pThat);
|
||||
|
||||
template <typename T>
|
||||
static void RetardedSpecWrittenByRetards(T *pThat);
|
||||
|
||||
public:
|
||||
|
||||
template <class T, class ...Args>
|
||||
AuSPtr<T> NewClass(Args &&...args);
|
||||
|
||||
// note: callers can use AuHUPOf_t<Z> pUniquePointer = AuNullHeapPointer<Z>()
|
||||
// update: no longer required with memory model update 2024/09
|
||||
// AuHUPOf_t<T> or AuUPtr<T> will do
|
||||
|
||||
template <class T, class Z /* cast to */ = T, class ...Args>
|
||||
AuUPtr<Z, decltype(&AuHeap::DeleteThat<Z>)> NewClassUnique(Args &&...args);
|
||||
|
||||
template <class T, class ...Args>
|
||||
AuSPtr<T> NewClassArray(AuUInt uElements, Args &&... fillCtr);
|
||||
|
||||
// note: despite dtor awareness, this is intended for allocating POD arrays of uAlignment
|
||||
// this is used by the memory views clone routine.
|
||||
template <class T, class ...Args>
|
||||
AuSPtr<T> NewClassArray2(AuUInt uElements, AuUInt uAlignment, Args &&... fillCtr);
|
||||
|
||||
// note: callers can use AuHUPOf_t<T> pUniquePointer = AuNullHeapPointer<T>()
|
||||
// update: no longer required with memory model update 2024/09
|
||||
// AuHUPOf_t<T> or AuUPtr<T> will do
|
||||
|
||||
template <class T, class ...Args>
|
||||
AuUPtr<T, decltype(&AuHeap::DeleteThat<T>)> NewClassArrayUnique(AuUInt uElements, Args &&... fillCtr);
|
||||
|
||||
template <class T, class ...Args>
|
||||
AuUPtr<T, decltype(&AuHeap::DeleteThat<T>)> NewClassArray2Unique(AuUInt uElements, AuUInt uAlignment, Args &&... fillCtr);
|
||||
|
||||
template <class T>
|
||||
cstatic AuUPtr<T, decltype(&AuHeap::DeleteThat<T>)> NullUniquePointer();
|
||||
|
||||
template <class Z, class T>
|
||||
cstatic AuUPtr<Z, decltype(&AuHeap::DeleteThat<Z>)> CastPointer(AuUPtr<T, decltype(&AuHeap::DeleteThat<T>)> &&pInPointer);
|
||||
|
||||
template <typename T>
|
||||
using HUPOf_t = AuUPtr<T, decltype(&AuHeap::DeleteThat<T>)>;
|
||||
|
||||
protected:
|
||||
friend struct AuHeapAccessor;
|
||||
friend struct Aurora::Memory::ProxyHeap;
|
||||
|
||||
virtual AuSPtr<AuHeap> GetSelfReference() = 0; // may return empty/default. not all heaps are sharable.
|
||||
virtual AuHeap *GetSelfReferenceRaw() = 0;
|
||||
|
||||
virtual AU_ALLOC void *_ZAlloc(AuUInt uLength) = 0;
|
||||
virtual AU_ALLOC void *_ZAlloc(AuUInt uLength, AuUInt uAlignment) = 0;
|
||||
virtual AU_ALLOC void *_FAlloc(AuUInt uLength) = 0;
|
||||
virtual AU_ALLOC void *_FAlloc(AuUInt uLength, AuUInt uAlignment) = 0;
|
||||
virtual AU_ALLOC void *_ZRealloc(void *pBase, AuUInt uLength, AuUInt uAlign) = 0;
|
||||
virtual AU_ALLOC void *_ZRealloc(void *pBase, AuUInt uLength) = 0;
|
||||
virtual AU_ALLOC void *_FRealloc(void *pBase, AuUInt uLength, AuUInt uAlign) = 0;
|
||||
virtual AU_ALLOC void *_FRealloc(void *pBase, AuUInt uLength) = 0;
|
||||
virtual void _Free(void* pBase) = 0;
|
||||
};
|
590
Include/auROXTL/MemoryModel/auHeap.ipp
Executable file
590
Include/auROXTL/MemoryModel/auHeap.ipp
Executable file
@ -0,0 +1,590 @@
|
||||
/***
|
||||
Copyright (C) 2021-2024 Jamie Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: AuHeap.ipp
|
||||
File: Heap.inl
|
||||
Date: 2024-7-14
|
||||
Date: 2021-6-9
|
||||
Author: Reece
|
||||
Note: moved from Runtime to ROXTL
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
template<typename T>
|
||||
T AuHeap::ZAlloc(AuUInt 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 AuHeap::ZAlloc(AuUInt uLength, AuUInt uAlignment)
|
||||
{
|
||||
return reinterpret_cast<T>(_ZAlloc(uLength, uAlignment));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T *AuHeap::ZAlloc()
|
||||
{
|
||||
return reinterpret_cast<T *>(_ZAlloc(sizeof(T), alignof(T)));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T *AuHeap::NewArray(AuUInt uLength)
|
||||
{
|
||||
return ZAlloc<T *>(uLength * sizeof(T), alignof(T));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T *AuHeap::NewArray(AuUInt uLength, AuUInt uAlignment)
|
||||
{
|
||||
return ZAlloc<T *>(uLength * sizeof(T), uAlignment);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T AuHeap::FAlloc(AuUInt 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 AuHeap::FAlloc(AuUInt uLength, AuUInt uAlignment)
|
||||
{
|
||||
return reinterpret_cast<T>(_FAlloc(uLength, uAlignment));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T *AuHeap::FAlloc()
|
||||
{
|
||||
return reinterpret_cast<T *>(_FAlloc(sizeof(T), alignof(T)));
|
||||
}
|
||||
|
||||
// Reallocs
|
||||
template<typename T>
|
||||
T AuHeap::ZRealloc(T pHead, AuUInt 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 AuHeap::ZRealloc(T pHead, AuUInt uLength, AuUInt uAlignment)
|
||||
{
|
||||
return reinterpret_cast<T>(_ZRealloc(reinterpret_cast<void *>(pHead), uLength, uAlignment));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T AuHeap::FRealloc(T pHead, AuUInt 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 AuHeap::FRealloc(T pHead, AuUInt uLength, AuUInt uAlignment)
|
||||
{
|
||||
return reinterpret_cast<T>(_FRealloc(reinterpret_cast<void *>(pHead), uLength, uAlignment));
|
||||
}
|
||||
|
||||
// Free
|
||||
template<typename T>
|
||||
void AuHeap::Free(T pHead)
|
||||
{
|
||||
_Free(reinterpret_cast<void *>(pHead));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void AuHeap::DeleteThat(T *pThat)
|
||||
{
|
||||
static const auto kAlignment = AuMax(alignof(T), sizeof(void *));
|
||||
|
||||
if constexpr (AuIsClass_v<T> &&
|
||||
!AuIsTriviallyDestructible_v<T>)
|
||||
{
|
||||
pThat->~T();
|
||||
}
|
||||
|
||||
auto &pAuHeap = *(AuHeap **)(((char *)pThat) - kAlignment);
|
||||
pAuHeap->_Free(&pAuHeap);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void AuHeap::DeleteThatArray(T *pThat)
|
||||
{
|
||||
static const auto kAlignment = AuMax(alignof(T), sizeof(void *) * 2);
|
||||
|
||||
auto pVoids = (void **)(((char *)pThat) - kAlignment);
|
||||
auto pAuHeap = (AuHeap *)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();
|
||||
}
|
||||
}
|
||||
|
||||
pAuHeap->_Free(pVoids);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void AuHeap::DeleteThatArray2(T *pThat)
|
||||
{
|
||||
auto pBase = ((void **)pThat)[-1];
|
||||
|
||||
auto pVoids = (void **)pBase;
|
||||
auto pAuHeap = (AuHeap *)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();
|
||||
}
|
||||
}
|
||||
|
||||
pAuHeap->_Free(pVoids);
|
||||
}
|
||||
template <typename T, typename Z>
|
||||
void AuHeap::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 &pAuHeap = *(AuHeap **)(((char *)pBaseClass) - kAlignment);
|
||||
pAuHeap->_Free(&pAuHeap);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void AuHeap::RetardedSpecWrittenByRetards(T *pThat)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
template <class T, class ...Args>
|
||||
AuSPtr<T> AuHeap::NewClass(Args &&...args)
|
||||
{
|
||||
static const auto kAlignment = AuMax(alignof(T), sizeof(void *));
|
||||
AuUInt8 *pPtr;
|
||||
|
||||
#if defined(AURORA_PROXYHEAP_REF_BASE_UAF)
|
||||
auto pThat = this->GetSelfReferenceRaw();
|
||||
if (!pThat)
|
||||
{
|
||||
pThat = this;
|
||||
}
|
||||
#else
|
||||
auto pThat = this;
|
||||
#endif
|
||||
|
||||
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, &AuHeap::DeleteThat<T>, AuPMRAllocator<T> { this });
|
||||
}
|
||||
AUROXTL_COMMODITY_CATCH
|
||||
{
|
||||
AuHeap::DeleteThat<T>(pTThat);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, class Z, class ...Args>
|
||||
AuUPtr<Z, decltype(&AuHeap::DeleteThat<Z>)> AuHeap::NewClassUnique(Args &&...args)
|
||||
{
|
||||
static const auto kAlignment = AuMax(alignof(T), sizeof(void *));
|
||||
AuUInt8 *pPtr;
|
||||
|
||||
#if defined(AURORA_PROXYHEAP_REF_BASE_UAF)
|
||||
auto pThat = this->GetSelfReferenceRaw();
|
||||
if (!pThat)
|
||||
{
|
||||
pThat = this;
|
||||
}
|
||||
#else
|
||||
auto pThat = this;
|
||||
#endif
|
||||
|
||||
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(&AuHeap::DeleteThat<Z>)>(nullptr, &AuHeap::RetardedSpecWrittenByRetards<Z>);
|
||||
}
|
||||
|
||||
*(void **)pPtr = pThat;
|
||||
|
||||
if constexpr (AuIsSame_v<T, Z>)
|
||||
{
|
||||
return AuUPtr<T, decltype(&AuHeap::DeleteThat<T>)>((T *)(pPtr + kAlignment), &AuHeap::DeleteThat<T>);
|
||||
}
|
||||
else
|
||||
{
|
||||
return AuHeap::CastPointer<Z>(AuMove(AuUPtr<T, decltype(&AuHeap::DeleteThat<T>)>((T *)(pPtr + kAlignment), &AuHeap::DeleteThat<T>)));
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, class ...Args>
|
||||
AuSPtr<T> AuHeap::NewClassArray(AuUInt uElements, Args &&... fillCtr)
|
||||
{
|
||||
const auto kAlignment = AuMax(alignof(T), sizeof(void *) * 2);
|
||||
AuUInt8 *pPtr;
|
||||
|
||||
if (!uElements)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
#if defined(AURORA_PROXYHEAP_REF_BASE_UAF)
|
||||
auto pThat = this->GetSelfReferenceRaw();
|
||||
if (!pThat)
|
||||
{
|
||||
pThat = this;
|
||||
}
|
||||
#else
|
||||
auto pThat = this;
|
||||
#endif
|
||||
|
||||
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_AuHeap_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, &AuHeap::DeleteThatArray<T>, AuPMRAllocator<T> { this });
|
||||
}
|
||||
AUROXTL_COMMODITY_CATCH
|
||||
{
|
||||
AuHeap::DeleteThatArray<T>(pTThat);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, class ...Args>
|
||||
AuSPtr<T> AuHeap::NewClassArray2(AuUInt uElements, AuUInt uAlignment, Args &&... fillCtr)
|
||||
{
|
||||
const auto kAlignment = AuMax(uAlignment, sizeof(void *) * 4);
|
||||
AuUInt8 *pPtr;
|
||||
|
||||
if (!uElements)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
#if defined(AURORA_PROXYHEAP_REF_BASE_UAF)
|
||||
auto pThat = this->GetSelfReferenceRaw();
|
||||
if (!pThat)
|
||||
{
|
||||
pThat = this;
|
||||
}
|
||||
#else
|
||||
auto pThat = this;
|
||||
#endif
|
||||
|
||||
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_AuHeap_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;
|
||||
((void **)(pPtr + kAlignment))[-1] = pPtr;
|
||||
auto pTThat = (T *)(pPtr + kAlignment);
|
||||
|
||||
AUROXTL_COMMODITY_TRY
|
||||
{
|
||||
return AuSPtr<T>(pTThat, &AuHeap::DeleteThatArray2<T>, AuPMRAllocator<T> { this });
|
||||
}
|
||||
AUROXTL_COMMODITY_CATCH
|
||||
{
|
||||
AuHeap::DeleteThatArray2<T>(pTThat);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, class ...Args>
|
||||
AuUPtr<T, decltype(&AuHeap::DeleteThat<T>)> AuHeap::NewClassArrayUnique(AuUInt uElements, Args &&... fillCtr)
|
||||
{
|
||||
const auto kAlignment = AuMax(alignof(T), sizeof(void *) * 2);
|
||||
AuUInt8 *pPtr;
|
||||
|
||||
if (!uElements)
|
||||
{
|
||||
return AuUPtr<T, decltype(&AuHeap::DeleteThat<T>)>(nullptr, &AuHeap::RetardedSpecWrittenByRetards<T>);
|
||||
}
|
||||
|
||||
#if defined(AURORA_PROXYHEAP_REF_BASE_UAF)
|
||||
auto pThat = this->GetSelfReferenceRaw();
|
||||
if (!pThat)
|
||||
{
|
||||
pThat = this;
|
||||
}
|
||||
#else
|
||||
auto pThat = this;
|
||||
#endif
|
||||
|
||||
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_AuHeap_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(&AuHeap::DeleteThat<T>)>(nullptr, &AuHeap::RetardedSpecWrittenByRetards<T>);
|
||||
}
|
||||
|
||||
auto pVoids = (void **)pPtr;
|
||||
pVoids[0] = pThat;
|
||||
pVoids[1] = (void *)uElements;
|
||||
|
||||
return AuUPtr<T, decltype(&AuHeap::DeleteThat<T>)>((T *)(pPtr + kAlignment), &AuHeap::DeleteThatArray<T>);
|
||||
}
|
||||
|
||||
template <class T, class ...Args>
|
||||
AuUPtr<T, decltype(&AuHeap::DeleteThat<T>)> AuHeap::NewClassArray2Unique(AuUInt uElements, AuUInt uAlignment, Args &&... fillCtr)
|
||||
{
|
||||
const auto kAlignment = AuMax(uAlignment, sizeof(void *) * 4);
|
||||
AuUInt8 *pPtr;
|
||||
|
||||
if (!uElements)
|
||||
{
|
||||
return AuUPtr<T, decltype(&AuHeap::DeleteThat<T>)>(nullptr, &AuHeap::RetardedSpecWrittenByRetards<T>);
|
||||
}
|
||||
|
||||
#if defined(AURORA_PROXYHEAP_REF_BASE_UAF)
|
||||
auto pThat = this->GetSelfReferenceRaw();
|
||||
if (!pThat)
|
||||
{
|
||||
pThat = this;
|
||||
}
|
||||
#else
|
||||
auto pThat = this;
|
||||
#endif
|
||||
|
||||
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_AuHeap_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(&AuHeap::DeleteThat<T>)>(nullptr, &AuHeap::RetardedSpecWrittenByRetards<T>);
|
||||
}
|
||||
|
||||
auto pVoids = (void **)pPtr;
|
||||
pVoids[0] = pThat;
|
||||
pVoids[1] = (void *)uElements;
|
||||
|
||||
((void **)(pPtr + kAlignment))[-1] = pPtr;
|
||||
auto pTThat = (T *)(pPtr + kAlignment);
|
||||
|
||||
return AuUPtr<T, decltype(&AuHeap::DeleteThat<T>)>(pTThat, &AuHeap::DeleteThatArray2<T>);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
AuUPtr<T, decltype(&AuHeap::DeleteThat<T>)> AuHeap::NullUniquePointer()
|
||||
{
|
||||
return AuUPtr<T, decltype(&AuHeap::DeleteThat<T>)>(nullptr, &AuHeap::RetardedSpecWrittenByRetards<T>);
|
||||
}
|
||||
|
||||
template <class Z, class T>
|
||||
AuUPtr<Z, decltype(&AuHeap::DeleteThat<Z>)> AuHeap::CastPointer(AuUPtr<T, decltype(&AuHeap::DeleteThat<T>)> &&pInPointer)
|
||||
{
|
||||
if (!pInPointer)
|
||||
{
|
||||
return NullUniquePointer<Z>();
|
||||
}
|
||||
else if (pInPointer.get_deleter() == &AuHeap::DeleteThat<T>)
|
||||
{
|
||||
return AuUPtr<Z, decltype(&AuHeap::DeleteThat<Z>)>(AuStaticCast<Z>(pInPointer.release()), &AuHeap::DeleteThatCastedOnce<Z, T>);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NullUniquePointer<Z>();
|
||||
}
|
||||
}
|
||||
|
||||
namespace __audetail
|
||||
{
|
||||
inline AuSPtr<AuUInt8> AllocateArray(AuHeap *pAuHeap, AuUInt uLength, AuUInt32 uAlignment)
|
||||
{
|
||||
return pAuHeap->NewClassArray2<AuUInt8>(uLength, uAlignment);
|
||||
}
|
||||
}
|
23
Include/auROXTL/MemoryModel/auHeapAccessor.hpp
Executable file
23
Include/auROXTL/MemoryModel/auHeapAccessor.hpp
Executable file
@ -0,0 +1,23 @@
|
||||
/***
|
||||
Copyright (C) 2021-2024 Jamie Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: auHeapAccessor.hpp
|
||||
File: Heap.hpp
|
||||
Date: 2021-6-9
|
||||
Author: Reece
|
||||
Note: moved from Runtime to ROXTL
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
struct AuHeapAccessor
|
||||
{
|
||||
cstatic AuSPtr<AuHeap> GetSelfReference(AuHeap *pHeap)
|
||||
{
|
||||
return pHeap->GetSelfReference();
|
||||
}
|
||||
|
||||
cstatic AuHeap *GetSelfReferenceRaw(AuHeap *pHeap)
|
||||
{
|
||||
return pHeap->GetSelfReferenceRaw();
|
||||
}
|
||||
};
|
22
Include/auROXTL/MemoryModel/auHeapStats.hpp
Executable file
22
Include/auROXTL/MemoryModel/auHeapStats.hpp
Executable file
@ -0,0 +1,22 @@
|
||||
/***
|
||||
Copyright (C) 2022-2024 Jamie Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: HeapStats.hpp
|
||||
Date: 2022-12-07
|
||||
Author: Reece
|
||||
Note: Moved from Runtime
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
struct AuHeapStats
|
||||
{
|
||||
AuUInt uBytesAllocatedLifetime {};
|
||||
AuUInt uBytesFreeLifetime {};
|
||||
|
||||
AuUInt uBytesCapacity {};
|
||||
|
||||
AuUInt uBytesLiveCounter {};
|
||||
AuUInt uBytesPeakCounter {};
|
||||
|
||||
bool bIsSharedWithOtherHeaps {};
|
||||
};
|
150
Include/auROXTL/MemoryModel/auMemoryAllocate.hpp
Executable file
150
Include/auROXTL/MemoryModel/auMemoryAllocate.hpp
Executable file
@ -0,0 +1,150 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(AURORA_ROXTL_HAS_RUNTIME) && AURORA_ROXTL_HAS_RUNTIME
|
||||
namespace Aurora::Memory
|
||||
{
|
||||
AuHeap *GetDefaultDiscontiguousHeap();
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace __audetail
|
||||
{
|
||||
#if defined(AURORA_ROXTL_HAS_RUNTIME) && AURORA_ROXTL_HAS_RUNTIME
|
||||
inline AuHeap *gDefaultDiscontiguousHeap = Aurora::Memory::GetDefaultDiscontiguousHeap();
|
||||
#else
|
||||
inline AuHeap *gDefaultDiscontiguousHeap = &gDefaultDummyHeap;
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class T, typename... Args>
|
||||
auline AuSPtr<T> AuMakeShared(Args &&... args)
|
||||
{
|
||||
using Z = AuRemoveConst_t<T>;
|
||||
|
||||
#if !defined(AURORA_RUNTIME_HEADERS_ALWAYS_LOOKUP_HEAP)
|
||||
|
||||
try
|
||||
{
|
||||
#if defined(AURORA_ROXTL_ALLOCATORS_USE_STD)
|
||||
return AURORA_RUNTIME_MAKE_SHARED<T>(AuForward<Args>(args)...);
|
||||
#else
|
||||
auto pNext = Aurora::Memory::__FAlloc(sizeof(T), alignof(T));
|
||||
if (!pNext)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto pNextClass = (Z *)pNext;
|
||||
new (pNextClass) Z (AuForward<Args>(args)...);
|
||||
return AuSSPtr<T>(pNextClass, Aurora::Memory::DefaultRuntimeDeleter<Z> {}, Aurora::Memory::SharedControlBlockAllocator<T> {});
|
||||
#endif
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
return __audetail::gDefaultDiscontiguousHeap->NewClass<Z, Args...>(AuForward<Args>(args)...);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
using AuHUPOf_t = AuUPtr<T, void(*)(T *)>;
|
||||
|
||||
template <class T>
|
||||
auto AuNullHeapPointer()
|
||||
{
|
||||
return AuHeapNullUniquePointer<T>();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
auto AuNullPointer()
|
||||
{
|
||||
return AuHeapNullUniquePointer<T>();
|
||||
}
|
||||
|
||||
template <class T, class ...Args>
|
||||
AuHUPOf_t<T> AuNewClassArrayUnique(AuUInt uElements, Args &&... fillCtr)
|
||||
{
|
||||
return __audetail::gDefaultDiscontiguousHeap->NewClassArrayUnique<T, Args...>(uElements, AuForward<Args>(fillCtr)...);
|
||||
}
|
||||
|
||||
template <class T, class ...Args>
|
||||
AuSPtr<T> AuNewClassArray(AuUInt uElements, Args &&... fillCtr)
|
||||
{
|
||||
return __audetail::gDefaultDiscontiguousHeap->NewClassArray<T, Args...>(uElements, AuForward<Args>(fillCtr)...);
|
||||
}
|
||||
|
||||
template <class T, class Z = T, class ...Args>
|
||||
AuHUPOf_t<Z> AuNewClassUnique(Args &&...args)
|
||||
{
|
||||
return __audetail::gDefaultDiscontiguousHeap->NewClassUnique<T, Z, Args...>(AuForward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <class T, class ...Args>
|
||||
AuSPtr<T> AuNewClass(Args &&...args)
|
||||
{
|
||||
#if !defined(AURORA_RUNTIME_HEADERS_ALWAYS_LOOKUP_HEAP)
|
||||
return AuMakeShared<T, Args...>(AuForward<Args>(args)...);
|
||||
#else
|
||||
return __audetail::gDefaultDiscontiguousHeap->NewClass<T, Args...>(AuForward<Args>(args)...);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class T, class ...Args>
|
||||
AuHUPOf_t<T> AuNewClassArrayUnique(AuHeap *pHeap, AuUInt uElements, Args &&... fillCtr)
|
||||
{
|
||||
return pHeap->NewClassArrayUnique<T, Args...>(uElements, AuForward<Args>(fillCtr)...);
|
||||
}
|
||||
|
||||
template <class T, class ...Args>
|
||||
AuSPtr<T> AuNewClassArray(AuHeap *pHeap, AuUInt uElements, Args &&... fillCtr)
|
||||
{
|
||||
return pHeap->NewClassArray<T, Args...>(uElements, AuForward<Args>(fillCtr)...);
|
||||
}
|
||||
|
||||
template <class T, class ...Args>
|
||||
AuHUPOf_t<T> AuNewClassUnique(AuHeap *pHeap, Args &&...args)
|
||||
{
|
||||
return pHeap->NewClassUnique<T, Args...>(AuForward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <class T, class ...Args>
|
||||
AuSPtr<T> AuNewClass(AuHeap *pHeap, Args &&...args)
|
||||
{
|
||||
return pHeap->NewClass<T, Args...>(AuForward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <class T, class ...Args>
|
||||
AuHUPOf_t<T> AuNewClassArrayUnique(const AuSPtr<AuHeap> &pHeap, AuUInt uElements, Args &&... fillCtr)
|
||||
{
|
||||
return pHeap->NewClassArrayUnique<T, Args...>(uElements, AuForward<Args>(fillCtr)...);
|
||||
}
|
||||
|
||||
template <class T, class ...Args>
|
||||
AuSPtr<T> AuNewClassArray(const AuSPtr<AuHeap> &pHeap, AuUInt uElements, Args &&... fillCtr)
|
||||
{
|
||||
return pHeap->NewClassArray<T, Args...>(uElements, AuForward<Args>(fillCtr)...);
|
||||
}
|
||||
|
||||
template <class T, class Z = T, class ...Args>
|
||||
AuHUPOf_t<Z> AuNewClassUnique(const AuSPtr<AuHeap> &pHeap, Args &&...args)
|
||||
{
|
||||
return pHeap->NewClassUnique<T, Z, Args...>(AuForward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <class T, class ...Args>
|
||||
AuSPtr<T> AuNewClass(const AuSPtr<AuHeap> &pHeap, Args &&...args)
|
||||
{
|
||||
return pHeap->NewClass<T, Args...>(AuForward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <class Z, class T>
|
||||
AuHUPOf_t<Z> AuCastPointer(AuHUPOf_t<T> &&pInPointer)
|
||||
{
|
||||
// TODO: we can do better with this memory model update
|
||||
return AuHeapCastPointer<Z>(AuMove(pInPointer));
|
||||
}
|
314
Include/auROXTL/MemoryModel/auMemoryView.hpp
Executable file
314
Include/auROXTL/MemoryModel/auMemoryView.hpp
Executable file
@ -0,0 +1,314 @@
|
||||
/***
|
||||
Copyright (C) 2021-2024 Jamie Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: auAuMemoryView.hpp
|
||||
File: AuMemoryView.hpp
|
||||
Date: 2021-9-14
|
||||
Author: Reece
|
||||
Notes: Moved from Runtime
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
struct AuMemoryViewControlBlock
|
||||
{
|
||||
// Free-after-use mitigator: ensures a non-zero flag is kept whilst other memory views are present
|
||||
// This helps mitigate:
|
||||
// -> Take view from object
|
||||
// -> Make view shared
|
||||
// -> Pass off shared view to another subsystem
|
||||
// -> Use the aforementioned object to resize, release, or do something bad with the memory pointed to by the initial view
|
||||
// Mitgation: SysAssert(!pObject->uInUse)
|
||||
AuAUInt32 *pInUseCounter {};
|
||||
|
||||
// Mitigation (cont) and reducing code reuse:
|
||||
// -> Allow for [shared!] memory views to have a shared freestanding owner
|
||||
// -> Ensure reference counters or other forms of memory management don't free the owner before us
|
||||
// (Consider inverse construction order, for instance, we'd have to always call AuMemoryView::ResetControlBlock()
|
||||
// in a derived subclass, in order release the pInUseCounter reference before the derived shared members get released)
|
||||
AuSSPtr<void> pPinner; // WARNING: as usual, std types don't validate their allocator, and our shared ptrs can be different between binaries!
|
||||
|
||||
void *pCallbackHandle {};
|
||||
|
||||
// Called on zero condition (pInUseCounter == 0), or when the view is destroyed or moved (if no pInUseCounter).
|
||||
void (*pfCallbackOnZero)(void *) {};
|
||||
|
||||
inline ~AuMemoryViewControlBlock();
|
||||
inline void Release();
|
||||
};
|
||||
|
||||
// A memory view that can be reinterpret cast to any type. May contain shared pointer control blocks for persistency.
|
||||
template<bool Readonly_b>
|
||||
struct AuMemoryView
|
||||
{
|
||||
using U8_t = AuConditional_t<Readonly_b, const AuUInt8 *, AuUInt8 *>;
|
||||
using Void_t = AuConditional_t<Readonly_b, const void *, void *>;
|
||||
|
||||
constexpr AuMemoryView();
|
||||
|
||||
template<typename T, AU_TEMPLATE_ENABLE_WHEN(AuIsBaseOfTemplate<AURORA_RUNTIME_AU_LIST, T>::value)>
|
||||
constexpr AuMemoryView(T &list)
|
||||
{
|
||||
this->ptr = list.data();
|
||||
this->length = list.size() * sizeof(typename T::value_type);
|
||||
}
|
||||
|
||||
constexpr AuMemoryView(const AuROString &str);
|
||||
|
||||
constexpr AuMemoryView(const AuRONString &str);
|
||||
|
||||
constexpr AuMemoryView(const AuString &str);
|
||||
|
||||
AuMemoryView(const AuMemoryView &view);
|
||||
|
||||
AuMemoryView(const AuMemoryView &view,
|
||||
const AuSPtr<void> &pThat,
|
||||
void *pCallbackHandle = nullptr,
|
||||
void (*pfCallbackOnZero)(void *) = nullptr);
|
||||
|
||||
constexpr AuMemoryView(AuMemoryView &&view);
|
||||
|
||||
template<typename T, int Z>
|
||||
constexpr AuMemoryView(T(&a)[Z]);
|
||||
|
||||
template<typename T, int Z>
|
||||
constexpr AuMemoryView(AuArray<T, Z> &view);
|
||||
|
||||
template<typename T>
|
||||
constexpr AuMemoryView(T *start, T *end);
|
||||
|
||||
template<typename T>
|
||||
constexpr AuMemoryView(T *start, T *end, AuAUInt32 *pInUseCounter, void *pCallbackHandle = nullptr, void (*pfCallbackOnZero)(void *) = nullptr);
|
||||
|
||||
template<typename T>
|
||||
constexpr AuMemoryView(T *start, T *end, AuAUInt32 *pInUseCounter, const AuSPtr<void> &pRAIIOwner, void *pCallbackHandle = nullptr, void (*pfCallbackOnZero)(void *) = nullptr);
|
||||
|
||||
template<typename T>
|
||||
constexpr AuMemoryView(T *start, AuUInt length); // WARNING: length != count
|
||||
// where T = whogivesafuck
|
||||
|
||||
template<typename T>
|
||||
constexpr AuMemoryView(T *start, AuUInt length, AuAUInt32 *pInUseCounter, void *pCallbackHandle = nullptr, void (*pfCallbackOnZero)(void *) = nullptr); // WARNING: length != count
|
||||
|
||||
template<typename T>
|
||||
constexpr AuMemoryView(T *start, AuUInt length, AuAUInt32 *pInUseCounter, const AuSPtr<void> &pRAIIOwner, void *pCallbackHandle = nullptr, void (*pfCallbackOnZero)(void *) = nullptr); // WARNING: length != count
|
||||
|
||||
private:
|
||||
template<typename T>
|
||||
AuMemoryView(T *start, AuUInt length, const AuMemoryViewControlBlock ©Block);
|
||||
|
||||
public:
|
||||
|
||||
AuMemoryView &operator =(AuMemoryView &&view);
|
||||
AuMemoryView &operator =(const AuMemoryView &view);
|
||||
|
||||
constexpr AuUInt ToPointerValue() const;
|
||||
|
||||
constexpr AuUInt ToLength() const;
|
||||
constexpr AuUInt Length() const;
|
||||
|
||||
constexpr AuUInt ToSize() const;
|
||||
constexpr AuUInt Size() const;
|
||||
constexpr AuUInt size() const;
|
||||
|
||||
template<typename T = AuUInt8>
|
||||
constexpr AuUInt ToCount() const;
|
||||
template<typename T = AuUInt8>
|
||||
constexpr AuUInt Count() const;
|
||||
|
||||
template<typename T>
|
||||
AuConditional_t<Readonly_b, const T *, T *> Begin() const;
|
||||
|
||||
template<typename T>
|
||||
AuConditional_t<Readonly_b, const T*, T*> End() const;
|
||||
|
||||
constexpr bool HasMemory() const;
|
||||
|
||||
constexpr operator bool() const;
|
||||
|
||||
constexpr U8_t ToPointer() const;
|
||||
|
||||
constexpr U8_t begin() const;
|
||||
constexpr U8_t end() const;
|
||||
constexpr U8_t Begin() const;
|
||||
constexpr U8_t End() const;
|
||||
|
||||
AuMemoryView AtOffset(AuUInt uOffset) const;
|
||||
AuMemoryView Take(AuUInt uLength) const;
|
||||
|
||||
AuMemoryView Clone() const;
|
||||
AuMemoryView Clone(AuHeap *pHeap, AuUInt32 uAlignment = alignof(double)) const;
|
||||
|
||||
bool TryCloneSelf(bool bResetOnFailure = true);
|
||||
|
||||
AuUInt CopyInto(const AuMemoryView<false> &write) const;
|
||||
|
||||
template<bool bThat = Readonly_b, AU_TEMPLATE_ENABLE_WHEN(!bThat)>
|
||||
AuUInt CopyFrom(const AuMemoryView<true> &read) const
|
||||
{
|
||||
auto uLength = AuMin(this->uLength, read.uLength);
|
||||
AuMemcpy(this->pBase, read.pBase, uLength);
|
||||
return uLength;
|
||||
}
|
||||
|
||||
bool HasControlBlock() const;
|
||||
|
||||
/// Creates a shader pointer of the view with an optional parent
|
||||
AuSPtr<AuMemoryView> TryPromoteToSharedView(AuSPtr<void> pParent = {}) const;
|
||||
|
||||
/// Creates a shader pointer of the view with an optional parent
|
||||
/// If *this already contains a shared parent, will return nullptr
|
||||
AuSPtr<AuMemoryView> TryPromoteToSharedViewNoParentNesting(AuSPtr<void> pParent = {}) const;
|
||||
|
||||
/// Shares ownership of pCopy, returning false if there is no shared parent.
|
||||
bool TryDemoteFromSharedView(const AuSPtr<AuMemoryView> &pCopy);
|
||||
|
||||
/// Shares ownership of pCopy, returning false if there is no shared parent.
|
||||
bool TryDemoteFromReference(const AuMemoryView &refCopy);
|
||||
|
||||
/// Copies the memory view of a shared memory view.
|
||||
/// If the memory view has a shared parent, the memory view and its parent shared pointer is copied into *this.
|
||||
/// If the memory view does not have a shared parent, the memory view and its control block is copied into *this.
|
||||
void DemoteFromSharedView(const AuSPtr<AuMemoryView> &pCopy);
|
||||
|
||||
/// Interop for other APIs that allow for pinning shared pointers (std::shared_ptr)
|
||||
AuSPtr<void> ToSharedControlBlock(bool *pbFailed = nullptr);
|
||||
|
||||
union
|
||||
{
|
||||
Void_t /*const*/ ptr;
|
||||
Void_t /*const*/ pBase;
|
||||
U8_t ptrU8;
|
||||
AuUInt uPtr;
|
||||
};
|
||||
union
|
||||
{
|
||||
AuUInt /*const*/ length;
|
||||
AuUInt /*const*/ uLength;
|
||||
};
|
||||
|
||||
private:
|
||||
AuMemoryViewControlBlock controlBlock;
|
||||
};
|
||||
|
||||
using AuMemoryViewRead = AuMemoryView<true>;
|
||||
using AuMemoryViewWrite = AuMemoryView<false>;
|
||||
|
||||
// A memory view with an output variable reference for bytes consumed/provided scenarios.
|
||||
// ( they happen enough to justify this class for binding engines. )
|
||||
// ( this is also easier to bind than arbitrary POD pointers of no assertable lifespan by typical style expectations. )
|
||||
template<bool Readonly_b>
|
||||
struct AuMemoryViewStream : AuMemoryView<Readonly_b>
|
||||
{
|
||||
template<typename T, AU_TEMPLATE_ENABLE_WHEN(AuIsBaseOfTemplate<AURORA_RUNTIME_AU_LIST, T>::value)>
|
||||
constexpr AuMemoryViewStream(T &list, AuUInt &length) : AuMemoryView<Readonly_b>(list), outVariable(length)
|
||||
{
|
||||
outVariable = 0;
|
||||
}
|
||||
|
||||
constexpr AuMemoryViewStream(const AuString &str, AuUInt &length) : AuMemoryView<Readonly_b>(str), outVariable(length)
|
||||
{
|
||||
outVariable = 0;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr AuMemoryViewStream(T *start, T *end, AuUInt &length) : AuMemoryView<Readonly_b>(start, end), outVariable(length)
|
||||
{
|
||||
outVariable = 0;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr AuMemoryViewStream(T *start, AuUInt &length) : AuMemoryView<Readonly_b>(start, length), outVariable(length)
|
||||
{
|
||||
outVariable = 0;
|
||||
}
|
||||
|
||||
template<typename T, int Z>
|
||||
constexpr AuMemoryViewStream(AuArray<T, Z> &view,
|
||||
AuUInt &length) :
|
||||
AuMemoryView<Readonly_b>(view),
|
||||
outVariable(length)
|
||||
{
|
||||
outVariable = 0;
|
||||
}
|
||||
|
||||
template<typename T, typename AuEnableIf<AuIsBaseOfTemplate<AURORA_RUNTIME_AU_LIST, T>::value>::type* = nullptr>
|
||||
constexpr AuMemoryViewStream(T &list) : AuMemoryView<Readonly_b>(list), outVariable(unused)
|
||||
{
|
||||
outVariable = 0;
|
||||
}
|
||||
|
||||
constexpr AuMemoryViewStream(const AuString &str) :
|
||||
AuMemoryView<Readonly_b>(str),
|
||||
outVariable(unused)
|
||||
{
|
||||
outVariable = 0;
|
||||
}
|
||||
|
||||
constexpr AuMemoryViewStream(const AuROString &str) :
|
||||
AuMemoryView<Readonly_b>(str),
|
||||
outVariable(unused)
|
||||
{
|
||||
outVariable = 0;
|
||||
}
|
||||
|
||||
constexpr AuMemoryViewStream(const AuRONString &str) :
|
||||
AuMemoryView<Readonly_b>(str),
|
||||
outVariable(unused)
|
||||
{
|
||||
outVariable = 0;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr AuMemoryViewStream(T *start, T *end) : AuMemoryView<Readonly_b>(start, end), outVariable(unused)
|
||||
{
|
||||
outVariable = 0;
|
||||
}
|
||||
|
||||
constexpr AuMemoryViewStream(AuMemoryView<Readonly_b> in) : AuMemoryView<Readonly_b>(in.ptr, in.length), outVariable(unused)
|
||||
{
|
||||
outVariable = 0;
|
||||
}
|
||||
|
||||
constexpr AuMemoryViewStream(AuMemoryView<Readonly_b> in, AuUInt &len) : AuMemoryView<Readonly_b>(in.ptr, in.length), outVariable(len)
|
||||
{
|
||||
outVariable = 0;
|
||||
}
|
||||
|
||||
template<typename T, int Z>
|
||||
constexpr AuMemoryViewStream(T(&a)[Z]) : AuMemoryView<Readonly_b>(a), outVariable(unused)
|
||||
{
|
||||
outVariable = 0;
|
||||
}
|
||||
|
||||
constexpr bool HasMemory() const
|
||||
{
|
||||
return this->ptr && this->length;
|
||||
}
|
||||
|
||||
constexpr operator bool() const
|
||||
{
|
||||
return HasMemory();
|
||||
}
|
||||
|
||||
void CopyStreamInto(const AuMemoryView<false> &write) const
|
||||
{
|
||||
auto uLength = AuMin(this->uLength, write.uLength);
|
||||
AuMemcpy(write.pBase, this->pBase, uLength);
|
||||
this->outVariable = uLength;
|
||||
}
|
||||
|
||||
template<bool bThat = Readonly_b, AU_TEMPLATE_ENABLE_WHEN(!bThat)>
|
||||
void CopyStreamFrom(const AuMemoryView<true> &read) const
|
||||
{
|
||||
auto uLength = AuMin(this->uLength, read.uLength);
|
||||
AuMemcpy(this->pBase, read.pBase, uLength);
|
||||
this->outVariable = uLength;
|
||||
}
|
||||
|
||||
AuUInt &outVariable;
|
||||
private:
|
||||
AuUInt unused;
|
||||
};
|
||||
|
||||
using AuMemoryViewStreamRead = AuMemoryViewStream<true>;
|
||||
using AuMemoryViewStreamWrite = AuMemoryViewStream<false>;
|
624
Include/auROXTL/MemoryModel/auMemoryView.ipp
Executable file
624
Include/auROXTL/MemoryModel/auMemoryView.ipp
Executable file
@ -0,0 +1,624 @@
|
||||
/***
|
||||
Copyright (C) 2021-2024 Jamie Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: auAuMemoryView.ipp
|
||||
File: AuMemoryView.hpp
|
||||
Date: 2021-9-14
|
||||
Author: Reece
|
||||
Notes: Moved from Runtime
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
AuMemoryViewControlBlock::~AuMemoryViewControlBlock()
|
||||
{
|
||||
this->Release();
|
||||
}
|
||||
|
||||
void AuMemoryViewControlBlock::Release()
|
||||
{
|
||||
if (auto pCounter = AuExchange(this->pInUseCounter, nullptr))
|
||||
{
|
||||
if (AuAtomicSub(pCounter, 1u) == 0)
|
||||
{
|
||||
if (this->pfCallbackOnZero)
|
||||
{
|
||||
this->pfCallbackOnZero(this->pCallbackHandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this->pfCallbackOnZero)
|
||||
{
|
||||
this->pfCallbackOnZero(this->pCallbackHandle);
|
||||
}
|
||||
}
|
||||
|
||||
AuResetMember(this->pPinner);
|
||||
AuResetMember(this->pfCallbackOnZero);
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
constexpr AuMemoryView<Readonly_b>::AuMemoryView()
|
||||
{
|
||||
this->ptr = nullptr;
|
||||
this->length = 0;
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
constexpr AuMemoryView<Readonly_b>::AuMemoryView(const AuROString &str)
|
||||
{
|
||||
static_assert(Readonly_b, "ReadOnly string view must not be placed in a writable memory view");
|
||||
this->ptr = str.data();
|
||||
this->length = str.size();
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
constexpr AuMemoryView<Readonly_b>::AuMemoryView(const AuRONString &str)
|
||||
{
|
||||
static_assert(Readonly_b, "ReadOnly string view must not be placed in a writable memory view");
|
||||
this->ptr = str.data();
|
||||
this->length = str.size();
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
constexpr AuMemoryView<Readonly_b>::AuMemoryView(const AuString &str)
|
||||
{
|
||||
this->ptr = str.data();
|
||||
this->length = str.size();
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
AuMemoryView<Readonly_b>::AuMemoryView(const AuMemoryView &view)
|
||||
{
|
||||
this->ptr = view.ptr;
|
||||
this->length = view.length;
|
||||
this->controlBlock = view.controlBlock;
|
||||
if (this->controlBlock.pInUseCounter)
|
||||
{
|
||||
AuAtomicAdd(this->controlBlock.pInUseCounter, 1u);
|
||||
}
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
AuMemoryView<Readonly_b>::AuMemoryView(const AuMemoryView &view,
|
||||
const AuSPtr<void> &pThat,
|
||||
void *pCallbackHandle,
|
||||
void (*pfCallbackOnZero)(void *))
|
||||
{
|
||||
this->ptr = view.ptr;
|
||||
this->length = view.length;
|
||||
this->controlBlock.pInUseCounter = view.controlBlock.pInUseCounter;
|
||||
if (this->controlBlock.pInUseCounter)
|
||||
{
|
||||
AuAtomicAdd(this->controlBlock.pInUseCounter, 1u);
|
||||
}
|
||||
if (pThat)
|
||||
{
|
||||
if (view.controlBlock.pPinner)
|
||||
{
|
||||
auto pThat2 = AuMakeSharedArray<AuSPtr<void>>(2);
|
||||
this->controlBlock.pPinner = pThat2;
|
||||
if (!this->controlBlock.pPinner)
|
||||
{
|
||||
AuMemoryPanic("OOM");
|
||||
}
|
||||
pThat2.get()[0] = pThat;
|
||||
pThat2.get()[1] = view.controlBlock.pPinner;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->controlBlock.pPinner = pThat;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->controlBlock.pPinner = view.controlBlock.pPinner;
|
||||
}
|
||||
if (pfCallbackOnZero)
|
||||
{
|
||||
this->controlBlock.pCallbackHandle = pCallbackHandle;
|
||||
this->controlBlock.pfCallbackOnZero = pfCallbackOnZero;
|
||||
}
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
constexpr AuMemoryView<Readonly_b>::AuMemoryView(AuMemoryView &&view)
|
||||
{
|
||||
this->ptr = view.ptr;
|
||||
this->length = view.length;
|
||||
this->controlBlock.pInUseCounter = view.controlBlock.pInUseCounter;
|
||||
this->controlBlock.pPinner = AuMove(view.controlBlock.pPinner);
|
||||
this->controlBlock.pfCallbackOnZero = view.controlBlock.pfCallbackOnZero;
|
||||
this->controlBlock.pCallbackHandle = view.controlBlock.pCallbackHandle;
|
||||
view.controlBlock.pInUseCounter = nullptr;
|
||||
view.controlBlock.pfCallbackOnZero = nullptr;
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
template<typename T, int Z>
|
||||
constexpr AuMemoryView<Readonly_b>::AuMemoryView(T(&a)[Z])
|
||||
{
|
||||
this->ptr = &a[0];
|
||||
this->length = Z * sizeof(T);
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
template<typename T, int Z>
|
||||
constexpr AuMemoryView<Readonly_b>::AuMemoryView(AuArray<T, Z> &view)
|
||||
{
|
||||
this->ptr = view.begin();
|
||||
this->length = Z * sizeof(T);
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
template<typename T>
|
||||
constexpr AuMemoryView<Readonly_b>::AuMemoryView(T *start, T *end)
|
||||
{
|
||||
this->ptr = start;
|
||||
if constexpr (AuIsSame_v<T, Void_t>)
|
||||
{
|
||||
this->length = reinterpret_cast<const AuUInt8 *>(end) - reinterpret_cast<const AuUInt8 *>(start);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->length = (end - start) * sizeof(T);
|
||||
}
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
template<typename T>
|
||||
constexpr AuMemoryView<Readonly_b>::AuMemoryView(T *start, T *end, AuAUInt32 *pInUseCounter, void *pCallbackHandle, void (*pfCallbackOnZero)(void *))
|
||||
{
|
||||
this->ptr = start;
|
||||
if constexpr (AuIsSame_v<T, Void_t>)
|
||||
{
|
||||
this->length = reinterpret_cast<const AuUInt8 *>(end) - reinterpret_cast<const AuUInt8 *>(start);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->length = (end - start) * sizeof(T);
|
||||
}
|
||||
|
||||
this->controlBlock.pInUseCounter = pInUseCounter;
|
||||
AuAtomicAdd(pInUseCounter, 1u);
|
||||
this->controlBlock.pCallbackHandle = pCallbackHandle;
|
||||
this->controlBlock.pfCallbackOnZero = pfCallbackOnZero;
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
template<typename T>
|
||||
constexpr AuMemoryView<Readonly_b>::AuMemoryView(T *start, T *end, AuAUInt32 *pInUseCounter, const AuSPtr<void> &pRAIIOwner, void *pCallbackHandle, void (*pfCallbackOnZero)(void *))
|
||||
{
|
||||
this->ptr = start;
|
||||
if constexpr (AuIsSame_v<T, Void_t>)
|
||||
{
|
||||
this->length = reinterpret_cast<const AuUInt8 *>(end) - reinterpret_cast<const AuUInt8 *>(start);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->length = (end - start) * sizeof(T);
|
||||
}
|
||||
|
||||
this->controlBlock.pInUseCounter = pInUseCounter;
|
||||
AuAtomicAdd(pInUseCounter, 1u);
|
||||
this->controlBlock.pPinner = pRAIIOwner;
|
||||
this->controlBlock.pCallbackHandle = pCallbackHandle;
|
||||
this->controlBlock.pfCallbackOnZero = pfCallbackOnZero;
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
template<typename T>
|
||||
constexpr AuMemoryView<Readonly_b>::AuMemoryView(T *start, AuUInt length) // WARNING: length != count
|
||||
// where T = whogivesafuck
|
||||
{
|
||||
this->ptr = start;
|
||||
this->length = length;
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
template<typename T>
|
||||
constexpr AuMemoryView<Readonly_b>::AuMemoryView(T *start, AuUInt length, AuAUInt32 *pInUseCounter, void *pCallbackHandle, void (*pfCallbackOnZero)(void *)) // WARNING: length != count
|
||||
{
|
||||
this->ptr = start;
|
||||
this->length = length;
|
||||
this->controlBlock.pInUseCounter = pInUseCounter;
|
||||
AuAtomicAdd(pInUseCounter, 1u);
|
||||
this->controlBlock.pCallbackHandle = pCallbackHandle;
|
||||
this->controlBlock.pfCallbackOnZero = pfCallbackOnZero;
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
template<typename T>
|
||||
constexpr AuMemoryView<Readonly_b>::AuMemoryView(T *start, AuUInt length, AuAUInt32 *pInUseCounter, const AuSPtr<void> &pRAIIOwner, void *pCallbackHandle, void (*pfCallbackOnZero)(void *)) // WARNING: length != count
|
||||
{
|
||||
this->ptr = start;
|
||||
this->length = length;
|
||||
this->controlBlock.pInUseCounter = pInUseCounter;
|
||||
AuAtomicAdd(pInUseCounter, 1u);
|
||||
this->controlBlock.pPinner = pRAIIOwner;
|
||||
this->controlBlock.pCallbackHandle = pCallbackHandle;
|
||||
this->controlBlock.pfCallbackOnZero = pfCallbackOnZero;
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
template<typename T>
|
||||
AuMemoryView<Readonly_b>::AuMemoryView(T *start, AuUInt length, const AuMemoryViewControlBlock ©Block)
|
||||
{
|
||||
this->ptr = start;
|
||||
this->length = length;
|
||||
this->controlBlock = copyBlock;
|
||||
if (this->controlBlock.pInUseCounter)
|
||||
{
|
||||
AuAtomicAdd(this->controlBlock.pInUseCounter, 1u);
|
||||
}
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
AuMemoryView<Readonly_b> &AuMemoryView<Readonly_b>::operator =(AuMemoryView &&view)
|
||||
{
|
||||
this->ptr = view.ptr;
|
||||
this->length = view.length;
|
||||
this->controlBlock.pInUseCounter = view.controlBlock.pInUseCounter;
|
||||
view.controlBlock.pInUseCounter = nullptr;
|
||||
this->controlBlock.pPinner = AuMove(view.controlBlock.pPinner);
|
||||
this->controlBlock.pfCallbackOnZero = view.controlBlock.pfCallbackOnZero;
|
||||
this->controlBlock.pCallbackHandle = view.controlBlock.pCallbackHandle;
|
||||
view.controlBlock.pfCallbackOnZero = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
AuMemoryView<Readonly_b> &AuMemoryView<Readonly_b>::operator =(const AuMemoryView &view)
|
||||
{
|
||||
this->ptr = view.ptr;
|
||||
this->length = view.length;
|
||||
this->controlBlock.pInUseCounter = view.controlBlock.pInUseCounter;
|
||||
if (this->controlBlock.pInUseCounter)
|
||||
{
|
||||
AuAtomicAdd(this->controlBlock.pInUseCounter, 1u);
|
||||
}
|
||||
this->controlBlock.pPinner = view.controlBlock.pPinner;
|
||||
this->controlBlock.pfCallbackOnZero = view.controlBlock.pfCallbackOnZero;
|
||||
this->controlBlock.pCallbackHandle = view.controlBlock.pCallbackHandle;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
constexpr AuUInt AuMemoryView<Readonly_b>::ToPointerValue() const
|
||||
{
|
||||
return this->uPtr;
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
constexpr AuUInt AuMemoryView<Readonly_b>::ToLength() const
|
||||
{
|
||||
return this->length;
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
constexpr AuUInt AuMemoryView<Readonly_b>::Length() const
|
||||
{
|
||||
return this->length;
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
constexpr AuUInt AuMemoryView<Readonly_b>::ToSize() const
|
||||
{
|
||||
return this->length;
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
constexpr AuUInt AuMemoryView<Readonly_b>::Size() const
|
||||
{
|
||||
return this->length;
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
template<typename T>
|
||||
constexpr AuUInt AuMemoryView<Readonly_b>::ToCount() const
|
||||
{
|
||||
return this->length / sizeof(T);
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
template<typename T>
|
||||
constexpr AuUInt AuMemoryView<Readonly_b>::Count() const
|
||||
{
|
||||
return this->length / sizeof(T);
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
template<typename T>
|
||||
AuConditional_t<Readonly_b, const T *, T *> AuMemoryView<Readonly_b>::Begin() const
|
||||
{
|
||||
return reinterpret_cast<AuConditional_t<Readonly_b, const T *, T *>>(ptr);
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
template<typename T>
|
||||
AuConditional_t<Readonly_b, const T*, T*> AuMemoryView<Readonly_b>::End() const
|
||||
{
|
||||
return Begin<T>() + ToCount<T>();
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
constexpr bool AuMemoryView<Readonly_b>::HasMemory() const
|
||||
{
|
||||
return this->ptr && this->length;
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
constexpr AuMemoryView<Readonly_b>::operator bool() const
|
||||
{
|
||||
return this->HasMemory();
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
constexpr AuMemoryView<Readonly_b>::U8_t AuMemoryView<Readonly_b>::ToPointer() const
|
||||
{
|
||||
return this->ptrU8;
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
constexpr AuMemoryView<Readonly_b>::U8_t AuMemoryView<Readonly_b>::begin() const
|
||||
{
|
||||
return this->ptrU8;
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
constexpr AuMemoryView<Readonly_b>::U8_t AuMemoryView<Readonly_b>::end() const
|
||||
{
|
||||
return this->ptrU8 + this->length;
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
constexpr AuMemoryView<Readonly_b>::U8_t AuMemoryView<Readonly_b>::Begin() const
|
||||
{
|
||||
return this->ptrU8;
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
constexpr AuMemoryView<Readonly_b>::U8_t AuMemoryView<Readonly_b>::End() const
|
||||
{
|
||||
return this->ptrU8 + this->length;
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
constexpr AuUInt AuMemoryView<Readonly_b>::size() const
|
||||
{
|
||||
return this->length;
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
AuMemoryView<Readonly_b> AuMemoryView<Readonly_b>::AtOffset(AuUInt uOffset) const
|
||||
{
|
||||
if (uOffset < this->uLength)
|
||||
{
|
||||
return AuMemoryView((AuUInt8 *)this->pBase + uOffset,
|
||||
this->uLength - uOffset,
|
||||
this->controlBlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
AuMemoryView<Readonly_b> AuMemoryView<Readonly_b>::Take(AuUInt uLength) const
|
||||
{
|
||||
if (uLength <= this->uLength)
|
||||
{
|
||||
return AuMemoryView((AuUInt8 *)this->pBase,
|
||||
uLength,
|
||||
this->controlBlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
AuMemoryView<Readonly_b> AuMemoryView<Readonly_b>::Clone() const
|
||||
{
|
||||
auto uLength = this->uLength;
|
||||
auto pData = AuMakeSharedArray<AuUInt8>(uLength);
|
||||
if (!pData)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
AuMemcpy(pData.get(), this->pBase, uLength);
|
||||
return AuMemoryView(AuMemoryView(pData.get(), uLength), pData);
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
AuMemoryView<Readonly_b> AuMemoryView<Readonly_b>::Clone(AuHeap *pHeap, AuUInt32 uAlignment) const
|
||||
{
|
||||
auto uLength = this->uLength;
|
||||
auto pData = __audetail::AllocateArray(pHeap, uLength, uAlignment);
|
||||
if (!pData)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
AuMemcpy(pData.get(), this->pBase, uLength);
|
||||
return AuMemoryView(AuMemoryView(pData.get(), uLength), pData);
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
bool AuMemoryView<Readonly_b>::TryCloneSelf(bool bResetOnFailure)
|
||||
{
|
||||
auto replacement = Clone();
|
||||
if (!replacement)
|
||||
{
|
||||
if (bResetOnFailure)
|
||||
{
|
||||
AuResetMember(*this);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
AuResetMember(*this, replacement);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
bool AuMemoryView<Readonly_b>::HasControlBlock() const
|
||||
{
|
||||
return this->controlBlock.pInUseCounter ||
|
||||
this->controlBlock.pPinner ||
|
||||
this->controlBlock.pfCallbackOnZero;
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
AuSPtr<AuMemoryView<Readonly_b>> AuMemoryView<Readonly_b>::TryPromoteToSharedView(AuSPtr<void> pParent) const
|
||||
{
|
||||
#if 0
|
||||
bool bHasControlBlock = this->HasControlBlock();
|
||||
|
||||
if (bHasControlBlock)
|
||||
{
|
||||
if (pParent)
|
||||
{
|
||||
return AuMakeShared<AuMemoryView>(*this, pParent);
|
||||
}
|
||||
else
|
||||
{
|
||||
return AuMakeShared<AuMemoryView>(*this);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pParent)
|
||||
{
|
||||
return AuMakeShared<AuMemoryView>(*this, pParent);
|
||||
}
|
||||
else
|
||||
{
|
||||
return {};
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (pParent)
|
||||
{
|
||||
return AuMakeShared<AuMemoryView>(*this, pParent);
|
||||
}
|
||||
|
||||
if (this->HasControlBlock())
|
||||
{
|
||||
return AuMakeShared<AuMemoryView>(*this);
|
||||
}
|
||||
|
||||
return {};
|
||||
#endif
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
AuSPtr<AuMemoryView<Readonly_b>> AuMemoryView<Readonly_b>::TryPromoteToSharedViewNoParentNesting(AuSPtr<void> pParent) const
|
||||
{
|
||||
if (this->HasControlBlock())
|
||||
{
|
||||
return AuMakeShared<AuMemoryView>(*this);
|
||||
}
|
||||
|
||||
if (pParent)
|
||||
{
|
||||
return AuMakeShared<AuMemoryView>(*this, pParent);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
bool AuMemoryView<Readonly_b>::TryDemoteFromSharedView(const AuSPtr<AuMemoryView<Readonly_b>> &pCopy)
|
||||
{
|
||||
if (pCopy && pCopy->HasControlBlock())
|
||||
{
|
||||
AuResetMember(*this, AuConstReference(*pCopy.get()));
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
bool AuMemoryView<Readonly_b>::TryDemoteFromReference(const AuMemoryView &refCopy)
|
||||
{
|
||||
if (refCopy.HasControlBlock())
|
||||
{
|
||||
AuResetMember(*this, refCopy);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
void AuMemoryView<Readonly_b>::DemoteFromSharedView(const AuSPtr<AuMemoryView<Readonly_b>> &pCopy)
|
||||
{
|
||||
if (!pCopy)
|
||||
{
|
||||
AuResetMember(*this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pCopy->HasControlBlock())
|
||||
{
|
||||
AuResetMember(*this, AuConstReference(*pCopy.get()));
|
||||
}
|
||||
else
|
||||
{
|
||||
AuResetMember(*this, AuConstReference(*pCopy.get()), pCopy);
|
||||
}
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
AuSPtr<void> AuMemoryView<Readonly_b>::ToSharedControlBlock(bool *pbFailed)
|
||||
{
|
||||
if (pbFailed)
|
||||
{
|
||||
*pbFailed = false;
|
||||
}
|
||||
|
||||
if (this->controlBlock.pInUseCounter)
|
||||
{
|
||||
auto pShared = AuMakeShared<AuMemoryViewControlBlock>();
|
||||
if (!pShared)
|
||||
{
|
||||
if (pbFailed)
|
||||
{
|
||||
*pbFailed = true;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
AuAtomicAdd(&this->controlBlock.pInUseCounter, 1u);
|
||||
pShared->pInUseCounter = this->controlBlock.pInUseCounter;
|
||||
pShared->pPinner = this->controlBlock.pPinner;
|
||||
pShared->pfCallbackOnZero = this->controlBlock.pfCallbackOnZero;
|
||||
pShared->pCallbackHandle = this->controlBlock.pCallbackHandle;
|
||||
return pShared;
|
||||
}
|
||||
|
||||
if (this->controlBlock.pPinner)
|
||||
{
|
||||
return this->controlBlock.pPinner;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
template<bool Readonly_b>
|
||||
AuUInt AuMemoryView<Readonly_b>::CopyInto(const AuMemoryView<false> &write) const
|
||||
{
|
||||
auto uLength = AuMin(this->uLength, write.uLength);
|
||||
AuMemcpy(write.pBase, this->pBase, uLength);
|
||||
return uLength;
|
||||
}
|
||||
|
263
Include/auROXTL/MemoryModel/auPMRAllocator.hpp
Executable file
263
Include/auROXTL/MemoryModel/auPMRAllocator.hpp
Executable file
@ -0,0 +1,263 @@
|
||||
/***
|
||||
Copyright (C) 2023-2024 Jamie Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: auPMRAllocator.hpp
|
||||
Date: 2023-12-22
|
||||
Author: Reece
|
||||
Note: Moved from Runtime
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
template <class T>
|
||||
struct AuPMRAllocator
|
||||
{
|
||||
using value_type = T;
|
||||
|
||||
using size_type = size_t;
|
||||
using difference_type = ptrdiff_t;
|
||||
|
||||
using propagate_on_container_move_assignment = AuTrueType;
|
||||
using propagate_on_container_copy_assignment = AuTrueType;
|
||||
using is_always_equal = AuFalseType;
|
||||
|
||||
#if defined(AU_LANG_CPP_17)
|
||||
using pointer = T *;
|
||||
using const_pointer = const T *;
|
||||
|
||||
using reference = T &;
|
||||
using const_reference = const T &;
|
||||
|
||||
template <class Z>
|
||||
struct rebind
|
||||
{
|
||||
using other = AuPMRAllocator<Z>;
|
||||
};
|
||||
|
||||
T *address(T &val) const noexcept
|
||||
{
|
||||
return std::addressof(val);
|
||||
}
|
||||
|
||||
const T *address(const T &val) const noexcept
|
||||
{
|
||||
return std::addressof(val);
|
||||
}
|
||||
#endif
|
||||
|
||||
inline AuPMRAllocator(AuSSPtr<AuHeap> pHeap) :
|
||||
#if defined(AU_NO_COMPRESS_CPPHEAP_WRAPPER)
|
||||
spHeap(pHeap),
|
||||
pHeap(pHeap.get())
|
||||
#else
|
||||
spHeap(pHeap)
|
||||
#endif
|
||||
{ }
|
||||
|
||||
inline AuPMRAllocator(AuHeap *pHeap, AuSSPtr<void> pThat = {}) :
|
||||
#if defined(AU_NO_COMPRESS_CPPHEAP_WRAPPER)
|
||||
spHeap(pThat),
|
||||
pHeap(pHeap)
|
||||
#else
|
||||
spHeap(AuSharedPointerFromShared(pHeap, pThat))
|
||||
#endif
|
||||
{ }
|
||||
|
||||
template <class B>
|
||||
inline AuPMRAllocator(const AuPMRAllocator<B> &that) :
|
||||
spHeap(that.spHeap)
|
||||
#if defined(AU_NO_COMPRESS_CPPHEAP_WRAPPER)
|
||||
,pHeap(that.pHeap)
|
||||
#endif
|
||||
{ }
|
||||
|
||||
inline AuPMRAllocator(const AuPMRAllocator &that) :
|
||||
spHeap(that.spHeap)
|
||||
#if defined(AU_NO_COMPRESS_CPPHEAP_WRAPPER)
|
||||
,pHeap(that.pHeap)
|
||||
#endif
|
||||
{ }
|
||||
|
||||
inline AuPMRAllocator(AuPMRAllocator &&that) :
|
||||
spHeap(that.spHeap)
|
||||
#if defined(AU_NO_COMPRESS_CPPHEAP_WRAPPER)
|
||||
,pHeap(that.pHeap)
|
||||
#endif
|
||||
{ }
|
||||
|
||||
|
||||
AU_DEF(AuPMRAllocator)
|
||||
AU_OPERATOR_COPY_MOVE(AuPMRAllocator)
|
||||
|
||||
void *allocate_bytes(std::size_t nbytes,
|
||||
std::size_t alignment = alignof(std::max_align_t))
|
||||
{
|
||||
if (auto pRet = this->GetHeapRaw()->FAlloc(nbytes, alignment))
|
||||
{
|
||||
return pRet;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
}
|
||||
|
||||
void deallocate_bytes(void *p,
|
||||
std::size_t nbytes,
|
||||
std::size_t alignment = alignof(std::max_align_t)) noexcept
|
||||
{
|
||||
return this->GetHeapRaw()->Free(p);
|
||||
}
|
||||
|
||||
#if defined(AU_LANG_CPP_23_)
|
||||
std::allocation_result<T *> allocate_at_least(const size_t count)
|
||||
{
|
||||
auto pThat = this->allocate(count);
|
||||
return { (T *)pThat, this->GetHeapRaw()->GetChunkSize(pThat) / sizeof(T) };
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class U, class... Args >
|
||||
void construct(U *p, Args&&... args)
|
||||
{
|
||||
new ((void *)p) U(AuForward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <class U, class... Args >
|
||||
void construct_at(U *p, Args&&... args)
|
||||
{
|
||||
new ((void *)p) U(AuForward<Args>(args)...);
|
||||
}
|
||||
|
||||
void deallocate(const T *pType,
|
||||
const size_t count) noexcept
|
||||
{
|
||||
this->deallocate_bytes((void *)pType, 0, 0);
|
||||
}
|
||||
|
||||
AU_ALLOC T *allocate(const size_t count)
|
||||
{
|
||||
if (!count)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return (T *)this->allocate_bytes(count * sizeof(T), alignof(T));
|
||||
}
|
||||
|
||||
template <class U>
|
||||
U *allocate_object(std::size_t n = 1)
|
||||
{
|
||||
return (U *)this->allocate_bytes(sizeof(U) * n, alignof(U));
|
||||
}
|
||||
|
||||
template <class U>
|
||||
void deallocate_object(U *p, std::size_t n = 1)
|
||||
{
|
||||
this->deallocate_bytes(p, 0, 0);
|
||||
}
|
||||
|
||||
template <class U, class... CtorArgs>
|
||||
U *new_object(CtorArgs&&... args)
|
||||
{
|
||||
U *p = this->allocate_object<U>();
|
||||
try
|
||||
{
|
||||
this->construct(p, AuForward<CtorArgs>(args)...);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
this->deallocate_object(p);
|
||||
throw;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
template <class U>
|
||||
void delete_object(U *p)
|
||||
{
|
||||
if constexpr (AuIsClass_v<U> &&
|
||||
!AuIsTriviallyDestructible_v<U>)
|
||||
{
|
||||
p->~U();
|
||||
}
|
||||
|
||||
this->deallocate_object(p);
|
||||
}
|
||||
|
||||
bool IsInitialized() const
|
||||
{
|
||||
#if defined(AU_NO_COMPRESS_CPPHEAP_WRAPPER)
|
||||
return bool(this->pHeap);
|
||||
#else
|
||||
return bool(this->spHeap);
|
||||
#endif
|
||||
}
|
||||
|
||||
AuSSPtr<AuHeap> GetHeap() const
|
||||
{
|
||||
#if defined(AU_NO_COMPRESS_CPPHEAP_WRAPPER)
|
||||
return AuSharedPointerFromShared(this->pHeap, this->spHeap);
|
||||
#else
|
||||
return this->spHeap;
|
||||
#endif
|
||||
}
|
||||
|
||||
AuHeap *GetHeapRaw() const
|
||||
{
|
||||
AuHeap *pRet {};
|
||||
|
||||
#if defined(AU_NO_COMPRESS_CPPHEAP_WRAPPER)
|
||||
pRet = this->pHeap;
|
||||
#else
|
||||
pRet = this->spHeap.get();
|
||||
#endif
|
||||
|
||||
if (pRet)
|
||||
{
|
||||
return pRet;
|
||||
}
|
||||
|
||||
#if defined(AU_NO_COMPRESS_CPPHEAP_WRAPPER)
|
||||
return this->pHeap = __audetail::gDefaultDiscontiguousHeap;
|
||||
#else
|
||||
return (this->spHeap = AuUnsafeRaiiToShared(__audetail::gDefaultDiscontiguousHeap)).get();
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class Z>
|
||||
bool operator==(const AuPMRAllocator<Z> &rhs) noexcept
|
||||
{
|
||||
return this->GetHeapRaw() == rhs.GetHeapRaw();
|
||||
}
|
||||
|
||||
template <class Z>
|
||||
bool operator!=(const AuPMRAllocator<Z> &rhs) noexcept
|
||||
{
|
||||
return this->GetHeapRaw() == rhs.GetHeapRaw();
|
||||
}
|
||||
|
||||
private:
|
||||
#if defined(AU_NO_COMPRESS_CPPHEAP_WRAPPER)
|
||||
mutable AuSSPtr<void> spHeap;
|
||||
mutable AuHeap *pHeap {};
|
||||
#else
|
||||
mutable AuSSPtr<AuHeap> spHeap;
|
||||
#endif
|
||||
|
||||
template <typename Z>
|
||||
friend struct AuPMRAllocator;
|
||||
};
|
||||
|
||||
template <class T, class Z>
|
||||
inline bool operator==(const AuPMRAllocator<T> &lhs,
|
||||
const AuPMRAllocator<Z> &rhs) noexcept
|
||||
{
|
||||
return lhs.GetHeapRaw() == rhs.GetHeapRaw();
|
||||
}
|
||||
|
||||
template <class T, class Z>
|
||||
inline bool operator!=(const AuPMRAllocator<T> &lhs,
|
||||
const AuPMRAllocator<Z> &rhs) noexcept
|
||||
{
|
||||
return lhs.GetHeapRaw() != rhs.GetHeapRaw();
|
||||
}
|
@ -7,14 +7,8 @@
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
namespace Aurora::Memory
|
||||
{
|
||||
struct Heap;
|
||||
}
|
||||
template <typename T>
|
||||
bool AuSetAllocator(T &that, AuHeap *pHeap);
|
||||
|
||||
template <typename T>
|
||||
static bool AuSetAllocator(T &that, Aurora::Memory::Heap *pHeap);
|
||||
|
||||
template <typename T>
|
||||
static bool AuSetAllocator(T &that, const AuSPtr<Aurora::Memory::Heap> &pHeap);
|
||||
|
||||
bool AuSetAllocator(T &that, const AuSPtr<AuHeap> &pHeap);
|
@ -12,7 +12,7 @@ namespace __audetail
|
||||
template <class T>
|
||||
struct AuHasSetAllocatorRawVoid
|
||||
{
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<void (C:: *)(Aurora::Memory::Heap *)>(&C::SetAllocator)));
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<void (C:: *)(AuHeap *)>(&C::SetAllocator)));
|
||||
template <class C> static constexpr AuFalseType Test(...);
|
||||
using type = decltype(Test<T>(0));
|
||||
};
|
||||
@ -20,14 +20,14 @@ namespace __audetail
|
||||
template <class T>
|
||||
struct AuHasSetAllocatorRawBool
|
||||
{
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<bool (C:: *)(Aurora::Memory::Heap *)>(&C::SetAllocator)));
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<bool (C:: *)(AuHeap *)>(&C::SetAllocator)));
|
||||
template <class C> static constexpr AuFalseType Test(...);
|
||||
using type = decltype(Test<T>(0));
|
||||
};
|
||||
template <class T>
|
||||
struct AuHasSetHeapRawVoid
|
||||
{
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<void (C:: *)(Aurora::Memory::Heap *)>(&C::SetHeap)));
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<void (C:: *)(AuHeap *)>(&C::SetHeap)));
|
||||
template <class C> static constexpr AuFalseType Test(...);
|
||||
using type = decltype(Test<T>(0));
|
||||
};
|
||||
@ -35,15 +35,15 @@ namespace __audetail
|
||||
template <class T>
|
||||
struct AuHasSetHeapRawBool
|
||||
{
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<bool (C:: *)(Aurora::Memory::Heap *)>(&C::SetHeap)));
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<bool (C:: *)(AuHeap *)>(&C::SetHeap)));
|
||||
template <class C> static constexpr AuFalseType Test(...);
|
||||
using type = decltype(Test<T>(0));
|
||||
};
|
||||
template <class T>
|
||||
struct AuHasSetAllocatorSVoid
|
||||
{
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<void (C:: *)(AuSPtr<Aurora::Memory::Heap>)>(&C::SetAllocator)));
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<void (C:: *)(const AuSPtr<Aurora::Memory::Heap> &)>(&C::SetAllocator)));
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<void (C:: *)(AuSPtr<AuHeap>)>(&C::SetAllocator)));
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<void (C:: *)(const AuSPtr<AuHeap> &)>(&C::SetAllocator)));
|
||||
template <class C> static constexpr AuFalseType Test(...);
|
||||
using type = decltype(Test<T>(0));
|
||||
};
|
||||
@ -51,8 +51,8 @@ namespace __audetail
|
||||
template <class T>
|
||||
struct AuHasSetAllocatorSBool
|
||||
{
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<bool (C:: *)(AuSPtr<Aurora::Memory::Heap>)>(&C::SetAllocator)));
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<bool (C:: *)(const AuSPtr<Aurora::Memory::Heap> &)>(&C::SetAllocator)));
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<bool (C:: *)(AuSPtr<AuHeap>)>(&C::SetAllocator)));
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<bool (C:: *)(const AuSPtr<AuHeap> &)>(&C::SetAllocator)));
|
||||
template <class C> static constexpr AuFalseType Test(...);
|
||||
using type = decltype(Test<T>(0));
|
||||
};
|
||||
@ -60,8 +60,8 @@ namespace __audetail
|
||||
template <class T>
|
||||
struct AuHasSetHeapSVoid
|
||||
{
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<void (C:: *)(AuSPtr<Aurora::Memory::Heap>)>(&C::SetHeap)));
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<void (C:: *)(const AuSPtr<Aurora::Memory::Heap> &)>(&C::SetHeap)));
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<void (C:: *)(AuSPtr<AuHeap>)>(&C::SetHeap)));
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<void (C:: *)(const AuSPtr<AuHeap> &)>(&C::SetHeap)));
|
||||
template <class C> static constexpr AuFalseType Test(...);
|
||||
using type = decltype(Test<T>(0));
|
||||
};
|
||||
@ -69,8 +69,8 @@ namespace __audetail
|
||||
template <class T>
|
||||
struct AuHasSetHeapSBool
|
||||
{
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<bool (C:: *)(AuSPtr<Aurora::Memory::Heap>)>(&C::SetHeap)));
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<bool (C:: *)(const AuSPtr<Aurora::Memory::Heap> &)>(&C::SetHeap)));
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<bool (C:: *)(AuSPtr<AuHeap>)>(&C::SetHeap)));
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<bool (C:: *)(const AuSPtr<AuHeap> &)>(&C::SetHeap)));
|
||||
template <class C> static constexpr AuFalseType Test(...);
|
||||
using type = decltype(Test<T>(0));
|
||||
};
|
||||
@ -78,8 +78,8 @@ namespace __audetail
|
||||
template <class T>
|
||||
struct AuHasSetHeapSharedSVoid
|
||||
{
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<void (C:: *)(AuSPtr<Aurora::Memory::Heap>)>(&C::SetHeapShared)));
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<void (C:: *)(const AuSPtr<Aurora::Memory::Heap> &)>(&C::SetHeapShared)));
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<void (C:: *)(AuSPtr<AuHeap>)>(&C::SetHeapShared)));
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<void (C:: *)(const AuSPtr<AuHeap> &)>(&C::SetHeapShared)));
|
||||
template <class C> static constexpr AuFalseType Test(...);
|
||||
using type = decltype(Test<T>(0));
|
||||
};
|
||||
@ -87,8 +87,8 @@ namespace __audetail
|
||||
template <class T>
|
||||
struct AuHasSetHeapSharedSBool
|
||||
{
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<bool (C:: *)(AuSPtr<Aurora::Memory::Heap>)>(&C::SetHeapShared)));
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<bool (C:: *)(const AuSPtr<Aurora::Memory::Heap> &)>(&C::SetHeapShared)));
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<bool (C:: *)(AuSPtr<AuHeap>)>(&C::SetHeapShared)));
|
||||
template <class C> static constexpr AuTrueType Test(decltype(static_cast<bool (C:: *)(const AuSPtr<AuHeap> &)>(&C::SetHeapShared)));
|
||||
template <class C> static constexpr AuFalseType Test(...);
|
||||
using type = decltype(Test<T>(0));
|
||||
};
|
||||
@ -136,7 +136,7 @@ namespace __audetail
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static bool AuSetAllocator(T &that, Aurora::Memory::Heap *pHeap)
|
||||
bool AuSetAllocator(T &that, AuHeap *pHeap)
|
||||
{
|
||||
if (!pHeap)
|
||||
{
|
||||
@ -335,7 +335,7 @@ static bool AuSetAllocator(T &that, Aurora::Memory::Heap *pHeap)
|
||||
|
||||
|
||||
template <typename T>
|
||||
static bool AuSetAllocator(T &that, const AuSPtr<Aurora::Memory::Heap> &pHeap)
|
||||
bool AuSetAllocator(T &that, const AuSPtr<AuHeap> &pHeap)
|
||||
{
|
||||
if (!pHeap)
|
||||
{
|
||||
|
71
Include/auROXTL/MemoryModel/auUniquePointer.hpp
Executable file
71
Include/auROXTL/MemoryModel/auUniquePointer.hpp
Executable file
@ -0,0 +1,71 @@
|
||||
/***
|
||||
Copyright (C) 2024 Jamie Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: auUniquePointer.hpp
|
||||
Date: 2024-09-13
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
template <typename T, typename Deleter_t = void(*)(T *)>
|
||||
struct AuUniquePointer
|
||||
{
|
||||
AuUniquePointer();
|
||||
AuUniquePointer(std::nullptr_t);
|
||||
explicit AuUniquePointer(T *pThat);
|
||||
explicit AuUniquePointer(T *pThat, const Deleter_t &deleter);
|
||||
explicit AuUniquePointer(T *pThat, Deleter_t &&deleter);
|
||||
|
||||
AuUniquePointer(AuUniquePointer &&that) noexcept;
|
||||
|
||||
template <typename U>
|
||||
AuUniquePointer(AuUniquePointer<U> &&that);
|
||||
|
||||
~AuUniquePointer();
|
||||
|
||||
AuUniquePointer &operator=(std::nullptr_t);
|
||||
|
||||
template <typename U>
|
||||
AuUniquePointer &operator=(AuUniquePointer<U> &&that) noexcept;
|
||||
AuUniquePointer &operator=(AuUniquePointer &&that) noexcept;
|
||||
|
||||
AuUniquePointer(AuUniquePointer const&) = delete;
|
||||
AuUniquePointer &operator=(AuUniquePointer const&) = delete;
|
||||
|
||||
T *operator->() const;
|
||||
T &operator*() const;
|
||||
|
||||
T *get() const;
|
||||
explicit operator bool() const;
|
||||
|
||||
T *Release() noexcept;
|
||||
T* release() noexcept;
|
||||
|
||||
void Swap(AuUniquePointer &that) noexcept;
|
||||
void swap(AuUniquePointer &that) noexcept;
|
||||
|
||||
void Reset();
|
||||
void reset();
|
||||
|
||||
const Deleter_t &GetDeleter() const noexcept;
|
||||
const Deleter_t &get_deleter() const noexcept;
|
||||
|
||||
private:
|
||||
T *pThat {};
|
||||
Deleter_t deleter {};
|
||||
};
|
||||
|
||||
template <typename T, typename Deleter_t>
|
||||
void Swap(AuUniquePointer<T, Deleter_t> &lhs, AuUniquePointer<T, Deleter_t> &rhs)
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <typename T, typename Deleter_t>
|
||||
void swap(AuUniquePointer<T, Deleter_t> &lhs, AuUniquePointer<T, Deleter_t> &rhs)
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
}
|
187
Include/auROXTL/MemoryModel/auUniquePointer.ipp
Executable file
187
Include/auROXTL/MemoryModel/auUniquePointer.ipp
Executable file
@ -0,0 +1,187 @@
|
||||
/***
|
||||
Copyright (C) 2024 Jamie Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: auUniquePointer.ipp
|
||||
Date: 2024-09-13
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
template <typename T, typename Deleter_t>
|
||||
AuUniquePointer<T, Deleter_t>::AuUniquePointer()
|
||||
{}
|
||||
|
||||
template <typename T, typename Deleter_t>
|
||||
AuUniquePointer<T, Deleter_t>::AuUniquePointer(std::nullptr_t)
|
||||
{}
|
||||
|
||||
template <typename T, typename Deleter_t>
|
||||
AuUniquePointer<T, Deleter_t>::AuUniquePointer(T *pThat) :
|
||||
pThat(pThat)
|
||||
{}
|
||||
|
||||
template <typename T, typename Deleter_t>
|
||||
AuUniquePointer<T, Deleter_t>::AuUniquePointer(T *pThat, const Deleter_t &deleter) :
|
||||
pThat(pThat),
|
||||
deleter(deleter)
|
||||
{}
|
||||
|
||||
template <typename T, typename Deleter_t>
|
||||
AuUniquePointer<T, Deleter_t>::AuUniquePointer(T *pThat, Deleter_t &&deleter) :
|
||||
pThat(pThat),
|
||||
deleter(AuMove(deleter))
|
||||
{}
|
||||
|
||||
template <typename T, typename Deleter_t>
|
||||
AuUniquePointer<T, Deleter_t>::AuUniquePointer(AuUniquePointer &&that) noexcept
|
||||
{
|
||||
that.Swap(*this);
|
||||
}
|
||||
|
||||
template <typename T, typename Deleter_t>
|
||||
template <typename U>
|
||||
AuUniquePointer<T, Deleter_t>::AuUniquePointer(AuUniquePointer<U> &&that)
|
||||
{
|
||||
AuUniquePointer<T> temp(that.Release(), that.GetDeleter());
|
||||
temp.Swap(*this);
|
||||
}
|
||||
|
||||
template <typename T, typename Deleter_t>
|
||||
AuUniquePointer<T, Deleter_t>::~AuUniquePointer()
|
||||
{
|
||||
if (!this->pThat)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if constexpr (AuIsFunction_v<Deleter_t>)
|
||||
{
|
||||
if (this->deleter)
|
||||
{
|
||||
this->deleter(this->pThat);
|
||||
}
|
||||
else
|
||||
{
|
||||
AuDefaultDeleter<T>()(this->pThat);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->deleter(this->pThat);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename Deleter_t>
|
||||
AuUniquePointer<T, Deleter_t> &AuUniquePointer<T, Deleter_t>::operator=(std::nullptr_t)
|
||||
{
|
||||
this->Reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, typename Deleter_t>
|
||||
template <typename U>
|
||||
AuUniquePointer<T, Deleter_t> &AuUniquePointer<T, Deleter_t>::operator=(AuUniquePointer<U> &&that) noexcept
|
||||
{
|
||||
AuUniquePointer<T> temp(that.Release(), that.GetDeleter());
|
||||
temp.Swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, typename Deleter_t>
|
||||
AuUniquePointer<T, Deleter_t> &AuUniquePointer<T, Deleter_t>::operator=(AuUniquePointer<T, Deleter_t> &&that) noexcept
|
||||
{
|
||||
that.Swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, typename Deleter_t>
|
||||
T *AuUniquePointer<T, Deleter_t>::operator->() const
|
||||
{
|
||||
return this->pThat;
|
||||
}
|
||||
|
||||
template <typename T, typename Deleter_t>
|
||||
T &AuUniquePointer<T, Deleter_t>::operator*() const
|
||||
{
|
||||
return *this->pThat;
|
||||
}
|
||||
|
||||
template <typename T, typename Deleter_t>
|
||||
T *AuUniquePointer<T, Deleter_t>::get() const
|
||||
{
|
||||
return this->pThat;
|
||||
}
|
||||
|
||||
template <typename T, typename Deleter_t>
|
||||
AuUniquePointer<T, Deleter_t>::operator bool() const
|
||||
{
|
||||
return this->pThat;
|
||||
}
|
||||
|
||||
template <typename T, typename Deleter_t>
|
||||
T *AuUniquePointer<T, Deleter_t>::Release() noexcept
|
||||
{
|
||||
T *pRet {};
|
||||
AuSwap(pRet, this->pThat);
|
||||
return pRet;
|
||||
}
|
||||
|
||||
template <typename T, typename Deleter_t>
|
||||
T *AuUniquePointer<T, Deleter_t>::release() noexcept
|
||||
{
|
||||
return this->Release();
|
||||
}
|
||||
|
||||
template <typename T, typename Deleter_t>
|
||||
void AuUniquePointer<T, Deleter_t>::Swap(AuUniquePointer &that) noexcept
|
||||
{
|
||||
AuSwap(this->pThat, that.pThat);
|
||||
AuSwap(this->deleter, that.deleter);
|
||||
}
|
||||
|
||||
template <typename T, typename Deleter_t>
|
||||
void AuUniquePointer<T, Deleter_t>::swap(AuUniquePointer &that) noexcept
|
||||
{
|
||||
this->Swap(that);
|
||||
}
|
||||
|
||||
template <typename T, typename Deleter_t>
|
||||
void AuUniquePointer<T, Deleter_t>::Reset()
|
||||
{
|
||||
if (auto pThat = Release())
|
||||
{
|
||||
if constexpr (AuIsFunction_v<Deleter_t>)
|
||||
{
|
||||
if (this->deleter)
|
||||
{
|
||||
this->deleter(pThat);
|
||||
}
|
||||
else
|
||||
{
|
||||
AuDefaultDeleter<T>()(pThat);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->deleter(pThat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename Deleter_t>
|
||||
void AuUniquePointer<T, Deleter_t>::reset()
|
||||
{
|
||||
this->Reset();
|
||||
}
|
||||
|
||||
template <typename T, typename Deleter_t>
|
||||
const Deleter_t &AuUniquePointer<T, Deleter_t>::GetDeleter() const noexcept
|
||||
{
|
||||
return this->deleter;
|
||||
}
|
||||
|
||||
template <typename T, typename Deleter_t>
|
||||
const Deleter_t &AuUniquePointer<T, Deleter_t>::get_deleter() const noexcept
|
||||
{
|
||||
return this->GetDeleter();
|
||||
}
|
@ -172,7 +172,19 @@ using Type = Type ## SOO;
|
||||
AUROXTL_INTERFACE_SOO_HDR_EX2(vis, Type, extends, targetSize, (AU_NO_COPY_NO_MOVE(Type ## SOO)), ## __VA_ARGS__)
|
||||
|
||||
#define AUROXTL_INTERFACE_SOO_HDR(Type, extends, targetSize, ...) \
|
||||
AUROXTL_INTERFACE_SOO_HDR_EX(, Type, extends, targetSize, ## __VA_ARGS__)
|
||||
AUROXTL_INTERFACE_SOO_HDR_EX(, Type, extends, targetSize, ## __VA_ARGS__) \
|
||||
\
|
||||
template <class ... T> \
|
||||
extends ## Unique_t Type ## UniqueOnHeap(AuHeap *pHeap, T &&... args) \
|
||||
{ \
|
||||
return pHeap->NewClassUnique<Type>(AuForward<T>(args)...); \
|
||||
} \
|
||||
\
|
||||
template <class ... T> \
|
||||
extends ## Shared_t Type ## SharedOnHeap(AuHeap *pHeap, T &&... args) \
|
||||
{ \
|
||||
return pHeap->NewClass<Type>(AuForward<T>(args)...); \
|
||||
}
|
||||
|
||||
#define AUROXTL_INTERFACE_SOO_SRC_EX(vis, Type, FullType, ...) \
|
||||
vis Type ## SOO::Type ## SOO(AU_FOR_EACH_FIRST(_AUROXTL_INTERRFACE_SOO_EMITTER_0, _AUROXTL_INTERRFACE_SOO_EMITTER_1, ## __VA_ARGS__, (AuUInt32, uSize))) \
|
||||
|
@ -141,15 +141,33 @@ namespace Aurora::Memory
|
||||
#endif
|
||||
}
|
||||
|
||||
template < class Y, class Deleter >
|
||||
ExSharedPtr(AURORA_RUNTIME_AU_UNIQUE_PTR<Y, Deleter> &&r) : Base_t(AuMove(r))
|
||||
template <class Y, class Deleter>
|
||||
ExSharedPtr(AURORA_RUNTIME_AU_UNIQUE_PTR<Y, Deleter> &&r)
|
||||
{
|
||||
if constexpr (AuIsFunction_v<Deleter>)
|
||||
{
|
||||
if (r.get_deleter())
|
||||
{
|
||||
this->~ExSharedPtr();
|
||||
new (this) ExSharedPtr(r.release(), r.get_deleter());
|
||||
}
|
||||
else
|
||||
{
|
||||
this->~ExSharedPtr();
|
||||
new (this) ExSharedPtr(r.release());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->~ExSharedPtr();
|
||||
new (this) ExSharedPtr(r.release(), r.get_deleter());
|
||||
}
|
||||
|
||||
#if !defined(_AURORA_NULLEXPT_ENABLE_UB)
|
||||
_cache();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
template <class T_t, typename B_t>
|
||||
void swap(ExSharedPtr<T_t, B_t> &in)
|
||||
{
|
||||
|
@ -17,7 +17,7 @@ template <class T, typename Z, typename LessThan_t = AuHash::less<T>, class Allo
|
||||
using AuBST = AURORA_RUNTIME_AU_BST<T, Z, LessThan_t, Allocator_t>;
|
||||
|
||||
template <class T, typename Z, typename LessThan_t = AuHash::less<T>>
|
||||
using AuBSTOfHeap = AuBST<T, Z, LessThan_t, Aurora::Memory::PmrCppHeapWrapper<AuPair<const T, Z>>>;
|
||||
using AuBSTOfHeap = AuBST<T, Z, LessThan_t, AuPMRAllocator<AuPair<const T, Z>>>;
|
||||
|
||||
template<typename T>
|
||||
struct AuIsBST : AuFalseType
|
||||
|
@ -17,7 +17,7 @@ template <class T, class Z, class Hash_t = AuHash::hash<T>, class Equal_t = AuHa
|
||||
using AuHashMap = AURORA_RUNTIME_AU_HASH_MAP<T, Z, Hash_t, Equal_t, Allocator_t>;
|
||||
|
||||
template <class T, class Z, class Hash_t = AuHash::hash<T>, class Equal_t = AuHash::equal<T>>
|
||||
using AuHashMapOfHeap = AuHashMap<T, Z, Hash_t, Equal_t, Aurora::Memory::PmrCppHeapWrapper<AuPair<const T, Z>>>;
|
||||
using AuHashMapOfHeap = AuHashMap<T, Z, Hash_t, Equal_t, AuPMRAllocator<AuPair<const T, Z>>>;
|
||||
|
||||
template<typename T>
|
||||
struct AuIsHashMap : AuFalseType
|
||||
|
@ -26,4 +26,4 @@
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
using AuListOfHeap = AuList<T, Aurora::Memory::PmrCppHeapWrapper<T>>;
|
||||
using AuListOfHeap = AuList<T, AuPMRAllocator<T>>;
|
@ -12,6 +12,18 @@
|
||||
|
||||
#include "auTypes.hpp"
|
||||
|
||||
struct AuHeap;
|
||||
|
||||
namespace __audetail
|
||||
{
|
||||
extern AuHeap *gDefaultDiscontiguousHeap;
|
||||
}
|
||||
|
||||
namespace Aurora::Memory
|
||||
{
|
||||
struct ProxyHeap;
|
||||
}
|
||||
|
||||
#if !defined(AURORA_RUNTIME_AU_SHARED_PTR)
|
||||
#define AURORA_RUNTIME_AU_SHARED_PTR std::shared_ptr
|
||||
#endif
|
||||
@ -24,15 +36,19 @@ template <class T>
|
||||
using AuWPtr = AURORA_RUNTIME_AU_WEAK_PTR<T>;
|
||||
|
||||
#if !defined(AURORA_RUNTIME_AU_UNIQUE_PTR)
|
||||
#define AURORA_RUNTIME_AU_UNIQUE_PTR std::unique_ptr
|
||||
#define AURORA_RUNTIME_AU_UNIQUE_PTR AuUniquePointer
|
||||
#endif
|
||||
|
||||
#include <auROXTL/MemoryModel/auUniquePointer.hpp>
|
||||
#include "STLShims/ExtendStlLikeSharedPtr.hpp"
|
||||
|
||||
template <class T>
|
||||
using AuSPtr = typename Aurora::Memory::ExSharedPtr<T, AURORA_RUNTIME_AU_SHARED_PTR<T>>;
|
||||
|
||||
template <class T, typename Deleter_t>
|
||||
template <class T>
|
||||
using AuSSPtr = typename AURORA_RUNTIME_AU_SHARED_PTR<T>;
|
||||
|
||||
template <class T, typename Deleter_t = void(*)(T *)>
|
||||
using AuUPtr = AURORA_RUNTIME_AU_UNIQUE_PTR<T, Deleter_t>;
|
||||
|
||||
#if !defined(AU_AuEnableSharedFromThis)
|
||||
@ -99,13 +115,14 @@ static void auline AuSafeDelete(T *in)
|
||||
#define AURORA_RUNTIME_AU_DEFAULT_DELETER std::default_delete
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
struct AuPMRAllocator;
|
||||
|
||||
namespace Aurora::Memory
|
||||
{
|
||||
template <class T>
|
||||
struct CppHeapWrapper;
|
||||
|
||||
template <class T>
|
||||
struct PmrCppHeapWrapper;
|
||||
|
||||
#if defined(AURORA_ROXTL_ALLOCATORS_USE_STD)
|
||||
|
||||
@ -306,31 +323,7 @@ namespace Aurora::Memory
|
||||
#endif
|
||||
|
||||
template <class T, typename... Args>
|
||||
static auline AuSPtr<T> AuMakeShared(Args&&... args)
|
||||
{
|
||||
using Z = AuRemoveConst_t<T>;
|
||||
|
||||
try
|
||||
{
|
||||
#if defined(AURORA_ROXTL_ALLOCATORS_USE_STD)
|
||||
return AURORA_RUNTIME_MAKE_SHARED<T>(AuForward<Args>(args)...);
|
||||
#else
|
||||
auto pNext = Aurora::Memory::__FAlloc(sizeof(T), alignof(T));
|
||||
if (!pNext)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto pNextClass = (Z *)pNext;
|
||||
new (pNextClass) Z (AuForward<Args>(args)...);
|
||||
return std::shared_ptr<T>(pNextClass, Aurora::Memory::DefaultRuntimeDeleter<Z> {}, Aurora::Memory::SharedControlBlockAllocator<T> {});
|
||||
#endif
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
}
|
||||
AuSPtr<T> AuMakeShared(Args&&... args);
|
||||
|
||||
template <class T, typename... Args>
|
||||
static auline AuSPtr<T> AuMakeSharedPanic(Args&&... args)
|
||||
@ -418,17 +411,18 @@ namespace __audetail
|
||||
char a;
|
||||
};
|
||||
|
||||
inline AuSPtr<Dummy> gDummy;
|
||||
|
||||
inline AuSPtr<Dummy> GetDummyDeleter()
|
||||
{
|
||||
static AuSPtr<Dummy> d;
|
||||
if (!d)
|
||||
if (!gDummy)
|
||||
{
|
||||
#if defined(AURORA_COMPILER_MSVC)
|
||||
return d;
|
||||
return gDummy;
|
||||
#endif
|
||||
d = AuMakeShared<Dummy>();
|
||||
gDummy = AuMakeShared<Dummy>();
|
||||
}
|
||||
return d;
|
||||
return gDummy;
|
||||
}
|
||||
}
|
||||
|
||||
@ -459,3 +453,13 @@ inline constexpr bool operator!=(const Aurora::Memory::BaseAuroraRuntimeAllocato
|
||||
}
|
||||
|
||||
#include <auROXTL/MemoryModel/auSetAllocator.hpp>
|
||||
|
||||
#include <auROXTL/MemoryModel/auPMRAllocator.hpp>
|
||||
|
||||
#include <auROXTL/MemoryModel/auHeapStats.hpp>
|
||||
#include <auROXTL/MemoryModel/auHeap.hpp>
|
||||
#include <auROXTL/MemoryModel/auHeapAccessor.hpp>
|
||||
|
||||
#include <auROXTL/MemoryModel/auDummyHeap.hpp>
|
||||
|
||||
#include <auROXTL/MemoryModel/auMemoryAllocate.hpp>
|
@ -169,6 +169,8 @@ namespace __audetail
|
||||
#include <auROXTL/auVector.hpp>
|
||||
#include <auROXTL/auArray.hpp>
|
||||
#include <auROXTL/auArrayList.hpp>
|
||||
#include <auROXTL/auAtomic.hpp>
|
||||
#include <auROXTL/MemoryModel/auMemoryView.hpp>
|
||||
#include <auROXTL/auOptional.hpp>
|
||||
#include <auROXTL/auOptionalEx.hpp>
|
||||
#include <auROXTL/Iterators/auUTF8Iterator.hpp>
|
||||
|
@ -78,6 +78,10 @@ namespace __audetail
|
||||
|
||||
#include <auROXTL/MemoryModel/auSetAllocator.ipp>
|
||||
|
||||
#include <auROXTL/MemoryModel/auHeap.ipp>
|
||||
#include <auROXTL/MemoryModel/auUniquePointer.ipp>
|
||||
#include <auROXTL/MemoryModel/auMemoryView.ipp>
|
||||
|
||||
struct IAuNullDelegate
|
||||
{
|
||||
virtual void OnCall() = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user