Skip to content

Instantly share code, notes, and snippets.

@dpasca
Last active August 29, 2015 14:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dpasca/c7b024036c81fd6c5326 to your computer and use it in GitHub Desktop.
Save dpasca/c7b024036c81fd6c5326 to your computer and use it in GitHub Desktop.
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