You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
202 lines
4.4 KiB
202 lines
4.4 KiB
template<class T> class TArray
|
|
{
|
|
|
|
public:
|
|
|
|
TArray(unsigned size) : _size(size), _count(0), _aItem( 0 )
|
|
{
|
|
if ( 0 != size )
|
|
{
|
|
_aItem = new T [_size];
|
|
memset( _aItem, 0, _size * sizeof(T) );
|
|
}
|
|
}
|
|
|
|
TArray() : _size(0), _count(0), _aItem(0) {}
|
|
|
|
~TArray()
|
|
{
|
|
delete [] _aItem;
|
|
}
|
|
|
|
void Add( const T &newItem, unsigned position )
|
|
{
|
|
if (position >= _count)
|
|
{
|
|
if (position >= _size)
|
|
_GrowToSize( position );
|
|
|
|
_count = position + 1;
|
|
}
|
|
|
|
_aItem[position] = newItem;
|
|
}
|
|
|
|
void Append( const T &newItem )
|
|
{
|
|
Add( newItem, Count() );
|
|
}
|
|
|
|
void Insert(const T& newItem, unsigned pos)
|
|
{
|
|
if (_count == _size)
|
|
{
|
|
unsigned newsize;
|
|
if ( _size == 0 )
|
|
newsize = 16;
|
|
else
|
|
newsize = _size * 2;
|
|
T *aNew = new T [newsize];
|
|
memcpy( aNew,
|
|
_aItem,
|
|
pos * sizeof( T ) );
|
|
memcpy( aNew + pos + 1,
|
|
_aItem + pos,
|
|
(_count - pos) * sizeof(T));
|
|
|
|
delete (BYTE *) _aItem;
|
|
_aItem = aNew;
|
|
_size = newsize;
|
|
}
|
|
else
|
|
{
|
|
memmove ( _aItem + pos + 1,
|
|
_aItem + pos,
|
|
(_count - pos) * sizeof(T));
|
|
}
|
|
_aItem[pos] = newItem;
|
|
_count++;
|
|
}
|
|
|
|
void Remove (unsigned position)
|
|
{
|
|
if (pos < _count - 1)
|
|
{
|
|
memmove ( _aItem + pos,
|
|
_aItem + pos + 1,
|
|
(_count - pos - 1) * sizeof(T));
|
|
}
|
|
memset( _aItem + _count - 1, 0, sizeof(T) );
|
|
_count--;
|
|
if (_count == 0)
|
|
{
|
|
delete (BYTE*) _aItem;
|
|
_aItem = 0;
|
|
_size = 0;
|
|
}
|
|
}
|
|
|
|
unsigned Size () const { return _size; }
|
|
|
|
T& Get (unsigned position) const
|
|
{
|
|
return _aItem[position];
|
|
}
|
|
|
|
void Clear()
|
|
{
|
|
delete [] _aItem;
|
|
_aItem = 0;
|
|
_size = 0;
|
|
_count = 0;
|
|
}
|
|
|
|
unsigned Count() const { return _count; }
|
|
|
|
void SetSize(unsigned position)
|
|
{
|
|
if (position >= _size)
|
|
_GrowToSize(position);
|
|
}
|
|
|
|
void Shrink()
|
|
{
|
|
// make size == count, to save memory
|
|
|
|
if ( 0 == _count )
|
|
{
|
|
Clear();
|
|
}
|
|
else if ( _count != _size )
|
|
{
|
|
T * p = new T [_count];
|
|
_size = _count;
|
|
RtlCopyMemory( p, _aItem, _count * sizeof T );
|
|
delete (BYTE *) _aItem;
|
|
_aItem = p;
|
|
}
|
|
}
|
|
|
|
T* Acquire ()
|
|
{
|
|
T *temp = _aItem;
|
|
_aItem = 0;
|
|
_count = 0;
|
|
_size = 0;
|
|
return temp;
|
|
}
|
|
|
|
void Duplicate( TArray<T> & aFrom )
|
|
{
|
|
Clear();
|
|
|
|
if ( 0 != aFrom.Count() )
|
|
{
|
|
_size = _count = aFrom.Count();
|
|
_aItem = new T [_size];
|
|
memcpy( _aItem, aFrom._aItem, _size * sizeof( T ) );
|
|
}
|
|
}
|
|
|
|
T & operator[]( unsigned position )
|
|
{
|
|
if ( position >= _count )
|
|
{
|
|
if ( position >= _size )
|
|
_GrowToSize( position );
|
|
|
|
_count = position + 1;
|
|
}
|
|
|
|
return _aItem[position];
|
|
}
|
|
|
|
T & operator[]( unsigned position ) const
|
|
{
|
|
return _aItem[position];
|
|
}
|
|
|
|
T const * GetPointer() { return _aItem; }
|
|
|
|
unsigned SizeOfInUse() const { return sizeof T * Count(); }
|
|
|
|
protected:
|
|
|
|
void _GrowToSize( unsigned position )
|
|
{
|
|
unsigned newsize = _size * 2;
|
|
if ( newsize == 0 )
|
|
newsize = 16;
|
|
for( ; position >= newsize; newsize *= 2)
|
|
continue;
|
|
|
|
T *aNew = new T [newsize];
|
|
if (_size > 0)
|
|
{
|
|
memcpy( aNew,
|
|
_aItem,
|
|
_size * sizeof( T ) );
|
|
}
|
|
memset( aNew + _size,
|
|
0,
|
|
(newsize-_size) * sizeof(T) );
|
|
delete (BYTE*) _aItem;
|
|
_aItem = aNew;
|
|
_size = newsize;
|
|
}
|
|
|
|
T * _aItem;
|
|
unsigned _size;
|
|
unsigned _count;
|
|
};
|
|
|