Browse Source

core: dynamic arrays can now have up to 8 typed members.

legacy
Sam Hocevar sam 12 years ago
parent
commit
cf85ee132d
1 changed files with 249 additions and 171 deletions
  1. +249
    -171
      src/array.h

+ 249
- 171
src/array.h View File

@@ -11,7 +11,8 @@
// //
// The Array class // The Array class
// --------------- // ---------------
// A very simple Array class not unlike the std::vector.
// A very simple Array class not unlike the std::vector, with some nice
// additional features, eg. Array<int,float> for automatic arrays of structs.
// //


#if !defined __LOL_ARRAY_H__ #if !defined __LOL_ARRAY_H__
@@ -22,22 +23,27 @@
namespace lol namespace lol
{ {


template<typename T1, typename T2 = void, typename T3 = void> class Array
/*
* The base array type
* FIXME: only works properly with POD types for now
*/

template<typename T> class ArrayBase
{ {
public: public:
typedef struct { T1 m1; T2 m2; T3 m3; } Element;
typedef T Element;


inline Array() : m_data(0), m_count(0), m_reserved(0) {}
inline ~Array() { delete[] m_data; }
inline ArrayBase() : m_data(0), m_count(0), m_reserved(0) {}
inline ~ArrayBase() { delete[] m_data; }


Array(Array const& that) : m_data(0), m_count(0), m_reserved(0)
ArrayBase(ArrayBase const& that) : m_data(0), m_count(0), m_reserved(0)
{ {
Reserve(that.m_reserved); Reserve(that.m_reserved);
memcpy(m_data, that.m_data, m_count * sizeof(Element)); memcpy(m_data, that.m_data, m_count * sizeof(Element));
m_count = that.m_count; m_count = that.m_count;
} }


Array& operator=(Array const& that)
ArrayBase& operator=(ArrayBase const& that)
{ {
m_data = 0; m_data = 0;
m_count = 0; m_count = 0;
@@ -58,38 +64,24 @@ public:
return m_data[n]; return m_data[n];
} }


inline Array<T1, T2, T3> const& operator<<(Element const &x)
inline ArrayBase<T> const& operator<<(T const &x)
{ {
if (m_count >= m_reserved) if (m_count >= m_reserved)
{ {
/* Protect ourselves against insertion of an element that is
* already in m_data. */
Element tmp = x;
T tmp = x;
Reserve(m_count * 13 / 8 + 8); Reserve(m_count * 13 / 8 + 8);
m_data[m_count++] = tmp; m_data[m_count++] = tmp;
} }
else else
{
m_data[m_count++] = x; m_data[m_count++] = x;
}
return *this; return *this;
} }


inline void Append(T1 const &m1, T2 const &m2, T3 const &m3)
inline void Append(T const &x)
{ {
if (m_count >= m_reserved)
{
T1 tmp1 = m1; T2 tmp2 = m2; T3 tmp3 = m3;
Reserve(m_count * 13 / 8 + 8);
m_data[m_count].m1 = tmp1;
m_data[m_count].m2 = tmp2;
m_data[m_count].m3 = tmp3;
}
else
{
m_data[m_count].m1 = m1;
m_data[m_count].m2 = m2;
m_data[m_count].m3 = m3;
}
++m_count;
*this << x;
} }


void Remove(int pos) void Remove(int pos)
@@ -122,203 +114,289 @@ public:
inline int Count() const { return m_count; } inline int Count() const { return m_count; }
inline int Bytes() const { return m_count * sizeof(Element); } inline int Bytes() const { return m_count * sizeof(Element); }


private:
protected:
Element *m_data; Element *m_data;
int m_count, m_reserved; int m_count, m_reserved;
}; };


template<typename T1, typename T2> class Array<T1, T2, void>
/*
* Element types
*/

template<typename T1, typename T2, typename T3 = void, typename T4 = void,
typename T5 = void, typename T6 = void, typename T7 = void,
typename T8 = void>
class ArrayElement
{ {
public: public:
typedef struct { T1 m1; T2 m2; } Element;
T1 m1; T2 m2; T3 m3; T4 m4; T5 m5; T6 m6; T7 m7; T8 m8;
};


inline Array() : m_data(0), m_count(0), m_reserved(0) {}
inline ~Array() { delete[] m_data; }
template<typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7>
class ArrayElement<T1, T2, T3, T4, T5, T6, T7, void>
{
public:
T1 m1; T2 m2; T3 m3; T4 m4; T5 m5; T6 m6; T7 m7;
};


Array(Array const& that) : m_data(0), m_count(0), m_reserved(0)
{
Reserve(that.m_reserved);
memcpy(m_data, that.m_data, m_count * sizeof(Element));
m_count = that.m_count;
}
template<typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6>
class ArrayElement<T1, T2, T3, T4, T5, T6, void, void>
{
public:
T1 m1; T2 m2; T3 m3; T4 m4; T5 m5; T6 m6;
};


Array& operator=(Array const& that)
{
m_data = 0;
m_count = 0;
m_reserved = 0;
Reserve(that.m_reserved);
memcpy(m_data, that.m_data, that.m_count * sizeof(Element));
m_count = that.m_count;
return *this;
}
template<typename T1, typename T2, typename T3, typename T4, typename T5>
class ArrayElement<T1, T2, T3, T4, T5, void, void, void>
{
public:
T1 m1; T2 m2; T3 m3; T4 m4; T5 m5;
};


inline Element& operator[](int n)
{
return m_data[n];
}
template<typename T1, typename T2, typename T3, typename T4>
class ArrayElement<T1, T2, T3, T4, void, void, void, void>
{
public:
T1 m1; T2 m2; T3 m3; T4 m4;
};


inline Element const& operator[](int n) const
{
return m_data[n];
}
template<typename T1, typename T2, typename T3>
class ArrayElement<T1, T2, T3, void, void, void, void, void>
{
public:
T1 m1; T2 m2; T3 m3;
};

template<typename T1, typename T2>
class ArrayElement<T1, T2, void, void, void, void, void, void>
{
public:
T1 m1; T2 m2;
};

/*
* Array specialisations implementing specific setters
*/


inline Array<T1, T2> const& operator<<(Element const &x)
template<typename T1, typename T2 = void, typename T3 = void,
typename T4 = void, typename T5 = void, typename T6 = void,
typename T7 = void, typename T8 = void>
class Array : public ArrayBase<ArrayElement<T1, T2, T3, T4, T5, T6, T7, T8> >
{
public:
inline void Append(T1 const &m1, T2 const &m2, T3 const &m3, T4 const &m4,
T5 const &m5, T6 const &m6, T7 const &m7, T8 const &m8)
{ {
if (m_count >= m_reserved)
if (this->m_count >= this->m_reserved)
{ {
/* Protect ourselves against insertion of an element that is
* already in m_data. */
Element tmp = x;
Reserve(m_count * 13 / 8 + 8);
m_data[m_count++] = tmp;
T1 tmp1 = m1; T2 tmp2 = m2; T3 tmp3 = m3; T4 tmp4 = m4;
T5 tmp5 = m5; T6 tmp6 = m6; T7 tmp7 = m7; T8 tmp8 = m8;
Reserve(this->m_count * 13 / 8 + 8);
this->m_data[this->m_count].m1 = tmp1;
this->m_data[this->m_count].m2 = tmp2;
this->m_data[this->m_count].m3 = tmp3;
this->m_data[this->m_count].m4 = tmp4;
this->m_data[this->m_count].m5 = tmp5;
this->m_data[this->m_count].m6 = tmp6;
this->m_data[this->m_count].m7 = tmp7;
this->m_data[this->m_count].m8 = tmp8;
} }
else else
m_data[m_count++] = x;
return *this;
{
this->m_data[this->m_count].m1 = m1;
this->m_data[this->m_count].m2 = m2;
this->m_data[this->m_count].m3 = m3;
this->m_data[this->m_count].m4 = m4;
this->m_data[this->m_count].m5 = m5;
this->m_data[this->m_count].m6 = m6;
this->m_data[this->m_count].m7 = m7;
this->m_data[this->m_count].m8 = m8;
}
++this->m_count;
} }
};


inline void Append(T1 const &m1, T2 const &m2)
template<typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7>
class Array<T1, T2, T3, T4, T5, T6, T7, void>
: public ArrayBase<ArrayElement<T1, T2, T3, T4, T5, T6, T7, void> >
{
public:
inline void Append(T1 const &m1, T2 const &m2, T3 const &m3, T4 const &m4,
T5 const &m5, T6 const &m6, T7 const &m7)
{ {
if (m_count >= m_reserved)
if (this->m_count >= this->m_reserved)
{ {
T1 tmp1 = m1; T2 tmp2 = m2;
Reserve(m_count * 13 / 8 + 8);
m_data[m_count].m1 = tmp1;
m_data[m_count].m2 = tmp2;
T1 tmp1 = m1; T2 tmp2 = m2; T3 tmp3 = m3; T4 tmp4 = m4;
T5 tmp5 = m5; T6 tmp6 = m6; T7 tmp7 = m7;
Reserve(this->m_count * 13 / 8 + 8);
this->m_data[this->m_count].m1 = tmp1;
this->m_data[this->m_count].m2 = tmp2;
this->m_data[this->m_count].m3 = tmp3;
this->m_data[this->m_count].m4 = tmp4;
this->m_data[this->m_count].m5 = tmp5;
this->m_data[this->m_count].m6 = tmp6;
this->m_data[this->m_count].m7 = tmp7;
} }
else else
{ {
m_data[m_count].m1 = m1;
m_data[m_count].m2 = m2;
this->m_data[this->m_count].m1 = m1;
this->m_data[this->m_count].m2 = m2;
this->m_data[this->m_count].m3 = m3;
this->m_data[this->m_count].m4 = m4;
this->m_data[this->m_count].m5 = m5;
this->m_data[this->m_count].m6 = m6;
this->m_data[this->m_count].m7 = m7;
} }
++m_count;
}

void Remove(int pos)
{
memmove(m_data + pos, m_data + pos + 1, m_count - pos - 1);
m_count--;
}

void Remove(int pos, int count)
{
memmove(m_data + pos, m_data + pos + count, m_count - pos - count);
m_count -= count;
++this->m_count;
} }
};


void Reserve(int count)
template<typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6>
class Array<T1, T2, T3, T4, T5, T6, void, void>
: public ArrayBase<ArrayElement<T1, T2, T3, T4, T5, T6, void, void> >
{
public:
inline void Append(T1 const &m1, T2 const &m2, T3 const &m3, T4 const &m4,
T5 const &m5, T6 const &m6)
{ {
if (count <= (int)m_reserved)
return;

Element *tmp = new Element[count];
if (m_data)
if (this->m_count >= this->m_reserved)
{ {
memcpy(tmp, m_data, m_count * sizeof(Element));
delete[] m_data;
T1 tmp1 = m1; T2 tmp2 = m2; T3 tmp3 = m3; T4 tmp4 = m4;
T5 tmp5 = m5; T6 tmp6 = m6;
Reserve(this->m_count * 13 / 8 + 8);
this->m_data[this->m_count].m1 = tmp1;
this->m_data[this->m_count].m2 = tmp2;
this->m_data[this->m_count].m3 = tmp3;
this->m_data[this->m_count].m4 = tmp4;
this->m_data[this->m_count].m5 = tmp5;
this->m_data[this->m_count].m6 = tmp6;
} }
m_data = tmp;
m_reserved = count;
else
{
this->m_data[this->m_count].m1 = m1;
this->m_data[this->m_count].m2 = m2;
this->m_data[this->m_count].m3 = m3;
this->m_data[this->m_count].m4 = m4;
this->m_data[this->m_count].m5 = m5;
this->m_data[this->m_count].m6 = m6;
}
++this->m_count;
} }

inline int Count() const { return m_count; }
inline int Bytes() const { return m_count * sizeof(Element); }

private:
Element *m_data;
int m_count, m_reserved;
}; };


template<typename T1> class Array<T1, void, void>
template<typename T1, typename T2, typename T3, typename T4, typename T5>
class Array<T1, T2, T3, T4, T5, void, void, void>
: public ArrayBase<ArrayElement<T1, T2, T3, T4, T5, void, void, void> >
{ {
public: public:
typedef T1 Element;

inline Array() : m_data(0), m_count(0), m_reserved(0) {}
inline ~Array() { delete[] m_data; }

Array(Array const& that) : m_data(0), m_count(0), m_reserved(0)
{
Reserve(that.m_reserved);
memcpy(m_data, that.m_data, m_count * sizeof(Element));
m_count = that.m_count;
}

Array& operator=(Array const& that)
{
m_data = 0;
m_count = 0;
m_reserved = 0;
Reserve(that.m_reserved);
memcpy(m_data, that.m_data, that.m_count * sizeof(Element));
m_count = that.m_count;
return *this;
}

inline Element& operator[](int n)
{
return m_data[n];
}

inline Element const& operator[](int n) const
{
return m_data[n];
}

inline Array<T1> const& operator<<(T1 const &x)
inline void Append(T1 const &m1, T2 const &m2, T3 const &m3, T4 const &m4,
T5 const &m5)
{ {
if (m_count >= m_reserved)
if (this->m_count >= this->m_reserved)
{ {
T1 tmp = x;
Reserve(m_count * 13 / 8 + 8);
m_data[m_count++] = tmp;
T1 tmp1 = m1; T2 tmp2 = m2; T3 tmp3 = m3; T4 tmp4 = m4;
T5 tmp5 = m5;
Reserve(this->m_count * 13 / 8 + 8);
this->m_data[this->m_count].m1 = tmp1;
this->m_data[this->m_count].m2 = tmp2;
this->m_data[this->m_count].m3 = tmp3;
this->m_data[this->m_count].m4 = tmp4;
this->m_data[this->m_count].m5 = tmp5;
} }
else else
{ {
m_data[m_count++] = x;
this->m_data[this->m_count].m1 = m1;
this->m_data[this->m_count].m2 = m2;
this->m_data[this->m_count].m3 = m3;
this->m_data[this->m_count].m4 = m4;
this->m_data[this->m_count].m5 = m5;
} }
return *this;
}

inline void Append(T1 const &x)
{
*this << x;
++this->m_count;
} }
};


void Remove(int pos)
template<typename T1, typename T2, typename T3, typename T4>
class Array<T1, T2, T3, T4, void, void, void, void>
: public ArrayBase<ArrayElement<T1, T2, T3, T4, void, void, void, void> >
{
public:
inline void Append(T1 const &m1, T2 const &m2, T3 const &m3, T4 const &m4)
{ {
memmove(m_data + pos, m_data + pos + 1, m_count - pos - 1);
m_count--;
if (this->m_count >= this->m_reserved)
{
T1 tmp1 = m1; T2 tmp2 = m2; T3 tmp3 = m3; T4 tmp4 = m4;
Reserve(this->m_count * 13 / 8 + 8);
this->m_data[this->m_count].m1 = tmp1;
this->m_data[this->m_count].m2 = tmp2;
this->m_data[this->m_count].m3 = tmp3;
this->m_data[this->m_count].m4 = tmp4;
}
else
{
this->m_data[this->m_count].m1 = m1;
this->m_data[this->m_count].m2 = m2;
this->m_data[this->m_count].m3 = m3;
this->m_data[this->m_count].m4 = m4;
}
++this->m_count;
} }
};


void Remove(int pos, int count)
template<typename T1, typename T2, typename T3>
class Array<T1, T2, T3, void, void, void, void, void>
: public ArrayBase<ArrayElement<T1, T2, T3, void, void, void, void, void> >
{
public:
inline void Append(T1 const &m1, T2 const &m2, T3 const &m3)
{ {
memmove(m_data + pos, m_data + pos + count, m_count - pos - count);
m_count -= count;
if (this->m_count >= this->m_reserved)
{
T1 tmp1 = m1; T2 tmp2 = m2; T3 tmp3 = m3;
Reserve(this->m_count * 13 / 8 + 8);
this->m_data[this->m_count].m1 = tmp1;
this->m_data[this->m_count].m2 = tmp2;
this->m_data[this->m_count].m3 = tmp3;
}
else
{
this->m_data[this->m_count].m1 = m1;
this->m_data[this->m_count].m2 = m2;
this->m_data[this->m_count].m3 = m3;
}
++this->m_count;
} }
};


void Reserve(int count)
template<typename T1, typename T2>
class Array<T1, T2, void, void, void, void, void, void>
: public ArrayBase<ArrayElement<T1, T2, void, void, void, void, void, void> >
{
public:
inline void Append(T1 const &m1, T2 const &m2)
{ {
if (count <= (int)m_reserved)
return;

Element *tmp = new Element[count];
if (m_data)
if (this->m_count >= this->m_reserved)
{ {
memcpy(tmp, m_data, m_count * sizeof(Element));
delete[] m_data;
T1 tmp1 = m1; T2 tmp2 = m2;
Reserve(this->m_count * 13 / 8 + 8);
this->m_data[this->m_count].m1 = tmp1;
this->m_data[this->m_count].m2 = tmp2;
} }
m_data = tmp;
m_reserved = count;
else
{
this->m_data[this->m_count].m1 = m1;
this->m_data[this->m_count].m2 = m2;
}
++this->m_count;
} }
};


inline int Count() const { return m_count; }
inline int Bytes() const { return m_count * sizeof(Element); }

private:
Element *m_data;
int m_count, m_reserved;
template<typename T>
class Array<T, void, void, void, void, void, void, void> : public ArrayBase<T>
{
}; };


} /* namespace lol */ } /* namespace lol */


Loading…
Cancel
Save