Plasma Engine  2.0
Loading...
Searching...
No Matches
Allocator_inl.h
1
2PL_ALWAYS_INLINE plAllocator::plAllocator() = default;
3
4PL_ALWAYS_INLINE plAllocator::~plAllocator() = default;
5
6
7namespace plMath
8{
9 // due to #include order issues, we have to forward declare this function here
10
11 PL_FOUNDATION_DLL plUInt64 SafeMultiply64(plUInt64 a, plUInt64 b, plUInt64 c, plUInt64 d);
12} // namespace plMath
13
14namespace plInternal
15{
16 template <typename T>
18 {
19 PL_ALWAYS_INLINE NewInstance(T* pInstance, plAllocator* pAllocator)
20 {
21 m_pInstance = pInstance;
22 m_pAllocator = pAllocator;
23 }
24
25 template <typename U>
26 PL_ALWAYS_INLINE NewInstance(NewInstance<U>&& other)
27 {
28 m_pInstance = other.m_pInstance;
29 m_pAllocator = other.m_pAllocator;
30
31 other.m_pInstance = nullptr;
32 other.m_pAllocator = nullptr;
33 }
34
35 PL_ALWAYS_INLINE NewInstance(std::nullptr_t) {}
36
37 template <typename U>
38 PL_ALWAYS_INLINE NewInstance<U> Cast()
39 {
40 return NewInstance<U>(static_cast<U*>(m_pInstance), m_pAllocator);
41 }
42
43 PL_ALWAYS_INLINE operator T*() { return m_pInstance; }
44
45 PL_ALWAYS_INLINE T* operator->() { return m_pInstance; }
46
47 T* m_pInstance = nullptr;
48 plAllocator* m_pAllocator = nullptr;
49 };
50
51 template <typename T>
52 PL_ALWAYS_INLINE bool operator<(const NewInstance<T>& lhs, T* rhs)
53 {
54 return lhs.m_pInstance < rhs;
55 }
56
57 template <typename T>
58 PL_ALWAYS_INLINE bool operator<(T* lhs, const NewInstance<T>& rhs)
59 {
60 return lhs < rhs.m_pInstance;
61 }
62
63 template <typename T>
64 PL_FORCE_INLINE void Delete(plAllocator* pAllocator, T* pPtr)
65 {
66 if (pPtr != nullptr)
67 {
69 pAllocator->Deallocate(pPtr);
70 }
71 }
72
73 template <typename T>
74 PL_FORCE_INLINE T* CreateRawBuffer(plAllocator* pAllocator, size_t uiCount)
75 {
76 plUInt64 safeAllocationSize = plMath::SafeMultiply64(uiCount, sizeof(T));
77 return static_cast<T*>(pAllocator->Allocate(static_cast<size_t>(safeAllocationSize), PL_ALIGNMENT_OF(T))); // Down-cast to size_t for 32-bit
78 }
79
80 PL_FORCE_INLINE void DeleteRawBuffer(plAllocator* pAllocator, void* pPtr)
81 {
82 if (pPtr != nullptr)
83 {
84 pAllocator->Deallocate(pPtr);
85 }
86 }
87
88 template <typename T>
89 inline plArrayPtr<T> CreateArray(plAllocator* pAllocator, plUInt32 uiCount)
90 {
91 T* buffer = CreateRawBuffer<T>(pAllocator, uiCount);
93
94 return plArrayPtr<T>(buffer, uiCount);
95 }
96
97 template <typename T>
98 inline void DeleteArray(plAllocator* pAllocator, plArrayPtr<T> arrayPtr)
99 {
100 T* buffer = arrayPtr.GetPtr();
101 if (buffer != nullptr)
102 {
103 plMemoryUtils::Destruct(buffer, arrayPtr.GetCount());
104 pAllocator->Deallocate(buffer);
105 }
106 }
107
108 template <typename T>
109 PL_FORCE_INLINE T* ExtendRawBuffer(T* pPtr, plAllocator* pAllocator, size_t uiCurrentCount, size_t uiNewCount, plTypeIsPod)
110 {
111 return (T*)pAllocator->Reallocate(pPtr, uiCurrentCount * sizeof(T), uiNewCount * sizeof(T), PL_ALIGNMENT_OF(T));
112 }
113
114 template <typename T>
115 PL_FORCE_INLINE T* ExtendRawBuffer(T* pPtr, plAllocator* pAllocator, size_t uiCurrentCount, size_t uiNewCount, plTypeIsMemRelocatable)
116 {
117 return (T*)pAllocator->Reallocate(pPtr, uiCurrentCount * sizeof(T), uiNewCount * sizeof(T), PL_ALIGNMENT_OF(T));
118 }
119
120 template <typename T>
121 PL_FORCE_INLINE T* ExtendRawBuffer(T* pPtr, plAllocator* pAllocator, size_t uiCurrentCount, size_t uiNewCount, plTypeIsClass)
122 {
123 static_assert(!std::is_trivial<T>::value,
124 "POD type is treated as class. Use PL_DECLARE_POD_TYPE(YourClass) or PL_DEFINE_AS_POD_TYPE(ExternalClass) to mark it as POD.");
125
126 T* pNewMem = CreateRawBuffer<T>(pAllocator, uiNewCount);
127 plMemoryUtils::RelocateConstruct(pNewMem, pPtr, uiCurrentCount);
128 DeleteRawBuffer(pAllocator, pPtr);
129 return pNewMem;
130 }
131
132 template <typename T>
133 PL_FORCE_INLINE T* ExtendRawBuffer(T* pPtr, plAllocator* pAllocator, size_t uiCurrentCount, size_t uiNewCount)
134 {
135 PL_ASSERT_DEV(uiCurrentCount < uiNewCount, "Shrinking of a buffer is not implemented yet");
136 PL_ASSERT_DEV(!(uiCurrentCount == uiNewCount), "Same size passed in twice.");
137 if (pPtr == nullptr)
138 {
139 PL_ASSERT_DEV(uiCurrentCount == 0, "current count must be 0 if ptr is nullptr");
140
141 return CreateRawBuffer<T>(pAllocator, uiNewCount);
142 }
143 return ExtendRawBuffer(pPtr, pAllocator, uiCurrentCount, uiNewCount, plGetTypeClass<T>());
144 }
145} // namespace plInternal
Base class for all memory allocators.
Definition Allocator.h:23
virtual void * Allocate(size_t uiSize, size_t uiAlign, plMemoryUtils::DestructorFunction destructorFunc=nullptr)=0
Interface, do not use this directly, always use the new/delete macros below.
This class encapsulates an array and it's size. It is recommended to use this class instead of plain ...
Definition ArrayPtr.h:37
PL_ALWAYS_INLINE plUInt32 GetCount() const
Returns the number of elements in the array.
Definition ArrayPtr.h:142
PL_ALWAYS_INLINE PointerType GetPtr() const
Returns the pointer to the array.
Definition ArrayPtr.h:118
static void RelocateConstruct(T *pDestination, T *pSource, size_t uiCount=1)
Constructs uiCount objects of type T in a raw buffer at pDestination from an existing array of object...
static void Construct(T *pDestination, size_t uiCount=1)
Constructs uiCount objects of type T in a raw buffer at pDestination.
static void Destruct(T *pDestination, size_t uiCount=1)
Destructs uiCount objects of type T at pDestination.
This namespace provides common math-functionality as functions.
Definition Constants.h:6
PL_FOUNDATION_DLL plUInt64 SafeMultiply64(plUInt64 a, plUInt64 b, plUInt64 c=1, plUInt64 d=1)
returns a * b. If an overflow happens, the program is terminated.
Definition Math.cpp:200
If there is an % operator which takes a plTypeIsMemRelocatable and returns a CompileTimeTrueType T is...
Definition TypeTraits.h:67
Definition Allocator_inl.h:18
Type traits.
Definition TypeTraits.h:12