3 #if !defined(_DEBUG) || defined(MEMINFO)
4 import "instance" // TOFIX: This is required to build Debug on Ubuntu 10.04, GCC 4.4.3
9 extern int __ecereVMethodID_class_OnCopy;
10 extern int __ecereVMethodID_class_OnFree;
11 extern int __ecereVMethodID_class_OnSerialize;
12 extern int __ecereVMethodID_class_OnUnserialize;
15 public class MapNode<class KT, class V> : private AVLNode<KT>
21 // THIS IS MISSING CODE FOR struct KEYS
24 get { return AVLNode::key; }
25 set { AVLNode::key = value; }
29 get { return this ? this.value : (V)0; }
30 set { this.value = value; }
34 // BECAUSE WE'RE PRIVATELY INHERITING, UNTIL public() works
35 property thisclass prev { get { return (MapNode<KT,V>)AVLNode::prev; } }
36 property thisclass next { get { return (MapNode<KT,V>)AVLNode::next; } }
37 property thisclass minimum { get { return (MapNode<KT,V>)AVLNode::minimum; } }
38 property thisclass maximum { get { return (MapNode<KT,V>)AVLNode::maximum; } }
41 public struct MapIterator<class KT, class V> : Iterator<V, IT = KT>
45 set { container = (Container<V, IT>)value; }
46 get { return (Map<KT, V>)container; }
50 get { return ((Map<KT, V>)container).GetKey((MapNode<KT, V>)pointer); }
54 get { return container.GetData(pointer); }
55 set { container.SetData(pointer, value); }
59 public class Map<class MT, class V> : CustomAVLTree<MapNode<MT, V>, I = MT, D = V, KT = MT>
63 MT GetKey(MapNode<KT, V> node)
65 if(class(MT).type == structClass)
66 return (MT)(((byte *)&(uint64)node.key) + __ENDIAN_PAD(sizeof(void *)));
70 V GetData(MapNode<MT, V> node)
74 // Adjust node pointer for non-standard AVLNode
75 if(class(MT).type == structClass)
76 node = (MapNode<MT, V>)(((byte *) node) + class(MT).structSize - sizeof(node.AVLNode::key));
77 return (class(V).type == structClass) ? (MT)&node.value : node.value;
82 bool SetData(MapNode<MT, V> node, MT value)
84 // Adjust node pointer for non-standard AVLNode
85 if(class(MT).type == structClass)
86 node = (MapNode<MT, V>)(((byte *) node) + class(MT).structSize - sizeof(node.AVLNode::key));
88 if(class(V).type == structClass)
89 memcpy((void *)&node.value, (void *)value, class(V).structSize);
95 MapNode<MT, V> Add(BT _newNode)
97 MapNode<MT, V> newNode = (MapNode<MT, V>) _newNode;
98 if(class(MT).type == structClass || class(V).type == structClass)
100 MapNode<MT, V> realNode = (MapNode<MT, V>)GetAtPosition(newNode.key, true, null);
101 SetData(realNode, newNode.value);
106 MapNode<MT, V> node = root ? root.Find(class(MT), (T)newNode.key) : null;
109 Class Tclass = class(MT);
110 void (* onCopy)(void *, void *, void *) = Tclass._vTbl[__ecereVMethodID_class_OnCopy];
112 if((Tclass.type == systemClass && !Tclass.byValueSystemClass) || Tclass.type == bitClass || Tclass.type == enumClass || Tclass.type == unitClass)
113 onCopy(Tclass, (byte *)&newNode.key + __ENDIAN_PAD(Tclass.typeSize), (byte *)&newNode.key + __ENDIAN_PAD(Tclass.typeSize));
115 onCopy(Tclass, (byte *)&newNode.key + __ENDIAN_PAD(sizeof(void *)), (void *)newNode.key);
117 CustomAVLTree::Add((T)newNode);
128 void FreeKey(MapNode<MT, V> node)
130 if(class(MT).type == structClass)
132 // TODO: Make this easier...
133 Class Tclass = class(MT);
134 ((void (*)(void *, void *))(void *)Tclass._vTbl[__ecereVMethodID_class_OnFree])(Tclass, (((byte *)&node.key) + __ENDIAN_PAD(sizeof(void *))));
142 MapNode<MT, V> node = root;
147 MapNode<MT, V> left = node.left;
153 MapNode<MT, V> right = node.right;
159 MapNode<MT, V> parent = node.parent;
170 void Remove(MapNode<MT, V> node)
172 CustomAVLTree::Remove(node);
179 MapNode<MT, V> node = root;
184 MapNode<MT, V> left = node.left;
190 MapNode<MT, V> right = node.right;
196 MapNode<MT, V> parent = node.parent;
197 V value = GetData(node);
209 void Delete(MapNode<MT, V> node)
211 V value = GetData(node);
217 MapNode<MT, V> Find(V value)
219 return (MapNode<MT, V>)Container::Find(value);
222 MapNode<MT, V> GetAtPosition(const MT pos, bool create, bool * justAdded)
224 AVLNode addNode = null;
225 AddSide addSide = compare;
226 MapNode<MT, V> node = root ? root.FindEx(class(MT), pos, &addNode, &addSide) : null;
229 Class Tclass = class(MT);
230 void (* onCopy)(void *, void *, void *) = Tclass._vTbl[__ecereVMethodID_class_OnCopy];
231 if(class(MT).type == structClass || class(V).type == structClass)
233 uint size = sizeof(class MapNode<MT, V>);
235 if(class(MT).type == structClass) size += class(MT).typeSize - sizeof(node.AVLNode::key);
236 if(class(V).type == structClass)
237 size += class(V).typeSize - sizeof(uint64); //sizeof(*&node.value); // TODO: Simplify code generation for this sizeof
238 node = (MapNode<MT, V>)new0 byte[size];
242 node = MapNode<MT, V> { key = pos };
244 if((Tclass.type == systemClass && !Tclass.byValueSystemClass) || Tclass.type == bitClass || Tclass.type == enumClass || Tclass.type == unitClass)
245 // onCopy(Tclass, (byte *)&node.key + __ENDIAN_PAD(Tclass.typeSize), (byte *)&pos + __ENDIAN_PAD(Tclass.typeSize));
246 memcpy((byte *)&node.key + __ENDIAN_PAD(Tclass.typeSize), (byte *)&pos + __ENDIAN_PAD(Tclass.typeSize), Tclass.typeSize);
248 onCopy(Tclass, (byte *)&node.key + __ENDIAN_PAD(sizeof(void *)), (void *)pos);
249 CustomAVLTree::AddEx((T)(uintptr)node, (T)(uintptr)addNode, addSide);
250 if(justAdded) *justAdded = true;
255 void Copy(Container<T> source)
259 if(!eClass_IsDerived(source._class, class(Map)))
261 for(i = source.GetFirst(); i; i = source.GetNext(i))
263 MapNode<MT, V> srcNode = (MapNode<MT, V>)source.GetData(i);
264 MapNode<MT, V> destNode = (MapNode<MT, V>)GetAtPosition(srcNode.key, true, null);
265 SetData(destNode, srcNode.value);
267 // ADDED THIS HERE TO FREE BUILTIN CONTAINERS ASSIGNED TO A MAP
268 if(source._class == class(BuiltInContainer))
273 public property Map mapSrc
279 if(value && eClass_IsDerived(value._class, class(Map)))
281 for(i = value.GetFirst(); i; i = value.GetNext(i))
283 MapNode<MT, V> srcNode = (MapNode<MT, V>)i;
284 MapNode<MT, V> destNode = (MapNode<MT, V>)GetAtPosition(srcNode.key, true, null);
285 SetData(destNode, GetData(srcNode));
291 void OnSerialize(IOChannel channel)
293 uint count = GetCount();
295 Class Kclass = class(MT);
296 Class Dclass = class(V);
297 bool kIsNormalClass = (Kclass.type == normalClass) && Kclass.structSize;
298 bool dIsNormalClass = (Dclass.type == normalClass) && Dclass.structSize;
301 for(i = GetFirst(); i; i = GetNext(i))
303 MapNode<MT, V> srcNode = (MapNode<MT, V>)i;
304 MT key = GetKey((MapNode<KT, V>)srcNode);
305 D data = GetData(srcNode);
306 Class kEclass = kIsNormalClass ? ((Instance)key)._class : Kclass;
307 Class dEclass = dIsNormalClass ? ((Instance)data)._class : Dclass;
309 ((void (*)(void *, void *, void *))(void *)kEclass._vTbl[__ecereVMethodID_class_OnSerialize])(kEclass,
310 ((Kclass.type == systemClass && !Kclass.byValueSystemClass) || Kclass.type == bitClass || Kclass.type == enumClass || Kclass.type == unitClass) ? &key : (void *)key, channel);
311 ((void (*)(void *, void *, void *))(void *)dEclass._vTbl[__ecereVMethodID_class_OnSerialize])(dEclass,
312 ((Dclass.type == systemClass && !Dclass.byValueSystemClass) || Dclass.type == bitClass || Dclass.type == enumClass || Dclass.type == unitClass) ? &data : (void *)data, channel);
316 void OnUnserialize(IOChannel channel)
319 thisclass container = eInstance_New(_class.fullName);
320 Class Kclass = class(MT);
321 Class Dclass = class(V);
324 for(c = 0; c < count; c++)
326 MapNode<MT, V> destNode;
329 ((void (*)(void *, void *, void *))(void *)Kclass._vTbl[__ecereVMethodID_class_OnUnserialize])(Kclass, &key, channel);
330 ((void (*)(void *, void *, void *))(void *)Dclass._vTbl[__ecereVMethodID_class_OnUnserialize])(Dclass, &data, channel);
331 destNode = (MapNode<MT, V>)container.GetAtPosition(key, true, null);
332 container.SetData(destNode, data);