diff --git a/src/array.h b/src/array.h index e75a0c07..c3c96b40 100644 --- a/src/array.h +++ b/src/array.h @@ -11,7 +11,8 @@ // // 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 for automatic arrays of structs. // #if !defined __LOL_ARRAY_H__ @@ -22,22 +23,27 @@ namespace lol { -template class Array +/* + * The base array type + * FIXME: only works properly with POD types for now + */ + +template class ArrayBase { 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); memcpy(m_data, that.m_data, m_count * sizeof(Element)); m_count = that.m_count; } - Array& operator=(Array const& that) + ArrayBase& operator=(ArrayBase const& that) { m_data = 0; m_count = 0; @@ -58,38 +64,24 @@ public: return m_data[n]; } - inline Array const& operator<<(Element const &x) + inline ArrayBase const& operator<<(T const &x) { 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); m_data[m_count++] = tmp; } else + { m_data[m_count++] = x; + } 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) @@ -122,203 +114,289 @@ public: inline int Count() const { return m_count; } inline int Bytes() const { return m_count * sizeof(Element); } -private: +protected: Element *m_data; int m_count, m_reserved; }; -template class Array +/* + * Element types + */ + +template +class ArrayElement { 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 +class ArrayElement +{ +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 +class ArrayElement +{ +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 +class ArrayElement +{ +public: + T1 m1; T2 m2; T3 m3; T4 m4; T5 m5; +}; - inline Element& operator[](int n) - { - return m_data[n]; - } +template +class ArrayElement +{ +public: + T1 m1; T2 m2; T3 m3; T4 m4; +}; - inline Element const& operator[](int n) const - { - return m_data[n]; - } +template +class ArrayElement +{ +public: + T1 m1; T2 m2; T3 m3; +}; + +template +class ArrayElement +{ +public: + T1 m1; T2 m2; +}; + +/* + * Array specialisations implementing specific setters + */ - inline Array const& operator<<(Element const &x) +template +class Array : public ArrayBase > +{ +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 - 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 +class Array + : public ArrayBase > +{ +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 { - 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 +class Array + : public ArrayBase > +{ +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 class Array +template +class Array + : public ArrayBase > { 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 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 { - 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 +class Array + : public ArrayBase > +{ +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 +class Array + : public ArrayBase > +{ +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 +class Array + : public ArrayBase > +{ +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 +class Array : public ArrayBase +{ }; } /* namespace lol */