ecere/com/containers/LinkList: Fixed issue in 32 bit
[sdk] / ecere / src / com / containers / LinkList.ec
1 namespace com;
2
3 import "Container"
4
5 public struct LinkElement<class T:void *>
6 {
7    T prev, next;
8 };
9
10 public class ListItem : IteratorPointer
11 {
12    class_fixed
13 public:
14    union
15    {
16       LinkElement<thisclass> link;
17       struct { thisclass prev, next; };
18    };
19 }
20
21 public class LinkList<class LT:void * = ListItem, bool circ = false, link = LT::link> : Container<LT>
22 {
23    class_fixed
24 public:
25    LT first, last;
26    int count;
27
28    // Generic iterator support
29    LT GetFirst() { return first; }
30    LT GetLast() { return last; }
31    LT GetPrev(IteratorPointer item) { return ((LT)item).link.prev; }
32    LT GetNext(IteratorPointer item) { return ((LT)item).link.next; }
33    LT GetData(IteratorPointer pointer) { return (LT)pointer; }
34
35    IteratorPointer GetAtPosition(const I pos, bool create, bool * justAdded)
36    {
37       int c;
38       LT item;
39       for(c = 0, item = first; c < (int)pos && item; c++, item = item.link.next);
40       return (IteratorPointer)item;
41    }
42    bool SetData(IteratorPointer pointer, LT data)
43    {
44       // Not supported for LinkList
45       return false;
46    }
47
48    IteratorPointer Add(LT item)
49    {
50       if(item)
51       {
52          item.link.prev = last;
53          if(item.link.prev)
54             item.link.prev.link.next = item;
55          if(!first) first = item;
56          last = item;
57          item.link.next = circ ? first : null;
58          if(circ)
59             first.link.prev = item;
60          count++;
61       }
62       return (IteratorPointer)item;
63    }
64
65    IteratorPointer Insert(IteratorPointer _prevItem, T item)
66    {
67       LT prevItem = (LT)_prevItem;
68       if(item && prevItem != item)
69       {
70          item.link.prev = prevItem ? prevItem : (circ ? last : null);
71          if(prevItem)
72          {
73             item.link.next = prevItem.link.next;
74             prevItem.link.next = item;
75          }
76          else
77          {
78             item.link.next = first;
79             first = item;
80             if(circ)
81             {
82                if(item.link.prev)
83                   item.link.prev.link.next = item;
84                else
85                   item.link.next = item;
86             }
87          }
88          if(prevItem == last) last = item;
89          if(item.link.next)
90             item.link.next.link.prev = item;
91          count++;
92          return (IteratorPointer)item;
93       }
94       return null;
95    }
96
97    void Remove(IteratorPointer _item)
98    {
99       LT item = (LT)_item;
100       if(item)
101       {
102          if(item.link.prev)
103             item.link.prev.link.next = item.link.next;
104          if(item.link.next)
105             item.link.next.link.prev = item.link.prev;
106          if(circ && last == first)
107             last = first = null;
108          else
109          {
110             if(last == item) last = item.link.prev;
111             if(first == item) first = item.link.next;
112          }
113          item.link.prev = null;
114          item.link.next = null;
115          count--;
116       }
117    }
118
119    void Move(IteratorPointer _item, IteratorPointer _prevItem)
120    {
121       LT item = (LT)_item;
122       LT prevItem = (LT)_prevItem;
123       if(item)
124       {
125          if(prevItem != item && (first != item || prevItem))
126          {
127             if(item.link.prev)
128                item.link.prev.link.next = item.link.next;
129             if(item.link.next)
130                item.link.next.link.prev = item.link.prev;
131             if(item == first) first = item.link.next;
132             if(item == last)  last = item.link.prev;
133
134             if(prevItem == last)
135                last = item;
136
137             item.link.prev = prevItem ? prevItem : (circ ? last : null);
138             if(prevItem)
139             {
140                item.link.next = prevItem.link.next;
141                prevItem.link.next = item;
142             }
143             else
144             {
145                item.link.next = first;
146                first = item;
147                if(circ)
148                {
149                    if(item.link.prev)
150                       item.link.prev.link.next = item;
151                    else
152                       item.link.next = item;
153                }
154             }
155             if(item.link.next)
156                item.link.next.link.prev = item;
157          }
158       }
159    }
160
161    IteratorPointer Find(LT value)
162    {
163       return (IteratorPointer)value;
164    }
165
166    void Free()
167    {
168       LT item;
169       while((item = first))
170       {
171          Remove(item);
172          delete item;
173       }
174    }
175
176    // TOFIX: This compiles without error but produces bad code, since the virtual method prototype is an IteratorPointer which should be a pointer, not a uint64
177    //void Delete(LT item)
178    void Delete(void * item)
179    {
180       Remove(item);
181       delete item;
182    }
183 }