Last active
August 29, 2015 14:20
-
-
Save dpasca/c7b024036c81fd6c5326 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
template <class _T, size_t _SIZE> | |
class DArray | |
{ | |
U32 mBuff[ (sizeof(_T) * _SIZE + 3) / 4 ]; | |
size_t mSize = 0; | |
#if defined(_DEBUG) || defined(DEBUG) | |
_T *mpDbgPtr = (_T *)mBuff; | |
#endif | |
public: | |
typedef const _T *const_iterator; | |
typedef _T *iterator; | |
public: | |
DArray() {} | |
DArray( const DArray &from ) | |
{ | |
*this = from; | |
} | |
DArray( DArray &&from ) | |
{ | |
*this = std::move( from ); | |
} | |
~DArray() { clear(); } | |
DArray &operator=(const DArray& from) | |
{ | |
resize( from.size() ); | |
for (size_t i=0; i != from.mSize; ++i) | |
(*this)[i] = from[i]; | |
return *this; | |
} | |
DArray &operator=(DArray&& from) | |
{ | |
resize( from.size() ); | |
for (size_t i=0; i != from.mSize; ++i) | |
(*this)[i] = std::move( from[i] ); | |
from.resize( 0 ); | |
return *this; | |
} | |
public: | |
size_t size() const { return mSize; } | |
size_t size_bytes() const { return mSize * sizeof(_T); } | |
size_t capacity() const { return _SIZE; } | |
void clear() { return resize( 0 ); } | |
bool is_full() const { return size() == capacity(); } | |
_T *data() { return ( _T *)( void *)mBuff; } | |
const _T *data() const { return (const _T *)(const void *)mBuff; } | |
iterator begin() { return data(); } | |
const_iterator begin() const { return data(); } | |
iterator end() { return data() + mSize; } | |
const_iterator end() const { return data() + mSize; } | |
void resize( size_t newSize ) | |
{ | |
if ( newSize == mSize ) | |
return; | |
if ( newSize > _SIZE ) | |
DEX_BAD_ALLOC( | |
"Failed to resize() a DArray. Max allowed is " SIZE_T_FMT | |
" requested is " SIZE_T_FMT ".", | |
_SIZE, | |
newSize ); | |
if ( newSize < mSize ) | |
{ | |
for (size_t i=newSize; i < mSize; ++i) | |
(*this)[i].~_T(); | |
} | |
else | |
{ | |
for (size_t i=mSize; i < newSize; ++i) | |
new (data() + i) _T; | |
} | |
mSize = newSize; | |
} | |
_T *grow( size_t n=1 ) | |
{ | |
size_t fromIdx = size(); | |
resize( fromIdx + n ); | |
return data() + fromIdx; | |
} | |
void erase( iterator it ) | |
{ | |
if NOT( it >= begin() && it < end() ) | |
DEX_OUT_OF_RANGE( "Out of bounds !" ); | |
size_t idx = it - begin(); | |
(*this)[idx].~_T(); | |
for (size_t i=idx; i < mSize-1; ++i) | |
(*this)[i] = std::move( (*this)[i+1] ); | |
mSize -= 1; | |
} | |
void insert( iterator itBefore, _T &val ) | |
{ | |
if ( mSize == 0 ) // being stl-like.. I hope ! | |
{ | |
resize( 1 ); | |
(*this)[0] = val; | |
return; | |
} | |
else | |
if ( itBefore == end() ) | |
{ | |
push_back( val ); | |
return; | |
} | |
if NOT( itBefore >= begin() && itBefore < end() ) | |
DEX_OUT_OF_RANGE( "Out of bounds !" ); | |
size_t idx = itBefore - data(); | |
resize( mSize + 1 ); | |
for (size_t i=mSize; i > (idx+1); --i) | |
(*this)[i-1] = std::move( (*this)[i-2] ); | |
(*this)[idx] = val; | |
} | |
void push_front( const _T &val ) | |
{ | |
grow(); | |
for (size_t i=mSize; i > 1; --i) | |
(*this)[i-1] = std::move( (*this)[i-2] ); | |
(*this)[0] = val; | |
} | |
void push_back( const _T &val ) | |
{ | |
*grow() = val; | |
} | |
void pop_back() | |
{ | |
DASSERT( mSize >= 1 ); | |
resize( mSize - 1 ); | |
} | |
iterator find( const _T &val ) | |
{ | |
for (size_t i=0; i < mSize; ++i) | |
if ( (*this)[i] == val ) | |
return data() + i; | |
return end(); | |
} | |
const _T &back() const { DASSERT( mSize >= 1 ); return data()[mSize-1]; } | |
_T &back() { DASSERT( mSize >= 1 ); return data()[mSize-1]; } | |
const _T &operator[]( size_t idx ) const { DASSERT( idx < mSize ); return data()[ idx ]; } | |
_T &operator[]( size_t idx ) { DASSERT( idx < mSize ); return data()[ idx ]; } | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment