Compare commits
2 Commits
21f35e0bea
...
a563ba611f
Author | SHA1 | Date | |
---|---|---|---|
a563ba611f | |||
c3a1ae1576 |
@ -69,11 +69,19 @@
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
using name ## Unique_t = AuUPtr<type>; \
|
||||
using name ## SmallUnique_t = AuUPtr<type, CppDeleter ## name>; \
|
||||
using name ## SUnique_t = AuUPtr<type, CppDeleter ## name>; \
|
||||
using name ## Unique_t = name ## SmallUnique_t; \
|
||||
using name ## GUnique_t = AuHUPOf_t<type>; \
|
||||
template <class ... T> \
|
||||
name ## Unique_t name ## Unique(T &&... args) \
|
||||
name ## GUnique_t name ## GenericUnique(T &&... args) \
|
||||
{ \
|
||||
return name ## Unique_t(name ## New(AuForward<T &&>(args)...), name ## Release); \
|
||||
return name ## GUnique_t(name ## New(AuForward<T &&>(args)...), name ## Release); \
|
||||
} \
|
||||
template <class ... T> \
|
||||
name ## SmallUnique_t name ## Unique(T &&... args) \
|
||||
{ \
|
||||
return name ## SmallUnique_t(name ## New(AuForward<T &&>(args)...)); \
|
||||
} \
|
||||
\
|
||||
using name ## Shared_t = AuSPtr<type>; \
|
||||
@ -290,4 +298,14 @@ struct AuStringOwnedException : AuStringException
|
||||
|
||||
#include "Objects/Objects.hpp"
|
||||
|
||||
#include "AU_USING.hpp"
|
||||
#include "AU_USING.hpp"
|
||||
|
||||
#if defined(AURORA_ROXTL_HAS_DELETER_ASSERT)
|
||||
#define _AUROXTL_DELETER_ASSERT(pThat, Type) \
|
||||
if (pThat.GetDeleter() != Type::Get()) \
|
||||
{ \
|
||||
AuMemoryPanic("Invalid Deleter"); \
|
||||
}
|
||||
#else
|
||||
#define _AUROXTL_DELETER_ASSERT(pThat, Type)
|
||||
#endif
|
26
Include/auROXTL/MemoryModel/AuHeapUniqueDeleterClass.hpp
Executable file
26
Include/auROXTL/MemoryModel/AuHeapUniqueDeleterClass.hpp
Executable file
@ -0,0 +1,26 @@
|
||||
/***
|
||||
Copyright (C) 2024 Jamie Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: AuHeapUniqueDeleterClass.hpp
|
||||
Date: 2024-09-22
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
template <typename Type, typename Expects = Type>
|
||||
struct AuHeapUniqueDeleterClass : AuHeapAccessor2
|
||||
{
|
||||
inline static auto Get()
|
||||
{
|
||||
return AuHeapAccessor2::Get<Type>();
|
||||
}
|
||||
|
||||
inline void operator()(Expects *pThat) const
|
||||
{
|
||||
if (!pThat)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Get()((Type *)pThat);
|
||||
}
|
||||
};
|
@ -141,6 +141,7 @@ public:
|
||||
|
||||
protected:
|
||||
friend struct AuHeapAccessor;
|
||||
friend struct AuHeapAccessor2;
|
||||
friend struct Aurora::Memory::ProxyHeap;
|
||||
|
||||
virtual AuSPtr<AuHeap> GetSelfReference() = 0; // may return empty/default. not all heaps are sharable.
|
||||
@ -155,4 +156,4 @@ protected:
|
||||
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;
|
||||
};
|
||||
};
|
@ -21,3 +21,13 @@ struct AuHeapAccessor
|
||||
return pHeap->GetSelfReferenceRaw();
|
||||
}
|
||||
};
|
||||
|
||||
struct AuHeapAccessor2
|
||||
{
|
||||
protected:
|
||||
template <typename Type>
|
||||
inline static auto Get()
|
||||
{
|
||||
return &AuHeap::DeleteThat<Type>;
|
||||
}
|
||||
};
|
@ -8,6 +8,91 @@
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
//
|
||||
// AuHUPOf_t<T> AuNewClassArrayUnique<T>([pHeap, ]uElements, ...)
|
||||
// AuUPtr<T> AuNewClassArrayUnique<T>([pHeap, ]uElements, ...) [ 2024/09 ]
|
||||
// AuSPtr<T> AuNewClassArray<T>([pHeap, ]uElements, ...)
|
||||
// AuHUPOf_t<Z> AuNewClassUnique<T, Z = T>([pHeap, ] ...)
|
||||
// AuUPtr<Z> AuNewClassUnique<T, Z = T>([pHeap, ] ...)
|
||||
// sizeof( AuHUPOf_t<T> ) ==
|
||||
// sizeof( AuUPtr<T> ) == [ 2024/09 ]
|
||||
// 2 * sizeof( void * )
|
||||
// AuHPtr<T> AuNewClassSmallUnique<T>([pHeap, ] ...) [ 2024/09 ]
|
||||
// sizeof( AuHPtr<T> ) == sizeof( void * )
|
||||
// AuSPtr<T> AuNewClass([pHeap, ] ...)
|
||||
// sizeof(AuSPtr<T>) ~= 2x (void *)
|
||||
// AuHUPOf_t<T> AuNullHeapPointer<T>()
|
||||
// AuUPtr<T> AuNullHeapPointer<T>() [ 2024/09 ]
|
||||
// AuSPtr<T> AuMakeShared(...)
|
||||
//
|
||||
// AuSPtr<T> - shared
|
||||
//
|
||||
// AuSSPtr<T> - shared (special. if the shared pointer container is too big, this type may shrink it down. )
|
||||
// (this maybe useful for storing parent pointers in foreign places or small slots. )
|
||||
//
|
||||
// AuHPtr<T> - unique with immutable instantiated deleter (...<T>) of derived main class (= T)
|
||||
//
|
||||
// AuHUPOf_t<T> - unique of a function callback; relevant prior to 2024/09.
|
||||
// - could be assigned to null with AuNullHeapPointer; relevant prior to 2024/09.
|
||||
// - use me instead of AuUPtr<T NO DELETER> to be compatible to pre 2024/09 codebases.
|
||||
//
|
||||
// AuUPtr<T, Deleter_t> - close to what youd expect from a std::unique_pointer with special edge cases.
|
||||
//
|
||||
// AuUPtr<T> - prior to 2024/09, invalid
|
||||
// AuUPtr<T> - after 2024/09, an empty function callback unique pointer container. 2x void*
|
||||
// - use me for maximum laziness
|
||||
// after 2024/09:
|
||||
// std::shared_ptr<T> a = { AuSPtr<T>() }
|
||||
// std::unique_ptr<T, ...> a = { AuUPtr<T, ...>().Release(), AuUPtr<T, ...>().GetDeleter() }
|
||||
// AuUPtr<T, ...> a = { std::unique_ptr<T, ...>().release(), std::unique_ptr<T, ...>().get_deleter() }
|
||||
// AuSPtr<T> a = { std::shared_ptr<T>() }
|
||||
// AuHUPOf_t<T> a = AuNullHeapPointer<T>() (2x void * sized container)
|
||||
// AuUPtr<T> a = AuNullHeapPointer<T>() (2x void * sized container)
|
||||
// AuHUPOf_t<T> a { AuMove(AuUPtr<T>) } (2x void * sized container)
|
||||
// AuUPtr<T> a { AuMove(AuHUPOf_t<T>) } (2x void * sized container)
|
||||
// AuUPtr<T> a { _new Kot() } (2x void * sized container)
|
||||
// AuSPtr<T> a { AuMove(a) } (N/A Shared Pointer)
|
||||
// AuHUPOf_t<T> a { } (2x void * sized container)
|
||||
// AuUPtr<T> a { } (2x void * sized container)
|
||||
// AuHUPOf_t<T> a = SomeAPI(...) (2x void * sized container)
|
||||
// AuUPtr<T> a = SomeAPI(...) (2x void * sized container)
|
||||
// AuUPtr<T> a = SOOObjectGenericUnique(...) (2x void * sized container)
|
||||
// AuHUPOf_t<T> a = SOOObjectGenericUniqueOnHeap(pMyHeap, ...) (2x void * sized container)
|
||||
// AuUPtr<T> a = SOOObjectGenericUniqueOnHeap(pMyHeap, ...) (2x void * sized container)
|
||||
// AuUPtr<T,Deleter>|SOOOnHeapUnique_t a =
|
||||
// SOOObjectUniqueOnHeap(pMyHeap, ...) (void* sized container)
|
||||
// AuSPtr<T> a = SOOObjectSharedOnHeap(pMyHeap) (N/A Shared Pointer)
|
||||
// SOOObject...cont as FuncName
|
||||
// AuUPtr<T,Deleter>|FuncNameUnique_t a = FuncNameUnique() (void* sized container)
|
||||
// AuUPtr<T> a = FuncNameGenericUnique() (2x void * sized container)
|
||||
// AuUPtr<T,Deleter>|FuncNameSmallUnique_t a = FuncNameUnique() (void* sized container - old behaviour, lower overhead)
|
||||
// AuHPtr<T> a = FuncNameGenericUnique() (void* sized container - old behaviour, lower overhead)
|
||||
// AuSPtr<T> a = FuncNameShared() (N/A Shared Pointer)
|
||||
// AuHPtrs of SmallUnique's are becoming the new AuHUPOf_t<T>()
|
||||
// before 2024/09:
|
||||
// std::shared_ptr<T> a = { AuSPtr<T>() }
|
||||
// AuUPtr<T, ...> a = { std::unique_ptr<T, ...>().release(), std::unique_ptr<T, ...>().get_deleter() }
|
||||
// AuSPtr<T> a = { std::shared_ptr<T>() }
|
||||
// AuUPtr<T, AuDefaultDeleter<...>> a { _new Kot() } (void * sized container)
|
||||
// AuHUPOf_t<T> a = AuNullHeapPointer<T>() (2x void * sized container)
|
||||
// AuSPtr<T> a { AuMove(a) } (N/A Shared Pointer)
|
||||
// AuHUPOf_t<T> a = pHeap->XXXXUnique(...) (2x void * sized container)
|
||||
// AuHUPOf_t<T> a = AuNewXXXXUnique(...) (2x void * sized container)
|
||||
// AuHUPOf_t<T> a = SomeAPI(...) (2x void * sized container)
|
||||
// AuUPtr<T, ...> a = FuncNameUnique() (void* sized container)
|
||||
// AuUPtr<T,Deleter>|FuncNameUnique_t a = FuncNameUnique() (void* sized container)
|
||||
// AuSPtr<T> a = FuncNameShared() (N/A Shared Pointer)
|
||||
// AuHPtr<T> - did not exist
|
||||
// but still:
|
||||
// AuHUPOf_t<T> will be kept around just in case we need to build against the spec, I suppose.
|
||||
//
|
||||
// AuUPtr is a superset of the C++ std::unique_ptr, no matter the era.
|
||||
// std::unique_ptr<???, ???> must be substitutable with an AuUPtr<???, ???>
|
||||
//
|
||||
// (modern) AuHPtr replaces in-library use cases for AuHUPOf_t and AuUPtr<T NO DELETER>.
|
||||
// ironically enough, we've just reintented a new AuHUPOf_t.
|
||||
//
|
||||
|
||||
#if defined(AURORA_ROXTL_HAS_RUNTIME) && AURORA_ROXTL_HAS_RUNTIME
|
||||
namespace Aurora::Memory
|
||||
{
|
||||
@ -59,9 +144,26 @@ auline AuSPtr<T> AuMakeShared(Args &&... args)
|
||||
#endif
|
||||
}
|
||||
|
||||
// can carry casts
|
||||
// 2024/09 onward, this is an artifact from when we were using STL unique pointers
|
||||
// this is now the same as AuUPtr<U> as implemented by <auROXTL/MemoryModel/auUniquePointer.hpp>.
|
||||
// beforehand, AuUPtr<T> needed a destructor of a class deallocator with a nonnull constructor (something something nulls are bad mokay we can just design them out).
|
||||
// In either case, AuHUPOf_t could be cast at least once.
|
||||
// In either case, the sizeof this is always 2x (void *)-ish.
|
||||
// In either case, can carry T[]
|
||||
template <typename T>
|
||||
using AuHUPOf_t = AuUPtr<T, void(*)(T *)>;
|
||||
|
||||
// cannot carry casts, is equal to sizeof(void *)
|
||||
template <typename T>
|
||||
using AuHSUPOf_t = AuUPtr<T, AuHeapUniqueDeleterClass<T>>;
|
||||
|
||||
// used for non-api unique allocates, where T = base and derived type, and the container sizeof is only void *.
|
||||
// cannot carry T[]
|
||||
// cannot carry derived -> interface casts
|
||||
template <typename T>
|
||||
using AuHPtr = AuHSUPOf_t<T>;
|
||||
|
||||
template <class T>
|
||||
auto AuNullHeapPointer()
|
||||
{
|
||||
@ -114,10 +216,10 @@ 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)
|
||||
template <class T, class Z = T, class ...Args>
|
||||
AuHUPOf_t<Z> AuNewClassUnique(AuHeap *pHeap, Args &&...args)
|
||||
{
|
||||
return pHeap->NewClassUnique<T, Args...>(AuForward<Args>(args)...);
|
||||
return pHeap->NewClassUnique<T, Z, Args...>(AuForward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <class T, class ...Args>
|
||||
@ -126,6 +228,35 @@ AuSPtr<T> AuNewClass(AuHeap *pHeap, Args &&...args)
|
||||
return pHeap->NewClass<T, Args...>(AuForward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <class T, class ...Args>
|
||||
AuHPtr<T> AuNewClassUniqueSmall(AuHeap *pHeap, Args &&...args)
|
||||
{
|
||||
if (!pHeap)
|
||||
{
|
||||
return AuHPtr<T> {};
|
||||
}
|
||||
auto pThat = pHeap->NewClassUnique<T, T, Args...>(AuForward<Args>(args)...);
|
||||
if (!pThat)
|
||||
{
|
||||
return AuHPtr<T> {};
|
||||
}
|
||||
auto pMyPointerNow = pThat.Release()->AsPointer();
|
||||
_AUROXTL_DELETER_ASSERT(pThat, AuHeapUniqueDeleterClass<T>);
|
||||
return AuHPtr<T> { pMyPointerNow };
|
||||
}
|
||||
|
||||
template <class T, class ...Args>
|
||||
AuHPtr<T> AuNewClassUniqueSmall(const AuSPtr<AuHeap> &pHeap, Args &&...args)
|
||||
{
|
||||
return AuNewClassUniqueSmall<T, Args...>(pHeap.get(), AuForward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <class T, class ...Args>
|
||||
AuHPtr<T> AuNewClassUniqueSmall(Args &&...args)
|
||||
{
|
||||
return AuNewClassUniqueSmall<T, Args...>(__audetail::gDefaultDiscontiguousHeap, AuForward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <class T, class ...Args>
|
||||
AuHUPOf_t<T> AuNewClassArrayUnique(const AuSPtr<AuHeap> &pHeap, AuUInt uElements, Args &&... fillCtr)
|
||||
{
|
||||
|
@ -112,8 +112,13 @@ struct AU_ALIGN(sizeof(AuUInt)) Type ## SOO
|
||||
using Type ## SOO_t = Type ## SOO; \
|
||||
using Type = Type ## SOO; \
|
||||
\
|
||||
using CppDeleterSOOX ## Type = AuHeapUniqueDeleterClass<Type, extends>; \
|
||||
using Type ## OnHeapUnique_t = AuUPtr<extends, CppDeleterSOOX ## Type>; \
|
||||
using Type ## UniqueOnHeap_t = Type ## OnHeapUnique_t; \
|
||||
using Type ## GenericUniqueOnHeap_t = AuUPtr<extends>; \
|
||||
\
|
||||
template <class ... T> \
|
||||
AuUPtr<extends> Type ## UniqueOnHeap(AuHeap *pHeap, T &&... args) \
|
||||
AuUPtr<extends> Type ## GenericUniqueOnHeap(AuHeap *pHeap, T &&... args) \
|
||||
{ \
|
||||
auto pThat = pHeap->NewClassUnique<Type>(AuForward<T>(args)...); \
|
||||
if (!pThat) \
|
||||
@ -127,6 +132,19 @@ using Type = Type ## SOO;
|
||||
} \
|
||||
\
|
||||
template <class ... T> \
|
||||
Type ## OnHeapUnique_t Type ## UniqueOnHeap(AuHeap *pHeap, T &&... args) \
|
||||
{ \
|
||||
auto pThat = pHeap->NewClassUnique<Type>(AuForward<T>(args)...); \
|
||||
if (!pThat) \
|
||||
{ \
|
||||
return Type ## OnHeapUnique_t {}; \
|
||||
} \
|
||||
auto pMyPointerNow = pThat.Release()->AsPointer(); \
|
||||
_AUROXTL_DELETER_ASSERT(pThat.GetDeleter(), CppDeleterSOOX ## Type); \
|
||||
return Type ## OnHeapUnique_t { pMyPointerNow }; \
|
||||
} \
|
||||
\
|
||||
template <class ... T> \
|
||||
AuSPtr<extends> Type ## SharedOnHeap(AuHeap *pHeap, T &&... args) \
|
||||
{ \
|
||||
auto pThat = pHeap->NewClass<Type>(AuForward<T>(args)...); \
|
||||
|
@ -459,6 +459,7 @@ inline constexpr bool operator!=(const Aurora::Memory::BaseAuroraRuntimeAllocato
|
||||
#include <auROXTL/MemoryModel/auHeapStats.hpp>
|
||||
#include <auROXTL/MemoryModel/auHeap.hpp>
|
||||
#include <auROXTL/MemoryModel/auHeapAccessor.hpp>
|
||||
#include <auROXTL/MemoryModel/AuHeapUniqueDeleterClass.hpp>
|
||||
|
||||
#include <auROXTL/MemoryModel/auDummyHeap.hpp>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user