Skip to content

Commit ff80671

Browse files
Refactored td to properly use Concepts
1 parent 9fe1a95 commit ff80671

31 files changed

Lines changed: 429 additions & 383 deletions

Allocator/Arena_ULL.ixx

Lines changed: 38 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
module;
66
#include <type_traits>
7+
#include <concepts>
78
#include "include/Allocator.h"
89

910
export module SG_Allocator:Arena;
@@ -23,11 +24,13 @@ export namespace SG_Allocator {
2324
* @tparam blockSize Number of bytes per block
2425
* @tparam maxSublifetimes Max number of simultaneously open sublifetimes
2526
*/
26-
template<arenaSize_t blockSize, localSize_t maxSublifetimes>
27-
class Arena_ULL : private BaseArena {
27+
template<std::integral auto blockSize, localSize_t maxSublifetimes, std::integral arenaSize_t_ = defaultArenaSize_t>
28+
class Arena_ULL {
2829
static_assert(blockSize > 0, "Blocksize must be > 0");
2930

3031
public:
32+
using arenaSize_t = arenaSize_t_;
33+
3134
Arena_ULL();
3235
Arena_ULL(const Arena_ULL&) = delete;
3336

@@ -57,17 +60,18 @@ export namespace SG_Allocator {
5760
arenaSize_t initialLength;
5861
};
5962

60-
ULL<PseudoArena, char> impl;
63+
ULL<PseudoArena<>, char> impl;
6164
LocalDataStructures::Stack<Sublifetime, maxSublifetimes> sublifetimeStack;
6265
};
63-
66+
static_assert(OptionalArena_c<Arena_ULL<100,100>, char, char>);
67+
static_assert(OptionalArena_c<Arena_ULL<100,100>, int, int>);
6468
}
6569

6670
/**
6771
* @brief Constructs an arena object with an Unrolled Linked List backend
6872
*/
69-
template<SG_Allocator::arenaSize_t blockSize, localSize_t maxSublifetimes>
70-
SG_Allocator::Arena_ULL<blockSize, maxSublifetimes>::Arena_ULL():
73+
template<std::integral auto blockSize, localSize_t maxSublifetimes, std::integral arenaSize_t_>
74+
SG_Allocator::Arena_ULL<blockSize, maxSublifetimes, arenaSize_t_>::Arena_ULL():
7175
impl(globalPseudoArena, blockSize),
7276
sublifetimeStack()
7377
{}
@@ -77,9 +81,9 @@ SG_Allocator::Arena_ULL<blockSize, maxSublifetimes>::Arena_ULL():
7781
* @tparam T Type to allocate space for
7882
* @return Pointer to allocated memory of type T*
7983
*/
80-
template<SG_Allocator::arenaSize_t blockSize, localSize_t maxSublifetimes>
84+
template<std::integral auto blockSize, localSize_t maxSublifetimes, std::integral arenaSize_t_>
8185
template<typename T>
82-
T * SG_Allocator::Arena_ULL<blockSize, maxSublifetimes>::alloc() {
86+
T * SG_Allocator::Arena_ULL<blockSize, maxSublifetimes, arenaSize_t_>::alloc() {
8387
#ifdef DISABLE_NONFUNDAMENTAL_ALLOC
8488
#ifndef NDEBUG
8589
static_assert(std::is_fundamental_v<T> || (std::is_standard_layout_v<T> && std::is_trivially_default_constructible_v<T> && std::is_trivially_copyable_v<T>) || std::is_pointer_v<T>);
@@ -94,9 +98,9 @@ T * SG_Allocator::Arena_ULL<blockSize, maxSublifetimes>::alloc() {
9498
* @param arrayLength Length of array to allocate
9599
* @return Pointer to allocated array (address of first element)
96100
*/
97-
template<SG_Allocator::arenaSize_t blockSize, localSize_t maxSublifetimes>
101+
template<std::integral auto blockSize, localSize_t maxSublifetimes, std::integral arenaSize_t_>
98102
template<typename T>
99-
T * SG_Allocator::Arena_ULL<blockSize, maxSublifetimes>::allocArray(const arenaSize_t& arrayLength) {
103+
T * SG_Allocator::Arena_ULL<blockSize, maxSublifetimes, arenaSize_t_>::allocArray(const arenaSize_t& arrayLength) {
100104
return impl.allocArray<T>(arrayLength);
101105
}
102106

@@ -107,9 +111,9 @@ T * SG_Allocator::Arena_ULL<blockSize, maxSublifetimes>::allocArray(const arenaS
107111
* @param args Values of constructor args (can be empty)
108112
* @return Pointer to allocated memory of type T*
109113
*/
110-
template<SG_Allocator::arenaSize_t blockSize, localSize_t maxSublifetimes>
114+
template<std::integral auto blockSize, localSize_t maxSublifetimes, std::integral arenaSize_t_>
111115
template<typename T, typename ... ConstructorArgs>
112-
T * SG_Allocator::Arena_ULL<blockSize, maxSublifetimes>::allocConstruct(ConstructorArgs&&... args) {
116+
T * SG_Allocator::Arena_ULL<blockSize, maxSublifetimes, arenaSize_t_>::allocConstruct(ConstructorArgs&&... args) {
113117
return new (impl.alloc<T>()) T(args...);
114118
}
115119

@@ -121,9 +125,9 @@ T * SG_Allocator::Arena_ULL<blockSize, maxSublifetimes>::allocConstruct(Construc
121125
* @param args Values of constructor args (can be empty)
122126
* @return Pointer to allocated array (address of first element)
123127
*/
124-
template<SG_Allocator::arenaSize_t blockSize, localSize_t maxSublifetimes>
128+
template<std::integral auto blockSize, localSize_t maxSublifetimes, std::integral arenaSize_t_>
125129
template<typename T, typename ... ConstructorArgs>
126-
T * SG_Allocator::Arena_ULL<blockSize, maxSublifetimes>::allocConstructArray(const arenaSize_t& arrayLength, ConstructorArgs&&... args) {
130+
T * SG_Allocator::Arena_ULL<blockSize, maxSublifetimes, arenaSize_t_>::allocConstructArray(const arenaSize_t& arrayLength, ConstructorArgs&&... args) {
127131
T* out = allocArray<T>(arrayLength);
128132
for (auto i = 0; i < arrayLength; i++) new (&out[i]) T(args...);
129133
return out;
@@ -132,17 +136,17 @@ T * SG_Allocator::Arena_ULL<blockSize, maxSublifetimes>::allocConstructArray(con
132136
/**
133137
* @brief Marks all memory in arena as overwritable, and deallocates non-root blocks - DOES NOT CALL DESTRUCTORS
134138
*/
135-
template<SG_Allocator::arenaSize_t blockSize, localSize_t maxSublifetimes>
136-
void SG_Allocator::Arena_ULL<blockSize, maxSublifetimes>::clear() {
139+
template<std::integral auto blockSize, localSize_t maxSublifetimes, std::integral arenaSize_t_>
140+
void SG_Allocator::Arena_ULL<blockSize, maxSublifetimes, arenaSize_t_>::clear() {
137141
impl.clear();
138142
sublifetimeStack.clear();
139143
}
140144

141145
/**
142146
* @brief Marks all memory in arena as overwritable, but does not deallocate non-root blocks - DOES NOT CALL DESTRUCTORS
143147
*/
144-
template<SG_Allocator::arenaSize_t blockSize, localSize_t maxSublifetimes>
145-
void SG_Allocator::Arena_ULL<blockSize, maxSublifetimes>::softClear() {
148+
template<std::integral auto blockSize, localSize_t maxSublifetimes, std::integral arenaSize_t_>
149+
void SG_Allocator::Arena_ULL<blockSize, maxSublifetimes, arenaSize_t_>::softClear() {
146150
impl.softClear();
147151
sublifetimeStack.clear();
148152
}
@@ -151,58 +155,56 @@ void SG_Allocator::Arena_ULL<blockSize, maxSublifetimes>::softClear() {
151155
* @brief Pre-allocates enough blocks to fit the specified number of bytes
152156
* @param newSize Size to allocate space up to
153157
*/
154-
template<SG_Allocator::arenaSize_t blockSize, localSize_t maxSublifetimes>
155-
void SG_Allocator::Arena_ULL<blockSize, maxSublifetimes>::expand(const arenaSize_t& newSize) {
158+
template<std::integral auto blockSize, localSize_t maxSublifetimes, std::integral arenaSize_t_>
159+
void SG_Allocator::Arena_ULL<blockSize, maxSublifetimes, arenaSize_t_>::expand(const arenaSize_t& newSize) {
156160
impl.expand(newSize);
157161
}
158162

159163
/**
160164
*
161165
* @return Max number of bytes that can be allocated before a new block is required
162166
*/
163-
template<SG_Allocator::arenaSize_t blockSize, localSize_t maxSublifetimes>
164-
SG_Allocator::arenaSize_t SG_Allocator::Arena_ULL<blockSize, maxSublifetimes>::maxSize() const {
167+
template<std::integral auto blockSize, localSize_t maxSublifetimes, std::integral arenaSize_t_>
168+
SG_Allocator::Arena_ULL<blockSize, maxSublifetimes, arenaSize_t_>::arenaSize_t SG_Allocator::Arena_ULL<blockSize, maxSublifetimes, arenaSize_t_>::maxSize() const {
165169
return impl.maxSize();
166170
}
167171

168172
/**
169173
*
170174
* @return Current number of bytes that have been allocated within the Arena. Includes fragmented memory that may occur at block tails
171175
*/
172-
template<SG_Allocator::arenaSize_t blockSize, localSize_t maxSublifetimes>
173-
SG_Allocator::arenaSize_t SG_Allocator::Arena_ULL<blockSize, maxSublifetimes>::usedSpace() const {
176+
template<std::integral auto blockSize, localSize_t maxSublifetimes, std::integral arenaSize_t_>
177+
SG_Allocator::Arena_ULL<blockSize, maxSublifetimes, arenaSize_t_>::arenaSize_t SG_Allocator::Arena_ULL<blockSize, maxSublifetimes, arenaSize_t_>::usedSpace() const {
174178
return impl.length();
175179
}
176180

177181
/**
178182
* @brief Begin a sublifetime and add it to the top of the sublifetime stack
179183
*/
180-
template<SG_Allocator::arenaSize_t blockSize, localSize_t maxSublifetimes>
181-
void SG_Allocator::Arena_ULL<blockSize, maxSublifetimes>::sublifetime_open() {
184+
template<std::integral auto blockSize, localSize_t maxSublifetimes, std::integral arenaSize_t_>
185+
void SG_Allocator::Arena_ULL<blockSize, maxSublifetimes, arenaSize_t_>::sublifetime_open() {
182186
Sublifetime sl;
183187
sl.initialLength = impl.length();
184-
sl.rootNode = NodeExaminer<PseudoArena, char>::currentTail(impl);
188+
sl.rootNode = NodeExaminer<PseudoArena<>, char>::currentTail(impl);
185189
sublifetimeStack.push(sl);
186190
}
187191

188192
/**
189193
* @brief Pop a sublifetime from the sublifetime stack and deallocate memory allocated and blocks created since it opened. DOES NOT CALL DESTRUCTORS
190194
*/
191-
template<SG_Allocator::arenaSize_t blockSize, localSize_t maxSublifetimes>
192-
void SG_Allocator::Arena_ULL<blockSize, maxSublifetimes>::sublifetime_rollback(){
195+
template<std::integral auto blockSize, localSize_t maxSublifetimes, std::integral arenaSize_t_>
196+
void SG_Allocator::Arena_ULL<blockSize, maxSublifetimes, arenaSize_t_>::sublifetime_rollback(){
193197
Sublifetime rollback = sublifetimeStack.pop();
194-
NodeExaminer<PseudoArena, char>::setTail(impl, rollback.rootNode, rollback.initialLength);
195-
NodeExaminer<PseudoArena, char>::shrink(impl);
198+
NodeExaminer<PseudoArena<>, char>::setTail(impl, rollback.rootNode, rollback.initialLength);
199+
NodeExaminer<PseudoArena<>, char>::shrink(impl);
196200
}
197201

198202
/**
199203
* Pop a sublifetime from the sublifetime stack and deallocate memory allocated but not blocks created since it opened. DOES NOT CALL DESTRUCTORS
200204
*/
201-
template<SG_Allocator::arenaSize_t blockSize, localSize_t maxSublifetimes>
202-
void SG_Allocator::Arena_ULL<blockSize, maxSublifetimes>::sublifetime_softRollback(){
205+
template<std::integral auto blockSize, localSize_t maxSublifetimes, std::integral arenaSize_t_>
206+
void SG_Allocator::Arena_ULL<blockSize, maxSublifetimes, arenaSize_t_>::sublifetime_softRollback(){
203207
Sublifetime rollback = sublifetimeStack.pop();
204-
NodeExaminer<PseudoArena, char>::setTail(impl, rollback.rootNode, rollback.initialLength);
208+
NodeExaminer<PseudoArena<>, char>::setTail(impl, rollback.rootNode, rollback.initialLength);
205209
}
206210

207-
208-

Allocator/BaseArena.ixx

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,47 @@
11
//
22
// Created by nickberryman on 1/12/25.
33
//
4+
module;
5+
#include <concepts>
6+
47
export module SG_Allocator:BaseArena;
58
import SG_AllocatorConfigs;
69
import Logger;
710

811
export namespace SG_Allocator {
12+
template <typename T, typename canAlloc, typename... canAllocArgs>
13+
concept BaseArena_c = requires(T t, canAlloc a, typename T::arenaSize_t siz, canAllocArgs... args)
14+
{
15+
typename T::arenaSize_t;
16+
{t.template alloc<canAlloc>()} -> std::same_as<canAlloc*>;
17+
{t.template allocArray<canAlloc>(3)} -> std::same_as<canAlloc*>;
18+
{t.template allocConstruct<canAlloc>(args...)} -> std::same_as<canAlloc*>;
19+
{t.template allocConstructArray<canAlloc>(3, args...)} -> std::same_as<canAlloc*>;
20+
{t.sublifetime_open()};
21+
{t.sublifetime_rollback()};
22+
{t.sublifetime_softRollback()};
23+
{t.clear()};
24+
{t.softClear()};
25+
{t.expand(siz)};
26+
{t.maxSize()} -> std::same_as<typename T::arenaSize_t>;
27+
{t.usedSpace()} -> std::same_as<typename T::arenaSize_t>;
28+
};
29+
30+
template <typename T, typename canAlloc, typename... canAllocArgs>
31+
concept OptionalArena_c = requires(T t, canAlloc* a)
32+
{
33+
{t.softDelete(a)};
34+
{t.softDeleteArray(a)};
35+
} && BaseArena_c<T, canAlloc, canAllocArgs...>;
36+
937
/**
10-
* @brief Base class for arena allocators. Should only be inhereted from, never used directly
11-
*
38+
* @brief Base class for arena allocators. Should only be inherited from, never used directly
39+
*
1240
*/
1341
class BaseArena {
1442
public:
43+
using arenaSize_t = defaultArenaSize_t;
44+
1545
template<typename T> inline T* alloc(){Logging::assert_except(0); return nullptr;};
1646
template<typename T> inline T* allocArray(arenaSize_t arrayLength){Logging::assert_except(0); return nullptr;};
1747
template<typename T, typename... ConstructorArgs> inline T* allocConstruct(ConstructorArgs... args){Logging::assert_except(0); return nullptr;};

0 commit comments

Comments
 (0)