ecere/com/containers/List: Worked around too much memory being allocated
[sdk] / ecere / src / com / containers / List.ec
1 namespace com;
2
3 import "instance" // TOFIX: This is required to build Debug on Ubuntu 10.04, GCC 4.4.3
4 import "LinkList"
5
6 public class Link : ListItem
7 {
8    class_fixed
9 public:
10    uint64 data;
11 }
12
13 public class List<class LLT> : LinkList<Link, T = LLT, D = LLT>
14 {
15    class_fixed
16    // Generic iterator support
17    LLT GetData(Link link)
18    {
19       return link ? ((class(LLT) && class(LLT).type == structClass) ? (LLT)&link.data : (LLT)link.data) : (LLT)0;
20    }
21
22    bool SetData(Link link, LLT value)
23    {
24       if(class(LLT).type == structClass)
25          memcpy((void *)&link.data, (void *)(uintptr)value, class(LLT).structSize);
26       else
27          link.data = (uint64)value;
28       return true;
29    }
30
31    Link Insert(Link after, LLT value)
32    {
33       Link link;
34       Class cLLT = class(LLT);
35       if(cLLT && cLLT.type == structClass)
36       {
37          uint sType = cLLT.structSize;
38          link = (Link)new0 byte[sizeof(class ListItem) + sType];
39          memcpy((void *)&link.data, (void *)value, sType);
40       }
41       else
42       {
43          // TOFIX: This allocates too much data?
44          // link = Link { data = (uint64)value };
45          link = (Link)new0 byte[sizeof(class ListItem) + sizeof(uint64)];
46          link.data = (uint64)value;
47       }
48       LinkList::Insert(after, (LT)link);
49       return link;
50    }
51
52    Link Add(LLT value)
53    {
54       return (Link)Insert(last, value);
55    }
56
57    void Remove(Link link)
58    {
59       LinkList::Remove(link);
60       delete link;
61    }
62
63    void Delete(Link link)
64    {
65       D data = GetData(link);
66       delete data;
67       Remove(link);
68    }
69
70    void Free()
71    {
72       LT item;
73       while((item = first))
74       {
75          D data = GetData(item);
76          delete data;
77          Remove(item);
78       }
79    }
80
81    Link Find(const LLT value)
82    {
83       return (Link)Container::Find(value);
84    }
85 }