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