sead
Loading...
Searching...
No Matches
seadObjArray.h
Go to the documentation of this file.
1#pragma once
2
3#include <algorithm>
4#include <basis/seadAssert.h>
5#include <basis/seadNew.h>
6#include <container/seadFreeList.h>
7#include <container/seadPtrArray.h>
8
9namespace sead {
10
11// An ObjArray is a container that allocates elements using a FreeList and also keeps an array of pointers for fast access to each element.
12template <typename T>
13class ObjArray : public PtrArrayImpl
14{
15public:
16 ObjArray() = default;
17 ObjArray(s32 max_num, void* buf) { setBuffer(max_num, buf); }
18
19 void allocBuffer(s32 capacity, Heap* heap, s32 alignment = cDefaultAlignment)
20 {
21 SEAD_ASSERT(mPtrs == nullptr);
22
23 if (capacity < 1)
24 {
25 SEAD_ASSERT_MSG(false, "capacity[%d] must be larger than zero", capacity);
26 return;
27 }
28
29 setBuffer(capacity, new (heap, alignment) u8[calculateWorkBufferSize(capacity)]);
30 }
31
32 bool tryAllocBuffer(s32 capacity, Heap* heap, s32 alignment = cDefaultAlignment)
33 {
34 SEAD_ASSERT(mPtrs == nullptr);
35
36 if (capacity < 1)
37 {
38 SEAD_ASSERT_MSG(false, "capacity[%d] must be larger than zero", capacity);
39 return false;
40 }
41
42 auto* buf = new (heap, alignment) u8[calculateWorkBufferSize(capacity)];
43 if (!buf)
44 return false;
45
46 setBuffer(capacity, buf);
47 return true;
48 }
49
50 void setBuffer(s32 max_num, void* buf)
51 {
52 if (!buf)
53 {
54 SEAD_ASSERT_MSG(false, "buf is null");
55 return;
56 }
57
58 mFreeList.init(buf, ElementSize, max_num);
59 PtrArrayImpl::setBuffer(max_num, reinterpret_cast<u8*>(buf) + ElementSize * max_num);
60 }
61
63 {
64 if (!isBufferReady())
65 return;
66
67 clear();
68
70 delete[] static_cast<u8*>(mFreeList.work());
71
73 mPtrs = nullptr;
74 mPtrNumMax = 0;
75 }
76
77 T* at(s32 pos) const { return static_cast<T*>(PtrArrayImpl::at(pos)); }
78 T* unsafeAt(s32 pos) const { return static_cast<T*>(PtrArrayImpl::unsafeAt(pos)); }
79 T* operator()(s32 pos) const { return unsafeAt(pos); }
80 T* operator[](s32 pos) const { return at(pos); }
81
82 // XXX: Does this use at()?
83 T* front() const { return at(0); }
84 T* back() const { return at(mPtrNum - 1); }
85
86 void pushBack(const T& item)
87 {
88 if (isFull())
89 {
90 SEAD_ASSERT_MSG(false, "buffer full.");
91
92 }
93 else
94 {
96 }
97 }
98
99 template <class... Args>
100 T* emplaceBack(Args&&... args)
101 {
102 if (isFull())
103 {
104 SEAD_ASSERT_MSG(false, "buffer full.");
105 return nullptr;
106 }
107 T* item = new (mFreeList.get()) T(std::forward<Args>(args)...);
109 return item;
110 }
111
112 void insert(s32 pos, const T& item) { PtrArrayImpl::insert(pos, alloc(item)); }
113
114 void erase(int index) { erase(index, 1); }
115
116 void erase(int index, int count)
117 {
118 if (index + count <= size())
119 {
120 for (int i = index; i < index + count; ++i)
121 {
122 auto* ptr = unsafeAt(i);
123 ptr->~T();
125 }
126 }
127 PtrArrayImpl::erase(index, count);
128 }
129
130 void clear()
131 {
132 for (s32 i = 0; i < mPtrNum; ++i)
133 {
134 auto* ptr = unsafeAt(i);
135 ptr->~T();
137 }
138 mPtrNum = 0;
139 }
140
141 using CompareCallback = s32 (*)(const T*, const T*);
142
143 void sort() { sort(compareT); }
144 void sort(CompareCallback cmp) { PtrArrayImpl::sort(cmp); }
145 void heapSort() { heapSort(compareT); }
146 void heapSort(CompareCallback cmp) { PtrArrayImpl::heapSort(cmp); }
147
148 bool equal(const ObjArray& other, CompareCallback cmp) const
149 {
150 return PtrArrayImpl::equal(other, cmp);
151 }
152
153 s32 compare(const ObjArray& other, CompareCallback cmp) const
154 {
155 return PtrArrayImpl::compare(other, cmp);
156 }
157
158 s32 binarySearch(const T* ptr) const { return PtrArrayImpl::binarySearch(ptr, compareT); }
159 s32 binarySearch(const T* ptr, CompareCallback cmp) const
160 {
161 return PtrArrayImpl::binarySearch(ptr, cmp);
162 }
163
164 bool operator==(const ObjArray& other) const { return equal(other, compareT); }
165 bool operator!=(const ObjArray& other) const { return !(*this == other); }
166 bool operator<(const ObjArray& other) const { return compare(other) < 0; }
167 bool operator<=(const ObjArray& other) const { return compare(other) <= 0; }
168 bool operator>(const ObjArray& other) const { return compare(other) > 0; }
169 bool operator>=(const ObjArray& other) const { return compare(other) >= 0; }
170
171 void uniq() { PtrArrayImpl::uniq(compareT); }
172 void uniq(CompareCallback cmp) { PtrArrayImpl::uniq(cmp); }
173
175 {
176 public:
177 iterator(T* const* pptr) : mPPtr{pptr} {}
178 bool operator==(const iterator& other) const { return mPPtr == other.mPPtr; }
179 bool operator!=(const iterator& other) const { return !(*this == other); }
181 {
182 ++mPPtr;
183 return *this;
184 }
185 T& operator*() const { return **mPPtr; }
186 T* operator->() const { return *mPPtr; }
187
188 private:
189 T* const* mPPtr;
190 };
191
192 iterator begin() const { return iterator(data()); }
193 iterator end() const { return iterator(data() + mPtrNum); }
194
196 {
197 public:
198 constIterator(const T* const* pptr) : mPPtr{pptr} {}
199 bool operator==(const constIterator& other) const { return mPPtr == other.mPPtr; }
200 bool operator!=(const constIterator& other) const { return !(*this == other); }
202 {
203 ++mPPtr;
204 return *this;
205 }
206 const T& operator*() const { return **mPPtr; }
207 const T* operator->() const { return *mPPtr; }
208
209 private:
210 const T* const* mPPtr;
211 };
212
214 constIterator constEnd() const { return constIterator(data() + mPtrNum); }
215
216 T** data() const { return reinterpret_cast<T**>(mPtrs); }
217
218private:
219 union Node
220 {
223 };
224
225public:
226 static constexpr size_t ElementSize = sizeof(Node);
227
228 static constexpr size_t calculateWorkBufferSize(size_t n)
229 {
230 return n * (ElementSize + sizeof(T*));
231 }
232
233protected:
234 T* alloc(const T& item)
235 {
236 void* storage = mFreeList.get();
237 if (!storage)
238 return nullptr;
239 return new (storage) T(item);
240 }
241
242 static s32 compareT(const void* a, const void* b)
243 {
244 return compareT(static_cast<const T*>(a), static_cast<const T*>(b));
245 }
246
247 static s32 compareT(const T* a, const T* b)
248 {
249 if (*a < *b)
250 return -1;
251 if (*b < *a)
252 return 1;
253 return 0;
254 }
255
256protected:
258};
259
260template <typename T, s32 N>
261class FixedObjArray : public ObjArray<T>
262{
263public:
265
266 // These do not make sense for a *fixed* array.
267 void setBuffer(s32 ptrNumMax, void* buf) = delete;
268 void allocBuffer(s32 ptrNumMax, Heap* heap, s32 alignment = cDefaultAlignment) = delete;
269 bool tryAllocBuffer(s32 ptrNumMax, Heap* heap, s32 alignment = cDefaultAlignment) = delete;
270 void freeBuffer() = delete;
271
272private:
273 alignas(std::max(alignof(T), alignof(T*))) u8 mWork[ObjArray<T>::calculateWorkBufferSize(N)];
274};
275
276} // namespace sead
Definition seadObjArray.h:262
u8 mWork[ObjArray< T >::calculateWorkBufferSize(N)]
Definition seadObjArray.h:273
void freeBuffer()=delete
void allocBuffer(s32 ptrNumMax, Heap *heap, s32 alignment=cDefaultAlignment)=delete
FixedObjArray()
Definition seadObjArray.h:264
void setBuffer(s32 ptrNumMax, void *buf)=delete
bool tryAllocBuffer(s32 ptrNumMax, Heap *heap, s32 alignment=cDefaultAlignment)=delete
Definition seadFreeList.h:10
void put(void *ptr)
Definition seadFreeList.h:54
void * work() const
Definition seadFreeList.h:52
void * get()
Definition seadFreeList.h:36
void cleanup()
Definition seadFreeList.h:46
Definition seadHeap.h:23
Definition seadObjArray.h:196
constIterator & operator++()
Definition seadObjArray.h:201
const T *const * mPPtr
Definition seadObjArray.h:210
const T & operator*() const
Definition seadObjArray.h:206
bool operator==(const constIterator &other) const
Definition seadObjArray.h:199
bool operator!=(const constIterator &other) const
Definition seadObjArray.h:200
const T * operator->() const
Definition seadObjArray.h:207
constIterator(const T *const *pptr)
Definition seadObjArray.h:198
Definition seadObjArray.h:175
bool operator!=(const iterator &other) const
Definition seadObjArray.h:179
T * operator->() const
Definition seadObjArray.h:186
T & operator*() const
Definition seadObjArray.h:185
iterator & operator++()
Definition seadObjArray.h:180
T *const * mPPtr
Definition seadObjArray.h:189
iterator(T *const *pptr)
Definition seadObjArray.h:177
bool operator==(const iterator &other) const
Definition seadObjArray.h:178
Definition seadObjArray.h:14
static constexpr size_t calculateWorkBufferSize(size_t n)
Definition seadObjArray.h:228
void heapSort()
Definition seadObjArray.h:145
static s32 compareT(const T *a, const T *b)
Definition seadObjArray.h:247
void insert(s32 pos, const T &item)
Definition seadObjArray.h:112
void pushBack(const T &item)
Definition seadObjArray.h:86
void erase(int index, int count)
Definition seadObjArray.h:116
bool operator<=(const ObjArray &other) const
Definition seadObjArray.h:167
void erase(int index)
Definition seadObjArray.h:114
void sort(CompareCallback cmp)
Definition seadObjArray.h:144
s32 compare(const ObjArray &other, CompareCallback cmp) const
Definition seadObjArray.h:153
sead::FreeList mFreeList
Definition seadObjArray.h:257
bool operator==(const ObjArray &other) const
Definition seadObjArray.h:164
void freeBuffer()
Definition seadObjArray.h:62
constIterator constEnd() const
Definition seadObjArray.h:214
void uniq()
Definition seadObjArray.h:171
bool operator!=(const ObjArray &other) const
Definition seadObjArray.h:165
T ** data() const
Definition seadObjArray.h:216
T * at(s32 pos) const
Definition seadObjArray.h:77
T * front() const
Definition seadObjArray.h:83
constIterator constBegin() const
Definition seadObjArray.h:213
T * alloc(const T &item)
Definition seadObjArray.h:234
T * emplaceBack(Args &&... args)
Definition seadObjArray.h:100
bool operator>=(const ObjArray &other) const
Definition seadObjArray.h:169
void setBuffer(s32 max_num, void *buf)
Definition seadObjArray.h:50
iterator end() const
Definition seadObjArray.h:193
void sort()
Definition seadObjArray.h:143
T * operator[](s32 pos) const
Definition seadObjArray.h:80
iterator begin() const
Definition seadObjArray.h:192
bool tryAllocBuffer(s32 capacity, Heap *heap, s32 alignment=cDefaultAlignment)
Definition seadObjArray.h:32
static constexpr size_t ElementSize
Definition seadObjArray.h:226
ObjArray(s32 max_num, void *buf)
Definition seadObjArray.h:17
bool equal(const ObjArray &other, CompareCallback cmp) const
Definition seadObjArray.h:148
void allocBuffer(s32 capacity, Heap *heap, s32 alignment=cDefaultAlignment)
Definition seadObjArray.h:19
void clear()
Definition seadObjArray.h:130
T * back() const
Definition seadObjArray.h:84
ObjArray()=default
void uniq(CompareCallback cmp)
Definition seadObjArray.h:172
T * operator()(s32 pos) const
Definition seadObjArray.h:79
bool operator>(const ObjArray &other) const
Definition seadObjArray.h:168
s32 binarySearch(const T *ptr, CompareCallback cmp) const
Definition seadObjArray.h:159
static s32 compareT(const void *a, const void *b)
Definition seadObjArray.h:242
T * unsafeAt(s32 pos) const
Definition seadObjArray.h:78
void heapSort(CompareCallback cmp)
Definition seadObjArray.h:146
bool operator<(const ObjArray &other) const
Definition seadObjArray.h:166
s32 binarySearch(const T *ptr) const
Definition seadObjArray.h:158
Definition seadPtrArray.h:13
void uniq(CompareCallbackImpl cmp)
bool isBufferReady() const
Definition seadPtrArray.h:29
void heapSort(CompareCallbackImpl cmp)
bool equal(const PtrArrayImpl &o, CompareCallbackImpl cmp) const
void ** mPtrs
Definition seadPtrArray.h:103
void pushBack(void *ptr)
Definition seadPtrArray.h:60
bool isFull() const
Definition seadPtrArray.h:31
void sort(CompareCallbackImpl cmp)
Definition seadPtrArray.cpp:44
Definition seadAssert.h:44
#define SEAD_ASSERT(condition)
Definition seadAssert.h:24
#define SEAD_ASSERT_MSG(condition, format,...)
Definition seadAssert.h:33
Definition seadObjArray.h:220
void * next_node
Definition seadObjArray.h:221
T elem
Definition seadObjArray.h:222