Stringify.vala 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. namespace Invercargill.Operators {
  2. /**
  3. * Default stringify function for a generic type.
  4. *
  5. * Marshalling, same as hash()/equality()/comparison():
  6. * - inline types (bool, char/uchar, int/uint, long/ulong, enums)
  7. * arrive as a pointer-sized integer carrying the value itself.
  8. * - always-boxed types (int64, uint64, float, double and nullable
  9. * forms) arrive as pointers to the boxed payloads and are
  10. * dereferenced (a null box stringifies as "null").
  11. *
  12. * char stringifies as the character, not its numeric code (typeof
  13. * (char) == typeof(int8), so this branch must come first and serves
  14. * both). uchar stringifies numerically, matching uint8. Enums
  15. * stringify as their value nick when registered, falling back to
  16. * the numeric value.
  17. *
  18. * Note: typeof(T) cannot distinguish T=int from T=int? (same GType);
  19. * inline branches serve the non-nullable forms.
  20. */
  21. public static StringifyDelegate<T> stringify<T>() {
  22. var type = typeof(T);
  23. if(type == typeof(string)) { return i => (string)i; }
  24. else if(type == typeof(char)) { return i => ((char)i).to_string(); }
  25. else if(type == typeof(int)) { return i => ((int)i).to_string(); }
  26. else if(type == typeof(uint8)) { return i => ((uint8)i).to_string(); }
  27. else if(type == typeof(int16)) { return i => ((int16)i).to_string(); }
  28. else if(type == typeof(uint16)) { return i => ((uint16)i).to_string(); }
  29. else if(type == typeof(uint)) { return i => ((uint)i).to_string(); }
  30. else if(type == typeof(int64)) { return i => ((int64?)i) == null ? "null" : ((int64)((int64?)i)).to_string(); }
  31. else if(type == typeof(uint64)) { return i => ((uint64?)i) == null ? "null" : ((uint64)((uint64?)i)).to_string(); }
  32. else if(type == typeof(double)) { return i => ((double?)i) == null ? "null" : ((double)((double?)i)).to_string(); }
  33. else if(type == typeof(float)) { return i => ((float?)i) == null ? "null" : ((float)((float?)i)).to_string(); }
  34. else if(type == typeof(long)) { return i => ((long)i).to_string(); }
  35. else if(type == typeof(ulong)) { return i => ((ulong)i).to_string(); }
  36. else if(type == typeof(bool)) { return i => ((bool)i).to_string(); }
  37. else if(type.is_enum()) {
  38. var enum_class = (EnumClass)type.class_ref();
  39. return i => { var v = enum_class.get_value((int)i); return v == null ? ((int)i).to_string() : v.value_nick; };
  40. }
  41. else if(type.is_a(typeof(Stringifyable))) { return i => ((Stringifyable)i).to_string(); }
  42. else if(type.is_a(typeof(BinaryData))) { return i => "0x" + ((BinaryData)i).to_hex(); }
  43. return i => @"[$(type.name()) at 0x$(((int)i).to_string("%x"))]";
  44. }
  45. }