#ifndef sptplarr_h
#define sptplarr_h
#include <assert.h>
#include <string.h>
#include "sptexc.h"
namespace spt
{
namespace tpl
{
///
template<class T>
class Array
{
public:
Array();
Array(long count);
Array(Array<T> &array);
virtual ~Array();
Array<T> & operator=(Array<T> &array);
public:
void Create(long count);
void SetCount(long count);
void SetSize(long size);
void Release();
void Empty(){ m_count = 0; }
public:
void SetAll(T elem);
void AddElem(T &elem);
void SetPerAllocSize(long size){ if(size > 0) m_per_alloc_size = size; }
public:
long GetSize(){ return m_size; }
long GetCount(){ return m_count; }
T * GetBuffer(){ return m_data; }
bool IsEmpty(){ return m_count == 0; }
bool IsReleased(){ return m_data == NULL; }
bool IsInside(long pos){ return pos >= 0 && pos < m_count; }
long GetPerAllocSize(){ return m_per_alloc_size; }
public:
T & operator[](long pos){ return m_data[pos]; }
protected:
void Resize(long size);
private:
void Init();
long GetNeedAllocSize(long size);
private:
T *m_data;
long m_count;
long m_size;
long m_per_alloc_size;
};
///
template<class T>
Array<T>::Array()
{
Init();
}
template<class T>
Array<T>::Array(Array<T> &array)
{
Init();
*this = array;
}
template<class T>
Array<T>::Array(long count)
{
Init();
Create(count);
}
template<class T>
Array<T>::~Array()
{
Release();
}
template<class T>
Array<T> & Array<T>::operator=(Array<T> &array)
{
if(this == &array)
return *this;
SetCount(array.m_count);
for(long i=0; i<m_count; i++)
m_data[i] = array.m_data[i];
return *this;
}
///
template<class T>
inline void Array<T>::Init()
{
m_data = NULL;
m_count = m_size = 0;
m_per_alloc_size = sptDefaultPerAllocSize;
assert(m_per_alloc_size > 0);
}
template<class T>
inline void Array<T>::Release()
{
delete[] m_data;
Init();
}
template<class T>
void Array<T>::Resize(long size)
{
if(size < 0)
return;
if(size == 0)
{
Release();
return;
}
size = GetNeedAllocSize(size);
if(m_count == 0)
{
Release();
m_data = new T [size];
if(m_data == NULL)
throw Exception(fail_alloc);
m_count = 0;
m_size = size;
}
else
{
long count = spt_min(m_count, size);
long tmp_size = count * sizeof(T);
char *tmp = new char [tmp_size];
if(tmp == NULL)
throw Exception(fail_alloc);
T *data = new T [size];
if(data == NULL)
throw Exception(fail_alloc);
memcpy(tmp, m_data, tmp_size);
memcpy(m_data, data, tmp_size);
memcpy(data, tmp, tmp_size);
delete[] tmp;
Release();
m_data = data;
m_count = count;
m_size = size;
}
}
template<class T>
inline long Array<T>::GetNeedAllocSize(long size)
{
assert(size > 0);
assert(m_per_alloc_size > 0);
return (size + m_per_alloc_size + 1) / m_per_alloc_size * m_per_alloc_size;
}
template<class T>
inline void Array<T>::Create(long count)
{
Release();
SetCount(count);
}
template<class T>
inline void Array<T>::SetCount(long count)
{
if(count > m_size)
Resize(count);
m_count = count;
}
template<class T>
inline void Array<T>::SetSize(long size)
{
if(size > m_size)
Resize(size);
}
///
template<class T>
inline void Array<T>::SetAll(T elem)
{
for(long i=0; i<m_count; i++)
m_data[i] = elem;
}
template<class T>
inline void Array<T>::AddElem(T &elem)
{
SetCount(m_count + 1);
m_data[m_count - 1] = elem;
}
///
} // namespace tpl
} // namespace spt
#endif
// sptplarr.h
#define sptplarr_h
#include <assert.h>
#include <string.h>
#include "sptexc.h"
namespace spt
{
namespace tpl
{
///
template<class T>
class Array
{
public:
Array();
Array(long count);
Array(Array<T> &array);
virtual ~Array();
Array<T> & operator=(Array<T> &array);
public:
void Create(long count);
void SetCount(long count);
void SetSize(long size);
void Release();
void Empty(){ m_count = 0; }
public:
void SetAll(T elem);
void AddElem(T &elem);
void SetPerAllocSize(long size){ if(size > 0) m_per_alloc_size = size; }
public:
long GetSize(){ return m_size; }
long GetCount(){ return m_count; }
T * GetBuffer(){ return m_data; }
bool IsEmpty(){ return m_count == 0; }
bool IsReleased(){ return m_data == NULL; }
bool IsInside(long pos){ return pos >= 0 && pos < m_count; }
long GetPerAllocSize(){ return m_per_alloc_size; }
public:
T & operator[](long pos){ return m_data[pos]; }
protected:
void Resize(long size);
private:
void Init();
long GetNeedAllocSize(long size);
private:
T *m_data;
long m_count;
long m_size;
long m_per_alloc_size;
};
///
template<class T>
Array<T>::Array()
{
Init();
}
template<class T>
Array<T>::Array(Array<T> &array)
{
Init();
*this = array;
}
template<class T>
Array<T>::Array(long count)
{
Init();
Create(count);
}
template<class T>
Array<T>::~Array()
{
Release();
}
template<class T>
Array<T> & Array<T>::operator=(Array<T> &array)
{
if(this == &array)
return *this;
SetCount(array.m_count);
for(long i=0; i<m_count; i++)
m_data[i] = array.m_data[i];
return *this;
}
///
template<class T>
inline void Array<T>::Init()
{
m_data = NULL;
m_count = m_size = 0;
m_per_alloc_size = sptDefaultPerAllocSize;
assert(m_per_alloc_size > 0);
}
template<class T>
inline void Array<T>::Release()
{
delete[] m_data;
Init();
}
template<class T>
void Array<T>::Resize(long size)
{
if(size < 0)
return;
if(size == 0)
{
Release();
return;
}
size = GetNeedAllocSize(size);
if(m_count == 0)
{
Release();
m_data = new T [size];
if(m_data == NULL)
throw Exception(fail_alloc);
m_count = 0;
m_size = size;
}
else
{
long count = spt_min(m_count, size);
long tmp_size = count * sizeof(T);
char *tmp = new char [tmp_size];
if(tmp == NULL)
throw Exception(fail_alloc);
T *data = new T [size];
if(data == NULL)
throw Exception(fail_alloc);
memcpy(tmp, m_data, tmp_size);
memcpy(m_data, data, tmp_size);
memcpy(data, tmp, tmp_size);
delete[] tmp;
Release();
m_data = data;
m_count = count;
m_size = size;
}
}
template<class T>
inline long Array<T>::GetNeedAllocSize(long size)
{
assert(size > 0);
assert(m_per_alloc_size > 0);
return (size + m_per_alloc_size + 1) / m_per_alloc_size * m_per_alloc_size;
}
template<class T>
inline void Array<T>::Create(long count)
{
Release();
SetCount(count);
}
template<class T>
inline void Array<T>::SetCount(long count)
{
if(count > m_size)
Resize(count);
m_count = count;
}
template<class T>
inline void Array<T>::SetSize(long size)
{
if(size > m_size)
Resize(size);
}
///
template<class T>
inline void Array<T>::SetAll(T elem)
{
for(long i=0; i<m_count; i++)
m_data[i] = elem;
}
template<class T>
inline void Array<T>::AddElem(T &elem)
{
SetCount(m_count + 1);
m_data[m_count - 1] = elem;
}
///
} // namespace tpl
} // namespace spt
#endif
// sptplarr.h