OpenBarnyard
 
Loading...
Searching...
No Matches
T2Vector.h
Go to the documentation of this file.
1#pragma once
2
4
5template <typename T, TINT MaxSize>
7{
8public:
9 class Iterator
10 {
11 public:
12 friend class T2Vector;
13
14 public:
15 constexpr Iterator( T2Vector* a_pVector )
16 : m_iIndex( 0 ), m_pVector( a_pVector ) {}
17 constexpr Iterator( TINT a_iIndex, T2Vector* a_pVector )
18 : m_iIndex( a_iIndex ), m_pVector( a_pVector ) {}
19 constexpr Iterator( const Iterator& a_rOther )
20 : m_iIndex( a_rOther.m_iIndex ), m_pVector( a_rOther.m_pVector ) {}
21
22 constexpr TINT Index() const noexcept
23 {
24 return m_iIndex;
25 }
26
27 T* Get() noexcept
28 {
29 return &m_pVector->At( m_iIndex );
30 }
31
32 const T* Get() const noexcept
33 {
34 return &m_pVector->At( m_iIndex );
35 }
36
37 T& Value() noexcept
38 {
39 return m_pVector->At( m_iIndex );
40 }
41
42 const T& Value() const noexcept
43 {
44 return m_pVector->At( m_iIndex );
45 }
46
47 Iterator Next() const
48 {
49 Iterator temp = *this;
50 temp.m_iIndex += 1;
51 return temp;
52 }
53
54 Iterator Prev() const
55 {
56 Iterator temp = *this;
57 temp.m_iIndex -= 1;
58 return temp;
59 }
60
61 operator T*()
62 {
63 return &Value();
64 }
65
66 operator const T*() const
67 {
68 return &Value();
69 }
70
71 T& operator*() noexcept
72 {
73 return Value();
74 }
75
76 const T& operator*() const noexcept
77 {
78 return Value();
79 }
80
81 T* operator->() noexcept
82 {
83 return &Value();
84 }
85
86 const T* operator->() const noexcept
87 {
88 return &Value();
89 }
90
91 TBOOL operator==( const Iterator& a_rOther ) const noexcept
92 {
93 return a_rOther.m_pVector == m_pVector && a_rOther.m_iIndex == m_iIndex;
94 }
95
96 TBOOL operator>( const Iterator& a_rOther ) const noexcept
97 {
98 return a_rOther.m_pVector == m_pVector && a_rOther.m_iIndex > m_iIndex;
99 }
100
101 TBOOL operator>=( const Iterator& a_rOther ) const noexcept
102 {
103 return a_rOther.m_pVector == m_pVector && a_rOther.m_iIndex >= m_iIndex;
104 }
105
106 TBOOL operator<( const Iterator& a_rOther ) const noexcept
107 {
108 return a_rOther.m_pVector == m_pVector && a_rOther.m_iIndex < m_iIndex;
109 }
110
111 TBOOL operator<=( const Iterator& a_rOther ) const noexcept
112 {
113 return a_rOther.m_pVector == m_pVector && a_rOther.m_iIndex <= m_iIndex;
114 }
115
116 constexpr Iterator operator++( TINT ) noexcept
117 {
118 Iterator temp = *this;
119 m_iIndex++;
120 return temp;
121 }
122
123 constexpr Iterator operator--( TINT ) noexcept
124 {
125 Iterator temp = *this;
126 m_iIndex--;
127 return temp;
128 }
129
130 constexpr Iterator& operator++() noexcept
131 {
132 m_iIndex++;
133 return *this;
134 }
135
136 constexpr Iterator& operator--() noexcept
137 {
138 m_iIndex--;
139 return *this;
140 }
141
142 constexpr Iterator& operator=( const Iterator& a_rOther ) noexcept
143 {
144 m_iIndex = a_rOther.m_iIndex;
145 m_pVector = a_rOther.m_pVector;
146 return *this;
147 }
148
149 Iterator operator+( TINT a_uiValue ) const noexcept
150 {
151 TASSERT( m_iIndex + a_uiValue < m_pVector->Size() );
152 return Iterator( m_iIndex + a_uiValue, m_pVector );
153 }
154
155 Iterator operator-( TINT a_uiValue ) const noexcept
156 {
157 TASSERT( m_iIndex - a_uiValue < m_pVector->Size() );
158 return Iterator( m_iIndex - a_uiValue, m_pVector );
159 }
160
161 Iterator& operator+=( TINT a_uiValue ) const noexcept
162 {
163 TASSERT( m_iIndex + a_uiValue < m_pVector->Size() );
164 m_iIndex += a_uiValue;
165 return *this;
166 }
167
168 Iterator& operator-=( TINT a_uiValue ) const noexcept
169 {
170 TASSERT( m_iIndex - a_uiValue < m_pVector->Size() );
171 m_iIndex -= a_uiValue;
172 return *this;
173 }
174
175 private:
176 TINT m_iIndex;
177 T2Vector* m_pVector;
178 };
179
180public:
181 constexpr static TINT CAPACITY = MaxSize;
182
183public:
185 {
186 m_iNumElements = 0;
187 }
188
190 {
191 Clear();
192 }
193
194 Iterator InsertBefore( Iterator a_itInsertBefore, const T& a_rcItem = T() )
195 {
196 InsertGap( a_itInsertBefore.Index(), 1 );
197 TConstruct<T>( &AtUnsafe( a_itInsertBefore.Index() ), a_rcItem );
198
199 return Iterator( a_itInsertBefore.Index(), this );
200 }
201
202 Iterator InsertAfter( Iterator a_itInsertAfter, const T& a_rcItem = T() )
203 {
204 InsertGap( a_itInsertAfter.Index() + 1, 1 );
205 TConstruct<T>( &AtUnsafe( a_itInsertAfter.Index() + 1 ), a_rcItem );
206
207 return Iterator( a_itInsertAfter.Index() + 1, this );
208 }
209
210 template <class... Args>
211 Iterator EmplaceBack( Args&&... args )
212 {
213 TASSERT( m_iNumElements < CAPACITY );
214 TConstruct<T>( &AtUnsafe( m_iNumElements++ ), std::forward<Args>( args )... );
215
216 return Iterator( m_iNumElements - 1, this );
217 }
218
219 Iterator PushBack( const T& item = T() )
220 {
221 TASSERT( m_iNumElements < CAPACITY );
222 TConstruct<T>( &AtUnsafe( m_iNumElements++ ), item );
223
224 return Iterator( m_iNumElements - 1, this );
225 }
226
227 void PopBack()
228 {
229 TASSERT( m_iNumElements > 0 );
230 AtUnsafe( --m_iNumElements ).~T();
231 }
232
233 void PopFront()
234 {
235 TASSERT( m_iNumElements > 0 );
236 Erase( Begin() );
237 }
238
239 void Clear()
240 {
241 for ( TINT i = 0; i < Size(); i++ )
242 AtUnsafe( i ).~T();
243
244 m_iNumElements = 0;
245 }
246
247 void Copy( const T2Vector<T, MaxSize>& a_rcCopyFrom )
248 {
249 TINT i;
250 for ( i = 0; i < a_rcCopyFrom.Size(); i++ )
251 {
252 TConstruct<T>( &AtUnsafe( i ), a_rcCopyFrom.At( i ) );
253 }
254
255 if ( Size() > a_rcCopyFrom.Size() )
256 {
257 for ( ; i < Size(); i++ )
258 {
259 AtUnsafe( i ).~T();
260 }
261 }
262
263 m_iNumElements = a_rcCopyFrom.Size();
264 }
265
266 Iterator Find( const T& a_rValue )
267 {
268 for ( auto it = Begin(); it != End(); it++ )
269 {
270 if ( it.Value() == a_rValue )
271 return it;
272 }
273
274 return End();
275 }
276
277 // Erases element preserving order
278 void Erase( const Iterator& a_rIterator )
279 {
280 TINT uiItemIndex = a_rIterator.Index();
281 TASSERT( uiItemIndex < m_iNumElements );
282
283 AtUnsafe( uiItemIndex ).~T();
284
285 if ( uiItemIndex + 1 < Size() )
286 {
287 for ( TINT i = uiItemIndex + 1; i < Size(); i++ )
288 {
289 TConstruct<T>( &AtUnsafe( i - 1 ), std::move( AtUnsafe( i ) ) );
290 AtUnsafe( i ).~T();
291 }
292 }
293
294 m_iNumElements--;
295 }
296
297 // Finds and erases element preserving order
298 void FindAndErase( const T& a_rcItem )
299 {
300 auto it = Find( a_rcItem );
301
302 if ( it != End() )
303 Erase( it );
304 }
305
306 // Erases element ignoring order but with a faster algorithm
307 void EraseFast( Iterator& a_rIterator )
308 {
309 TINT uiItemIndex = a_rIterator.Index();
310 TASSERT( uiItemIndex < m_iNumElements );
311
312 a_rIterator.Value() = Back().Value();
313 PopBack();
314 }
315
316 // Finds and erases element ignoring order but with a faster algorithm
317 void FindAndEraseFast( const T& a_rcItem )
318 {
319 auto it = Find( a_rcItem );
320
321 if ( it != End() )
322 EraseFast( it );
323 }
324
325 TINT Size() const
326 {
327 return m_iNumElements;
328 }
329
330 constexpr TINT Capacity() const
331 {
332 return CAPACITY;
333 }
334
336 {
337 return Size() == 0;
338 }
339
341 {
342 TASSERT( m_iNumElements > 0 );
343 return Iterator( 0, this );
344 }
345
347 {
348 TASSERT( m_iNumElements > 0 );
349 return Iterator( m_iNumElements - 1, this );
350 }
351
352 constexpr Iterator Begin()
353 {
354 return Iterator( this );
355 }
356
357 constexpr Iterator End()
358 {
359 return Iterator( m_iNumElements, this );
360 }
361
362 T& At( TINT a_iIndex )
363 {
364 TASSERT( a_iIndex < m_iNumElements );
365 return *(T*)( m_aBuffer + a_iIndex * sizeof( T ) );
366 }
367
368 const T& At( TINT a_iIndex ) const
369 {
370 TASSERT( a_iIndex < m_iNumElements );
371 return *(const T*)( m_aBuffer + a_iIndex * sizeof( T ) );
372 }
373
374 T& operator[]( TINT a_iIndex )
375 {
376 return At( a_iIndex );
377 }
378
379 const T& operator[]( TINT a_iIndex ) const
380 {
381 return At( a_iIndex );
382 }
383
384private:
385 TFORCEINLINE constexpr T& AtUnsafe( TINT a_iIndex )
386 {
387 return *( (T*)( m_aBuffer ) + a_iIndex );
388 }
389
390 TFORCEINLINE constexpr const T& AtUnsafe( TINT a_iIndex ) const
391 {
392 return *( (T*)( m_aBuffer ) + a_iIndex );
393 }
394
395 void InsertGap( TINT a_iGapAt, TINT a_iGapSize, TBOOL a_bUseMemMove = TTRUE )
396 {
397 TASSERT( m_iNumElements + a_iGapSize <= CAPACITY );
398
399 if ( m_iNumElements > a_iGapAt )
400 {
401 if ( a_bUseMemMove )
402 {
403 // Unsafe way but suitable with simple types
404 // Note: Seems that in Barnyard there's no other way of adding a gap but in newer Toshi branches there is so I'm adding it here too anyways
405 TUtil::MemMove( &AtUnsafe( a_iGapAt + a_iGapSize ), &AtUnsafe( a_iGapAt ), ( m_iNumElements - a_iGapAt ) * sizeof( T ) );
406 }
407 else
408 {
409 // This is much safer
410 for ( TINT i = m_iNumElements - 1, k = i + a_iGapSize; i >= a_iGapAt; i--, k-- )
411 {
412 TConstruct<T>( &AtUnsafe( k ), std::move( AtUnsafe( i ) ) );
413 AtUnsafe( i ).~T();
414 }
415 }
416 }
417
418 m_iNumElements += a_iGapSize;
419 }
420
421private:
422 TINT m_iNumElements;
423 TBYTE m_aBuffer[ MaxSize * sizeof( T ) ];
424};
425
TFORCEINLINE T * TConstruct(T *a_pMemory, Args &&... args)
Constructs an object in place.
Definition TMemory.h:431
#define TASSERT(X,...)
Definition Defines.h:138
#define TOSHI_NAMESPACE_START
Definition Defines.h:47
#define TFORCEINLINE
Definition Defines.h:74
#define TOSHI_NAMESPACE_END
Definition Defines.h:50
int TINT
Definition Typedefs.h:7
#define TTRUE
Definition Typedefs.h:25
bool TBOOL
Definition Typedefs.h:6
uint8_t TBYTE
Definition Typedefs.h:19
TBOOL IsEmpty() const
Definition T2Vector.h:335
void PopFront()
Definition T2Vector.h:233
void FindAndErase(const T &a_rcItem)
Definition T2Vector.h:298
Iterator InsertAfter(Iterator a_itInsertAfter, const T &a_rcItem=T())
Definition T2Vector.h:202
void Copy(const T2Vector< T, MaxSize > &a_rcCopyFrom)
Definition T2Vector.h:247
void Clear()
Definition T2Vector.h:239
Iterator Front()
Definition T2Vector.h:340
Iterator PushBack(const T &item=T())
Definition T2Vector.h:219
T & operator[](TINT a_iIndex)
Definition T2Vector.h:374
const T & At(TINT a_iIndex) const
Definition T2Vector.h:368
void PopBack()
Definition T2Vector.h:227
constexpr TINT Capacity() const
Definition T2Vector.h:330
Iterator Back()
Definition T2Vector.h:346
void Erase(const Iterator &a_rIterator)
Definition T2Vector.h:278
T & At(TINT a_iIndex)
Definition T2Vector.h:362
~T2Vector()
Definition T2Vector.h:189
Iterator EmplaceBack(Args &&... args)
Definition T2Vector.h:211
constexpr Iterator Begin()
Definition T2Vector.h:352
Iterator Find(const T &a_rValue)
Definition T2Vector.h:266
TINT Size() const
Definition T2Vector.h:325
void FindAndEraseFast(const T &a_rcItem)
Definition T2Vector.h:317
const T & operator[](TINT a_iIndex) const
Definition T2Vector.h:379
static constexpr TINT CAPACITY
Definition T2Vector.h:181
Iterator InsertBefore(Iterator a_itInsertBefore, const T &a_rcItem=T())
Definition T2Vector.h:194
void EraseFast(Iterator &a_rIterator)
Definition T2Vector.h:307
constexpr Iterator End()
Definition T2Vector.h:357
constexpr Iterator & operator=(const Iterator &a_rOther) noexcept
Definition T2Vector.h:142
friend class T2Vector
Definition T2Vector.h:12
const T & Value() const noexcept
Definition T2Vector.h:42
Iterator Next() const
Definition T2Vector.h:47
Iterator Prev() const
Definition T2Vector.h:54
const T * Get() const noexcept
Definition T2Vector.h:32
TBOOL operator<(const Iterator &a_rOther) const noexcept
Definition T2Vector.h:106
constexpr Iterator & operator++() noexcept
Definition T2Vector.h:130
T & Value() noexcept
Definition T2Vector.h:37
T & operator*() noexcept
Definition T2Vector.h:71
T * operator->() noexcept
Definition T2Vector.h:81
constexpr Iterator(T2Vector *a_pVector)
Definition T2Vector.h:15
constexpr Iterator & operator--() noexcept
Definition T2Vector.h:136
TBOOL operator>(const Iterator &a_rOther) const noexcept
Definition T2Vector.h:96
Iterator operator-(TINT a_uiValue) const noexcept
Definition T2Vector.h:155
const T & operator*() const noexcept
Definition T2Vector.h:76
const T * operator->() const noexcept
Definition T2Vector.h:86
constexpr Iterator(const Iterator &a_rOther)
Definition T2Vector.h:19
T * Get() noexcept
Definition T2Vector.h:27
Iterator & operator+=(TINT a_uiValue) const noexcept
Definition T2Vector.h:161
constexpr TINT Index() const noexcept
Definition T2Vector.h:22
TBOOL operator<=(const Iterator &a_rOther) const noexcept
Definition T2Vector.h:111
constexpr Iterator(TINT a_iIndex, T2Vector *a_pVector)
Definition T2Vector.h:17
Iterator operator+(TINT a_uiValue) const noexcept
Definition T2Vector.h:149
Iterator & operator-=(TINT a_uiValue) const noexcept
Definition T2Vector.h:168
TBOOL operator==(const Iterator &a_rOther) const noexcept
Definition T2Vector.h:91
constexpr Iterator operator--(TINT) noexcept
Definition T2Vector.h:123
TBOOL operator>=(const Iterator &a_rOther) const noexcept
Definition T2Vector.h:101
constexpr Iterator operator++(TINT) noexcept
Definition T2Vector.h:116
static void * MemMove(void *dst, const void *src, TSIZE size)
Definition TUtil.h:93