1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-16 15:24:10 +02:00
Beef/IDE/mintest/minlib/src/System/Object.bf

607 lines
11 KiB
Beef

using System;
using System.Reflection;
using System.Collections.Generic;
using System.Diagnostics;
namespace System
{
interface IDisposable
{
void Dispose() mut;
}
interface IPrintable
{
void Print(String outString);
}
#if BF_LARGE_COLLECTIONS
typealias int_cosize = int64;
#else
typealias int_cosize = int32;
#endif
[AlwaysInclude]
static class CompilerSettings
{
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
public const bool cHasDebugFlags = true;
#else
public const bool cHasDebugFlags = false;
#endif
public const bool cHasVDataExtender = true;
public const int32 cVDataIntefaceSlotCount = 16;
}
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
[AlwaysInclude]
#endif
struct CallStackAddr : int
{
}
class Object : IHashable
{
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
int mClassVData;
int mDbgAllocInfo;
#else
ClassVData* mClassVData;
#endif
public virtual ~this()
{
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
mClassVData = ((mClassVData & ~0x08) | 0x80);
#endif
}
int IHashable.GetHashCode()
{
return (int)(void*)this;
}
public Type GetType()
{
Type type;
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
ClassVData* maskedVData = (ClassVData*)(void*)(mClassVData & ~(int)0xFF);
type = maskedVData.mType;
#else
type = mClassVData.mType;
#endif
if ((type.[Friend]mTypeFlags & TypeFlags.Boxed) != 0)
{
//int32 underlyingType = (int32)((TypeInstance)type).mUnderlyingType;
type = Type.[Friend]GetType(((TypeInstance)type).[Friend]mUnderlyingType);
}
return type;
}
[NoShow]
Type RawGetType()
{
Type type;
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
ClassVData* maskedVData = (ClassVData*)(void*)(mClassVData & ~(int)0xFF);
type = maskedVData.mType;
#else
type = mClassVData.mType;
#endif
return type;
}
#if BF_ALLOW_HOT_SWAPPING
[NoShow]
public virtual Object DynamicCastToTypeId(int32 typeId)
{
if (typeId == (int32)RawGetType().[Friend]mTypeId)
return this;
return null;
}
[NoShow]
public virtual Object DynamicCastToInterface(int32 typeId)
{
return null;
}
#endif
public virtual void ToString(String strBuffer)
{
//strBuffer.Set(stack string(GetType().mName));
RawGetType().GetName(strBuffer);
}
/*public virtual int GetHashCode()
{
return (int)(intptr)(void*)this;
}*/
[NoShow, SkipCall]
protected virtual void GCMarkMembers()
{
//PrintF("Object.GCMarkMembers %08X\n", this);
}
static void ToString(Object obj, String strBuffer)
{
if (obj == null)
strBuffer.Append("null");
else
obj.ToString(strBuffer);
}
}
interface IResult<T>
{
T GetBaseResult();
}
struct ValueType
{
public static extern bool Equals<T>(T val1, T val2);
}
struct Function : int
{
}
[AlwaysInclude]
struct Pointer : IHashable
{
void* mVal;
public int GetHashCode()
{
return (int)mVal;
}
[AlwaysInclude]
Object GetBoxed()
{
return new box this;
}
}
struct Pointer<T> : IHashable
{
T* mVal;
public int GetHashCode()
{
return (int)(void*)mVal;
}
}
struct MethodReference<T>
{
T mVal;
}
struct SizedArray<T, CSize> where CSize : const int
{
T[CSize] mVal;
public int Count
{
[Inline]
get
{
return CSize;
}
}
public explicit static operator T[CSize] (Self val)
{
return val.mVal;
}
public override void ToString(String strBuffer) mut
{
if (typeof(T) == typeof(char8))
{
strBuffer.Append((char8*)&mVal, CSize);
return;
}
strBuffer.Append('(');
for (int i < CSize)
{
if (i != 0)
strBuffer.Append(", ");
mVal[i].ToString(strBuffer);
}
strBuffer.Append(')');
}
}
struct Void : void
{
}
struct Boolean : bool
{
}
struct Char8 : char8
{
public bool IsWhiteSpace
{
get
{
switch (this)
{
case ' ', '\t', '\n', '\r', '\xa0', '\x85': return true;
default: return false;
}
}
}
}
struct Char16 : char16
{
}
struct Char32 : char32
{
public extern bool IsLower
{
get;
}
}
struct Int8 : int8
{
}
struct UInt8 : uint8
{
}
struct Int16 : int16, IOpComparable, IIsNaN
{
public static int operator<=>(Int16 a, Int16 b)
{
return (int16)a <=> (int16)b;
}
bool IIsNaN.IsNaN
{
[SkipCall]
get
{
return false;
}
}
}
struct UInt16 : uint16
{
}
struct UInt32 : uint32, IHashable, IOpComparable, IIsNaN, IOpNegatable
{
public const int32 MaxValue = 0x7FFFFFFF;
public const int32 MinValue = -0x80000000;
public static int operator<=>(UInt32 a, UInt32 b)
{
return (uint32)a <=> (uint32)b;
}
public static UInt32 operator-(UInt32 value)
{
if (value != 0)
Runtime.FatalError("Cannot negate positive unsigned integer");
return 0;
}
public this()
{
}
bool IIsNaN.IsNaN
{
[SkipCall]
get
{
return false;
}
}
public int GetHashCode()
{
return (.)this;
}
}
struct Int64 : int64
{
public const int64 MaxValue = 0x7FFFFFFFFFFFFFFFL;
//public const long MinValue = -0x8000000000000000L;
public const int64 MinValue = -0x7FFFFFFFFFFFFFFFL; //TODO: Should be one lower!
public override void ToString(String strBuffer)
{
// Dumb, make better.
char8[] strChars = scope:: char8[16];
int32 charIdx = 14;
int64 valLeft = (int64)this;
while (valLeft > 0)
{
strChars[charIdx] = (char8)('0' + (valLeft % 10));
valLeft /= 10;
charIdx--;
}
if (charIdx == 14)
strChars[charIdx--] = '0';
char8* charPtr = &strChars[charIdx + 1];
strBuffer.Append(scope:: String(charPtr));
}
}
struct UInt64 : uint64
{
}
struct Float : float
{
public bool IsNegative
{
get
{
return this < 0;
}
}
[StdCall, CLink]
static extern int32 ftoa(float val, char8* str);
static extern int32 ToString(float val, char8* str);
public override void ToString(String strBuffer)
{
char8[128] outBuff = ?;
//ftoa((float)this, &outBuff);
int len = ToString((float)this, &outBuff);
strBuffer.Append(&outBuff, len);
}
}
struct Int : int, IOpComparable, IOpAddable, IOpDividable, IIsNaN
{
public static int operator<=>(Int a, Int b)
{
return (int)a <=> (int)b;
}
public static Int operator+(Int a, Int b)
{
return (int)a + (int)b;
}
public static Self operator/(Self a, Self b)
{
return (int)a / (int)b;
}
bool IIsNaN.IsNaN
{
[SkipCall]
get
{
return false;
}
}
}
struct UInt : uint, IOpComparable, IIsNaN
{
public static int operator<=>(UInt a, UInt b)
{
return (uint)a <=> (uint)b;
}
bool IIsNaN.IsNaN
{
[SkipCall]
get
{
return false;
}
}
}
struct Int32 : int32, IHashable, IOpComparable, IIsNaN
{
public const int32 MaxValue = 0x7FFFFFFF;
public const int32 MinValue = -0x80000000;
public static int operator<=>(Int32 a, Int32 b)
{
return (int32)a <=> (int32)b;
}
public this()
{
this = (Int32)345;
}
bool IIsNaN.IsNaN
{
[SkipCall]
get
{
return false;
}
}
public int GetHashCode()
{
return (int32)this;
}
public int32 GetBaseResult()
{
return (int32)this + 4;
}
public override void ToString(String strBuffer)
{
// Dumb, make better.
char8[] strChars = scope:: char8[16];
int32 charIdx = 14;
int32 valLeft = (int32)this;
while (valLeft > 0)
{
strChars[charIdx] = (char8)('0' + (valLeft % 10));
valLeft /= 10;
charIdx--;
}
if (charIdx == 14)
strChars[charIdx--] = '0';
char8* charPtr = &strChars[charIdx + 1];
strBuffer.Append(scope:: String(charPtr));
}
}
struct Enum
{
public static Result<T> Parse<T>(String str) where T : Enum
{
var typeInst = (TypeInstance)typeof(T);
for (var field in typeInst.GetFields())
{
if (str == field.[Friend]mFieldData.mName)
return .Ok(*((T*)(&field.[Friend]mFieldData.mConstValue)));
}
return .Err;
}
}
class Delegate
{
void* mFuncPtr;
void* mTarget;
public static bool Equals(Delegate a, Delegate b)
{
if ((Object)a == (Object)b)
return true;
if ((Object)a == null || (Object)b == null)
return false;
return (a.mFuncPtr == b.mFuncPtr) && (a.mTarget == b.mTarget);
}
public Result<void*> GetFuncPtr()
{
if (mTarget != null)
return .Err;//("Delegate target method must be static");
return mFuncPtr;
}
public void SetFuncPtr(void* ptr, void* target = null)
{
mTarget = target;
mFuncPtr = ptr;
}
protected override void GCMarkMembers()
{
GC.Mark(Internal.UnsafeCastToObject(mTarget));
}
}
struct DeferredCall
{
public int64 mMethodId;
public DeferredCall* mNext;
public void Cancel() mut
{
mMethodId = 0;
}
}
delegate void Action();
delegate void Action<T1>(T1 p1);
delegate void Action<T1, T2>(T1 p1, T2 p2);
delegate TResult Func<TResult>();
delegate TResult Func<T1, TResult>(T1 p1);
delegate TResult Func<T1, T2, TResult>(T1 p1, T2 p2);
delegate int32 Comparison<T>(T a, T b);
}
static
{
public static mixin NOP()
{
}
public static mixin ToStackString(var obj)
{
var str = scope:: String();
obj.ToString(str);
str
}
public static mixin Try(var result)
{
if (result case .Err(var err))
return .Err((.)err);
result.Get()
}
public static mixin DeleteContainerAndItems(var container)
{
if (container != null)
{
for (var value in container)
delete value;
delete container;
}
}
public static mixin DeleteContainerItems(var container)
{
if (container != null)
{
for (var value in container)
delete value;
}
}
public static mixin DeleteAndNullify(var val)
{
delete val;
val = null;
}
[NoReturn]
public static void ThrowUnimplemented()
{
Debug.FatalError();
}
public static mixin ScopedAlloc(int size, int align)
{
void* data;
if (size <= 128)
{
data = scope:mixin uint8[size]* { ? };
}
else
{
data = new uint8[size]* { ? };
defer:mixin delete data;
}
data
}
}