Advertisement
Guest User

TaggedUnion

a guest
Nov 4th, 2014
223
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 1.96 KB | None | 0 0
  1. public struct TaggedUnion<T1,T2>
  2. {
  3.     public TaggedUnion(T1 value) { _union=new _Union{Type1=value}; _id=1; }
  4.     public TaggedUnion(T2 value) { _union=new _Union{Type2=value}; _id=2; }
  5.  
  6.     public T1 Type1 { get{ if(_id!=1)_TypeError(1); return _union.Type1; } set{ _union.Type1=value; _id=1; } }
  7.     public T2 Type2 { get{ if(_id!=2)_TypeError(2); return _union.Type2; } set{ _union.Type2=value; _id=2; } }
  8.  
  9.     public static explicit operator T1(TaggedUnion<T1,T2> value) { return value.Type1; }
  10.     public static explicit operator T2(TaggedUnion<T1,T2> value) { return value.Type2; }
  11.     public static implicit operator TaggedUnion<T1,T2>(T1 value) { return new TaggedUnion<T1,T2>(value); }
  12.     public static implicit operator TaggedUnion<T1,T2>(T2 value) { return new TaggedUnion<T1,T2>(value); }
  13.  
  14.     public byte Tag {get{ return _id; }}
  15.  
  16.     public Type GetUnionType()
  17.     {switch(_id){
  18.         case 1:  return typeof(T1);
  19.         case 2:  return typeof(T2);
  20.         default: return typeof(void);
  21.     }}
  22.  
  23.     public override string ToString()
  24.     {switch(_id){
  25.         case 1:  return _union.Type1.ToString();
  26.         case 2:  return _union.Type2.ToString();
  27.         default: return "void";
  28.     }}
  29.  
  30.     _Union _union;
  31.     byte _id;
  32.     void _TypeError(byte id) { throw new InvalidCastException(/* todo */); }
  33.  
  34.     [StructLayout(LayoutKind.Explicit)]
  35.     struct _Union
  36.     {
  37.         [FieldOffset(0)] public T1 Type1;
  38.         [FieldOffset(0)] public T2 Type2;
  39.     }
  40. }
  41.  
  42. public static class TaggedUnion
  43. {
  44.     // System.TypeLoadException: Could not load type '_Union' because generic types cannot have explicit layout.
  45.     public static void test()
  46.     {
  47.         TaggedUnion<int, double> foo = 1;
  48.  
  49.         Debug.Assert(foo.GetUnionType() == typeof(int));
  50.         { int bar = (int) foo; }
  51.         try {
  52.             double bar = (double)foo;
  53.             Debug.Assert(false);
  54.         } catch (InvalidCastException) {}
  55.  
  56.         foo = 1.0;
  57.  
  58.         Debug.Assert(foo.GetUnionType() == typeof(double));
  59.         { double bar = (double) foo; }
  60.  
  61.         try { Console.WriteLine((int)foo); Debug.Assert(false); }
  62.         catch (InvalidCastException) {}
  63.     }
  64. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement