123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203 |
- #pragma once
- #include "BFPlatform.h"
- NS_BF_BEGIN;
- class AllocatorCLib
- {
- public:
- template <typename T>
- T* allocate(intptr count)
- {
- return (T*)malloc(sizeof(T) * count);
- }
- void deallocate(void* ptr)
- {
- free(ptr);
- }
- void* rawAllocate(intptr size)
- {
- return malloc(size);
- }
- void rawDeallocate(void* ptr)
- {
- free(ptr);
- }
- bool deallocateAll()
- {
- return false;
- }
- };
- template <typename T, typename TAlloc = AllocatorCLib >
- class ArrayBase : public TAlloc
- {
- public:
- typedef T value_type;
- typedef int int_cosize;
- T* mVals;
- int_cosize mSize;
- int_cosize mAllocSize;
- struct iterator
- {
- public:
- typedef std::random_access_iterator_tag iterator_category;
- typedef T value_type;
- typedef intptr difference_type;
- typedef T* pointer;
- typedef T& reference;
- public:
- T* mPtr;
- public:
- iterator()
- {
- mPtr = NULL;
- }
- iterator(T* ptr)
- {
- mPtr = ptr;
- }
- iterator& operator++()
- {
- mPtr++;
- return *this;
- }
- iterator operator++(int)
- {
- auto prevVal = *this;
- mPtr++;
- return prevVal;
- }
- iterator& operator--()
- {
- mPtr--;
- return *this;
- }
- iterator operator--(int)
- {
- auto prevVal = *this;
- mPtr--;
- return prevVal;
- }
- iterator& operator+=(intptr offset)
- {
- mPtr += offset;
- return *this;
- }
- bool operator!=(const iterator& itr) const
- {
- return itr.mPtr != mPtr;
- }
- bool operator==(const iterator& itr) const
- {
- return itr.mPtr == mPtr;
- }
- intptr operator-(const iterator& itr) const
- {
- return mPtr - itr.mPtr;
- }
- iterator operator+(intptr offset) const
- {
- iterator itr(mPtr + offset);
- return itr;
- }
- iterator operator-(intptr offset) const
- {
- iterator itr(mPtr - offset);
- return itr;
- }
- T& operator*() const
- {
- return *mPtr;
- }
- T* operator->() const
- {
- return mPtr;
- }
- bool operator<(const iterator& val2) const
- {
- return mPtr < val2.mPtr;
- }
- bool operator>(const iterator& val2) const
- {
- return mPtr > val2.mPtr;
- }
- bool operator<=(const iterator& val2) const
- {
- return mPtr <= val2.mPtr;
- }
- bool operator>=(const iterator& val2) const
- {
- return mPtr >= val2.mPtr;
- }
- };
- struct const_iterator
- {
- public:
- typedef std::random_access_iterator_tag iterator_category;
- typedef T value_type;
- typedef intptr difference_type;
- typedef const T* pointer;
- typedef const T& reference;
- public:
- const T* mPtr;
- public:
- const_iterator(const T* ptr)
- {
- mPtr = ptr;
- }
- const_iterator& operator++()
- {
- mPtr++;
- return *this;
- }
- const_iterator operator++(int)
- {
- auto prevVal = *this;
- mPtr++;
- return prevVal;
- }
- bool operator!=(const const_iterator& itr) const
- {
- return itr.mPtr != mPtr;
- }
- bool operator==(const const_iterator& itr) const
- {
- return itr.mPtr == mPtr;
- }
- intptr operator-(const iterator& itr) const
- {
- return mPtr - itr.mPtr;
- }
- const_iterator operator+(intptr offset) const
- {
- const_iterator itr(mPtr + offset);
- return itr;
- }
- const T& operator*() const
- {
- return *mPtr;
- }
- const T* operator->() const
- {
- return mPtr;
- }
- bool operator<(const const_iterator& val2) const
- {
- return mPtr < val2.mPtr;
- }
- };
- private:
-
- public:
- ArrayBase()
- {
- mVals = NULL;
- mSize = 0;
- mAllocSize = 0;
- }
-
- ArrayBase(ArrayBase<T, TAlloc>&& val)
- {
- mVals = val.mVals;
- mSize = val.mSize;
- mAllocSize = val.mAllocSize;
- val.mVals = NULL;
- val.mSize = 0;
- val.mAllocSize = 0;
- }
-
- T& operator[](intptr idx)
- {
- BF_ASSERT((uintptr)idx < (uintptr)mSize);
- return mVals[idx];
- }
- const T& operator[](intptr idx) const
- {
- BF_ASSERT((uintptr)idx < (uintptr)mSize);
- return mVals[idx];
- }
- bool operator==(const ArrayBase& arrB) const
- {
- if (mSize != arrB.mSize)
- return false;
- for (intptr i = 0; i < mSize; i++)
- if (mVals[i] != arrB.mVals[i])
- return false;
- return true;
- }
- bool operator!=(const ArrayBase& arrB) const
- {
- if (mSize != arrB.mSize)
- return true;
- for (intptr i = 0; i < mSize; i++)
- if (mVals[i] != arrB.mVals[i])
- return true;
- return true;
- }
- const_iterator begin() const
- {
- return mVals;
- }
- const_iterator end() const
- {
- return mVals + mSize;
- }
- iterator begin()
- {
- return mVals;
- }
- iterator end()
- {
- return mVals + mSize;
- }
- T& front() const
- {
- return mVals[0];
- }
- T& back() const
- {
- return mVals[mSize - 1];
- }
- intptr size() const
- {
- return mSize;
- }
- int Count() const
- {
- return (int)mSize;
- }
- bool empty() const
- {
- return mSize == 0;
- }
- bool IsEmpty() const
- {
- return mSize == 0;
- }
- intptr GetFreeCount()
- {
- return mAllocSize - mSize;
- }
-
- /*void Free()
- {
- if (mVals != NULL)
- {
- deallocate(mVals);
- }
- mVals = NULL;
- mAllocSize = 0;
- mSize = 0;
- }*/
- T GetSafe(intptr idx)
- {
- if ((idx < 0) || (idx >= mSize))
- return T();
- return mVals[idx];
- }
- void GetSafe(intptr idx, T& val)
- {
- if ((idx < 0) || (idx >= mSize))
- return;
- val = mVals[idx];
- }
- T GetLastSafe()
- {
- if (mSize == 0)
- return T();
- return mVals[mSize - 1];
- }
- T GetFirstSafe()
- {
- if (mSize == 0)
- return T();
- return mVals[0];
- }
- bool Contains(const T& val)
- {
- for (intptr i = 0; i < mSize; i++)
- if (mVals[i] == val)
- return true;
- return false;
- }
- intptr IndexOf(const T& val)
- {
- for (intptr i = 0; i < mSize; i++)
- if (mVals[i] == val)
- return i;
- return -1;
- }
-
- intptr IndexOf(const T& val, int startIdx)
- {
- for (intptr i = startIdx; i < mSize; i++)
- if (mVals[i] == val)
- return i;
- return -1;
- }
- intptr LastIndexOf(const T& val)
- {
- for (intptr i = mSize - 1; i >= 0; i--)
- if (mVals[i] == val)
- return i;
- return -1;
- }
- void MoveTo(ArrayBase<T>& dest)
- {
- dest.mVals = this->mVals;
- dest.mSize = this->mSize;
- dest.mAllocSize = this->mAllocSize;
- this->mVals = NULL;
- this->mSize = 0;
- this->mAllocSize = 0;
- }
- void Sort(std::function<bool(const T&, const T&)> pred)
- {
- std::sort(this->begin(), this->end(), pred);
- }
- };
- // NON-POD
- template <typename T, typename TAlloc, bool TIsPod>
- class ArrayImpl : public ArrayBase<T, TAlloc>
- {
- public:
- typedef int int_cosize;
- protected:
- void MoveArray(T* to, T* from, intptr count)
- {
- if (to < from)
- {
- // Prefer in-order moves
- for (intptr i = 0; i < count; i++)
- new (&to[i]) T(std::move(from[i]));
- }
- else
- {
- for (intptr i = count - 1; i >= 0; i--)
- new (&to[i]) T(std::move(from[i]));
- }
- }
- void SetBufferSize(intptr newSize)
- {
- T* newVals = TAlloc::template allocate<T>(newSize);
- if (this->mVals != NULL)
- {
- if (this->mSize > 0)
- MoveArray(newVals, this->mVals, this->mSize);
- TAlloc::deallocate(this->mVals);
- }
- this->mVals = newVals;
- this->mAllocSize = (int_cosize)newSize;
- }
- void EnsureFree(intptr freeCount)
- {
- if (this->mSize + freeCount > this->mAllocSize)
- SetBufferSize(BF_MAX(this->mAllocSize + this->mAllocSize / 2 + 1, this->mSize + freeCount));
- }
- public:
- using ArrayBase<T, TAlloc>::ArrayBase;
- ArrayImpl() : ArrayBase<T, TAlloc>()
- {
- }
- ArrayImpl(const ArrayImpl& val)
- {
- this->mVals = NULL;
- this->mSize = 0;
- this->mAllocSize = 0;
- *this = val;
- }
- ArrayImpl(ArrayImpl&& val) : ArrayBase<T, TAlloc>(std::move(val))
- {
- }
- ~ArrayImpl()
- {
- for (intptr i = 0; i < this->mSize; i++)
- this->mVals[i].~T(); //-V595
- if (this->mVals != NULL)
- {
- TAlloc::deallocate(this->mVals);
- }
- }
- void Resize(intptr size)
- {
- while (size < this->mSize)
- pop_back();
- if (size > this->mSize)
- {
- Reserve(size);
- while (size > this->mSize)
- new (&this->mVals[this->mSize++]) T();
- }
- }
- void Reserve(intptr size)
- {
- if (size > this->mAllocSize)
- SetBufferSize(size);
- }
- void SetSize(intptr size)
- {
- if (size > this->mAllocSize)
- SetBufferSize(size);
- this->mSize = (int_cosize)size;
- }
- void Clear()
- {
- for (intptr i = 0; i < this->mSize; i++)
- this->mVals[i].~T();
- this->mSize = 0;
- }
- void Dispose()
- {
- Clear();
- delete this->mVals;
- this->mVals = NULL;
- this->mAllocSize = 0;
- }
- ArrayImpl& operator=(const ArrayImpl& val)
- {
- if (&val == this)
- return *this;
- for (intptr i = 0; i < this->mSize; i++)
- this->mVals[i].~T();
- this->mSize = 0;
- if (val.mSize > this->mAllocSize)
- SetBufferSize(val.mSize);
- Resize(val.mSize);
- for (intptr i = 0; i < val.mSize; i++)
- new (&this->mVals[i]) T(val.mVals[i]);
- this->mSize = val.mSize;
- return *this;
- }
- ArrayImpl& operator=(ArrayImpl&& val)
- {
- if (this->mVals != NULL)
- {
- for (intptr i = 0; i < this->mSize; i++)
- this->mVals[i].~T();
- TAlloc::deallocate(this->mVals);
- }
-
- this->mVals = val.mVals;
- this->mSize = val.mSize;
- this->mAllocSize = val.mAllocSize;
- val.mVals = NULL;
- return *this;
- }
- void RemoveAt(intptr idx)
- {
- BF_ASSERT((uintptr)idx < (uintptr)this->mSize);
- this->mVals[idx].~T();
- // If we're removing the last element then we don't have to move anything
- if (idx != this->mSize - 1)
- {
- intptr moveCount = this->mSize - idx - 1;
- MoveArray(this->mVals + idx, this->mVals + idx + 1, moveCount);
- }
- this->mSize--;
- }
- // 'Fast' because it's allowed to change item order
- void RemoveAtFast(intptr idx)
- {
- BF_ASSERT((uintptr)idx < (uintptr)this->mSize);
- this->mVals[idx].~T();
- // If we're removing the last element then we don't have to move anything
- if (idx != this->mSize - 1)
- {
- new (&this->mVals[idx]) T(std::move(this->mVals[this->mSize - 1]));
- }
- this->mSize--;
- }
- void RemoveRange(intptr idx, intptr length)
- {
- BF_ASSERT(
- ((uintptr)idx < (uintptr)this->mSize) &&
- ((uintptr)length > 0) &&
- ((uintptr)(idx + length) <= (uintptr)this->mSize));
- for (intptr i = idx; i < idx + length; i++)
- this->mVals[i].~T();
- // If we're removing the last element then we don't have to move anything
- if (idx != this->mSize - length)
- {
- intptr moveCount = this->mSize - idx - length;
- MoveArray(this->mVals + idx, this->mVals + idx + length, moveCount);
- }
- this->mSize -= (int_cosize)length;
- }
- void Insert(intptr idx, const T& val)
- {
- BF_ASSERT((uintptr)idx <= (uintptr)this->mSize);
- if (this->mSize >= this->mAllocSize)
- {
- intptr newSize = this->mAllocSize + this->mAllocSize / 2 + 1;
- T* newVals = TAlloc::template allocate<T>(newSize);
- if (this->mVals != NULL)
- {
- if (idx > 0) // Copy left of idx
- MoveArray(newVals, this->mVals, idx);
- if (idx < this->mSize) // Copy right of idx
- MoveArray(newVals + idx + 1, this->mVals + idx, this->mSize - idx);
- TAlloc::deallocate(this->mVals);
- }
- this->mVals = newVals;
- this->mAllocSize = (int_cosize)newSize;
- }
- else if (idx != this->mSize)
- {
- intptr moveCount = this->mSize - idx;
- MoveArray(this->mVals + idx + 1, this->mVals + idx, moveCount);
- }
- new (&this->mVals[idx]) T(val);
- this->mSize++;
- }
- void Insert(intptr idx, const T* vals, intptr size)
- {
- BF_ASSERT((uintptr)idx <= (uintptr)this->mSize);
- if (this->mSize + size > this->mAllocSize)
- {
- intptr newSize = BF_MAX(this->mSize + size, this->mAllocSize + this->mAllocSize / 2 + 1);
- T* newVals = TAlloc::template allocate<T>(newSize);
- if (this->mVals != NULL)
- {
- if (idx > 0) // Copy left of idx
- MoveArray(newVals, this->mVals, idx);
- if (idx < this->mSize) // Copy right of idx
- MoveArray(newVals + idx + size, this->mVals + idx, this->mSize - idx);
- TAlloc::deallocate(this->mVals);
- }
- this->mVals = newVals;
- this->mAllocSize = (int_cosize)newSize;
- }
- else if (idx != this->mSize)
- {
- intptr moveCount = this->mSize - idx;
- MoveArray(this->mVals + idx + size, this->mVals + idx, moveCount);
- }
- for (intptr i = 0; i < size; i++)
- new (&this->mVals[idx + i]) T(vals[i]);
- this->mSize += (int_cosize)size;
- }
- void Insert(intptr idx, const T& val, intptr count)
- {
- BF_ASSERT((uintptr)idx <= (uintptr)this->mSize);
- if (this->mSize + count > this->mAllocSize)
- {
- intptr newSize = BF_MAX(this->mSize + count, this->mAllocSize + this->mAllocSize / 2 + 1);
- T* newVals = TAlloc::template allocate<T>(newSize);
- if (this->mVals != NULL)
- {
- if (idx > 0) // Copy left of idx
- MoveArray(this->newVals, this->mVals, idx);
- if (idx < this->mSize) // Copy right of idx
- MoveArray(newVals + idx + count, this->mVals + idx, this->mSize - idx);
- TAlloc::deallocate(this->mVals);
- }
- this->mVals = newVals;
- this->mAllocSize = (int_cosize)newSize;
- }
- else if (idx != this->mSize)
- {
- intptr moveCount = this->mSize - idx;
- MoveArray(this->mVals + idx + count, this->mVals + idx, moveCount);
- }
- for (intptr i = 0; i < count; i++)
- new (&this->mVals[idx + i]) T(val);
- this->mSize += (int_cosize)count;
- }
- bool Remove(const T& val)
- {
- for (intptr i = 0; i < this->mSize; i++)
- {
- if (this->mVals[i] == val)
- {
- RemoveAt(i);
- return true;
- }
- }
- return false;
- }
- typename ArrayBase<T, TAlloc>::iterator erase(typename ArrayBase<T, TAlloc>::iterator itr)
- {
- RemoveAt(itr.mPtr - this->mVals);
- return itr;
- }
- void push_back(const T& val)
- {
- if (this->mSize >= this->mAllocSize)
- SetBufferSize(this->mAllocSize + this->mAllocSize / 2 + 1);
- new (&this->mVals[this->mSize++]) T(val);
- }
- void pop_back()
- {
- BF_ASSERT(this->mSize > 0);
- this->mVals[this->mSize - 1].~T();
- --this->mSize;
- }
- void Add(const T& val)
- {
- if (this->mSize >= this->mAllocSize)
- SetBufferSize(this->mAllocSize + this->mAllocSize / 2 + 1);
- new (&this->mVals[this->mSize++]) T(val);
- }
- T& GetSafeRef(int idx)
- {
- BF_ASSERT(idx >= 0);
- while (idx >= this->mSize)
- this->Add(T());
- return this->mVals[idx];
- }
- };
- // POD
- template <typename T, typename TAlloc>
- class ArrayImpl<T, TAlloc, true> : public ArrayBase<T, TAlloc>
- {
- public:
- typedef int int_cosize;
- protected:
- void SetBufferSize(intptr newSize)
- {
- T* newVals = TAlloc::template allocate<T>(newSize);
- if (this->mVals != NULL)
- {
- if (this->mSize > 0)
- memcpy(newVals, this->mVals, this->mSize * sizeof(T));
- TAlloc::deallocate(this->mVals);
- }
- this->mVals = newVals;
- this->mAllocSize = (int_cosize)newSize;
- }
- void EnsureFree(intptr freeCount)
- {
- if (this->mSize + freeCount > this->mAllocSize)
- SetBufferSize(BF_MAX(this->mAllocSize + this->mAllocSize / 2 + 1, this->mSize + freeCount));
- }
- public:
- using ArrayBase<T, TAlloc>::ArrayBase;
- ArrayImpl() : ArrayBase<T, TAlloc>::ArrayBase()
- {
- }
- ArrayImpl(const ArrayImpl& val)
- {
- this->mVals = NULL;
- this->mSize = 0;
- this->mAllocSize = 0;
- *this = val;
- }
- ArrayImpl(ArrayImpl&& val) : ArrayBase<T, TAlloc>(std::move(val))
- {
- }
- ~ArrayImpl()
- {
- if (this->mVals != NULL)
- {
- TAlloc::deallocate(this->mVals);
- }
- }
-
- ArrayImpl& operator=(const ArrayImpl& val)
- {
- if (&val == this)
- return *this;
- this->mSize = 0;
- if (val.mSize > this->mAllocSize)
- SetBufferSize(val.mSize);
- memcpy(this->mVals, val.mVals, val.mSize * sizeof(T));
- this->mSize = val.mSize;
- return *this;
- }
- void Resize(intptr size)
- {
- if (size < this->mSize)
- this->mSize = (int_cosize)size;
- else if (size > this->mSize)
- {
- Reserve(size);
- memset(&this->mVals[this->mSize], 0, (size - this->mSize) * sizeof(T));
- this->mSize = (int_cosize)size;
- }
- }
- void ResizeRaw(intptr size)
- {
- if (size < this->mSize)
- this->mSize = (int_cosize)size;
- else if (size > this->mSize)
- {
- Reserve(size);
- this->mSize = (int_cosize)size;
- }
- }
- void Reserve(intptr size)
- {
- if (size > this->mAllocSize)
- SetBufferSize(size);
- }
- void SetSize(intptr size)
- {
- if (size > this->mAllocSize)
- SetBufferSize(size);
- this->mSize = (int_cosize)size;
- }
- void Clear()
- {
- this->mSize = 0;
- }
- void TrimExcess()
- {
- if (this->mSize > this->mAllocSize)
- SetBufferSize(this->mSize);
- }
- void Dispose()
- {
- Clear();
- delete this->mVals;
- this->mVals = NULL;
- this->mAllocSize = 0;
- }
- void RemoveAt(intptr idx)
- {
- BF_ASSERT((uintptr)idx < (uintptr)this->mSize);
- // If we're removing the last element then we don't have to move anything
- if (idx != this->mSize - 1)
- {
- intptr moveCount = this->mSize - idx - 1;
- memmove(this->mVals + idx, this->mVals + idx + 1, moveCount * sizeof(T));
- }
- this->mSize--;
- }
- // 'Fast' because it's allowed to change item order
- void RemoveAtFast(intptr idx)
- {
- BF_ASSERT((uintptr)idx < (uintptr)this->mSize);
- // If we're removing the last element then we don't have to move anything
- if (idx != this->mSize - 1)
- {
- this->mVals[idx] = this->mVals[this->mSize - 1];
- }
- this->mSize--;
- }
- void RemoveRange(intptr idx, intptr length)
- {
- BF_ASSERT(
- ((uintptr)idx < (uintptr)this->mSize) &&
- ((uintptr)length > 0) &&
- ((uintptr)(idx + length) <= (uintptr)this->mSize));
-
- // If we're removing the last element then we don't have to move anything
- if (idx != this->mSize - length)
- {
- intptr moveCount = this->mSize - idx - length;
- memmove(this->mVals + idx, this->mVals + idx + length, moveCount * sizeof(T));
- }
- this->mSize -= (int_cosize)length;
- }
- void Insert(intptr idx, const T& val)
- {
- BF_ASSERT((uintptr)idx <= (uintptr)this->mSize);
- if (this->mSize >= this->mAllocSize)
- {
- intptr newSize = this->mAllocSize + this->mAllocSize / 2 + 1;
- T* newVals = TAlloc::template allocate<T>(newSize);
- if (this->mVals != NULL)
- {
- if (idx > 0) // Copy left of idx
- memmove(newVals, this->mVals, idx * sizeof(T));
- if (idx < this->mSize) // Copy right of idx
- memmove(newVals + idx + 1, this->mVals + idx, (this->mSize - idx) * sizeof(T));
- TAlloc::deallocate(this->mVals);
- }
- this->mVals = newVals;
- this->mAllocSize = (int_cosize)newSize;
- }
- else if (idx != this->mSize)
- {
- intptr moveCount = this->mSize - idx;
- memmove(this->mVals + idx + 1, this->mVals + idx, moveCount * sizeof(T));
- }
- this->mVals[idx] = val;
- this->mSize++;
- }
- void Insert(intptr idx, const T* vals, intptr size)
- {
- BF_ASSERT((uintptr)idx <= (uintptr)this->mSize);
- if (this->mSize + size > this->mAllocSize)
- {
- intptr newSize = BF_MAX(this->mSize + size, this->mAllocSize + this->mAllocSize / 2 + 1);
- T* newVals = TAlloc::template allocate<T>(newSize);
- if (this->mVals != NULL)
- {
- if (idx > 0) // Copy left of idx
- memmove(newVals, this->mVals, idx * sizeof(T));
- if (idx < this->mSize) // Copy right of idx
- memmove(newVals + idx + size, this->mVals + idx, (this->mSize - idx) * sizeof(T));
- TAlloc::deallocate(this->mVals);
- }
- this->mVals = newVals;
- this->mAllocSize = (int_cosize)newSize;
- }
- else if (idx != this->mSize)
- {
- intptr moveCount = this->mSize - idx;
- memmove(this->mVals + idx + size, this->mVals + idx, moveCount * sizeof(T));
- }
- memcpy(&this->mVals[idx], vals, size * sizeof(T));
- this->mSize += (int_cosize)size;
- }
- void Insert(intptr idx, const T& val, intptr size)
- {
- BF_ASSERT((uintptr)idx <= (uintptr)this->mSize);
- if (this->mSize + size > this->mAllocSize)
- {
- intptr newSize = BF_MAX(this->mSize + size, this->mAllocSize + this->mAllocSize / 2 + 1);
- T* newVals = TAlloc::template allocate<T>(newSize);
- if (this->mVals != NULL)
- {
- if (idx > 0) // Copy left of idx
- memmove(newVals, this->mVals, idx * sizeof(T));
- if (idx < this->mSize) // Copy right of idx
- memmove(newVals + idx + size, this->mVals + idx, (this->mSize - idx) * sizeof(T));
- TAlloc::deallocate(this->mVals);
- }
- this->mVals = newVals;
- this->mAllocSize = (int_cosize)newSize;
- }
- else if (idx != this->mSize)
- {
- intptr moveCount = this->mSize - idx;
- memmove(this->mVals + idx + size, this->mVals + idx, moveCount * sizeof(T));
- }
- for (intptr i = 0; i < size; i++)
- this->mVals[idx + i] = val;
- this->mSize += (int_cosize)size;
- }
- bool Remove(const T& val)
- {
- for (intptr i = 0; i < this->mSize; i++)
- {
- if (this->mVals[i] == val)
- {
- RemoveAt(i);
- return true;
- }
- }
- return false;
- }
- bool RemoveAll(const T& val)
- {
- bool found = false;
- for (intptr i = 0; i < this->mSize; i++)
- {
- if (this->mVals[i] == val)
- {
- found = true;
- RemoveAt(i);
- i--;
- }
- }
- return found;
- }
- typename ArrayBase<T, TAlloc>::iterator erase(typename ArrayBase<T, TAlloc>::iterator itr)
- {
- RemoveAt(itr.mPtr - this->mVals);
- return itr;
- }
- void push_back(const T& val)
- {
- if (this->mSize >= this->mAllocSize)
- SetBufferSize(this->mAllocSize + this->mAllocSize / 2 + 1);
- this->mVals[this->mSize++] = val;
- }
- void pop_back()
- {
- BF_ASSERT(this->mSize > 0);
- --this->mSize;
- }
- void Add(const T& val)
- {
- if (this->mSize >= this->mAllocSize)
- SetBufferSize(this->mAllocSize + this->mAllocSize / 2 + 1);
- this->mVals[this->mSize++] = val;
- }
- T& GetSafeRef(int idx)
- {
- BF_ASSERT(idx >= 0);
- while (idx >= this->mSize)
- this->Add(T());
- return this->mVals[idx];
- }
- T* GrowUninitialized(int addSize)
- {
- if (this->mSize + addSize > this->mAllocSize)
- EnsureFree(addSize);
- this->mSize += (int_cosize)addSize;
- if (addSize == 0)
- return NULL;
- return &this->mVals[this->mSize - addSize];
- }
- template <typename TAlt>
- int BinarySearchAlt(const TAlt& val, const std::function<int(const T& lhs, const TAlt& rhs)>& func)
- {
- int lo = 0;
- int hi = this->mSize - 1;
- while (lo <= hi)
- {
- int i = (lo + hi) / 2;
- const T& midVal = this->mVals[i];
- int c = func(midVal, val);
- if (c == 0) return i;
- if (c < 0)
- lo = i + 1;
- else
- hi = i - 1;
- }
- return ~lo;
- }
- };
- template <typename T, typename TAlloc = AllocatorCLib >
- class Array : public ArrayImpl<T, TAlloc, std::is_pod<T>::value>
- {
- public:
- typedef ArrayImpl<T, TAlloc, std::is_pod<T>::value> _ArrayImpl;
- using ArrayImpl<T, TAlloc, std::is_pod<T>::value>::ArrayImpl;
- using _ArrayImpl::operator=;
- using _ArrayImpl::operator==;
- using _ArrayImpl::operator!=;
-
- Array() : _ArrayImpl()
- {
- }
- Array(const Array& val)
- {
- this->mVals = NULL;
- this->mSize = 0;
- this->mAllocSize = 0;
- *this = val;
- }
- Array(Array&& val) : _ArrayImpl(std::move(val))
- {
- }
- _ArrayImpl& operator=(const Array& val)
- {
- return _ArrayImpl::operator=(val);
- }
- _ArrayImpl& operator=(Array&& val)
- {
- return _ArrayImpl::operator=(val);
- }
- };
- template <typename T>
- class OwnedArray : public Array<T*>
- {
- public:
- typedef Array<T*> _Base;
- ~OwnedArray()
- {
- for (auto item : *this)
- delete item;
- }
- void Clear()
- {
- for (auto item : *this)
- delete item;
- _Base::Clear();
- }
- void ClearWithoutDeleting()
- {
- _Base::Clear();
- }
- T* Alloc()
- {
- T* item = new T();
- _Base::push_back(item);
- return item;
- }
- template <typename T2>
- T2* Alloc()
- {
- T2* item = new T2();
- _Base::push_back(item);
- return item;
- }
- };
- NS_BF_END;
- namespace std
- {
- template<typename T>
- struct hash<Beefy::Array<T> >
- {
- size_t operator()(const Beefy::Array<T>& val) const
- {
- return HashBytes((const uint8*)val.mVals, sizeof(T) * val.mSize);
- }
- };
- }
|