1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-07-03 14:56:01 +02:00
Beef/BeefLibs/corlib/src/Enum.bf

253 lines
4.8 KiB
Beef
Raw Normal View History

2019-08-23 11:56:54 -07:00
using System.Reflection;
2021-12-27 14:34:55 -05:00
using System.Collections;
2019-08-23 11:56:54 -07:00
namespace System
{
struct Enum
{
2022-06-24 06:45:35 -07:00
[NoShow(true)]
[Comptime(ConstEval=true)]
2022-06-24 06:45:35 -07:00
public static int GetCount<T>() where T : Enum
{
int count = 0;
2022-06-24 06:45:35 -07:00
for (var field in typeof(T).GetFields())
{
if (field.IsEnumCase)
count++;
}
return count;
}
2022-06-24 06:45:35 -07:00
[NoShow(true)]
[Comptime(ConstEval=true)]
2022-06-24 06:45:35 -07:00
public static var GetMinValue<T>() where T : Enum
{
2022-06-24 06:45:35 -07:00
Compiler.SetReturnType(typeof(T));
int? minValue = null;
2022-06-24 06:45:35 -07:00
for (var field in typeof(T).GetFields())
{
if (field.IsEnumCase)
{
if (minValue == null)
minValue = field.[Friend]mFieldData.mData;
else
minValue = Math.Min(minValue.Value, field.[Friend]mFieldData.mData);
}
}
return minValue.ValueOrDefault;
}
2022-06-24 06:45:35 -07:00
[NoShow(true)]
[Comptime(ConstEval=true)]
2022-06-24 06:45:35 -07:00
public static var GetMaxValue<T>() where T : Enum
{
2022-06-24 06:45:35 -07:00
Compiler.SetReturnType(typeof(T));
int? maxValue = null;
2022-06-24 06:45:35 -07:00
for (var field in typeof(T).GetFields())
{
if (field.IsEnumCase)
{
if (maxValue == null)
maxValue = field.[Friend]mFieldData.mData;
else
maxValue = Math.Max(maxValue.Value, field.[Friend]mFieldData.mData);
}
}
if (maxValue == null)
return -1;
return maxValue.ValueOrDefault;
}
2022-06-24 06:45:35 -07:00
[NoShow(true)]
2019-08-23 11:56:54 -07:00
public static void EnumToString(Type type, String strBuffer, int64 iVal)
{
for (var field in type.GetFields())
{
2021-12-29 12:44:04 -03:00
if (field.[Friend]mFieldData.mFlags.HasFlag(.EnumCase) &&
*(int64*)&field.[Friend]mFieldData.[Friend]mData == iVal)
2019-08-23 11:56:54 -07:00
{
strBuffer.Append(field.Name);
return;
}
}
iVal.ToString(strBuffer);
2019-08-23 11:56:54 -07:00
}
2022-06-24 06:45:35 -07:00
[NoShow(true)]
public static Result<T> Parse<T>(StringView str, bool ignoreCase = false) where T : enum
2019-08-23 11:56:54 -07:00
{
2021-12-29 12:44:04 -03:00
for (var (name, data) in GetEnumerator<T>())
2019-08-23 11:56:54 -07:00
{
2021-12-29 12:44:04 -03:00
if (str.Equals(name, ignoreCase))
return .Ok(data);
2022-02-14 13:41:27 -03:00
if (int64.Parse(str) case .Ok(let val) && val == (.)data)
return .Ok(data);
2019-08-23 11:56:54 -07:00
}
return .Err;
}
2022-06-24 06:45:35 -07:00
[NoShow(true)]
public static bool IsDefined<T>(T value) where T : Enum
where T : enum
2019-08-23 11:56:54 -07:00
{
2021-12-29 12:44:04 -03:00
for (var data in GetValues<T>())
{
2021-12-29 12:44:04 -03:00
if (data == (.)value)
return true;
}
return false;
}
2022-06-24 06:45:35 -07:00
[NoShow(true)]
2021-12-27 14:34:55 -05:00
public static EnumEnumerator<TEnum> GetEnumerator<TEnum>()
where TEnum : enum
{
return .();
}
2022-06-24 06:45:35 -07:00
[NoShow(true)]
2021-12-27 14:34:55 -05:00
public static EnumValuesEnumerator<TEnum> GetValues<TEnum>()
where TEnum : enum
{
return .();
}
2022-06-24 06:45:35 -07:00
[NoShow(true)]
2021-12-27 14:34:55 -05:00
public static EnumNamesEnumerator<TEnum> GetNames<TEnum>()
where TEnum : enum
{
return .();
}
2022-06-24 06:45:35 -07:00
[NoShow(true)]
2021-12-27 16:06:05 -03:00
private struct EnumFieldsEnumerator<TEnum>
where TEnum : enum
{
2021-12-27 16:06:05 -03:00
TypeInstance mTypeInstance;
int32 mIdx;
public this()
{
2021-12-27 16:06:05 -03:00
mTypeInstance = typeof(TEnum) as TypeInstance;
mIdx = -1;
}
2021-12-27 16:06:05 -03:00
public void Reset() mut
{
2021-12-27 16:06:05 -03:00
mIdx = -1;
}
2021-12-27 16:06:05 -03:00
public void Dispose()
{
}
2021-12-27 16:06:05 -03:00
public bool MoveNext() mut
{
2021-12-27 16:06:05 -03:00
if (mTypeInstance == null)
return false;
TypeInstance.FieldData* fieldData = null;
repeat
{
2021-12-27 16:06:05 -03:00
mIdx++;
if (mIdx == mTypeInstance.[Friend]mFieldDataCount)
return false;
fieldData = &mTypeInstance.[Friend]mFieldDataPtr[mIdx];
}
2021-12-27 16:06:05 -03:00
while (!fieldData.mFlags.HasFlag(.EnumCase));
return true;
}
2021-12-27 16:06:05 -03:00
public FieldInfo Current
{
2021-12-27 16:06:05 -03:00
get
{
var fieldData = &mTypeInstance.[Friend]mFieldDataPtr[mIdx];
return FieldInfo(mTypeInstance, fieldData);
}
}
2021-12-27 16:06:05 -03:00
public int32 Index
{
2021-12-27 16:06:05 -03:00
get
{
return mIdx;
}
}
public Result<FieldInfo> GetNext() mut
{
if (!MoveNext())
return .Err;
return Current;
}
}
2022-06-24 06:45:35 -07:00
[NoShow(true)]
2021-12-27 14:34:55 -05:00
public struct EnumEnumerator<TEnum> : EnumFieldsEnumerator<TEnum>, IEnumerator<(StringView name, TEnum value)>
where TEnum : enum
{
public new (StringView name, TEnum value) Current
{
get
{
return ((.)base.Current.[Friend]mFieldData.[Friend]mName, (.)*(int64*)&base.Current.[Friend]mFieldData.[Friend]mData);
2021-12-27 14:34:55 -05:00
}
}
public new Result<(StringView name, TEnum value)> GetNext() mut
{
if (!MoveNext())
return .Err;
return Current;
}
}
2022-06-24 06:45:35 -07:00
[NoShow(true)]
2021-12-27 16:06:05 -03:00
public struct EnumValuesEnumerator<TEnum> : EnumFieldsEnumerator<TEnum>, IEnumerator<TEnum>
where TEnum : enum
{
public new TEnum Current
{
get
{
return (.)*(int64*)&base.Current.[Friend]mFieldData.[Friend]mData;
}
}
public new Result<TEnum> GetNext() mut
{
if (!MoveNext())
return .Err;
return Current;
}
}
2022-06-24 06:45:35 -07:00
[NoShow(true)]
2021-12-27 16:06:05 -03:00
public struct EnumNamesEnumerator<TEnum> : EnumFieldsEnumerator<TEnum>, IEnumerator<StringView>
where TEnum : enum
{
public new StringView Current
{
get
{
return (.)base.Current.[Friend]mFieldData.[Friend]mName;
}
}
public new Result<StringView> GetNext() mut
{
if (!MoveNext())
return .Err;
return Current;
}
}
2019-08-23 11:56:54 -07:00
}
}