diff --git a/BeefLibs/corlib/src/Attribute.bf b/BeefLibs/corlib/src/Attribute.bf index 795eda52..af9f24aa 100644 --- a/BeefLibs/corlib/src/Attribute.bf +++ b/BeefLibs/corlib/src/Attribute.bf @@ -522,7 +522,7 @@ namespace System } - [AttributeUsage(.Method | .Constructor | .Class | .Struct | .Alias | .Property)] + [AttributeUsage(.Method | .Constructor | .Class | .Struct | .Alias | .Property | .Field)] public struct ErrorAttribute : Attribute { public this(String error) @@ -531,7 +531,7 @@ namespace System } } - [AttributeUsage(.Method | .Constructor | .Class | .Struct | .Alias | .Property)] + [AttributeUsage(.Method | .Constructor | .Class | .Struct | .Alias | .Property | .Field)] public struct WarnAttribute : Attribute { public this(String error) diff --git a/BeefLibs/corlib/src/Interop.bf b/BeefLibs/corlib/src/Interop.bf index 82039890..aa7d782c 100644 --- a/BeefLibs/corlib/src/Interop.bf +++ b/BeefLibs/corlib/src/Interop.bf @@ -1,3 +1,5 @@ +using System.Reflection; + namespace System { namespace Interop @@ -29,5 +31,54 @@ namespace System typealias c_ulong = uint64; #endif + + class FlexibleArary where T : struct, new + { + typealias ElementType = comptype(GetElementType()); + + int32 mCount; + T* mVal; + + static Type GetElementType() + { + var t = typeof(T); + if (t.IsGenericParam) + return typeof(void); + var field = t.GetField(t.FieldCount - 1).GetValueOrDefault(); + if ((field.FieldType == null) || (!field.FieldType.IsSizedArray) || (field.FieldType.Size != 0)) + Runtime.FatalError("Type must end in a zero-sized array"); + return (field.FieldType as SizedArrayType).UnderlyingType; + } + + public ref ElementType this[int index] + { + [Checked] + get + { + Runtime.Assert((uint)index < (uint)mCount); + return ref ((ElementType*)((uint8*)mVal + Math.Align(typeof(T).Size, typeof(ElementType).Align)))[index]; + } + + [Unchecked] + get + { + return ref ((ElementType*)((uint8*)mVal + Math.Align(typeof(T).Size, typeof(ElementType).Align)))[index]; + } + } + + public static ref T operator ->(Self self) => ref *self.mVal; + public ref T Value => ref *mVal; + public T* Ptr => mVal; + + [AllowAppend] + public this(int count) + { + var val = append T(); + var data = append ElementType[count]*; + mVal = val; + (void)data; + mCount = (.)count; + } + } } }