Changeset 1293


Ignore:
Timestamp:
Apr 25, 2012, 1:05:09 AM (8 years ago)
Author:
sam
Message:

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/array.h

    r1285 r1293  
    1212// The Array class
    1313// ---------------
    14 // A very simple Array class not unlike the std::vector.
     14// A very simple Array class not unlike the std::vector, with some nice
     15// additional features, eg. Array<int,float> for automatic arrays of structs.
    1516//
    1617
     
    2324{
    2425
    25 template<typename T1, typename T2 = void, typename T3 = void> class Array
    26 {
    27 public:
    28     typedef struct { T1 m1; T2 m2; T3 m3; } Element;
    29 
    30     inline Array() : m_data(0), m_count(0), m_reserved(0) {}
    31     inline ~Array() { delete[] m_data; }
    32 
    33     Array(Array const& that) : m_data(0), m_count(0), m_reserved(0)
     26/*
     27 * The base array type
     28 * FIXME: only works properly with POD types for now
     29 */
     30
     31template<typename T> class ArrayBase
     32{
     33public:
     34    typedef T Element;
     35
     36    inline ArrayBase() : m_data(0), m_count(0), m_reserved(0) {}
     37    inline ~ArrayBase() { delete[] m_data; }
     38
     39    ArrayBase(ArrayBase const& that) : m_data(0), m_count(0), m_reserved(0)
    3440    {
    3541        Reserve(that.m_reserved);
     
    3844    }
    3945
    40     Array& operator=(Array const& that)
     46    ArrayBase& operator=(ArrayBase const& that)
    4147    {
    4248        m_data = 0;
     
    5965    }
    6066
    61     inline Array<T1, T2, T3> const& operator<<(Element const &x)
     67    inline ArrayBase<T> const& operator<<(T const &x)
    6268    {
    6369        if (m_count >= m_reserved)
    6470        {
    65             /* Protect ourselves against insertion of an element that is
    66              * already in m_data. */
    67             Element tmp = x;
     71            T tmp = x;
    6872            Reserve(m_count * 13 / 8 + 8);
    6973            m_data[m_count++] = tmp;
    7074        }
    7175        else
     76        {
    7277            m_data[m_count++] = x;
     78        }
    7379        return *this;
    7480    }
    7581
    76     inline void Append(T1 const &m1, T2 const &m2, T3 const &m3)
    77     {
    78         if (m_count >= m_reserved)
    79         {
    80             T1 tmp1 = m1; T2 tmp2 = m2; T3 tmp3 = m3;
    81             Reserve(m_count * 13 / 8 + 8);
    82             m_data[m_count].m1 = tmp1;
    83             m_data[m_count].m2 = tmp2;
    84             m_data[m_count].m3 = tmp3;
    85         }
    86         else
    87         {
    88             m_data[m_count].m1 = m1;
    89             m_data[m_count].m2 = m2;
    90             m_data[m_count].m3 = m3;
    91         }
    92         ++m_count;
     82    inline void Append(T const &x)
     83    {
     84        *this << x;
    9385    }
    9486
     
    123115    inline int Bytes() const { return m_count * sizeof(Element); }
    124116
    125 private:
     117protected:
    126118    Element *m_data;
    127119    int m_count, m_reserved;
    128120};
    129121
    130 template<typename T1, typename T2> class Array<T1, T2, void>
    131 {
    132 public:
    133     typedef struct { T1 m1; T2 m2; } Element;
    134 
    135     inline Array() : m_data(0), m_count(0), m_reserved(0) {}
    136     inline ~Array() { delete[] m_data; }
    137 
    138     Array(Array const& that) : m_data(0), m_count(0), m_reserved(0)
    139     {
    140         Reserve(that.m_reserved);
    141         memcpy(m_data, that.m_data, m_count * sizeof(Element));
    142         m_count = that.m_count;
    143     }
    144 
    145     Array& operator=(Array const& that)
    146     {
    147         m_data = 0;
    148         m_count = 0;
    149         m_reserved = 0;
    150         Reserve(that.m_reserved);
    151         memcpy(m_data, that.m_data, that.m_count * sizeof(Element));
    152         m_count = that.m_count;
    153         return *this;
    154     }
    155 
    156     inline Element& operator[](int n)
    157     {
    158         return m_data[n];
    159     }
    160 
    161     inline Element const& operator[](int n) const
    162     {
    163         return m_data[n];
    164     }
    165 
    166     inline Array<T1, T2> const& operator<<(Element const &x)
    167     {
    168         if (m_count >= m_reserved)
    169         {
    170             /* Protect ourselves against insertion of an element that is
    171              * already in m_data. */
    172             Element tmp = x;
    173             Reserve(m_count * 13 / 8 + 8);
    174             m_data[m_count++] = tmp;
    175         }
    176         else
    177             m_data[m_count++] = x;
    178         return *this;
    179     }
    180 
     122/*
     123 * Element types
     124 */
     125
     126template<typename T1, typename T2, typename T3 = void, typename T4 = void,
     127         typename T5 = void, typename T6 = void, typename T7 = void,
     128         typename T8 = void>
     129class ArrayElement
     130{
     131public:
     132    T1 m1; T2 m2; T3 m3; T4 m4; T5 m5; T6 m6; T7 m7; T8 m8;
     133};
     134
     135template<typename T1, typename T2, typename T3, typename T4, typename T5,
     136         typename T6, typename T7>
     137class ArrayElement<T1, T2, T3, T4, T5, T6, T7, void>
     138{
     139public:
     140    T1 m1; T2 m2; T3 m3; T4 m4; T5 m5; T6 m6; T7 m7;
     141};
     142
     143template<typename T1, typename T2, typename T3, typename T4, typename T5,
     144         typename T6>
     145class ArrayElement<T1, T2, T3, T4, T5, T6, void, void>
     146{
     147public:
     148    T1 m1; T2 m2; T3 m3; T4 m4; T5 m5; T6 m6;
     149};
     150
     151template<typename T1, typename T2, typename T3, typename T4, typename T5>
     152class ArrayElement<T1, T2, T3, T4, T5, void, void, void>
     153{
     154public:
     155    T1 m1; T2 m2; T3 m3; T4 m4; T5 m5;
     156};
     157
     158template<typename T1, typename T2, typename T3, typename T4>
     159class ArrayElement<T1, T2, T3, T4, void, void, void, void>
     160{
     161public:
     162    T1 m1; T2 m2; T3 m3; T4 m4;
     163};
     164
     165template<typename T1, typename T2, typename T3>
     166class ArrayElement<T1, T2, T3, void, void, void, void, void>
     167{
     168public:
     169    T1 m1; T2 m2; T3 m3;
     170};
     171
     172template<typename T1, typename T2>
     173class ArrayElement<T1, T2, void, void, void, void, void, void>
     174{
     175public:
     176    T1 m1; T2 m2;
     177};
     178
     179/*
     180 * Array specialisations implementing specific setters
     181 */
     182
     183template<typename T1, typename T2 = void, typename T3 = void,
     184         typename T4 = void, typename T5 = void, typename T6 = void,
     185         typename T7 = void, typename T8 = void>
     186class Array : public ArrayBase<ArrayElement<T1, T2, T3, T4, T5, T6, T7, T8> >
     187{
     188public:
     189    inline void Append(T1 const &m1, T2 const &m2, T3 const &m3, T4 const &m4,
     190                       T5 const &m5, T6 const &m6, T7 const &m7, T8 const &m8)
     191    {
     192        if (this->m_count >= this->m_reserved)
     193        {
     194            T1 tmp1 = m1; T2 tmp2 = m2; T3 tmp3 = m3; T4 tmp4 = m4;
     195            T5 tmp5 = m5; T6 tmp6 = m6; T7 tmp7 = m7; T8 tmp8 = m8;
     196            Reserve(this->m_count * 13 / 8 + 8);
     197            this->m_data[this->m_count].m1 = tmp1;
     198            this->m_data[this->m_count].m2 = tmp2;
     199            this->m_data[this->m_count].m3 = tmp3;
     200            this->m_data[this->m_count].m4 = tmp4;
     201            this->m_data[this->m_count].m5 = tmp5;
     202            this->m_data[this->m_count].m6 = tmp6;
     203            this->m_data[this->m_count].m7 = tmp7;
     204            this->m_data[this->m_count].m8 = tmp8;
     205        }
     206        else
     207        {
     208            this->m_data[this->m_count].m1 = m1;
     209            this->m_data[this->m_count].m2 = m2;
     210            this->m_data[this->m_count].m3 = m3;
     211            this->m_data[this->m_count].m4 = m4;
     212            this->m_data[this->m_count].m5 = m5;
     213            this->m_data[this->m_count].m6 = m6;
     214            this->m_data[this->m_count].m7 = m7;
     215            this->m_data[this->m_count].m8 = m8;
     216        }
     217        ++this->m_count;
     218    }
     219};
     220
     221template<typename T1, typename T2, typename T3, typename T4, typename T5,
     222         typename T6, typename T7>
     223class Array<T1, T2, T3, T4, T5, T6, T7, void>
     224  : public ArrayBase<ArrayElement<T1, T2, T3, T4, T5, T6, T7, void> >
     225{
     226public:
     227    inline void Append(T1 const &m1, T2 const &m2, T3 const &m3, T4 const &m4,
     228                       T5 const &m5, T6 const &m6, T7 const &m7)
     229    {
     230        if (this->m_count >= this->m_reserved)
     231        {
     232            T1 tmp1 = m1; T2 tmp2 = m2; T3 tmp3 = m3; T4 tmp4 = m4;
     233            T5 tmp5 = m5; T6 tmp6 = m6; T7 tmp7 = m7;
     234            Reserve(this->m_count * 13 / 8 + 8);
     235            this->m_data[this->m_count].m1 = tmp1;
     236            this->m_data[this->m_count].m2 = tmp2;
     237            this->m_data[this->m_count].m3 = tmp3;
     238            this->m_data[this->m_count].m4 = tmp4;
     239            this->m_data[this->m_count].m5 = tmp5;
     240            this->m_data[this->m_count].m6 = tmp6;
     241            this->m_data[this->m_count].m7 = tmp7;
     242        }
     243        else
     244        {
     245            this->m_data[this->m_count].m1 = m1;
     246            this->m_data[this->m_count].m2 = m2;
     247            this->m_data[this->m_count].m3 = m3;
     248            this->m_data[this->m_count].m4 = m4;
     249            this->m_data[this->m_count].m5 = m5;
     250            this->m_data[this->m_count].m6 = m6;
     251            this->m_data[this->m_count].m7 = m7;
     252        }
     253        ++this->m_count;
     254    }
     255};
     256
     257template<typename T1, typename T2, typename T3, typename T4, typename T5,
     258         typename T6>
     259class Array<T1, T2, T3, T4, T5, T6, void, void>
     260  : public ArrayBase<ArrayElement<T1, T2, T3, T4, T5, T6, void, void> >
     261{
     262public:
     263    inline void Append(T1 const &m1, T2 const &m2, T3 const &m3, T4 const &m4,
     264                       T5 const &m5, T6 const &m6)
     265    {
     266        if (this->m_count >= this->m_reserved)
     267        {
     268            T1 tmp1 = m1; T2 tmp2 = m2; T3 tmp3 = m3; T4 tmp4 = m4;
     269            T5 tmp5 = m5; T6 tmp6 = m6;
     270            Reserve(this->m_count * 13 / 8 + 8);
     271            this->m_data[this->m_count].m1 = tmp1;
     272            this->m_data[this->m_count].m2 = tmp2;
     273            this->m_data[this->m_count].m3 = tmp3;
     274            this->m_data[this->m_count].m4 = tmp4;
     275            this->m_data[this->m_count].m5 = tmp5;
     276            this->m_data[this->m_count].m6 = tmp6;
     277        }
     278        else
     279        {
     280            this->m_data[this->m_count].m1 = m1;
     281            this->m_data[this->m_count].m2 = m2;
     282            this->m_data[this->m_count].m3 = m3;
     283            this->m_data[this->m_count].m4 = m4;
     284            this->m_data[this->m_count].m5 = m5;
     285            this->m_data[this->m_count].m6 = m6;
     286        }
     287        ++this->m_count;
     288    }
     289};
     290
     291template<typename T1, typename T2, typename T3, typename T4, typename T5>
     292class Array<T1, T2, T3, T4, T5, void, void, void>
     293  : public ArrayBase<ArrayElement<T1, T2, T3, T4, T5, void, void, void> >
     294{
     295public:
     296    inline void Append(T1 const &m1, T2 const &m2, T3 const &m3, T4 const &m4,
     297                       T5 const &m5)
     298    {
     299        if (this->m_count >= this->m_reserved)
     300        {
     301            T1 tmp1 = m1; T2 tmp2 = m2; T3 tmp3 = m3; T4 tmp4 = m4;
     302            T5 tmp5 = m5;
     303            Reserve(this->m_count * 13 / 8 + 8);
     304            this->m_data[this->m_count].m1 = tmp1;
     305            this->m_data[this->m_count].m2 = tmp2;
     306            this->m_data[this->m_count].m3 = tmp3;
     307            this->m_data[this->m_count].m4 = tmp4;
     308            this->m_data[this->m_count].m5 = tmp5;
     309        }
     310        else
     311        {
     312            this->m_data[this->m_count].m1 = m1;
     313            this->m_data[this->m_count].m2 = m2;
     314            this->m_data[this->m_count].m3 = m3;
     315            this->m_data[this->m_count].m4 = m4;
     316            this->m_data[this->m_count].m5 = m5;
     317        }
     318        ++this->m_count;
     319    }
     320};
     321
     322template<typename T1, typename T2, typename T3, typename T4>
     323class Array<T1, T2, T3, T4, void, void, void, void>
     324  : public ArrayBase<ArrayElement<T1, T2, T3, T4, void, void, void, void> >
     325{
     326public:
     327    inline void Append(T1 const &m1, T2 const &m2, T3 const &m3, T4 const &m4)
     328    {
     329        if (this->m_count >= this->m_reserved)
     330        {
     331            T1 tmp1 = m1; T2 tmp2 = m2; T3 tmp3 = m3; T4 tmp4 = m4;
     332            Reserve(this->m_count * 13 / 8 + 8);
     333            this->m_data[this->m_count].m1 = tmp1;
     334            this->m_data[this->m_count].m2 = tmp2;
     335            this->m_data[this->m_count].m3 = tmp3;
     336            this->m_data[this->m_count].m4 = tmp4;
     337        }
     338        else
     339        {
     340            this->m_data[this->m_count].m1 = m1;
     341            this->m_data[this->m_count].m2 = m2;
     342            this->m_data[this->m_count].m3 = m3;
     343            this->m_data[this->m_count].m4 = m4;
     344        }
     345        ++this->m_count;
     346    }
     347};
     348
     349template<typename T1, typename T2, typename T3>
     350class Array<T1, T2, T3, void, void, void, void, void>
     351  : public ArrayBase<ArrayElement<T1, T2, T3, void, void, void, void, void> >
     352{
     353public:
     354    inline void Append(T1 const &m1, T2 const &m2, T3 const &m3)
     355    {
     356        if (this->m_count >= this->m_reserved)
     357        {
     358            T1 tmp1 = m1; T2 tmp2 = m2; T3 tmp3 = m3;
     359            Reserve(this->m_count * 13 / 8 + 8);
     360            this->m_data[this->m_count].m1 = tmp1;
     361            this->m_data[this->m_count].m2 = tmp2;
     362            this->m_data[this->m_count].m3 = tmp3;
     363        }
     364        else
     365        {
     366            this->m_data[this->m_count].m1 = m1;
     367            this->m_data[this->m_count].m2 = m2;
     368            this->m_data[this->m_count].m3 = m3;
     369        }
     370        ++this->m_count;
     371    }
     372};
     373
     374template<typename T1, typename T2>
     375class Array<T1, T2, void, void, void, void, void, void>
     376  : public ArrayBase<ArrayElement<T1, T2, void, void, void, void, void, void> >
     377{
     378public:
    181379    inline void Append(T1 const &m1, T2 const &m2)
    182380    {
    183         if (m_count >= m_reserved)
     381        if (this->m_count >= this->m_reserved)
    184382        {
    185383            T1 tmp1 = m1; T2 tmp2 = m2;
    186             Reserve(m_count * 13 / 8 + 8);
    187             m_data[m_count].m1 = tmp1;
    188             m_data[m_count].m2 = tmp2;
    189         }
    190         else
    191         {
    192             m_data[m_count].m1 = m1;
    193             m_data[m_count].m2 = m2;
    194         }
    195         ++m_count;
    196     }
    197 
    198     void Remove(int pos)
    199     {
    200         memmove(m_data + pos, m_data + pos + 1, m_count - pos - 1);
    201         m_count--;
    202     }
    203 
    204     void Remove(int pos, int count)
    205     {
    206         memmove(m_data + pos, m_data + pos + count, m_count - pos - count);
    207         m_count -= count;
    208     }
    209 
    210     void Reserve(int count)
    211     {
    212         if (count <= (int)m_reserved)
    213             return;
    214 
    215         Element *tmp = new Element[count];
    216         if (m_data)
    217         {
    218             memcpy(tmp, m_data, m_count * sizeof(Element));
    219             delete[] m_data;
    220         }
    221         m_data = tmp;
    222         m_reserved = count;
    223     }
    224 
    225     inline int Count() const { return m_count; }
    226     inline int Bytes() const { return m_count * sizeof(Element); }
    227 
    228 private:
    229     Element *m_data;
    230     int m_count, m_reserved;
    231 };
    232 
    233 template<typename T1> class Array<T1, void, void>
    234 {
    235 public:
    236     typedef T1 Element;
    237 
    238     inline Array() : m_data(0), m_count(0), m_reserved(0) {}
    239     inline ~Array() { delete[] m_data; }
    240 
    241     Array(Array const& that) : m_data(0), m_count(0), m_reserved(0)
    242     {
    243         Reserve(that.m_reserved);
    244         memcpy(m_data, that.m_data, m_count * sizeof(Element));
    245         m_count = that.m_count;
    246     }
    247 
    248     Array& operator=(Array const& that)
    249     {
    250         m_data = 0;
    251         m_count = 0;
    252         m_reserved = 0;
    253         Reserve(that.m_reserved);
    254         memcpy(m_data, that.m_data, that.m_count * sizeof(Element));
    255         m_count = that.m_count;
    256         return *this;
    257     }
    258 
    259     inline Element& operator[](int n)
    260     {
    261         return m_data[n];
    262     }
    263 
    264     inline Element const& operator[](int n) const
    265     {
    266         return m_data[n];
    267     }
    268 
    269     inline Array<T1> const& operator<<(T1 const &x)
    270     {
    271         if (m_count >= m_reserved)
    272         {
    273             T1 tmp = x;
    274             Reserve(m_count * 13 / 8 + 8);
    275             m_data[m_count++] = tmp;
    276         }
    277         else
    278         {
    279             m_data[m_count++] = x;
    280         }
    281         return *this;
    282     }
    283 
    284     inline void Append(T1 const &x)
    285     {
    286         *this << x;
    287     }
    288 
    289     void Remove(int pos)
    290     {
    291         memmove(m_data + pos, m_data + pos + 1, m_count - pos - 1);
    292         m_count--;
    293     }
    294 
    295     void Remove(int pos, int count)
    296     {
    297         memmove(m_data + pos, m_data + pos + count, m_count - pos - count);
    298         m_count -= count;
    299     }
    300 
    301     void Reserve(int count)
    302     {
    303         if (count <= (int)m_reserved)
    304             return;
    305 
    306         Element *tmp = new Element[count];
    307         if (m_data)
    308         {
    309             memcpy(tmp, m_data, m_count * sizeof(Element));
    310             delete[] m_data;
    311         }
    312         m_data = tmp;
    313         m_reserved = count;
    314     }
    315 
    316     inline int Count() const { return m_count; }
    317     inline int Bytes() const { return m_count * sizeof(Element); }
    318 
    319 private:
    320     Element *m_data;
    321     int m_count, m_reserved;
     384            Reserve(this->m_count * 13 / 8 + 8);
     385            this->m_data[this->m_count].m1 = tmp1;
     386            this->m_data[this->m_count].m2 = tmp2;
     387        }
     388        else
     389        {
     390            this->m_data[this->m_count].m1 = m1;
     391            this->m_data[this->m_count].m2 = m2;
     392        }
     393        ++this->m_count;
     394    }
     395};
     396
     397template<typename T>
     398class Array<T, void, void, void, void, void, void, void> : public ArrayBase<T>
     399{
    322400};
    323401
Note: See TracChangeset for help on using the changeset viewer.