source: trunk/src/array.h @ 1285

Last change on this file since 1285 was 1285, checked in by sam, 9 years ago

core: add copy constructor and assignment operator to Array.

  • Property svn:keywords set to Id
File size: 7.5 KB
Line 
1//
2// Lol Engine
3//
4// Copyright: (c) 2010-2012 Sam Hocevar <sam@hocevar.net>
5//   This program is free software; you can redistribute it and/or
6//   modify it under the terms of the Do What The Fuck You Want To
7//   Public License, Version 2, as published by Sam Hocevar. See
8//   http://sam.zoy.org/projects/COPYING.WTFPL for more details.
9//
10
11//
12// The Array class
13// ---------------
14// A very simple Array class not unlike the std::vector.
15//
16
17#if !defined __LOL_ARRAY_H__
18#define __LOL_ARRAY_H__
19
20#include <stdint.h>
21
22namespace lol
23{
24
25template<typename T1, typename T2 = void, typename T3 = void> class Array
26{
27public:
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)
34    {
35        Reserve(that.m_reserved);
36        memcpy(m_data, that.m_data, m_count * sizeof(Element));
37        m_count = that.m_count;
38    }
39
40    Array& operator=(Array const& that)
41    {
42        m_data = 0;
43        m_count = 0;
44        m_reserved = 0;
45        Reserve(that.m_reserved);
46        memcpy(m_data, that.m_data, that.m_count * sizeof(Element));
47        m_count = that.m_count;
48        return *this;
49    }
50
51    inline Element& operator[](int n)
52    {
53        return m_data[n];
54    }
55
56    inline Element const& operator[](int n) const
57    {
58        return m_data[n];
59    }
60
61    inline Array<T1, T2, T3> const& operator<<(Element const &x)
62    {
63        if (m_count >= m_reserved)
64        {
65            /* Protect ourselves against insertion of an element that is
66             * already in m_data. */
67            Element tmp = x;
68            Reserve(m_count * 13 / 8 + 8);
69            m_data[m_count++] = tmp;
70        }
71        else
72            m_data[m_count++] = x;
73        return *this;
74    }
75
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;
93    }
94
95    void Remove(int pos)
96    {
97        memmove(m_data + pos, m_data + pos + 1, m_count - pos - 1);
98        m_count--;
99    }
100
101    void Remove(int pos, int count)
102    {
103        memmove(m_data + pos, m_data + pos + count, m_count - pos - count);
104        m_count -= count;
105    }
106
107    void Reserve(int count)
108    {
109        if (count <= (int)m_reserved)
110            return;
111
112        Element *tmp = new Element[count];
113        if (m_data)
114        {
115            memcpy(tmp, m_data, m_count * sizeof(Element));
116            delete[] m_data;
117        }
118        m_data = tmp;
119        m_reserved = count;
120    }
121
122    inline int Count() const { return m_count; }
123    inline int Bytes() const { return m_count * sizeof(Element); }
124
125private:
126    Element *m_data;
127    int m_count, m_reserved;
128};
129
130template<typename T1, typename T2> class Array<T1, T2, void>
131{
132public:
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
181    inline void Append(T1 const &m1, T2 const &m2)
182    {
183        if (m_count >= m_reserved)
184        {
185            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
228private:
229    Element *m_data;
230    int m_count, m_reserved;
231};
232
233template<typename T1> class Array<T1, void, void>
234{
235public:
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
319private:
320    Element *m_data;
321    int m_count, m_reserved;
322};
323
324} /* namespace lol */
325
326#endif // __LOL_ARRAY_H__
327
Note: See TracBrowser for help on using the repository browser.