Fixed many warnings
[sdk] / ecere / src / com / containers / Array.ec
1 namespace com;
2
3 import "Container"
4
5 #define Tsize ((class(T).type == noHeadClass || class(T).type == normalClass) ? sizeof(void *) : class(T).typeSize)
6
7 public class Array : Container
8 {
9    class_fixed
10
11 public:
12    T * array;
13    uint count;
14    uint minAllocSize;
15
16    ~Array()
17    {
18       delete array;
19    }
20
21    // Generic iterator support
22    IteratorPointer GetFirst() { return (IteratorPointer)array; }
23    IteratorPointer GetLast() { return (IteratorPointer)(array ? (array + (count - 1)) : null); }
24    IteratorPointer GetPrev(IteratorPointer ip)
25    {
26       T * item = (T *)ip;
27       return (IteratorPointer)((item && item > array) ? (item - 1) : null);
28    }
29    IteratorPointer GetNext(IteratorPointer ip)
30    {
31       T * item = (T *)ip;
32       return (IteratorPointer)((item && item < array + count - 1) ? (item + 1) : null);
33    }
34    T GetData(IteratorPointer ip)
35    {
36       T * item = (T *)ip;
37       return *item;
38    }
39    bool SetData(IteratorPointer ip, T value)
40    {
41       T * item = (T *)ip;
42       *item = value;
43       return true;
44    }
45    IteratorPointer GetAtPosition(I pos, bool create)
46    {
47       if((int)pos > count && create)
48       {
49          if((int)pos + 1 > minAllocSize)
50             array = renew array T[(int)pos + 1];
51          count = (int)pos + 1;
52       }
53       return ((int)pos < count && array) ? (IteratorPointer)(array + (int)pos) : null;
54    }
55    IteratorPointer Insert(IteratorPointer ip, T value)
56    {
57 /*
58       T * after = (T *)ip;
59       int offset = after ? (after - array) : 0;
60       if(count + 1 > minAllocSize)
61       {
62          array = renew array T[count + 1];
63          if(after) after = array + offset;
64       }
65       memmove(after ? (after + 2) : (array + 1), after ? (after + 1) : array, (count - offset) * Tsize);
66       if(after)
67          after[1] = value;
68       else
69          array[0] = value;
70       count++;
71       return (IteratorPointer)(after ? (after + 1) : array);
72 */
73       uint tsize = Tsize;
74       byte * pos = ip ? ((byte *)ip + tsize) : (byte *)array;
75       if(count+1 > minAllocSize)
76       {
77          int offset = pos - (byte *)array;
78          array = renew array T[count + 1];
79          pos = (byte *)array+offset;
80       }
81       memmove(pos + tsize, pos, (byte *)array+(count++) * tsize - pos);
82       *(T*)pos = value;
83       return (IteratorPointer)pos;
84    }
85
86    IteratorPointer Add(T value)
87    {
88       if(count + 1 > minAllocSize)
89          array = renew array T[count + 1];
90       array[count] = value;
91       return (IteratorPointer)(array + (count++));
92    }
93
94    void Remove(IteratorPointer ip)
95    {
96       T * it = (T *)ip;
97       memmove(it, it + 1, (count - (it - array) - 1) * Tsize);
98       count--;
99       if(count + 1 > minAllocSize)
100          array = renew array T[count];
101    }
102
103    void Move(IteratorPointer ip, IteratorPointer afterIp)
104    {
105       /*
106       T * it = (T *)ip;
107       T * after = (T *)afterIp;
108       */
109    }
110
111    virtual void RemoveAll()
112    {
113       if(minAllocSize && array)
114          array = renew0 array T[minAllocSize];
115       else
116          delete array;
117       count = 0;
118    }
119
120    virtual int GetCount() { return count; }
121
122    property uint size
123    {
124       get { return count; }
125       set
126       {
127          if(count != value)
128          {
129             if(value > minAllocSize)
130                array = renew0 array T[value];
131             else if(value > count)
132                memset(array + count, 0, (value - count) * Tsize);
133             count = value;
134          }
135       }
136    }
137
138    property uint minAllocSize
139    {
140       get { return minAllocSize; }
141       set
142       {
143          if(minAllocSize != value)
144          {
145             if(value > count)
146                array = renew array T[value];
147             minAllocSize = value;
148          }
149       }
150    }
151
152    virtual void Copy(Container source)
153    {
154       count = source.GetCount();
155       if(count > minAllocSize)
156          array = renew array T[count];
157
158       // TOFIX: Precomp fails on (BuiltInContainer *)
159       if((source._class == class(BuiltInContainer) && ((struct BuiltInContainer *)source)->type.type != structClass ) ||
160          eClass_IsDerived(source._class, class(Array)))
161       {
162          memcpy(array, ((Array)source).array, count * Tsize);
163       }
164       else
165       {
166          IteratorPointer i;
167          int c;
168          for(c = 0, i = source.GetFirst(); i; i = source.GetNext(i), c++)
169          {
170             D data = source.GetData(i);
171             array[c] = data;
172          }
173       }
174    }
175
176
177    void Free()
178    {
179       int c;
180       for(c = 0; c<count; c++)
181       {
182          T data = array[c];
183          delete data;
184       }
185       delete array;
186       count = 0;
187       minAllocSize = 0;
188    }
189
190    void Delete(IteratorPointer item)
191    {
192       T data = *(T*)item;
193       delete data;
194       Remove(item);
195    }
196 };