Initial git commit -- Transition from CodeGuard repository
[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(I pos, bool create)
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             if(prevItem)
138             {
139                item.link.next = prevItem.link.next;
140                prevItem.link.next = item;
141             }
142             else
143             {
144                item.link.next = first;
145                first = item;
146             }
147             item.link.prev = prevItem;
148             if(item.link.next) 
149                item.link.next.link.prev = item;
150          }
151       }
152    }
153
154    IteratorPointer Find(LT value)
155    {
156       return (IteratorPointer)value;
157    }
158
159    void Free()
160    {
161       LT item;
162       while(item = first)
163       {
164          Remove(item);
165          delete item;
166       }
167    }
168
169    void Delete(LT item)
170    {
171       Remove(item);
172       delete item;
173    }
174 }