3eddb2aa31c5d27d29d5d44092df438935255c56
[platform/core/csapi/tizenfx.git] / internals / src / EflSharp / EflSharp / eina_container_common.cs
1 #pragma warning disable 1591
2
3 using System;
4 using System.Linq;
5 using System.Runtime.InteropServices;
6 using System.Collections.Generic;
7
8 using Eina.Callbacks;
9 using static Eina.HashNativeFunctions;
10 using static Eina.InarrayNativeFunctions;
11 using static Eina.InlistNativeFunctions;
12 using static Eina.NativeCustomExportFunctions;
13
14 namespace Eina {
15
16 public enum ElementType { NumericType, StringType, ObjectType };
17
18 [StructLayout(LayoutKind.Sequential)]
19 public struct InlistMem
20 {
21     public IntPtr next {get;set;}
22     public IntPtr prev {get;set;}
23     public IntPtr last {get;set;}
24 }
25
26 [StructLayout(LayoutKind.Sequential)]
27 public struct InlistNode<T>
28 {
29     public InlistMem __in_list {get;set;}
30     public T Val {get;set;}
31 }
32
33 public interface IBaseElementTraits<T>
34 {
35     IntPtr ManagedToNativeAlloc(T man);
36     IntPtr ManagedToNativeAllocInlistNode(T man);
37     void ManagedToNativeCopyTo(T man, IntPtr mem);
38     void NativeFree(IntPtr nat);
39     void NativeFreeInlistNodeElement(IntPtr nat);
40     void NativeFreeInlistNode(IntPtr nat, bool freeElement);
41     void NativeFreeInplace(IntPtr nat);
42     void ResidueFreeInplace(IntPtr nat);
43     T NativeToManaged(IntPtr nat);
44     T NativeToManagedInlistNode(IntPtr nat);
45     T NativeToManagedInplace(IntPtr nat);
46     IntPtr EinaCompareCb();
47     IntPtr EinaFreeCb();
48     IntPtr EinaHashNew();
49     IntPtr EinaInarrayNew(uint step);
50     IntPtr EinaHashIteratorKeyNew(IntPtr hash);
51 }
52
53 public class StringElementTraits : IBaseElementTraits<string>
54 {
55     public StringElementTraits()
56     {
57     }
58
59     public IntPtr ManagedToNativeAlloc(string man)
60     {
61         IntPtr newstring = MemoryNative.StrDup(man);
62         return newstring;
63     }
64
65     public IntPtr ManagedToNativeAllocInlistNode(string man)
66     {
67         var node = new InlistNode<IntPtr>();
68         node.Val = ManagedToNativeAlloc(man);
69         GCHandle pinnedData = GCHandle.Alloc(node, GCHandleType.Pinned);
70         IntPtr ptr = pinnedData.AddrOfPinnedObject();
71         IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf<InlistMem>() + Marshal.SizeOf<IntPtr>());
72         pinnedData.Free();
73         return nat;
74     }
75
76     public void ManagedToNativeCopyTo(string man, IntPtr mem)
77     {
78         IntPtr stringptr = ManagedToNativeAlloc(man);
79         Marshal.WriteIntPtr(mem, stringptr);
80     }
81
82     public void NativeFree(IntPtr nat)
83     {
84         if (nat != IntPtr.Zero)
85             MemoryNative.Free(nat);
86     }
87
88     public void NativeFreeInlistNodeElement(IntPtr nat)
89     {
90         if (nat == IntPtr.Zero)
91             return;
92         var val = Marshal.PtrToStructure<IntPtr>
93             (nat + Marshal.SizeOf<InlistMem>());
94         NativeFree(val);
95     }
96
97     public void NativeFreeInlistNode(IntPtr nat, bool freeElement)
98     {
99         if (nat == IntPtr.Zero)
100             return;
101         if (freeElement)
102             NativeFreeInlistNodeElement(nat);
103         MemoryNative.Free(nat);
104     }
105
106     public void NativeFreeInplace(IntPtr nat)
107     {
108         MemoryNative.FreeRef(nat);
109     }
110
111     public void ResidueFreeInplace(IntPtr nat)
112     {
113     }
114
115     public string NativeToManaged(IntPtr nat)
116     {
117         if (nat == IntPtr.Zero)
118             return default(string);
119         return StringConversion.NativeUtf8ToManagedString(nat);
120     }
121
122     public string NativeToManagedInlistNode(IntPtr nat)
123     {
124         if (nat == IntPtr.Zero)
125         {
126             Eina.Log.Error("Null pointer for Inlist node.");
127             return default(string);
128         }
129         IntPtr ptr_location = nat + Marshal.SizeOf<InlistMem>();
130         return NativeToManaged(Marshal.ReadIntPtr(ptr_location));
131     }
132
133     // Strings inplaced are always a pointer, because they are variable-sized
134     public string NativeToManagedInplace(IntPtr nat)
135     {
136         if (nat == IntPtr.Zero)
137             return default(string);
138         nat = Marshal.ReadIntPtr(nat);
139         if (nat == IntPtr.Zero)
140             return default(string);
141         return NativeToManaged(nat);
142     }
143
144     public IntPtr EinaCompareCb()
145     {
146         return MemoryNative.StrCompareFuncPtrGet();
147     }
148
149     public IntPtr EinaFreeCb()
150     {
151         return MemoryNative.FreeFuncPtrGet();
152     }
153
154     public IntPtr EinaHashNew()
155     {
156         return eina_hash_string_superfast_new(IntPtr.Zero);
157     }
158
159     public IntPtr EinaInarrayNew(uint step)
160     {
161         return eina_inarray_new((uint)Marshal.SizeOf<IntPtr>(), step);
162     }
163
164     public IntPtr EinaHashIteratorKeyNew(IntPtr hash)
165     {
166         return eina_hash_iterator_key_new(hash);
167     }
168 }
169
170 public class EflObjectElementTraits<T> : IBaseElementTraits<T>
171 {
172     private System.Type concreteType = null;
173
174     public EflObjectElementTraits(System.Type concrete)
175     {
176         concreteType = concrete;
177     }
178
179     public IntPtr ManagedToNativeAlloc(T man)
180     {
181         IntPtr h = ((Efl.Eo.IWrapper)man).NativeHandle;
182         if (h == IntPtr.Zero)
183             return h;
184         return Efl.Eo.Globals.efl_ref(h);
185     }
186
187     public IntPtr ManagedToNativeAllocInlistNode(T man)
188     {
189         var node = new InlistNode<IntPtr>();
190         node.Val = ManagedToNativeAlloc(man);
191         GCHandle pinnedData = GCHandle.Alloc(node, GCHandleType.Pinned);
192         IntPtr ptr = pinnedData.AddrOfPinnedObject();
193         IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf<InlistMem>() + Marshal.SizeOf<IntPtr>());
194         pinnedData.Free();
195         return nat;
196     }
197
198     public void ManagedToNativeCopyTo(T man, IntPtr mem)
199     {
200         IntPtr v = ManagedToNativeAlloc(man);
201         Marshal.WriteIntPtr(mem, v);
202     }
203
204     public void NativeFree(IntPtr nat)
205     {
206         if (nat != IntPtr.Zero)
207             Efl.Eo.Globals.efl_unref(nat);
208     }
209
210     public void NativeFreeRef(IntPtr nat, bool unrefs)
211     {
212         if (unrefs)
213             NativeFree(nat);
214     }
215
216     public void NativeFreeInlistNodeElement(IntPtr nat)
217     {
218         if (nat == IntPtr.Zero)
219             return;
220         var val = Marshal.PtrToStructure<IntPtr>
221             (nat + Marshal.SizeOf<InlistMem>());
222         NativeFree(val);
223     }
224
225     public void NativeFreeInlistNode(IntPtr nat, bool freeElement)
226     {
227         if (nat == IntPtr.Zero)
228             return;
229         if (freeElement)
230             NativeFreeInlistNodeElement(nat);
231         MemoryNative.Free(nat);
232     }
233
234     public void NativeFreeInplace(IntPtr nat)
235     {
236         NativeFree(nat);
237     }
238
239     public void ResidueFreeInplace(IntPtr nat)
240     {
241     }
242
243     public T NativeToManaged(IntPtr nat)
244     {
245         if (nat == IntPtr.Zero)
246             return default(T);
247         return (T) Activator.CreateInstance(concreteType, Efl.Eo.Globals.efl_ref(nat));
248     }
249
250     public T NativeToManagedRef(IntPtr nat)
251     {
252         if (nat == IntPtr.Zero)
253             return default(T);
254         return NativeToManaged(nat);
255     }
256
257     public T NativeToManagedInlistNode(IntPtr nat)
258     {
259         if (nat == IntPtr.Zero)
260         {
261             Eina.Log.Error("Null pointer for Inlist node.");
262             return default(T);
263         }
264         IntPtr ptr_location = nat + Marshal.SizeOf<InlistMem>();
265         return NativeToManaged(Marshal.ReadIntPtr(ptr_location));
266     }
267
268     // EFL objects inplaced are always a pointer, because they are variable-sized
269     public T NativeToManagedInplace(IntPtr nat)
270     {
271         if (nat == IntPtr.Zero)
272             return default(T);
273         nat = Marshal.ReadIntPtr(nat);
274         if (nat == IntPtr.Zero)
275             return default(T);
276         return NativeToManaged(nat);
277     }
278
279     public IntPtr EinaCompareCb()
280     {
281         return MemoryNative.PtrCompareFuncPtrGet();
282     }
283
284     public IntPtr EinaFreeCb()
285     {
286         return MemoryNative.EflUnrefFuncPtrGet();
287     }
288
289     public IntPtr EinaHashNew()
290     {
291         return eina_hash_pointer_new(IntPtr.Zero);
292     }
293
294     public IntPtr EinaInarrayNew(uint step)
295     {
296         return eina_inarray_new((uint)Marshal.SizeOf<IntPtr>(), step);
297     }
298
299     public IntPtr EinaHashIteratorKeyNew(IntPtr hash)
300     {
301         return eina_hash_iterator_ptr_key_wrapper_new_custom_export_mono(hash);
302     }
303 }
304
305 public abstract class PrimitiveElementTraits<T>
306 {
307     private Eina_Compare_Cb dlgt = null;
308
309     public IntPtr ManagedToNativeAlloc(T man)
310     {
311         return PrimitiveConversion.ManagedToPointerAlloc(man);
312     }
313
314     public IntPtr ManagedToNativeAllocInlistNode(T man)
315     {
316         var node = new InlistNode<T>();
317         node.Val = man;
318         GCHandle pinnedData = GCHandle.Alloc(node, GCHandleType.Pinned);
319         IntPtr ptr = pinnedData.AddrOfPinnedObject();
320         int Tsize = Marshal.SizeOf<T>() < Marshal.SizeOf<IntPtr>() ? Marshal.SizeOf<IntPtr>() : Marshal.SizeOf<T>();
321         IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf<InlistMem>() + Tsize);
322         pinnedData.Free();
323         return nat;
324     }
325
326     public void NativeFree(IntPtr nat)
327     {
328         MemoryNative.Free(nat);
329     }
330
331     public void NativeFreeInlistNodeElement(IntPtr nat)
332     {
333         // Do nothing
334     }
335
336     public void NativeFreeInlistNode(IntPtr nat, bool freeElement)
337     {
338         MemoryNative.Free(nat);
339     }
340
341     public void NativeFreeInplace(IntPtr nat)
342     {
343         // Do nothing
344     }
345
346     public void ResidueFreeInplace(IntPtr nat)
347     {
348         NativeFree(nat);
349     }
350
351     public T NativeToManaged(IntPtr nat)
352     {
353         if (nat == IntPtr.Zero)
354         {
355             Eina.Log.Error("Null pointer on primitive/struct container.");
356             return default(T);
357         }
358         return PrimitiveConversion.PointerToManaged<T>(nat);
359     }
360
361     public T NativeToManagedRef(IntPtr nat)
362     {
363         return NativeToManaged(nat);
364     }
365
366
367     public T NativeToManagedInplace(IntPtr nat)
368     {
369         return NativeToManaged(nat);
370     }
371
372     private int PrimitiveCompareCb(IntPtr ptr1, IntPtr ptr2)
373     {
374         var m1 = (IComparable) NativeToManaged(ptr1);
375         var m2 = NativeToManaged(ptr2);
376         return m1.CompareTo(m2);
377     }
378
379     public IntPtr EinaCompareCb()
380     {
381         if (dlgt == null)
382             dlgt = new Eina_Compare_Cb(PrimitiveCompareCb);
383         return Marshal.GetFunctionPointerForDelegate(dlgt);
384     }
385
386     public IntPtr EinaFreeCb()
387     {
388         return MemoryNative.FreeFuncPtrGet();
389     }
390
391     public IntPtr EinaInarrayNew(uint step)
392     {
393         return eina_inarray_new((uint)Marshal.SizeOf<T>(), step);
394     }
395
396     public IntPtr EinaHashIteratorKeyNew(IntPtr hash)
397     {
398         return eina_hash_iterator_key_new(hash);
399     }
400 }
401
402 abstract public class Primitive32ElementTraits<T> : PrimitiveElementTraits<T>, IBaseElementTraits<T>
403 {
404     private static IBaseElementTraits<Int32> int32Traits = null;
405
406     public Primitive32ElementTraits()
407     {
408         if (int32Traits == null)
409             if (typeof(T) == typeof(Int32)) // avoid infinite recursion
410                 int32Traits = (IBaseElementTraits<Int32>)this;
411             else
412                 int32Traits = TraitFunctions.GetTypeTraits<Int32>();
413     }
414
415     public abstract void ManagedToNativeCopyTo(T man, IntPtr mem);
416     public abstract T NativeToManagedInlistNode(IntPtr nat);
417
418     public IntPtr ManagedToNativeAllocRef(T man, bool refs)
419     {
420         return int32Traits.ManagedToNativeAlloc(Convert.ToInt32((object)man));
421     }
422
423     public void NativeFreeRef(IntPtr nat, bool unrefs)
424     {
425         int32Traits.NativeFree(nat);
426     }
427
428     public IntPtr EinaHashNew()
429     {
430         return eina_hash_int32_new(IntPtr.Zero);
431     }
432 }
433
434 abstract public class Primitive64ElementTraits<T> : PrimitiveElementTraits<T>, IBaseElementTraits<T>
435 {
436     private static IBaseElementTraits<Int64> int64Traits = null;
437
438     public Primitive64ElementTraits()
439     {
440         if (int64Traits == null)
441             if (typeof(T) == typeof(Int64)) // avoid infinite recursion
442                 int64Traits = (IBaseElementTraits<Int64>)this;
443             else
444                 int64Traits = TraitFunctions.GetTypeTraits<Int64>();
445     }
446
447     public abstract void ManagedToNativeCopyTo(T man, IntPtr mem);
448     public abstract T NativeToManagedInlistNode(IntPtr nat);
449
450     public IntPtr ManagedToNativeAllocRef(T man, bool refs)
451     {
452         return int64Traits.ManagedToNativeAlloc(Convert.ToInt64((object)man));
453     }
454
455     public void NativeFreeRef(IntPtr nat, bool unrefs)
456     {
457         int64Traits.NativeFree(nat);
458     }
459
460     public IntPtr EinaHashNew()
461     {
462         return eina_hash_int64_new(IntPtr.Zero);
463     }
464 }
465
466 public class IntElementTraits : Primitive32ElementTraits<int>, IBaseElementTraits<int>
467 {
468     override public void ManagedToNativeCopyTo(int man, IntPtr mem)
469     {
470         var arr = new int[1];
471         arr[0] = man;
472         Marshal.Copy(arr, 0, mem, 1);
473     }
474     override public int NativeToManagedInlistNode(IntPtr nat)
475     {
476         if (nat == IntPtr.Zero)
477         {
478             Eina.Log.Error("Null pointer for Inlist node.");
479             return default(int);
480         }
481         IntPtr loc = nat + Marshal.SizeOf<InlistMem>();
482         var v = new int[1];
483         Marshal.Copy(loc, v, 0, 1);
484         return v[0];
485     }
486 }
487
488 public class CharElementTraits : Primitive32ElementTraits<char>, IBaseElementTraits<char>
489 {
490     override public void ManagedToNativeCopyTo(char man, IntPtr mem)
491     {
492         var arr = new char[1];
493         arr[0] = man;
494         Marshal.Copy(arr, 0, mem, 1);
495     }
496     override public char NativeToManagedInlistNode(IntPtr nat)
497     {
498         if (nat == IntPtr.Zero)
499         {
500             Eina.Log.Error("Null pointer for Inlist node.");
501             return default(char);
502         }
503         IntPtr loc = nat + Marshal.SizeOf<InlistMem>();
504         var v = new char[1];
505         Marshal.Copy(loc, v, 0, 1);
506         return v[0];
507     }
508 }
509 public class LongElementTraits : Primitive64ElementTraits<long>, IBaseElementTraits<long>
510 {
511     override public void ManagedToNativeCopyTo(long man, IntPtr mem)
512     {
513         var arr = new long[1];
514         arr[0] = man;
515         Marshal.Copy(arr, 0, mem, 1);
516     }
517     override public long NativeToManagedInlistNode(IntPtr nat)
518     {
519         if (nat == IntPtr.Zero)
520         {
521             Eina.Log.Error("Null pointer for Inlist node.");
522             return default(long);
523         }
524         IntPtr loc = nat + Marshal.SizeOf<InlistMem>();
525         var v = new long[1];
526         Marshal.Copy(loc, v, 0, 1);
527         return v[0];
528     }
529 }
530
531 public class ShortElementTraits : Primitive32ElementTraits<short>, IBaseElementTraits<short>
532 {
533     override public void ManagedToNativeCopyTo(short man, IntPtr mem)
534     {
535         var arr = new short[1];
536         arr[0] = man;
537         Marshal.Copy(arr, 0, mem, 1);
538     }
539     override public short NativeToManagedInlistNode(IntPtr nat)
540     {
541         if (nat == IntPtr.Zero)
542         {
543             Eina.Log.Error("Null pointer for Inlist node.");
544             return default(short);
545         }
546         IntPtr loc = nat + Marshal.SizeOf<InlistMem>();
547         var v = new short[1];
548         Marshal.Copy(loc, v, 0, 1);
549         return v[0];
550     }
551 }
552
553 public class FloatElementTraits : Primitive32ElementTraits<float>, IBaseElementTraits<float>
554 {
555     override public void ManagedToNativeCopyTo(float man, IntPtr mem)
556     {
557         var arr = new float[1];
558         arr[0] = man;
559         Marshal.Copy(arr, 0, mem, 1);
560     }
561     override public float NativeToManagedInlistNode(IntPtr nat)
562     {
563         if (nat == IntPtr.Zero)
564         {
565             Eina.Log.Error("Null pointer for Inlist node.");
566             return default(float);
567         }
568         IntPtr loc = nat + Marshal.SizeOf<InlistMem>();
569         var v = new float[1];
570         Marshal.Copy(loc, v, 0, 1);
571         return v[0];
572     }
573 }
574
575 public class DoubleElementTraits : Primitive64ElementTraits<double>, IBaseElementTraits<double>
576 {
577     override public void ManagedToNativeCopyTo(double man, IntPtr mem)
578     {
579         var arr = new double[1];
580         arr[0] = man;
581         Marshal.Copy(arr, 0, mem, 1);
582     }
583     override public double NativeToManagedInlistNode(IntPtr nat)
584     {
585         if (nat == IntPtr.Zero)
586         {
587             Eina.Log.Error("Null pointer for Inlist node.");
588             return default(double);
589         }
590         IntPtr loc = nat + Marshal.SizeOf<InlistMem>();
591         var v = new double[1];
592         Marshal.Copy(loc, v, 0, 1);
593         return v[0];
594     }
595 }
596
597 public class ByteElementTraits : Primitive32ElementTraits<byte>, IBaseElementTraits<byte>
598 {
599     override public void ManagedToNativeCopyTo(byte man, IntPtr mem)
600     {
601         var arr = new byte[1];
602         arr[0] = man;
603         Marshal.Copy(arr, 0, mem, 1);
604     }
605     override public byte NativeToManagedInlistNode(IntPtr nat)
606     {
607         if (nat == IntPtr.Zero)
608         {
609             Eina.Log.Error("Null pointer for Inlist node.");
610             return default(byte);
611         }
612         IntPtr loc = nat + Marshal.SizeOf<InlistMem>();
613         var v = new byte[1];
614         Marshal.Copy(loc, v, 0, 1);
615         return v[0];
616     }
617 }
618
619 public static class TraitFunctions
620 {
621     public static bool IsEflObject(System.Type type)
622     {
623         return typeof(Efl.Eo.IWrapper).IsAssignableFrom(type);
624     }
625
626     public static bool IsString(System.Type type)
627     {
628         return type == typeof(string);
629     }
630
631     public static Eina.ElementType GetElementTypeCode(System.Type type)
632     {
633         if (IsEflObject(type))
634             return ElementType.ObjectType;
635         else if (IsString(type))
636             return ElementType.StringType;
637         else
638             return ElementType.NumericType;
639     }
640
641     private static IDictionary<System.Type, object> register = new Dictionary<System.Type, object>();
642
643     private static System.Type AsEflInstantiableType(System.Type type)
644     {
645         if (!IsEflObject(type))
646             return null;
647
648         if (type.IsInterface)
649         {
650             string fullName = type.FullName + "Concrete";
651             return type.Assembly.GetType(fullName); // That was our best guess...
652         }
653
654         return type; // Not interface, so it should be a concrete.
655     }
656
657     public static object RegisterTypeTraits<T>()
658     {
659         Eina.Log.Debug($"Finding TypeTraits for {typeof(T).Name}");
660         object traits;
661         var type = typeof(T);
662         if (IsEflObject(type))
663         {
664             System.Type concrete = AsEflInstantiableType(type);
665             if (concrete == null || !type.IsAssignableFrom(concrete))
666                 throw new Exception("Failed to get a suitable concrete class for this type.");
667             traits = new EflObjectElementTraits<T>(concrete);
668         }
669         else if (IsString(type))
670             traits = new StringElementTraits();
671         else if (type.IsValueType)
672         {
673             if (type == typeof(int))
674                 traits = new IntElementTraits();
675             else if (type == typeof(char))
676                 traits = new CharElementTraits();
677             else if (type == typeof(long))
678                 traits = new LongElementTraits();
679             else if (type == typeof(short))
680                 traits = new ShortElementTraits();
681             else if (type == typeof(float))
682                 traits = new FloatElementTraits();
683             else if (type == typeof(double))
684                 traits = new DoubleElementTraits();
685             else if (type == typeof(byte))
686                 traits = new ByteElementTraits();
687             else
688                 throw new Exception("No traits registered for this type");
689         }
690         else
691             throw new Exception("No traits registered for this type");
692
693         register[type] = traits;
694         return traits;
695     }
696
697     public static object RegisterTypeTraits<T>(IBaseElementTraits<T> traits)
698     {
699         register[typeof(T)] = traits;
700         return traits;
701     }
702
703     public static IBaseElementTraits<T> GetTypeTraits<T>()
704     {
705         object traits;
706         if (!register.TryGetValue(typeof(T), out traits))
707             traits = RegisterTypeTraits<T>();
708         return (IBaseElementTraits<T>) traits;
709     }
710
711     //                  //
712     // Traits functions //
713     //                  //
714
715     // Convertion functions //
716
717     public static IntPtr ManagedToNativeAlloc<T>(T man)
718     {
719         return GetTypeTraits<T>().ManagedToNativeAlloc(man);
720     }
721
722     public static void ManagedToNativeCopyTo<T>(T man, IntPtr mem)
723     {
724         GetTypeTraits<T>().ManagedToNativeCopyTo(man, mem);
725     }
726
727     public static IntPtr ManagedToNativeAllocInlistNode<T>(T man)
728     {
729         return GetTypeTraits<T>().ManagedToNativeAllocInlistNode(man);
730     }
731
732     public static void NativeFree<T>(IntPtr nat)
733     {
734         GetTypeTraits<T>().NativeFree(nat);
735     }
736
737     public static void NativeFreeInlistNodeElement<T>(IntPtr nat)
738     {
739         GetTypeTraits<T>().NativeFreeInlistNodeElement(nat);
740     }
741
742     public static void NativeFreeInlistNode<T>(IntPtr nat, bool freeElement = true)
743     {
744         GetTypeTraits<T>().NativeFreeInlistNode(nat, freeElement);
745     }
746
747     public static void NativeFreeInplace<T>(IntPtr nat)
748     {
749         GetTypeTraits<T>().NativeFreeInplace(nat);
750     }
751
752     public static void ResidueFreeInplace<T>(IntPtr nat)
753     {
754         GetTypeTraits<T>().ResidueFreeInplace(nat);
755     }
756
757     public static T NativeToManaged<T>(IntPtr nat)
758     {
759         return GetTypeTraits<T>().NativeToManaged(nat);
760     }
761
762     public static T NativeToManagedInlistNode<T>(IntPtr nat)
763     {
764         return GetTypeTraits<T>().NativeToManagedInlistNode(nat);
765     }
766
767     public static T NativeToManagedInplace<T>(IntPtr nat)
768     {
769         return GetTypeTraits<T>().NativeToManagedInplace(nat);
770     }
771
772     // Misc //
773
774     public static IntPtr EinaCompareCb<T>()
775     {
776         return GetTypeTraits<T>().EinaCompareCb();
777     }
778
779     public static IntPtr EinaFreeCb<T>()
780     {
781         return GetTypeTraits<T>().EinaFreeCb();
782     }
783
784     public static IntPtr EinaHashNew<TKey>()
785     {
786         return GetTypeTraits<TKey>().EinaHashNew();
787     }
788
789     public static IntPtr EinaInarrayNew<T>(uint step)
790     {
791         return GetTypeTraits<T>().EinaInarrayNew(step);
792     }
793
794     public static IntPtr EinaHashIteratorKeyNew<T>(IntPtr hash)
795     {
796         return GetTypeTraits<T>().EinaHashIteratorKeyNew(hash);
797     }
798 }
799
800 }