MCRO
C++23 utilities for Unreal Engine.
Loading...
Searching...
No Matches
Allocator.h
Go to the documentation of this file.
1/** @noop License Comment
2 * @file
3 * @copyright
4 * This Source Code is subject to the terms of the Mozilla Public License, v2.0.
5 * If a copy of the MPL was not distributed with this file You can obtain one at
6 * https://mozilla.org/MPL/2.0/
7 *
8 * @author David Mórász
9 * @date 2025
10 */
11
12#pragma once
13
14#include "CoreMinimal.h"
15
16/**
17 * @brief
18 * Epic Games may not agree with standards because they know better, but sometimes we have to bare consequences of
19 * such wisdom. This namespace contains utilities which politely circumvent the obviously superior decisions Epic Games
20 * has made.
21 */
22namespace Mcro::Ansi
23{
24 namespace Detail
25 {
26 MCRO_API void OnInvalidAnsiAllocatorNum(int32 newNum, SIZE_T numBytesPerElement);
27 }
28
29 /**
30 * @brief Allocator that allocates memory using standard library functions.
31 *
32 * This is a copy of `FAnsiAllocator` in `Runtime/Core/Private/HAL/Allocators/AnsiAllocator.h` but since it's
33 * private, we have the MCRO version of it here.
34 */
35 class MCRO_API FAllocator
36 {
37 public:
38 using SizeType = int32;
39
40 enum { NeedsElementType = false };
41 enum { RequireRangeCheck = true };
42
45
46 class MCRO_API ForAnyElementType
47 {
48 public:
49 ForAnyElementType() : Data(nullptr) {}
50
51 /**
52 * @brief Moves the state of another allocator into this one.
53 *
54 * Assumes that the allocator is currently empty, i.e. memory may be allocated but any existing elements
55 * have already been destructed (if necessary).
56 *
57 * @param other The allocator to move the state from. This allocator should be left in a valid empty state.
58 */
59 FORCEINLINE void MoveToEmpty(ForAnyElementType& other)
60 {
61 check(this != &other);
62
63 if (Data) ::free(Data);
64
65 Data = other.Data;
66 other.Data = nullptr;
67 }
68
69 /** Destructor. */
70 FORCEINLINE ~ForAnyElementType()
71 {
72 if (Data) ::free(Data);
73 }
74
75 // FContainerAllocatorInterface
76 FORCEINLINE FScriptContainerElement* GetAllocation() const
77 {
78 return Data;
79 }
80 void ResizeAllocation(SizeType currentNum, SizeType newMax, SIZE_T numBytesPerElement);
81 SizeType CalculateSlackReserve(SizeType newMax, SIZE_T numBytesPerElement) const
82 {
83 return DefaultCalculateSlackReserve(newMax, numBytesPerElement, false);
84 }
85 SizeType CalculateSlackShrink(SizeType newMax, SizeType currentMax, SIZE_T numBytesPerElement) const
86 {
87 return DefaultCalculateSlackShrink(newMax, currentMax, numBytesPerElement, false);
88 }
89 SizeType CalculateSlackGrow(SizeType newMax, SizeType currentMax, SIZE_T numBytesPerElement) const
90 {
91 return DefaultCalculateSlackGrow(newMax, currentMax, numBytesPerElement, false);
92 }
93
94 SIZE_T GetAllocatedSize(SizeType currentMax, SIZE_T numBytesPerElement) const
95 {
96 return currentMax * numBytesPerElement;
97 }
98
99 bool HasAllocation() const
100 {
101 return !!Data;
102 }
103
105 {
106 return 0;
107 }
108
109 private:
110 ForAnyElementType(const ForAnyElementType&) = delete;
111 ForAnyElementType& operator=(const ForAnyElementType&) = delete;
112
113 /** A pointer to the container's elements. */
114 FScriptContainerElement* Data;
115 };
116
117 template<typename ElementType>
118 class MCRO_API ForElementType : public ForAnyElementType
119 {
120 public:
121
122 /** Default constructor. */
125
126 FORCEINLINE ElementType* GetAllocation() const
127 {
128 return (ElementType*)ForAnyElementType::GetAllocation();
129 }
130 };
131 };
132
133 /** @brief Allocator for sets to follow standard allocation behavior */
134 class FSetAllocator : public TSetAllocator<FAllocator, TInlineAllocator<1, FAllocator>> {};
135}
136
137/** @brief TArray alias which enforces standard memory allocations */
138template <typename T>
139using TAnsiArray = TArray<T, Mcro::Ansi::FAllocator>;
140
141/** @brief TSet alias which enforces standard memory allocations */
142template <typename T, typename KeyFuncs = DefaultKeyFuncs<T>>
143using TAnsiSet = TSet<T, KeyFuncs, Mcro::Ansi::FSetAllocator>;
144
145/** @brief TMap alias which enforces standard memory allocations */
146template <typename K, typename V, typename KeyFuncs = TDefaultMapHashableKeyFuncs<K, V, false>>
147using TAnsiMap = TMap<K, V, Mcro::Ansi::FSetAllocator, KeyFuncs>;
148
149template <>
150struct TAllocatorTraits<Mcro::Ansi::FAllocator> : TAllocatorTraitsBase<Mcro::Ansi::FAllocator>
151{
152 enum { IsZeroConstruct = true };
153};
TArray< T, Mcro::Ansi::FAllocator > TAnsiArray
TArray alias which enforces standard memory allocations.
Definition Allocator.h:139
TMap< K, V, Mcro::Ansi::FSetAllocator, KeyFuncs > TAnsiMap
TMap alias which enforces standard memory allocations.
Definition Allocator.h:147
TSet< T, KeyFuncs, Mcro::Ansi::FSetAllocator > TAnsiSet
TSet alias which enforces standard memory allocations.
Definition Allocator.h:143
SizeType CalculateSlackReserve(SizeType newMax, SIZE_T numBytesPerElement) const
Definition Allocator.h:81
FORCEINLINE void MoveToEmpty(ForAnyElementType &other)
Moves the state of another allocator into this one.
Definition Allocator.h:59
SizeType CalculateSlackShrink(SizeType newMax, SizeType currentMax, SIZE_T numBytesPerElement) const
Definition Allocator.h:85
void ResizeAllocation(SizeType currentNum, SizeType newMax, SIZE_T numBytesPerElement)
FORCEINLINE FScriptContainerElement * GetAllocation() const
Definition Allocator.h:76
SIZE_T GetAllocatedSize(SizeType currentMax, SIZE_T numBytesPerElement) const
Definition Allocator.h:94
SizeType CalculateSlackGrow(SizeType newMax, SizeType currentMax, SIZE_T numBytesPerElement) const
Definition Allocator.h:89
FORCEINLINE ElementType * GetAllocation() const
Definition Allocator.h:126
Allocator that allocates memory using standard library functions.
Definition Allocator.h:36
FAllocator ElementAllocator
Definition Allocator.h:43
FAllocator BitArrayAllocator
Definition Allocator.h:44
Allocator for sets to follow standard allocation behavior.
Definition Allocator.h:134
MCRO_API void OnInvalidAnsiAllocatorNum(int32 newNum, SIZE_T numBytesPerElement)
Epic Games may not agree with standards because they know better, but sometimes we have to bare conse...
Definition Allocator.h:23