3 import "instance" // TOFIX: This is required to build Debug on Ubuntu 10.04, GCC 4.4.3
7 extern int __ecereVMethodID_class_OnCopy;
8 extern int __ecereVMethodID_class_OnFree;
11 public class MapNode<class KT, class V> : private AVLNode<KT>
17 // THIS IS MISSING CODE FOR struct KEYS
20 get { return AVLNode::key; }
21 set { AVLNode::key = value; }
25 get { return this ? this.value : (V)0; }
26 set { this.value = value; }
30 // BECAUSE WE'RE PRIVATELY INHERITING, UNTIL public() works
31 property thisclass prev { get { return (MapNode<KT,V>)AVLNode::prev; } }
32 property thisclass next { get { return (MapNode<KT,V>)AVLNode::next; } }
33 property thisclass minimum { get { return (MapNode<KT,V>)AVLNode::minimum; } }
34 property thisclass maximum { get { return (MapNode<KT,V>)AVLNode::maximum; } }
37 public struct MapIterator<class KT, class V> : Iterator<V, IT = KT>
41 set { container = (Container<V, IT>)value; }
42 get { return (Map<KT, V>)container; }
46 get { return ((Map<KT, V>)container).GetKey((MapNode<KT, V>)pointer); }
50 get { return container.GetData(pointer); }
51 set { container.SetData(pointer, value); }
55 public class Map<class MT, class V> : CustomAVLTree<MapNode<MT, V>, I = MT, D = V, KT = MT>
59 MT GetKey(MapNode<KT, V> node)
61 if(class(MT).type == structClass)
62 return (MT)(((byte *)&(uint64)node.key) + __ENDIAN_PAD(sizeof(void *)));
66 V GetData(MapNode<MT, V> node)
70 // Adjust node pointer for non-standard AVLNode
71 if(class(MT).type == structClass)
72 node = (MapNode<MT, V>)(((byte *) node) + class(MT).structSize - sizeof(node.AVLNode::key));
73 return (class(V).type == structClass) ? (MT)&node.value : node.value;
78 bool SetData(MapNode<MT, V> node, MT value)
80 // Adjust node pointer for non-standard AVLNode
81 if(class(MT).type == structClass)
82 node = (MapNode<MT, V>)(((byte *) node) + class(MT).structSize - sizeof(node.AVLNode::key));
84 if(class(V).type == structClass)
85 memcpy((void *)&node.value, (void *)value, class(V).structSize);
91 MapNode<MT, V> Add(BT _newNode)
93 MapNode<MT, V> newNode = (MapNode<MT, V>) _newNode;
94 if(class(MT).type == structClass || class(V).type == structClass)
96 MapNode<MT, V> realNode = (MapNode<MT, V>)GetAtPosition(newNode.key, true);
97 SetData(realNode, newNode.value);
102 MapNode<MT, V> node = root ? root.Find(class(MT), (T)newNode.key) : null;
105 Class Tclass = class(MT);
107 if(Tclass.type == systemClass || Tclass.type == bitClass || Tclass.type == enumClass || Tclass.type == unitClass)
109 ((void (*)(void *, void *, void *))(void *)Tclass._vTbl[__ecereVMethodID_class_OnCopy])(Tclass, (((byte *)&(uint64)newNode.key) + __ENDIAN_PAD(Tclass.typeSize)),
110 (((byte *)&(uint64)newNode.key) + __ENDIAN_PAD(Tclass.typeSize)));
113 ((void (*)(void *, void *, void *))(void *)Tclass._vTbl[__ecereVMethodID_class_OnCopy])(Tclass, (((byte *)&(uint64)newNode.key) + __ENDIAN_PAD(sizeof(void *))), (void *)newNode.key);
115 CustomAVLTree::Add((T)newNode);
126 void Remove(MapNode<MT, V> node)
128 CustomAVLTree::Remove(node);
129 if(class(MT).type == structClass)
131 // TODO: Make this easier...
132 Class Tclass = class(MT);
133 ((void (*)(void *, void *))(void *)Tclass._vTbl[__ecereVMethodID_class_OnFree])(Tclass, (((byte *)&(uint64)node.key) + __ENDIAN_PAD(sizeof(void *))));
145 MapNode<MT, V> n = node;
147 // Adjust node pointer for non-standard AVLNode
148 if(class(MT).type == structClass)
149 n = (MapNode<MT, V>)(((byte *) node) + class(MT).structSize - sizeof(node.AVLNode::key));
156 void Delete(MapNode<MT, V> node)
162 MapNode<MT, V> Find(V value)
164 return (MapNode<MT, V>)Container::Find(value);
167 MapNode<MT, V> GetAtPosition(MT pos, bool create)
169 MapNode<MT, V> node = root ? root.Find(class(MT), pos) : null;
172 Class Tclass = class(MT);
173 if(class(MT).type == structClass || class(V).type == structClass)
175 uint size = sizeof(class MapNode<MT, V>);
177 if(class(MT).type == structClass) size += class(MT).typeSize - sizeof(node.AVLNode::key);
178 if(class(V).type == structClass) size += class(V).typeSize - sizeof(*&node.value);
179 node = (MapNode<MT, V>)new0 byte[size];
183 node = MapNode<MT, V> { key = pos };
185 if(Tclass.type == systemClass || Tclass.type == bitClass || Tclass.type == enumClass || Tclass.type == unitClass)
187 ((void (*)(void *, void *, void *))(void *)Tclass._vTbl[__ecereVMethodID_class_OnCopy])(Tclass, (((byte *)&(uint64)node.key) + __ENDIAN_PAD(Tclass.typeSize)),
188 (((byte *)&(uint64)pos) + __ENDIAN_PAD(Tclass.typeSize)));
191 ((void (*)(void *, void *, void *))(void *)Tclass._vTbl[__ecereVMethodID_class_OnCopy])(Tclass, (((byte *)&(uint64)node.key) + __ENDIAN_PAD(sizeof(void *))), (void *)pos);
192 CustomAVLTree::Add((T)node);
197 void Copy(Container<T> source)
201 if(!eClass_IsDerived(source._class, class(Map)))
203 for(i = source.GetFirst(); i; i = source.GetNext(i))
205 MapNode<MT, V> srcNode = (MapNode<MT, V>)source.GetData(i);
206 MapNode<MT, V> destNode = (MapNode<MT, V>)GetAtPosition(srcNode.key, true);
207 SetData(destNode, srcNode.value);
209 // ADDED THIS HERE TO FREE BUILTIN CONTAINERS ASSIGNED TO A MAP
210 if(source._class == class(BuiltInContainer))
215 public property Map mapSrc
221 if(eClass_IsDerived(value._class, class(Map)))
223 for(i = value.GetFirst(); i; i = value.GetNext(i))
225 MapNode<MT, V> srcNode = (MapNode<MT, V>)i;
226 MapNode<MT, V> destNode = (MapNode<MT, V>)GetAtPosition(srcNode.key, true);
227 SetData(destNode, GetData(srcNode));