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;
9 extern int __ecereVMethodID_class_OnSerialize;
10 extern int __ecereVMethodID_class_OnUnserialize;
13 public class MapNode<class KT, class V> : private AVLNode<KT>
19 // THIS IS MISSING CODE FOR struct KEYS
22 get { return AVLNode::key; }
23 set { AVLNode::key = value; }
27 get { return this ? this.value : (V)0; }
28 set { this.value = value; }
32 // BECAUSE WE'RE PRIVATELY INHERITING, UNTIL public() works
33 property thisclass prev { get { return (MapNode<KT,V>)AVLNode::prev; } }
34 property thisclass next { get { return (MapNode<KT,V>)AVLNode::next; } }
35 property thisclass minimum { get { return (MapNode<KT,V>)AVLNode::minimum; } }
36 property thisclass maximum { get { return (MapNode<KT,V>)AVLNode::maximum; } }
39 public struct MapIterator<class KT, class V> : Iterator<V, IT = KT>
43 set { container = (Container<V, IT>)value; }
44 get { return (Map<KT, V>)container; }
48 get { return ((Map<KT, V>)container).GetKey((MapNode<KT, V>)pointer); }
52 get { return container.GetData(pointer); }
53 set { container.SetData(pointer, value); }
57 public class Map<class MT, class V> : CustomAVLTree<MapNode<MT, V>, I = MT, D = V, KT = MT>
61 MT GetKey(MapNode<KT, V> node)
63 if(class(MT).type == structClass)
64 return (MT)(((byte *)&(uint64)node.key) + __ENDIAN_PAD(sizeof(void *)));
68 V GetData(MapNode<MT, V> node)
72 // Adjust node pointer for non-standard AVLNode
73 if(class(MT).type == structClass)
74 node = (MapNode<MT, V>)(((byte *) node) + class(MT).structSize - sizeof(node.AVLNode::key));
75 return (class(V).type == structClass) ? (MT)&node.value : node.value;
80 bool SetData(MapNode<MT, V> node, MT value)
82 // Adjust node pointer for non-standard AVLNode
83 if(class(MT).type == structClass)
84 node = (MapNode<MT, V>)(((byte *) node) + class(MT).structSize - sizeof(node.AVLNode::key));
86 if(class(V).type == structClass)
87 memcpy((void *)&node.value, (void *)value, class(V).structSize);
93 MapNode<MT, V> Add(BT _newNode)
95 MapNode<MT, V> newNode = (MapNode<MT, V>) _newNode;
96 if(class(MT).type == structClass || class(V).type == structClass)
98 MapNode<MT, V> realNode = (MapNode<MT, V>)GetAtPosition(newNode.key, true);
99 SetData(realNode, newNode.value);
104 MapNode<MT, V> node = root ? root.Find(class(MT), (T)newNode.key) : null;
107 Class Tclass = class(MT);
109 if((Tclass.type == systemClass && !Tclass.byValueSystemClass) || Tclass.type == bitClass || Tclass.type == enumClass || Tclass.type == unitClass)
111 ((void (*)(void *, void *, void *))(void *)Tclass._vTbl[__ecereVMethodID_class_OnCopy])(Tclass, (((byte *)&(uint64)newNode.key) + __ENDIAN_PAD(Tclass.typeSize)),
112 (((byte *)&(uint64)newNode.key) + __ENDIAN_PAD(Tclass.typeSize)));
115 ((void (*)(void *, void *, void *))(void *)Tclass._vTbl[__ecereVMethodID_class_OnCopy])(Tclass, (((byte *)&(uint64)newNode.key) + __ENDIAN_PAD(sizeof(void *))), (void *)newNode.key);
117 CustomAVLTree::Add((T)newNode);
128 void Remove(MapNode<MT, V> node)
130 CustomAVLTree::Remove(node);
131 if(class(MT).type == structClass)
133 // TODO: Make this easier...
134 Class Tclass = class(MT);
135 ((void (*)(void *, void *))(void *)Tclass._vTbl[__ecereVMethodID_class_OnFree])(Tclass, (((byte *)&(uint64)node.key) + __ENDIAN_PAD(sizeof(void *))));
147 MapNode<MT, V> n = node;
149 // Adjust node pointer for non-standard AVLNode
150 if(class(MT).type == structClass)
151 n = (MapNode<MT, V>)(((byte *) node) + class(MT).structSize - sizeof(node.AVLNode::key));
158 void Delete(MapNode<MT, V> node)
160 MapNode<MT, V> n = node;
162 // Adjust node pointer for non-standard AVLNode
163 if(class(MT).type == structClass)
164 n = (MapNode<MT, V>)(((byte *) node) + class(MT).structSize - sizeof(node.AVLNode::key));
171 MapNode<MT, V> Find(V value)
173 return (MapNode<MT, V>)Container::Find(value);
176 MapNode<MT, V> GetAtPosition(MT pos, bool create)
178 MapNode<MT, V> node = root ? root.Find(class(MT), pos) : null;
181 Class Tclass = class(MT);
182 if(class(MT).type == structClass || class(V).type == structClass)
184 uint size = sizeof(class MapNode<MT, V>);
186 if(class(MT).type == structClass) size += class(MT).typeSize - sizeof(node.AVLNode::key);
187 if(class(V).type == structClass) size += class(V).typeSize - sizeof(*&node.value);
188 node = (MapNode<MT, V>)new0 byte[size];
192 node = MapNode<MT, V> { key = pos };
194 if((Tclass.type == systemClass && !Tclass.byValueSystemClass) || Tclass.type == bitClass || Tclass.type == enumClass || Tclass.type == unitClass)
196 ((void (*)(void *, void *, void *))(void *)Tclass._vTbl[__ecereVMethodID_class_OnCopy])(Tclass, (((byte *)&(uint64)node.key) + __ENDIAN_PAD(Tclass.typeSize)),
197 (((byte *)&(uint64)pos) + __ENDIAN_PAD(Tclass.typeSize)));
200 ((void (*)(void *, void *, void *))(void *)Tclass._vTbl[__ecereVMethodID_class_OnCopy])(Tclass, (((byte *)&(uint64)node.key) + __ENDIAN_PAD(sizeof(void *))), (void *)pos);
201 CustomAVLTree::Add((T)node);
206 void Copy(Container<T> source)
210 if(!eClass_IsDerived(source._class, class(Map)))
212 for(i = source.GetFirst(); i; i = source.GetNext(i))
214 MapNode<MT, V> srcNode = (MapNode<MT, V>)source.GetData(i);
215 MapNode<MT, V> destNode = (MapNode<MT, V>)GetAtPosition(srcNode.key, true);
216 SetData(destNode, srcNode.value);
218 // ADDED THIS HERE TO FREE BUILTIN CONTAINERS ASSIGNED TO A MAP
219 if(source._class == class(BuiltInContainer))
224 public property Map mapSrc
230 if(eClass_IsDerived(value._class, class(Map)))
232 for(i = value.GetFirst(); i; i = value.GetNext(i))
234 MapNode<MT, V> srcNode = (MapNode<MT, V>)i;
235 MapNode<MT, V> destNode = (MapNode<MT, V>)GetAtPosition(srcNode.key, true);
236 SetData(destNode, GetData(srcNode));
242 void OnSerialize(IOChannel channel)
244 uint count = GetCount();
246 Class Kclass = class(MT);
247 Class Dclass = class(V);
248 bool kIsNormalClass = Kclass.type == normalClass;
249 bool dIsNormalClass = Dclass.type == normalClass;
252 for(i = GetFirst(); i; i = GetNext(i))
254 MapNode<MT, V> srcNode = (MapNode<MT, V>)i;
255 MT key = GetKey((MapNode<KT, V>)srcNode);
256 D data = GetData(srcNode);
257 Class kEclass = dIsNormalClass ? ((Instance)key)._class : Kclass;
258 Class dEclass = dIsNormalClass ? ((Instance)data)._class : Dclass;
260 ((void (*)(void *, void *, void *))(void *)kEclass._vTbl[__ecereVMethodID_class_OnSerialize])(kEclass,
261 ((Kclass.type == systemClass && !Kclass.byValueSystemClass) || Kclass.type == bitClass || Kclass.type == enumClass || Kclass.type == unitClass) ? &key : (void *)key, channel);
262 ((void (*)(void *, void *, void *))(void *)dEclass._vTbl[__ecereVMethodID_class_OnSerialize])(dEclass,
263 ((Dclass.type == systemClass && !Dclass.byValueSystemClass) || Dclass.type == bitClass || Dclass.type == enumClass || Dclass.type == unitClass) ? &data : (void *)data, channel);
267 void OnUnserialize(IOChannel channel)
270 thisclass container = eInstance_New(_class.fullName);
272 Class Kclass = class(MT);
273 Class Dclass = class(V);
276 for(c = 0; c < count; c++)
278 MapNode<MT, V> destNode;
281 ((void (*)(void *, void *, void *))(void *)Kclass._vTbl[__ecereVMethodID_class_OnUnserialize])(Kclass, &key, channel);
282 ((void (*)(void *, void *, void *))(void *)Dclass._vTbl[__ecereVMethodID_class_OnUnserialize])(Dclass, &data, channel);
283 destNode = (MapNode<MT, V>)container.GetAtPosition(key, true);
284 container.SetData(destNode, data);