Value
struct Value
A struct that can hold any value type or reference type without boxing primitive types or enums. Behavior matches
casting to/from object.
using System.Diagnostics.CodeAnalysis;
using System.Drawing;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace System
{
[NullableContext(1)]
[Nullable(0)]
internal readonly struct Value
{
[NullableContext(0)]
private readonly struct NullableTemplate<[IsUnmanaged] T> where T : struct
{
public readonly bool _hasValue;
public readonly T _value;
public NullableTemplate(T value)
{
_value = value;
_hasValue = true;
}
}
[NullableContext(0)]
private readonly struct PackedColor
{
private readonly struct CastColor
{
[Nullable(2)]
public readonly string Name;
public readonly long Argb;
public readonly short KnownColor;
public readonly short State;
}
private readonly int _argb;
private readonly short _knownColor;
private readonly short _state;
private PackedColor(int argb, KnownColor knownColor, short state)
{
_argb = argb;
_knownColor = (short)knownColor;
_state = state;
}
public static bool TryCreate([In] [IsReadOnly] ref Color color, out PackedColor packedColor)
{
CastColor castColor = Unsafe.As<Color, CastColor>(ref Unsafe.AsRef(ref color));
if (castColor.Name != null) {
packedColor = default(PackedColor);
return false;
}
packedColor = new PackedColor((int)castColor.Argb, (KnownColor)castColor.KnownColor, castColor.State);
return true;
}
public Color Extract()
{
if (_knownColor == 0) {
if (_state != 0)
return Color.FromArgb(_argb);
return Color.Empty;
}
return Color.FromKnownColor((KnownColor)_knownColor);
}
}
[Nullable(0)]
private sealed class PackedColorFlag : TypeFlag<Color>
{
public static PackedColorFlag Instance { get; } = new PackedColorFlag();
public override Color To([In] [IsReadOnly] Value value)
{
return value._union.PackedColor.Extract();
}
}
[NullableContext(0)]
private readonly struct PackedDateTimeOffset
{
private const ulong BaseTicks = 567709344000000000;
private const ulong MaxTicks = 711824532075855871;
private const int HourOffset = 14;
private const ulong TickMask = 144115188075855871;
private const ulong MinuteMask = 432345564227567616;
private const ulong HourMask = 17870283321406128128;
private const int MinuteShift = 57;
private const int HourShift = 59;
private readonly ulong _data;
private PackedDateTimeOffset(ulong data)
{
_data = data;
}
public static bool TryCreate(DateTimeOffset dateTime, TimeSpan offset, out PackedDateTimeOffset packed)
{
bool result = false;
packed = default(PackedDateTimeOffset);
ulong ticks = (ulong)dateTime.Ticks;
if (ticks > 567709344000000000 && ticks < 711824532075855871) {
int minutes = offset.Minutes;
if (minutes % 15 == 0) {
ulong num = (ulong)((long)(minutes / 15) << 57);
int num2 = offset.Hours + 14;
num = (ulong)((long)num | ((long)num2 << 59));
num |= ticks - 567709344000000000;
packed = new PackedDateTimeOffset(num);
result = true;
}
}
return result;
}
public DateTimeOffset Extract()
{
return new DateTimeOffset(offset: new TimeSpan((int)(((ulong)((long)_data & -576460752303423488) >> 59) - 14), (int)((_data & 432345564227567616) >> 57), 0), ticks: (long)((_data & 144115188075855871) + 567709344000000000));
}
}
[Nullable(0)]
private sealed class PackedDateTimeOffsetFlag : TypeFlag<DateTimeOffset>
{
public static PackedDateTimeOffsetFlag Instance { get; } = new PackedDateTimeOffsetFlag();
public override DateTimeOffset To([In] [IsReadOnly] Value value)
{
return value._union.PackedDateTimeOffset.Extract();
}
}
[Nullable(new byte[] {
0,
1
})]
private sealed class StraightCastFlag<[Nullable(2)] T> : TypeFlag<T>
{
public static StraightCastFlag<T> Instance { get; } = new StraightCastFlag<T>();
public override T To([In] [IsReadOnly] Value value)
{
return Unsafe.As<Union, T>(ref Unsafe.AsRef<Union>(ref value._union));
}
}
[Nullable(0)]
private abstract class TypeFlag
{
public abstract Type Type {
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get;
}
public abstract object ToObject([In] [IsReadOnly] Value value);
}
[Nullable(0)]
private abstract class TypeFlag<[Nullable(2)] T> : TypeFlag
{
public sealed override Type Type {
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get {
return typeof(T);
}
}
public override object ToObject([In] [IsReadOnly] Value value)
{
return this.To(ref value);
}
public abstract T To([In] [IsReadOnly] Value value);
}
[Nullable(0)]
private static class TypeFlags
{
internal static StraightCastFlag<bool> Boolean { get; } = StraightCastFlag<bool>.Instance;
internal static StraightCastFlag<char> Char { get; } = StraightCastFlag<char>.Instance;
internal static StraightCastFlag<byte> Byte { get; } = StraightCastFlag<byte>.Instance;
internal static StraightCastFlag<sbyte> SByte { get; } = StraightCastFlag<sbyte>.Instance;
internal static StraightCastFlag<short> Int16 { get; } = StraightCastFlag<short>.Instance;
internal static StraightCastFlag<ushort> UInt16 { get; } = StraightCastFlag<ushort>.Instance;
internal static StraightCastFlag<int> Int32 { get; } = StraightCastFlag<int>.Instance;
internal static StraightCastFlag<uint> UInt32 { get; } = StraightCastFlag<uint>.Instance;
internal static StraightCastFlag<long> Int64 { get; } = StraightCastFlag<long>.Instance;
internal static StraightCastFlag<ulong> UInt64 { get; } = StraightCastFlag<ulong>.Instance;
internal static StraightCastFlag<float> Single { get; } = StraightCastFlag<float>.Instance;
internal static StraightCastFlag<double> Double { get; } = StraightCastFlag<double>.Instance;
internal static StraightCastFlag<DateTime> DateTime { get; } = StraightCastFlag<System.DateTime>.Instance;
internal static UtcDateTimeOffsetFlag UtcDateTimeOffset { get; } = UtcDateTimeOffsetFlag.Instance;
internal static PackedDateTimeOffsetFlag PackedDateTimeOffset { get; } = PackedDateTimeOffsetFlag.Instance;
internal static PackedColorFlag PackedColor { get; } = PackedColorFlag.Instance;
internal static StraightCastFlag<Size> Size { get; } = StraightCastFlag<System.Drawing.Size>.Instance;
internal static StraightCastFlag<Point> Point { get; } = StraightCastFlag<System.Drawing.Point>.Instance;
}
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
[NullableContext(0)]
private struct Union
{
[FieldOffset(0)]
public byte Byte;
[FieldOffset(0)]
public sbyte SByte;
[FieldOffset(0)]
public char Char;
[FieldOffset(0)]
public bool Boolean;
[FieldOffset(0)]
public short Int16;
[FieldOffset(0)]
public ushort UInt16;
[FieldOffset(0)]
public int Int32;
[FieldOffset(0)]
public uint UInt32;
[FieldOffset(0)]
public long Int64;
[FieldOffset(0)]
public long Ticks;
[FieldOffset(0)]
public ulong UInt64;
[FieldOffset(0)]
public float Single;
[FieldOffset(0)]
public double Double;
[FieldOffset(0)]
public DateTime DateTime;
[FieldOffset(0)]
public PackedDateTimeOffset PackedDateTimeOffset;
[FieldOffset(0)]
public PackedColor PackedColor;
[FieldOffset(0)]
public Size Size;
[FieldOffset(0)]
public Point Point;
[FieldOffset(0)]
public (int Offset, int Count) Segment;
}
[Nullable(0)]
private sealed class UtcDateTimeOffsetFlag : TypeFlag<DateTimeOffset>
{
public static UtcDateTimeOffsetFlag Instance { get; } = new UtcDateTimeOffsetFlag();
public override DateTimeOffset To([In] [IsReadOnly] Value value)
{
return new DateTimeOffset(new DateTime(value._union.Ticks, DateTimeKind.Utc));
}
}
private readonly Union _union;
[Nullable(2)]
private readonly object _object;
[Nullable(2)]
public Type Type {
[NullableContext(2)]
get {
Type type;
if (_object == null)
type = null;
else {
TypeFlag typeFlag = _object as TypeFlag;
if (typeFlag != null)
type = typeFlag.Type;
else {
type = _object.GetType();
if (_union.UInt64 != 0) {
if (type == typeof(byte[]))
type = typeof(ArraySegment<byte>);
else if (type == typeof(char[])) {
type = typeof(ArraySegment<char>);
}
}
}
}
return type;
}
}
[NullableContext(2)]
public Value(object value)
{
_object = value;
_union = default(Union);
}
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
private static void ThrowInvalidCast([Nullable(2)] Type from, Type to)
{
throw new InvalidCastException((from?.Name ?? "<null>") + " cannot be cast to " + to.Name);
}
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
private static void ThrowInvalidOperation()
{
throw new InvalidOperationException();
}
public Value(byte value)
{
_union = default(Union);
_object = TypeFlags.Byte;
_union.Byte = value;
}
public Value(byte? value)
{
_union = default(Union);
if (value.HasValue) {
_object = TypeFlags.Byte;
_union.Byte = value.Value;
} else
_object = null;
}
public static implicit operator Value(byte value)
{
return new Value(value);
}
public static explicit operator byte([In] [IsReadOnly] ref Value value)
{
return value.GetValue<byte>();
}
public static implicit operator Value(byte? value)
{
return new Value(value);
}
public static explicit operator byte?([In] [IsReadOnly] ref Value value)
{
return value.GetValue<byte?>();
}
public Value(sbyte value)
{
_union = default(Union);
_object = TypeFlags.SByte;
_union.SByte = value;
}
public Value(sbyte? value)
{
_union = default(Union);
if (value.HasValue) {
_object = TypeFlags.SByte;
_union.SByte = value.Value;
} else
_object = null;
}
public static implicit operator Value(sbyte value)
{
return new Value(value);
}
public static explicit operator sbyte([In] [IsReadOnly] ref Value value)
{
return value.GetValue<sbyte>();
}
public static implicit operator Value(sbyte? value)
{
return new Value(value);
}
public static explicit operator sbyte?([In] [IsReadOnly] ref Value value)
{
return value.GetValue<sbyte?>();
}
public Value(bool value)
{
_union = default(Union);
_object = TypeFlags.Boolean;
_union.Boolean = value;
}
public Value(bool? value)
{
_union = default(Union);
if (value.HasValue) {
_object = TypeFlags.Boolean;
_union.Boolean = value.Value;
} else
_object = null;
}
public static implicit operator Value(bool value)
{
return new Value(value);
}
public static explicit operator bool([In] [IsReadOnly] ref Value value)
{
return value.GetValue<bool>();
}
public static implicit operator Value(bool? value)
{
return new Value(value);
}
public static explicit operator bool?([In] [IsReadOnly] ref Value value)
{
return value.GetValue<bool?>();
}
public Value(char value)
{
_union = default(Union);
_object = TypeFlags.Char;
_union.Char = value;
}
public Value(char? value)
{
_union = default(Union);
if (value.HasValue) {
_object = TypeFlags.Char;
_union.Char = value.Value;
} else
_object = null;
}
public static implicit operator Value(char value)
{
return new Value(value);
}
public static explicit operator char([In] [IsReadOnly] ref Value value)
{
return value.GetValue<char>();
}
public static implicit operator Value(char? value)
{
return new Value(value);
}
public static explicit operator char?([In] [IsReadOnly] ref Value value)
{
return value.GetValue<char?>();
}
public Value(short value)
{
_union = default(Union);
_object = TypeFlags.Int16;
_union.Int16 = value;
}
public Value(short? value)
{
_union = default(Union);
if (value.HasValue) {
_object = TypeFlags.Int16;
_union.Int16 = value.Value;
} else
_object = null;
}
public static implicit operator Value(short value)
{
return new Value(value);
}
public static explicit operator short([In] [IsReadOnly] ref Value value)
{
return value.GetValue<short>();
}
public static implicit operator Value(short? value)
{
return new Value(value);
}
public static explicit operator short?([In] [IsReadOnly] ref Value value)
{
return value.GetValue<short?>();
}
public Value(int value)
{
_union = default(Union);
_object = TypeFlags.Int32;
_union.Int32 = value;
}
public Value(int? value)
{
_union = default(Union);
if (value.HasValue) {
_object = TypeFlags.Int32;
_union.Int32 = value.Value;
} else
_object = null;
}
public static implicit operator Value(int value)
{
return new Value(value);
}
public static explicit operator int([In] [IsReadOnly] ref Value value)
{
return value.GetValue<int>();
}
public static implicit operator Value(int? value)
{
return new Value(value);
}
public static explicit operator int?([In] [IsReadOnly] ref Value value)
{
return value.GetValue<int?>();
}
public Value(long value)
{
_union = default(Union);
_object = TypeFlags.Int64;
_union.Int64 = value;
}
public Value(long? value)
{
_union = default(Union);
if (value.HasValue) {
_object = TypeFlags.Int64;
_union.Int64 = value.Value;
} else
_object = null;
}
public static implicit operator Value(long value)
{
return new Value(value);
}
public static explicit operator long([In] [IsReadOnly] ref Value value)
{
return value.GetValue<long>();
}
public static implicit operator Value(long? value)
{
return new Value(value);
}
public static explicit operator long?([In] [IsReadOnly] ref Value value)
{
return value.GetValue<long?>();
}
public Value(ushort value)
{
_union = default(Union);
_object = TypeFlags.UInt16;
_union.UInt16 = value;
}
public Value(ushort? value)
{
_union = default(Union);
if (value.HasValue) {
_object = TypeFlags.UInt16;
_union.UInt16 = value.Value;
} else
_object = null;
}
public static implicit operator Value(ushort value)
{
return new Value(value);
}
public static explicit operator ushort([In] [IsReadOnly] ref Value value)
{
return value.GetValue<ushort>();
}
public static implicit operator Value(ushort? value)
{
return new Value(value);
}
public static explicit operator ushort?([In] [IsReadOnly] ref Value value)
{
return value.GetValue<ushort?>();
}
public Value(uint value)
{
_union = default(Union);
_object = TypeFlags.UInt32;
_union.UInt32 = value;
}
public Value(uint? value)
{
_union = default(Union);
if (value.HasValue) {
_object = TypeFlags.UInt32;
_union.UInt32 = value.Value;
} else
_object = null;
}
public static implicit operator Value(uint value)
{
return new Value(value);
}
public static explicit operator uint([In] [IsReadOnly] ref Value value)
{
return value.GetValue<uint>();
}
public static implicit operator Value(uint? value)
{
return new Value(value);
}
public static explicit operator uint?([In] [IsReadOnly] ref Value value)
{
return value.GetValue<uint?>();
}
public Value(ulong value)
{
_union = default(Union);
_object = TypeFlags.UInt64;
_union.UInt64 = value;
}
public Value(ulong? value)
{
_union = default(Union);
if (value.HasValue) {
_object = TypeFlags.UInt64;
_union.UInt64 = value.Value;
} else
_object = null;
}
public static implicit operator Value(ulong value)
{
return new Value(value);
}
public static explicit operator ulong([In] [IsReadOnly] ref Value value)
{
return value.GetValue<ulong>();
}
public static implicit operator Value(ulong? value)
{
return new Value(value);
}
public static explicit operator ulong?([In] [IsReadOnly] ref Value value)
{
return value.GetValue<ulong?>();
}
public Value(float value)
{
_union = default(Union);
_object = TypeFlags.Single;
_union.Single = value;
}
public Value(float? value)
{
_union = default(Union);
if (value.HasValue) {
_object = TypeFlags.Single;
_union.Single = value.Value;
} else
_object = null;
}
public static implicit operator Value(float value)
{
return new Value(value);
}
public static explicit operator float([In] [IsReadOnly] ref Value value)
{
return value.GetValue<float>();
}
public static implicit operator Value(float? value)
{
return new Value(value);
}
public static explicit operator float?([In] [IsReadOnly] ref Value value)
{
return value.GetValue<float?>();
}
public Value(double value)
{
_union = default(Union);
_object = TypeFlags.Double;
_union.Double = value;
}
public Value(double? value)
{
_union = default(Union);
if (value.HasValue) {
_object = TypeFlags.Double;
_union.Double = value.Value;
} else
_object = null;
}
public static implicit operator Value(double value)
{
return new Value(value);
}
public static explicit operator double([In] [IsReadOnly] ref Value value)
{
return value.GetValue<double>();
}
public static implicit operator Value(double? value)
{
return new Value(value);
}
public static explicit operator double?([In] [IsReadOnly] ref Value value)
{
return value.GetValue<double?>();
}
public Value(Size value)
{
_union = default(Union);
_object = TypeFlags.Size;
_union.Size = value;
}
public Value(Size? value)
{
_union = default(Union);
if (value.HasValue) {
_object = TypeFlags.Size;
_union.Size = value.Value;
} else
_object = null;
}
public static implicit operator Value(Size value)
{
return new Value(value);
}
public static explicit operator Size([In] [IsReadOnly] ref Value value)
{
return value.GetValue<Size>();
}
public static implicit operator Value(Size? value)
{
return new Value(value);
}
public static explicit operator Size?([In] [IsReadOnly] ref Value value)
{
return value.GetValue<Size?>();
}
public Value(Point value)
{
_union = default(Union);
_object = TypeFlags.Point;
_union.Point = value;
}
public Value(Point? value)
{
_union = default(Union);
if (value.HasValue) {
_object = TypeFlags.Point;
_union.Point = value.Value;
} else
_object = null;
}
public static implicit operator Value(Point value)
{
return new Value(value);
}
public static explicit operator Point([In] [IsReadOnly] ref Value value)
{
return value.GetValue<Point>();
}
public static implicit operator Value(Point? value)
{
return new Value(value);
}
public static explicit operator Point?([In] [IsReadOnly] ref Value value)
{
return value.GetValue<Point?>();
}
public Value(Color value)
{
_union = default(Union);
if (PackedColor.TryCreate(ref value, out PackedColor packedColor)) {
_object = TypeFlags.PackedColor;
_union.PackedColor = packedColor;
} else
_object = value;
}
public Value(Color? value)
{
_union = default(Union);
if (!value.HasValue)
_object = null;
else
this = new Value(value.Value);
}
public static implicit operator Value(Color value)
{
return new Value(value);
}
public static explicit operator Color([In] [IsReadOnly] ref Value value)
{
return value.GetValue<Color>();
}
public static implicit operator Value(Color? value)
{
return new Value(value);
}
public static explicit operator Color?([In] [IsReadOnly] ref Value value)
{
return value.GetValue<Color?>();
}
public Value(DateTimeOffset value)
{
_union = default(Union);
TimeSpan offset = value.Offset;
PackedDateTimeOffset packed;
if (offset.Ticks == 0) {
_union.Ticks = value.Ticks;
_object = TypeFlags.UtcDateTimeOffset;
} else if (PackedDateTimeOffset.TryCreate(value, offset, out packed)) {
_union.PackedDateTimeOffset = packed;
_object = TypeFlags.PackedDateTimeOffset;
} else {
_object = value;
}
}
public Value(DateTimeOffset? value)
{
_union = default(Union);
if (!value.HasValue)
_object = null;
else
this = new Value(value.Value);
}
public static implicit operator Value(DateTimeOffset value)
{
return new Value(value);
}
public static explicit operator DateTimeOffset([In] [IsReadOnly] ref Value value)
{
return value.GetValue<DateTimeOffset>();
}
public static implicit operator Value(DateTimeOffset? value)
{
return new Value(value);
}
public static explicit operator DateTimeOffset?([In] [IsReadOnly] ref Value value)
{
return value.GetValue<DateTimeOffset?>();
}
public Value(DateTime value)
{
_union = default(Union);
_union.DateTime = value;
_object = TypeFlags.DateTime;
}
public Value(DateTime? value)
{
_union = default(Union);
if (value.HasValue) {
_object = TypeFlags.DateTime;
_union.DateTime = value.Value;
} else
_object = value;
}
public static implicit operator Value(DateTime value)
{
return new Value(value);
}
public static explicit operator DateTime([In] [IsReadOnly] ref Value value)
{
return value.GetValue<DateTime>();
}
public static implicit operator Value(DateTime? value)
{
return new Value(value);
}
public static explicit operator DateTime?([In] [IsReadOnly] ref Value value)
{
return value.GetValue<DateTime?>();
}
[NullableContext(0)]
public Value(ArraySegment<byte> segment)
{
_union = default(Union);
byte[] array = segment.Array;
ArgumentNullException.ThrowIfNull(array, "segment");
_object = array;
if (segment.Offset == 0 && segment.Count == 0)
_union.UInt64 = ulong.MaxValue;
else
_union.Segment = (segment.Offset, segment.Count);
}
public static implicit operator Value(ArraySegment<byte> value)
{
return new Value(value);
}
public static explicit operator ArraySegment<byte>([In] [IsReadOnly] ref Value value)
{
return value.GetValue<ArraySegment<byte>>();
}
[NullableContext(0)]
public Value(ArraySegment<char> segment)
{
_union = default(Union);
char[] array = segment.Array;
ArgumentNullException.ThrowIfNull(array, "segment");
_object = array;
if (segment.Offset == 0 && segment.Count == 0)
_union.UInt64 = ulong.MaxValue;
else
_union.Segment = (segment.Offset, segment.Count);
}
public static implicit operator Value(ArraySegment<char> value)
{
return new Value(value);
}
public static explicit operator ArraySegment<char>([In] [IsReadOnly] ref Value value)
{
return value.GetValue<ArraySegment<char>>();
}
public static implicit operator Value(decimal value)
{
return new Value(value);
}
public static explicit operator decimal([In] [IsReadOnly] ref Value value)
{
return value.GetValue<decimal>();
}
public static implicit operator Value(decimal? value)
{
if (!value.HasValue)
return new Value(value);
return new Value(value.Value);
}
public static explicit operator decimal?([In] [IsReadOnly] ref Value value)
{
return value.GetValue<decimal?>();
}
public static Value Create<[Nullable(2)] T>(T value)
{
if (typeof(T) == typeof(bool))
return new Value(Unsafe.As<T, bool>(ref Unsafe.AsRef(ref value)));
if (typeof(T) == typeof(byte))
return new Value(Unsafe.As<T, byte>(ref Unsafe.AsRef(ref value)));
if (typeof(T) == typeof(sbyte))
return new Value(Unsafe.As<T, sbyte>(ref Unsafe.AsRef(ref value)));
if (typeof(T) == typeof(char))
return new Value(Unsafe.As<T, char>(ref Unsafe.AsRef(ref value)));
if (typeof(T) == typeof(short))
return new Value(Unsafe.As<T, short>(ref Unsafe.AsRef(ref value)));
if (typeof(T) == typeof(int))
return new Value(Unsafe.As<T, int>(ref Unsafe.AsRef(ref value)));
if (typeof(T) == typeof(long))
return new Value(Unsafe.As<T, long>(ref Unsafe.AsRef(ref value)));
if (typeof(T) == typeof(ushort))
return new Value(Unsafe.As<T, ushort>(ref Unsafe.AsRef(ref value)));
if (typeof(T) == typeof(uint))
return new Value(Unsafe.As<T, uint>(ref Unsafe.AsRef(ref value)));
if (typeof(T) == typeof(ulong))
return new Value(Unsafe.As<T, ulong>(ref Unsafe.AsRef(ref value)));
if (typeof(T) == typeof(float))
return new Value(Unsafe.As<T, float>(ref Unsafe.AsRef(ref value)));
if (typeof(T) == typeof(double))
return new Value(Unsafe.As<T, double>(ref Unsafe.AsRef(ref value)));
if (typeof(T) == typeof(DateTime))
return new Value(Unsafe.As<T, DateTime>(ref Unsafe.AsRef(ref value)));
if (typeof(T) == typeof(DateTimeOffset))
return new Value(Unsafe.As<T, DateTimeOffset>(ref Unsafe.AsRef(ref value)));
if (typeof(T) == typeof(Color))
return new Value(Unsafe.As<T, Color>(ref Unsafe.AsRef(ref value)));
if (typeof(T) == typeof(bool?))
return new Value(Unsafe.As<T, bool?>(ref Unsafe.AsRef(ref value)));
if (typeof(T) == typeof(byte?))
return new Value(Unsafe.As<T, byte?>(ref Unsafe.AsRef(ref value)));
if (typeof(T) == typeof(sbyte?))
return new Value(Unsafe.As<T, sbyte?>(ref Unsafe.AsRef(ref value)));
if (typeof(T) == typeof(char?))
return new Value(Unsafe.As<T, char?>(ref Unsafe.AsRef(ref value)));
if (typeof(T) == typeof(short?))
return new Value(Unsafe.As<T, short?>(ref Unsafe.AsRef(ref value)));
if (typeof(T) == typeof(int?))
return new Value(Unsafe.As<T, int?>(ref Unsafe.AsRef(ref value)));
if (typeof(T) == typeof(long?))
return new Value(Unsafe.As<T, long?>(ref Unsafe.AsRef(ref value)));
if (typeof(T) == typeof(ushort?))
return new Value(Unsafe.As<T, ushort?>(ref Unsafe.AsRef(ref value)));
if (typeof(T) == typeof(uint?))
return new Value(Unsafe.As<T, uint?>(ref Unsafe.AsRef(ref value)));
if (typeof(T) == typeof(ulong?))
return new Value(Unsafe.As<T, ulong?>(ref Unsafe.AsRef(ref value)));
if (typeof(T) == typeof(float?))
return new Value(Unsafe.As<T, float?>(ref Unsafe.AsRef(ref value)));
if (typeof(T) == typeof(double?))
return new Value(Unsafe.As<T, double?>(ref Unsafe.AsRef(ref value)));
if (typeof(T) == typeof(DateTime?))
return new Value(Unsafe.As<T, DateTime?>(ref Unsafe.AsRef(ref value)));
if (typeof(T) == typeof(DateTimeOffset?))
return new Value(Unsafe.As<T, DateTimeOffset?>(ref Unsafe.AsRef(ref value)));
if (typeof(T) == typeof(ArraySegment<byte>))
return new Value(Unsafe.As<T, ArraySegment<byte>>(ref Unsafe.AsRef(ref value)));
if (typeof(T) == typeof(ArraySegment<char>))
return new Value(Unsafe.As<T, ArraySegment<char>>(ref Unsafe.AsRef(ref value)));
if (typeof(T).IsEnum)
return new Value(StraightCastFlag<T>.Instance, Unsafe.As<T, ulong>(ref value));
return new Value(value);
}
[SkipLocalsInit]
private Value(object o, ulong u)
{
Unsafe.SkipInit(out _union);
_object = o;
_union.UInt64 = u;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryGetValue<[Nullable(2)] T>(out T value)
{
if (_object != null && ((typeof(T) == typeof(bool) && _object == TypeFlags.Boolean) || (typeof(T) == typeof(byte) && _object == TypeFlags.Byte) || (typeof(T) == typeof(char) && _object == TypeFlags.Char) || (typeof(T) == typeof(double) && _object == TypeFlags.Double) || (typeof(T) == typeof(short) && _object == TypeFlags.Int16) || (typeof(T) == typeof(int) && _object == TypeFlags.Int32) || (typeof(T) == typeof(long) && _object == TypeFlags.Int64) || (typeof(T) == typeof(sbyte) && _object == TypeFlags.SByte) || (typeof(T) == typeof(float) && _object == TypeFlags.Single) || (typeof(T) == typeof(ushort) && _object == TypeFlags.UInt16) || (typeof(T) == typeof(uint) && _object == TypeFlags.UInt32) || (typeof(T) == typeof(ulong) && _object == TypeFlags.UInt64) || (typeof(T) == typeof(Size) && _object == TypeFlags.Size) || (typeof(T) == typeof(Point) && _object == TypeFlags.Point))) {
value = Unsafe.As<Union, T>(ref Unsafe.AsRef(ref _union));
return true;
}
if (typeof(T) == typeof(Color) && _object == TypeFlags.PackedColor) {
Color source = _union.PackedColor.Extract();
value = Unsafe.As<Color, T>(ref Unsafe.AsRef(ref source));
return true;
}
if (typeof(T) == typeof(DateTime) && _object == TypeFlags.DateTime) {
value = Unsafe.As<DateTime, T>(ref Unsafe.AsRef(ref _union.DateTime));
return true;
}
if (typeof(T) == typeof(DateTimeOffset) && _object == TypeFlags.UtcDateTimeOffset) {
DateTimeOffset source2 = new DateTimeOffset(_union.Ticks, TimeSpan.Zero);
value = Unsafe.As<DateTimeOffset, T>(ref Unsafe.AsRef(ref source2));
return true;
}
if (typeof(T) == typeof(DateTimeOffset) && _object == TypeFlags.PackedDateTimeOffset) {
DateTimeOffset source3 = _union.PackedDateTimeOffset.Extract();
value = Unsafe.As<DateTimeOffset, T>(ref Unsafe.AsRef(ref source3));
return true;
}
if (!typeof(T).IsValueType)
return TryGetObjectSlow(out value);
return TryGetValueSlow(out value);
}
private bool TryGetValueSlow<[Nullable(2)] T>(out T value)
{
bool result = false;
if (_object == null) {
value = default(T);
result = ((object)Nullable.GetUnderlyingType(typeof(T)) != null);
} else {
if (typeof(T).IsEnum) {
TypeFlag<T> typeFlag = _object as TypeFlag<T>;
if (typeFlag != null) {
value = typeFlag.To(ref this);
result = true;
goto IL_089f;
}
}
object object = _object;
if (object is T) {
T val = value = (T)object;
result = true;
} else if (typeof(T) == typeof(ArraySegment<byte>)) {
ulong uInt = _union.UInt64;
if (uInt != 0) {
byte[] array = _object as byte[];
if (array != null) {
ArraySegment<byte> source = (uInt != ulong.MaxValue) ? new ArraySegment<byte>(array, _union.Segment.Offset, _union.Segment.Count) : new ArraySegment<byte>(array, 0, 0);
value = Unsafe.As<ArraySegment<byte>, T>(ref source);
result = true;
goto IL_089f;
}
}
value = default(T);
} else if (typeof(T) == typeof(ArraySegment<char>)) {
ulong uInt2 = _union.UInt64;
if (uInt2 != 0) {
char[] array2 = _object as char[];
if (array2 != null) {
ArraySegment<char> source2 = (uInt2 != ulong.MaxValue) ? new ArraySegment<char>(array2, _union.Segment.Offset, _union.Segment.Count) : new ArraySegment<char>(array2, 0, 0);
value = Unsafe.As<ArraySegment<char>, T>(ref source2);
result = true;
goto IL_089f;
}
}
value = default(T);
} else if (typeof(T) == typeof(int?) && _object == TypeFlags.Int32) {
int? source3 = _union.Int32;
value = Unsafe.As<int?, T>(ref Unsafe.AsRef(ref source3));
result = true;
} else if (typeof(T) == typeof(long?) && _object == TypeFlags.Int64) {
long? source4 = _union.Int64;
value = Unsafe.As<long?, T>(ref Unsafe.AsRef(ref source4));
result = true;
} else if (typeof(T) == typeof(bool?) && _object == TypeFlags.Boolean) {
bool? source5 = _union.Boolean;
value = Unsafe.As<bool?, T>(ref Unsafe.AsRef(ref source5));
result = true;
} else if (typeof(T) == typeof(float?) && _object == TypeFlags.Single) {
float? source6 = _union.Single;
value = Unsafe.As<float?, T>(ref Unsafe.AsRef(ref source6));
result = true;
} else if (typeof(T) == typeof(double?) && _object == TypeFlags.Double) {
double? source7 = _union.Double;
value = Unsafe.As<double?, T>(ref Unsafe.AsRef(ref source7));
result = true;
} else if (typeof(T) == typeof(uint?) && _object == TypeFlags.UInt32) {
uint? source8 = _union.UInt32;
value = Unsafe.As<uint?, T>(ref Unsafe.AsRef(ref source8));
result = true;
} else if (typeof(T) == typeof(ulong?) && _object == TypeFlags.UInt64) {
ulong? source9 = _union.UInt64;
value = Unsafe.As<ulong?, T>(ref Unsafe.AsRef(ref source9));
result = true;
} else if (typeof(T) == typeof(char?) && _object == TypeFlags.Char) {
char? source10 = _union.Char;
value = Unsafe.As<char?, T>(ref Unsafe.AsRef(ref source10));
result = true;
} else if (typeof(T) == typeof(short?) && _object == TypeFlags.Int16) {
short? source11 = _union.Int16;
value = Unsafe.As<short?, T>(ref Unsafe.AsRef(ref source11));
result = true;
} else if (typeof(T) == typeof(ushort?) && _object == TypeFlags.UInt16) {
ushort? source12 = _union.UInt16;
value = Unsafe.As<ushort?, T>(ref Unsafe.AsRef(ref source12));
result = true;
} else if (typeof(T) == typeof(byte?) && _object == TypeFlags.Byte) {
byte? source13 = _union.Byte;
value = Unsafe.As<byte?, T>(ref Unsafe.AsRef(ref source13));
result = true;
} else if (typeof(T) == typeof(sbyte?) && _object == TypeFlags.SByte) {
sbyte? source14 = _union.SByte;
value = Unsafe.As<sbyte?, T>(ref Unsafe.AsRef(ref source14));
result = true;
} else if (typeof(T) == typeof(Color?) && _object == TypeFlags.PackedColor) {
Color? source15 = _union.PackedColor.Extract();
value = Unsafe.As<Color?, T>(ref Unsafe.AsRef(ref source15));
result = true;
} else if (typeof(T) == typeof(DateTime?) && _object == TypeFlags.DateTime) {
DateTime? source16 = _union.DateTime;
value = Unsafe.As<DateTime?, T>(ref Unsafe.AsRef(ref source16));
result = true;
} else if (typeof(T) == typeof(DateTimeOffset?) && _object == TypeFlags.UtcDateTimeOffset) {
DateTimeOffset? source17 = new DateTimeOffset(_union.Ticks, TimeSpan.Zero);
value = Unsafe.As<DateTimeOffset?, T>(ref Unsafe.AsRef(ref source17));
result = true;
} else if (typeof(T) == typeof(DateTimeOffset?) && _object == TypeFlags.PackedDateTimeOffset) {
DateTimeOffset? source18 = _union.PackedDateTimeOffset.Extract();
value = Unsafe.As<DateTimeOffset?, T>(ref Unsafe.AsRef(ref source18));
result = true;
} else {
Type underlyingType = Nullable.GetUnderlyingType(typeof(T));
if ((object)underlyingType != null && underlyingType.IsEnum) {
TypeFlag typeFlag2 = _object as TypeFlag;
if (typeFlag2 != null && typeFlag2.Type == underlyingType) {
switch (Unsafe.SizeOf<T>()) {
case 2: {
NullableTemplate<byte> source22 = new NullableTemplate<byte>(_union.Byte);
value = Unsafe.As<NullableTemplate<byte>, T>(ref Unsafe.AsRef(ref source22));
result = true;
break;
}
case 4: {
NullableTemplate<ushort> source21 = new NullableTemplate<ushort>(_union.UInt16);
value = Unsafe.As<NullableTemplate<ushort>, T>(ref Unsafe.AsRef(ref source21));
result = true;
break;
}
case 8: {
NullableTemplate<uint> source20 = new NullableTemplate<uint>(_union.UInt32);
value = Unsafe.As<NullableTemplate<uint>, T>(ref Unsafe.AsRef(ref source20));
result = true;
break;
}
case 16: {
NullableTemplate<ulong> source19 = new NullableTemplate<ulong>(_union.UInt64);
value = Unsafe.As<NullableTemplate<ulong>, T>(ref Unsafe.AsRef(ref source19));
result = true;
break;
}
default:
ThrowInvalidOperation();
value = default(T);
result = false;
break;
}
goto IL_089f;
}
}
value = default(T);
result = false;
}
}
goto IL_089f;
IL_089f:
return result;
}
private bool TryGetObjectSlow<[Nullable(2)] T>(out T value)
{
bool result = false;
if (_object == null)
value = default(T);
else if (typeof(T) == typeof(char[])) {
if (_union.UInt64 == 0 && _object is char[]) {
value = (T)_object;
result = true;
} else {
value = default(T);
result = false;
}
} else if (typeof(T) == typeof(byte[])) {
if (_union.UInt64 == 0 && _object is byte[]) {
value = (T)_object;
result = true;
} else {
value = default(T);
result = false;
}
} else if (typeof(T) == typeof(object)) {
TypeFlag typeFlag = _object as TypeFlag;
if (typeFlag != null) {
value = (T)typeFlag.ToObject(ref this);
result = true;
} else {
if (_union.UInt64 != 0) {
char[] array = _object as char[];
if (array != null) {
value = ((_union.UInt64 != ulong.MaxValue) ? ((T)(object)new ArraySegment<char>(array, _union.Segment.Offset, _union.Segment.Count)) : ((T)(object)new ArraySegment<char>(array, 0, 0)));
result = true;
goto IL_024b;
}
}
if (_union.UInt64 != 0) {
byte[] array2 = _object as byte[];
if (array2 != null) {
value = ((_union.UInt64 != ulong.MaxValue) ? ((T)(object)new ArraySegment<byte>(array2, _union.Segment.Offset, _union.Segment.Count)) : ((T)(object)new ArraySegment<byte>(array2, 0, 0)));
result = true;
goto IL_024b;
}
}
value = (T)_object;
result = true;
}
} else {
object object = _object;
if (object is T) {
T val = value = (T)object;
result = true;
} else {
value = default(T);
result = false;
}
}
goto IL_024b;
IL_024b:
return result;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public T GetValue<[Nullable(2)] T>()
{
if (!TryGetValue(out T value))
ThrowInvalidCast(Type, typeof(T));
return value;
}
}
}