sead
Loading...
Searching...
No Matches
seadRingBuffer.h
Go to the documentation of this file.
1#ifndef SEAD_RING_BUFFER_H_
2#define SEAD_RING_BUFFER_H_
3
4#include <basis/seadAssert.h>
5#include <basis/seadTypes.h>
6
7namespace sead {
8
9class Heap;
10
11template <typename T>
13{
14public:
16 : mBuffer(nullptr)
17 , mNum(0)
18 , mHead(0)
19 , mNumMax(0)
20 {
21 }
22
23 void setBuffer(s32 numMax, T* buf)
24 {
25 if (numMax > 0)
26 {
27 if (buf != nullptr)
28 {
29 mBuffer = buf;
30 mNum = 0;
31 mHead = 0;
32 mNumMax = numMax;
33 }
34 else
35 {
36 SEAD_ASSERT_MSG(false, "buf is null");
37 }
38 }
39 else
40 {
41 SEAD_ASSERT_MSG(false, "numMax[%d] must be larger than zero", numMax);
42 }
43 }
44
45 void allocBuffer(s32 numMax, Heap* heap, s32 alignment = 4);
46 bool tryAllocBuffer(s32 numMax, Heap* heap, s32 alignment = 4);
47 void freeBuffer();
48 bool isBufferReady() const { return mBuffer != nullptr; }
49 bool isEmpty() const { return mNum == 0; }
50 bool isFull() const { return mNum >= mNumMax; }
51 s32 size() const { return mNum; }
52 s32 maxSize() const { return mNumMax; }
53
54 void clear()
55 {
56 mNum = 0;
57 mHead = 0;
58 }
59
60 // ...
61
62 T& operator[] (s32 x)
63 {
64 if (static_cast<u32>(x) < static_cast<u32>(mNum))
65 {
66 return mBuffer[calcRealIndex(x)];
67 }
68 else
69 {
70 SEAD_ASSERT_MSG(false, "index exceeded [%d/%d/%d]", x, mNum, mNumMax);
71 return mBuffer[0];
72 }
73 }
74
75 const T& operator[] (s32 x) const
76 {
77 if (static_cast<u32>(x) < static_cast<u32>(mNum))
78 {
79 return mBuffer[calcRealIndex(x)];
80 }
81 else
82 {
83 SEAD_ASSERT_MSG(false, "index exceeded [%d/%d/%d]", x, mNum, mNumMax);
84 return mBuffer[0];
85 }
86 }
87
88 T* get(s32 x)
89 {
90 if (static_cast<u32>(x) < static_cast<u32>(mNum))
91 {
92 return &mBuffer[calcRealIndex(x)];
93 }
94 else
95 {
96 SEAD_ASSERT_MSG(false, "index exceeded [%d/%d/%d]", x, mNum, mNumMax);
97 return nullptr;
98 }
99 }
100
101 const T* get(s32 x) const
102 {
103 if (static_cast<u32>(x) < static_cast<u32>(mNum))
104 {
105 return &mBuffer[calcRealIndex(x)];
106 }
107 else
108 {
109 SEAD_ASSERT_MSG(false, "index exceeded [%d/%d/%d]", x, mNum, mNumMax);
110 return nullptr;
111 }
112 }
113
114 T* unsafeGet(s32 x)
115 {
116 SEAD_ASSERT_MSG(static_cast<u32>(x) < static_cast<u32>(mNum), "index exceeded [%d/%d/%d]", x, mNum, mNumMax);
117 return &mBuffer[calcRealIndex(x)];
118 }
119
120 const T* unsafeGet(s32 x) const
121 {
122 SEAD_ASSERT_MSG(static_cast<u32>(x) < static_cast<u32>(mNum), "index exceeded [%d/%d/%d]", x, mNum, mNumMax);
123 return &mBuffer[calcRealIndex(x)];
124 }
125
126 T& front()
127 {
128 return *unsafeGet(0);
129 }
130
131 const T& front() const
132 {
133 return *unsafeGet(0);
134 }
135
136 T& back()
137 {
138 if (mNum > 0)
139 {
140 return mBuffer[calcRealIndex(mNum - 1)];
141 }
142 else
143 {
144 SEAD_ASSERT_MSG(false, "no element");
145 return mBuffer[0];
146 }
147 }
148
149 const T& back() const
150 {
151 if (mNum > 0)
152 return *unsafeGet(mNum - 1);
153 else
154 {
155 SEAD_ASSERT_MSG(false, "no element");
156 return mBuffer[0];
157 }
158 }
159
160 // ...
161
162 void pushBack(const T& obj)
163 {
164 if (isFull())
165 {
166 SEAD_ASSERT_MSG(false, "list is full.");
167 return;
168 }
169
170 *unsafeGet(mNum++) = obj;
171 }
172
173 // ...
174
175protected:
176 s32 calcRealIndex(s32 x) const
177 {
178 s32 idx = mHead + x;
179 if (idx >= mNumMax)
180 idx -= mNumMax;
181 return idx;
182 }
183
184public:
186 {
187 public:
188 explicit iterator(RingBuffer* buffer, s32 index = 0)
189 : mIndex(index),
190 mBuffer(buffer)
191 {
192 }
193
194 friend bool operator==(const iterator& lhs, const iterator& rhs)
195 {
196 return lhs.mBuffer == rhs.mBuffer && lhs.mIndex == rhs.mIndex;
197 }
198
199 friend bool operator!=(const iterator& lhs, const iterator& rhs)
200 {
201 return lhs.mBuffer != rhs.mBuffer || lhs.mIndex != rhs.mIndex;
202 }
203
205 {
206 ++mIndex;
207 return *this;
208 }
209
210 T& operator*() const { return *mBuffer->unsafeGet(mIndex); }
211 T* operator->() const { return mBuffer->unsafeGet(mIndex); }
212
213 s32 getIndex() const { return mIndex; }
214
215 private:
218 };
219
220public:
222 {
223 return iterator(this);
224 }
225
227 {
228 return iterator(this, size());
229 }
230
231protected:
236};
237
238template <typename T, s32 N>
240{
241public:
243 : RingBuffer<T>()
244 {
245 RingBuffer<T>::setBuffer(N, mWork);
246 }
247
248protected:
249 void setBuffer(s32 numMax, T* buf);
250 void allocBuffer(s32 numMax, Heap* heap, s32 alignment = 4);
251 bool tryAllocBuffer(s32 numMax, Heap* heap, s32 alignment = 4);
253
254protected:
255 T mWork[N];
256};
257
258}
259
260#endif // SEAD_RING_BUFFER_H_
Definition seadRingBuffer.h:240
bool tryAllocBuffer(s32 numMax, Heap *heap, s32 alignment=4)
void setBuffer(s32 numMax, T *buf)
FixedRingBuffer()
Definition seadRingBuffer.h:242
T mWork[N]
Definition seadRingBuffer.h:255
void allocBuffer(s32 numMax, Heap *heap, s32 alignment=4)
Definition seadHeap.h:23
Definition seadRingBuffer.h:186
RingBuffer * mBuffer
Definition seadRingBuffer.h:217
T & operator*() const
Definition seadRingBuffer.h:210
friend bool operator==(const iterator &lhs, const iterator &rhs)
Definition seadRingBuffer.h:194
iterator & operator++()
Definition seadRingBuffer.h:204
iterator(RingBuffer *buffer, s32 index=0)
Definition seadRingBuffer.h:188
s32 getIndex() const
Definition seadRingBuffer.h:213
friend bool operator!=(const iterator &lhs, const iterator &rhs)
Definition seadRingBuffer.h:199
T * operator->() const
Definition seadRingBuffer.h:211
s32 mIndex
Definition seadRingBuffer.h:216
Definition seadRingBuffer.h:13
bool isBufferReady() const
Definition seadRingBuffer.h:48
iterator end()
Definition seadRingBuffer.h:226
T & back()
Definition seadRingBuffer.h:136
const T & back() const
Definition seadRingBuffer.h:149
void allocBuffer(s32 numMax, Heap *heap, s32 alignment=4)
bool tryAllocBuffer(s32 numMax, Heap *heap, s32 alignment=4)
void clear()
Definition seadRingBuffer.h:54
s32 calcRealIndex(s32 x) const
Definition seadRingBuffer.h:176
s32 mNumMax
Definition seadRingBuffer.h:233
s32 mHead
Definition seadRingBuffer.h:234
s32 mNum
Definition seadRingBuffer.h:235
void pushBack(const T &obj)
Definition seadRingBuffer.h:162
RingBuffer()
Definition seadRingBuffer.h:15
const T & operator[](s32 x) const
Definition seadRingBuffer.h:75
T & front()
Definition seadRingBuffer.h:126
T & operator[](s32 x)
Definition seadRingBuffer.h:62
s32 size() const
Definition seadRingBuffer.h:51
iterator begin()
Definition seadRingBuffer.h:221
const T * unsafeGet(s32 x) const
Definition seadRingBuffer.h:120
T * get(s32 x)
Definition seadRingBuffer.h:88
bool isFull() const
Definition seadRingBuffer.h:50
void setBuffer(s32 numMax, T *buf)
Definition seadRingBuffer.h:23
const T * get(s32 x) const
Definition seadRingBuffer.h:101
const T & front() const
Definition seadRingBuffer.h:131
bool isEmpty() const
Definition seadRingBuffer.h:49
T * mBuffer
Definition seadRingBuffer.h:232
T * unsafeGet(s32 x)
Definition seadRingBuffer.h:114
s32 maxSize() const
Definition seadRingBuffer.h:52
Definition seadAssert.h:44
#define SEAD_ASSERT_MSG(condition, format,...)
Definition seadAssert.h:33