Pārlūkot izejas kodu

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

legacy
Sam Hocevar sam pirms 12 gadiem
vecāks
revīzija
cf85ee132d
1 mainītis faili ar 249 papildinājumiem un 171 dzēšanām
  1. +249
    -171
      src/array.h

+ 249
- 171
src/array.h Parādīt failu

@@ -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<int,float> for automatic arrays of structs.
//

#if !defined __LOL_ARRAY_H__
@@ -22,22 +23,27 @@
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:
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<T1, T2, T3> const& operator<<(Element const &x)
inline ArrayBase<T> 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<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:
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
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
{
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:
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
{
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 */


Notiek ielāde…
Atcelt
Saglabāt