Initial git commit -- Transition from CodeGuard repository
[sdk] / ecere / src / com / containers / Container.ec
1 namespace com;
2
3 import "BuiltInContainer"
4
5 default:
6
7 static void UnusedFunction()
8 {
9    int a;
10    a.OnCompare(null);
11    a.OnCopy(null);
12    a.OnGetString(null, null, null);
13 }
14
15 extern int __ecereVMethodID_class_OnCompare;
16 extern int __ecereVMethodID_class_OnGetString;
17 private:
18
19 // CAUSES PROBLEM WHEN AFTER
20 public struct Iterator<class T, class IT = int>
21 {
22    Container<T, IT> container;
23 // private:
24    IteratorPointer pointer;
25
26 public:
27    property T data
28    {
29       get { return container.GetData(pointer); }
30       set { container.SetData(pointer, value); }
31    }
32
33    bool Prev()
34    {
35       if(pointer && container)
36          pointer = container.GetPrev(pointer);
37       else if(container)
38          pointer = container.GetLast();
39       return pointer != null;
40    }
41
42    bool Next()
43    {
44       if(pointer && container)
45          pointer = container.GetNext(pointer);
46       else if(container)
47          pointer = container.GetFirst();
48       return pointer != null;
49    }
50
51    T GetData()
52    {
53       return container.GetData(pointer);
54    }
55
56    bool SetData(T value)
57    {
58       return container.SetData(pointer, value);
59    };
60
61    bool Find(T value)
62    {
63       if(container)
64       {
65          Free();
66          pointer = container.Find(value);
67       }
68       return pointer != null;
69    }
70
71    void Remove()
72    {
73       if(container)
74          container.Remove(pointer);
75       pointer = null;
76    }
77
78    void Free()
79    {
80       if(container)
81          container.FreeIterator(pointer);
82    }
83
84    bool Index(IT index, bool create)
85    {
86       if(container)
87       {
88          Free();
89          pointer = container.GetAtPosition(index, create);
90          return pointer != null;
91       }
92       return false;
93    }
94 };
95
96 public class Container<class T, class I = int, class D = T>
97 {
98 public:
99    class_fixed
100    public property Container<T> copySrc { set { Copy(value); } }
101    property Iterator<T> firstIterator { get { value = { (Container<T>)this, pointer = GetFirst() }; } }
102    property Iterator<T> lastIterator  { get { value = { (Container<T>)this, pointer = GetLast() }; } }
103
104    virtual IteratorPointer GetFirst() { return null; }
105    virtual IteratorPointer GetLast()  { return null; }
106    virtual IteratorPointer GetPrev(IteratorPointer pointer) { return null; }
107    virtual IteratorPointer GetNext(IteratorPointer pointer) { return null; }
108    virtual D GetData(IteratorPointer pointer) { return (D)0; }
109    virtual bool SetData(IteratorPointer pointer, D data);
110    virtual IteratorPointer GetAtPosition(I pos, bool create) { return null; }
111
112    virtual IteratorPointer Insert(IteratorPointer after, T value);
113    virtual IteratorPointer Add(T value);
114    virtual void Remove(IteratorPointer it);
115    virtual void Move(IteratorPointer it, IteratorPointer after);
116
117    virtual void RemoveAll()
118    {
119       IteratorPointer i, next;
120       for(i = GetFirst(), next = i ? GetNext(i) : null; i; i = next, next = i ? GetNext(i) : null)
121          Remove(i);
122    }
123
124    virtual void Copy(Container<T> source)
125    {
126       IteratorPointer i;
127       RemoveAll();
128       for(i = source.GetFirst(); i; i = source.GetNext(i))
129       {
130          D data = source.GetData(i);
131          // WARNING: This doesn't make a new copy of the elements it adds
132          Add(data);
133       }
134    }
135
136    void OnFree()
137    {
138       if(this)
139       {
140          Free();
141          delete this;
142       }
143    }
144    
145    void OnCopy(Container<T> source)
146    {
147       if(source)
148       {
149          // BUG IN this = SYNTAX
150          Container<T> container = eInstance_New(source._class);
151          // See WARNING in Copy()
152          container.Copy(source);
153          *(void **)this = container;
154       }
155       else
156       {
157          *(void **)this = null;
158       }
159    }
160
161    virtual IteratorPointer Find(D value)
162    {
163       IteratorPointer i;
164       Class Dclass = class(D);
165       if((Dclass.type == systemClass || Dclass.type == bitClass || Dclass.type == enumClass || Dclass.type == unitClass))
166       {
167          for(i = GetFirst(); i; i = GetNext(i))
168          {
169             D data = GetData(i);
170             int result = Dclass._vTbl[__ecereVMethodID_class_OnCompare](Dclass, &value,&data);
171             if(!result)
172                return i;
173          }
174       }
175       else
176       {
177          for(i = GetFirst(); i; i = GetNext(i))
178          {
179             D data = GetData(i);
180             int result = Dclass._vTbl[__ecereVMethodID_class_OnCompare](Dclass, (void *)value, (void *)data);
181             if(!result)
182                return i;
183          }
184       }
185       return null;
186    }
187
188    virtual void FreeIterator(IteratorPointer it);
189    
190    virtual int GetCount()
191    {
192       int count = 0;
193       IteratorPointer i;
194       for(i = GetFirst(); i; i = GetNext(i)) count++;
195       return count;
196    }
197
198    virtual void Free()
199    {
200       IteratorPointer i;
201       while(i = GetFirst())
202          Delete(i);
203    }
204
205    virtual void Delete(IteratorPointer i)
206    {
207       D data = GetData(i);
208       delete data;
209       Remove(i);
210    }
211
212    char * OnGetString(char * tempString, void * fieldData, bool * needClass)
213    {
214       if(this)
215       {
216          char itemString[4096];//1024];
217          bool first = true;
218          IteratorPointer i;
219          tempString[0] = '\0';
220          for(i = GetFirst(); i; i = GetNext(i))
221          {
222             Class Dclass = class(D);
223             D data = GetData(i);
224             char * result;
225
226             itemString[0] = '\0';
227             
228             result = (char *)Dclass._vTbl[__ecereVMethodID_class_OnGetString](Dclass,
229                (Dclass.type == systemClass || Dclass.type == bitClass || Dclass.type == enumClass || Dclass.type == unitClass) ? &data : (void *)data, 
230                   itemString, 0);
231             if(!first) strcat(tempString, ", ");
232
233             strcat(tempString, result);         
234             first = false;
235          }
236       }
237       else
238          tempString[0] = 0;
239       return tempString;
240    }
241
242    void TakeOut(D d)
243    {
244       IteratorPointer i = Find(d);
245       if(i) Remove(i);
246    }
247
248    ~Container()
249    {
250       RemoveAll();
251    }
252 }