Last active
December 3, 2021 20:50
-
-
Save juliusfriedman/6f2cb28056c4b97ecffe59a435f068c7 to your computer and use it in GitHub Desktop.
Type System
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Of 8 bytes. | |
/// A structure which represents an: | |
/// <see cref="System.Object"/>, <see cref="System.Array"/> or <see cref="System.String"/>. | |
/// </summary> | |
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Explicit, Size = 8)] | |
public struct Invariant | |
{ | |
[System.Runtime.InteropServices.FieldOffset(0)] | |
public System.Array Array; | |
[System.Runtime.InteropServices.FieldOffset(0)] | |
public object Object; | |
[System.Runtime.InteropServices.FieldOffset(0)] | |
public string String; | |
/// <summary> | |
/// Used to interpret the address/memory of object which can be thought of as IntPtr* | |
/// Remember to deference the type 1 time to inspect the memory where ref object points to. | |
/// </summary> | |
/// <typeparam name="TType"></typeparam> | |
/// <param name="index"></param> | |
/// <param name="length"></param> | |
/// <returns></returns> | |
public System.Span<TType> GetSpan<TType>(int index, int length) => System.Runtime.InteropServices.MemoryMarshal.CreateSpan(ref System.Runtime.CompilerServices.Unsafe.Add(ref System.Runtime.CompilerServices.Unsafe.As<object, TType>(ref Object), index), length); | |
/// <summary> | |
/// Get a <see cref="System.IntPtr"/> which points to the address of <see cref="Object"/> | |
/// </summary> | |
/// <returns></returns> | |
public System.IntPtr ToPointer() => GetSpan<System.IntPtr>(0, 1)[0] + System.IntPtr.Size + System.IntPtr.Size; //Syncbloc, Rtti | |
/// <summary> | |
/// Allowing one to set the <see cref="System.Type"/> of <see cref="Object"/> | |
/// </summary> | |
public System.Type Type | |
{ | |
set | |
{ | |
System.Runtime.InteropServices.Marshal.WriteIntPtr(GetSpan<System.IntPtr>(0, 1)[0], value.TypeHandle.Value); | |
//System.Runtime.CompilerServices.Unsafe.AsRef(GetSpan<System.IntPtr>(0, 1)[0]) = value.TypeHandle.Value; | |
} | |
} | |
//Requires unsafe | |
//[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] | |
//public unsafe static System.IntPtr AddressOf<T>(ref T t) | |
//{ | |
// System.TypedReference reference = __makeref(t); | |
// return **(System.IntPtr**)(&reference); | |
//} | |
} | |
/// <summary> | |
/// A single value | |
/// Will implicitly convert to <see cref="Invariant"/> | |
/// </summary> | |
/// <typeparam name="T"></typeparam> | |
public ref struct Invariant<T> | |
{ | |
/// <summary> | |
/// The value | |
/// </summary> | |
public T Value; | |
/// <summary> | |
/// Implicit create <see cref="Invariant"/> | |
/// </summary> | |
/// <param name="src"></param> | |
public static implicit operator Invariant(Invariant<T> src) => new Invariant() { Object = src.Value }; | |
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] | |
public static T Alloc(Invariant invariant) => Alloc(invariant.ToPointer()); | |
/// <summary> | |
/// Allocate the value initializing the Object header and TypeHandle. | |
/// </summary> | |
/// <param name="bufferPtr"></param> | |
/// <returns></returns> | |
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] | |
public static T Alloc(System.IntPtr bufferPtr) | |
{ | |
var dataPointer = bufferPtr + 1; | |
//New way | |
//System.Runtime.CompilerServices.Unsafe.AsRef(bufferPtr) = System.IntPtr.Zero; | |
//System.Runtime.CompilerServices.Unsafe.AsRef(dataPointer) = typeof(T).TypeHandle.Value; | |
//Old way | |
System.Runtime.InteropServices.Marshal.WriteIntPtr(bufferPtr, System.IntPtr.Zero); //Object Header | |
System.Runtime.InteropServices.Marshal.WriteIntPtr(dataPointer, typeof(T).TypeHandle.Value); | |
return System.Runtime.CompilerServices.Unsafe.As<System.IntPtr, T>(ref dataPointer); //Pointer to the method table pointer | |
} | |
//[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] | |
//public unsafe static T Alloc(System.Span<byte> bytes) => Alloc((System.IntPtr)System.Runtime.CompilerServices.Unsafe.AsPointer(ref bytes.GetPinnableReference())); | |
//Could be exposed from a static Construct<T>(ref T) method but which constructor to invoke? | |
//private static unsafe class Constructor | |
//{ | |
// private static readonly delegate*<T, void> ConstructorHandle; | |
// static Constructor() | |
// { | |
// System.Type type = typeof(T); | |
// System.Reflection.ConstructorInfo constructorInfo = type.GetConstructor(System.Array.Empty<System.Type>()); | |
// Constructor.ConstructorHandle = (delegate*<T, void>)constructorInfo.MethodHandle.GetFunctionPointer(); | |
// } | |
// [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] | |
// internal static void Invoke(T returnObject) | |
// { | |
// Constructor.ConstructorHandle(returnObject); | |
// } | |
//} | |
/// <summary> | |
/// Creates a <see cref="System.Span{T}"/> | |
/// </summary> | |
/// <returns></returns> | |
public System.Span<T> GetSpan() => System.Runtime.InteropServices.MemoryMarshal.CreateSpan(ref Value, 1); | |
/// <summary> | |
/// Create a <see cref="System.Span{TType}"/> | |
/// </summary> | |
/// <typeparam name="TType"></typeparam> | |
/// <param name="index"></param> | |
/// <param name="length"></param> | |
/// <returns></returns> | |
public System.Span<TType> GetSpan<TType>(int index, int length) => System.Runtime.InteropServices.MemoryMarshal.CreateSpan(ref System.Runtime.CompilerServices.Unsafe.Add(ref System.Runtime.CompilerServices.Unsafe.As<T, TType>(ref Value), index), length); | |
} | |
/// <summary> | |
/// A wrapper around an "invariant" <typeparamref name="T"/> array; that is, without any covariance or contravariance. | |
/// Will implicitly convert to <see cref="Invariant"/> | |
/// </summary> | |
/// <typeparam name="T"></typeparam> | |
public ref struct InvariantArray<T> | |
{ | |
public T[] Array; | |
public static implicit operator Invariant(InvariantArray<T> src) => new Invariant() { Array = src.Array }; | |
/// <summary> | |
/// Gets a reference to the element at <paramref name="index"/> | |
/// </summary> | |
/// <param name="index"></param> | |
/// <returns></returns> | |
public ref T this[int index]=> ref Array[index]; | |
/// <summary> | |
/// Create a <see cref="System.Span{T}"/> from <see cref="Array"/> | |
/// </summary> | |
/// <param name="index"></param> | |
/// <param name="length"></param> | |
/// <returns></returns> | |
public System.Span<T> GetSpan(int index, int length) => System.Runtime.InteropServices.MemoryMarshal.CreateSpan(ref this[index], length); | |
/// <summary> | |
/// Create a <see cref="System.Span{TType}"/> from <see cref="Array"/> | |
/// </summary> | |
/// <typeparam name="TType"></typeparam> | |
/// <param name="index"></param> | |
/// <param name="length"></param> | |
/// <returns></returns> | |
public System.Span<TType> GetSpan<TType>(int index, int length) => System.Runtime.InteropServices.MemoryMarshal.CreateSpan(ref System.Runtime.CompilerServices.Unsafe.As<T, TType>(ref this[index]), length); | |
} | |
/// <summary> | |
/// Allows one to make a generic type which forwards to that type. | |
/// Allows for <see cref="Type{System.Type}"/> | |
/// </summary> | |
/// <typeparam name="T"></typeparam> | |
public class Type<T> : System.Type | |
{ | |
public Type() | |
{ | |
SystemType = typeof(T); | |
} | |
readonly System.Type SystemType; | |
public override System.Reflection.Assembly Assembly => SystemType.Assembly; | |
public override string AssemblyQualifiedName => SystemType.AssemblyQualifiedName; | |
public override System.Type BaseType => SystemType.BaseType; | |
public override string FullName => SystemType.FullName; | |
public override System.Guid GUID => SystemType.GUID; | |
public override System.Reflection.Module Module => SystemType.Module; | |
public override string Namespace => SystemType.Namespace; | |
public override System.Type UnderlyingSystemType => SystemType.UnderlyingSystemType; | |
public override string Name => SystemType.Name; | |
public override System.Reflection.ConstructorInfo[] GetConstructors(System.Reflection.BindingFlags bindingAttr) | |
{ | |
return SystemType.GetConstructors(bindingAttr); | |
} | |
public override object[] GetCustomAttributes(bool inherit) | |
{ | |
return SystemType.GetCustomAttributes(inherit); | |
} | |
public override object[] GetCustomAttributes(System.Type attributeType, bool inherit) | |
{ | |
return SystemType.GetCustomAttributes(attributeType, inherit); | |
} | |
public override System.Type GetElementType() | |
{ | |
return SystemType.GetElementType(); | |
} | |
public override System.Reflection.EventInfo GetEvent(string name, System.Reflection.BindingFlags bindingAttr) | |
{ | |
return SystemType.GetEvent(name, bindingAttr); | |
} | |
public override System.Reflection.EventInfo[] GetEvents(System.Reflection.BindingFlags bindingAttr) | |
{ | |
return SystemType.GetEvents(bindingAttr); | |
} | |
public override System.Reflection.FieldInfo GetField(string name, System.Reflection.BindingFlags bindingAttr) | |
{ | |
return SystemType.GetField(name, bindingAttr); | |
} | |
public override System.Reflection.FieldInfo[] GetFields(System.Reflection.BindingFlags bindingAttr) | |
{ | |
return SystemType.GetFields(bindingAttr); | |
} | |
public override System.Type GetInterface(string name, bool ignoreCase) | |
{ | |
return SystemType.GetInterface(name, ignoreCase); | |
} | |
public override System.Type[] GetInterfaces() | |
{ | |
return SystemType.GetInterfaces(); | |
} | |
public override System.Reflection.MemberInfo[] GetMembers(System.Reflection.BindingFlags bindingAttr) | |
{ | |
return SystemType.GetMembers(bindingAttr); | |
} | |
public override System.Reflection.MethodInfo[] GetMethods(System.Reflection.BindingFlags bindingAttr) | |
{ | |
return SystemType.GetMethods(bindingAttr); | |
} | |
public override System.Type GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) | |
{ | |
return SystemType.GetNestedType(name, bindingAttr); | |
} | |
public override System.Type[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) | |
{ | |
return SystemType.GetNestedTypes(bindingAttr); | |
} | |
public override System.Reflection.PropertyInfo[] GetProperties(System.Reflection.BindingFlags bindingAttr) | |
{ | |
return SystemType.GetProperties(bindingAttr); | |
} | |
public override object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] args, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters) | |
{ | |
return SystemType.InvokeMember(name, invokeAttr, binder, target, args, modifiers, culture, namedParameters); | |
} | |
public override bool IsDefined(System.Type attributeType, bool inherit) | |
{ | |
return SystemType.IsDefined(attributeType, inherit); | |
} | |
protected override System.Reflection.TypeAttributes GetAttributeFlagsImpl() | |
{ | |
return SystemType.Attributes; | |
} | |
protected override System.Reflection.ConstructorInfo GetConstructorImpl(System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, System.Type[] types, System.Reflection.ParameterModifier[] modifiers) | |
{ | |
return SystemType.GetConstructor(bindingAttr, binder, callConvention, types, modifiers); | |
} | |
protected override System.Reflection.MethodInfo GetMethodImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, System.Type[] types, System.Reflection.ParameterModifier[] modifiers) | |
{ | |
return SystemType.GetMethod(name, bindingAttr, binder, callConvention, types, modifiers); | |
} | |
protected override System.Reflection.PropertyInfo GetPropertyImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Type returnType, System.Type[] types, System.Reflection.ParameterModifier[] modifiers) | |
{ | |
return SystemType.GetProperty(name, bindingAttr, binder, returnType, types, modifiers); | |
} | |
protected override bool HasElementTypeImpl() | |
{ | |
return SystemType.HasElementType; | |
} | |
protected override bool IsArrayImpl() | |
{ | |
return SystemType.IsArray; | |
} | |
protected override bool IsByRefImpl() | |
{ | |
return SystemType.IsByRef; | |
} | |
protected override bool IsCOMObjectImpl() | |
{ | |
return SystemType.IsCOMObject; | |
} | |
protected override bool IsPointerImpl() | |
{ | |
return SystemType.IsPointer; | |
} | |
protected override bool IsPrimitiveImpl() | |
{ | |
return SystemType.IsPrimitive; | |
} | |
} | |
/// <summary> | |
/// Reresents a value from <see cref="Type{T}"/> | |
/// </summary> | |
/// <typeparam name="T"></typeparam> | |
public class ValueType<T> : Type<T> | |
{ | |
public T Value; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
///
/// Reveals the object header size
///
public static Invariant Null = new Invariant();