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
|
|
|
|
{
|
|
|
|
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) &&
|
2021-12-29 13:01:13 -05:00
|
|
|
*(int64*)&field.[Friend]mFieldData.[Friend]mData == iVal)
|
2019-08-23 11:56:54 -07:00
|
|
|
{
|
|
|
|
strBuffer.Append(field.Name);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2021-12-29 11:24:14 -05:00
|
|
|
iVal.ToString(strBuffer);
|
2019-08-23 11:56:54 -07:00
|
|
|
}
|
|
|
|
|
2020-11-10 05:44:23 -08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2021-12-27 13:45:52 -03:00
|
|
|
public static bool IsDefined<T>(T value)
|
|
|
|
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-27 13:45:52 -03:00
|
|
|
{
|
2021-12-29 12:44:04 -03:00
|
|
|
if (data == (.)value)
|
2021-12-27 13:45:52 -03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-12-27 14:34:55 -05:00
|
|
|
public static EnumEnumerator<TEnum> GetEnumerator<TEnum>()
|
|
|
|
where TEnum : enum
|
|
|
|
{
|
|
|
|
return .();
|
|
|
|
}
|
|
|
|
|
|
|
|
public static EnumValuesEnumerator<TEnum> GetValues<TEnum>()
|
2021-12-27 13:45:52 -03:00
|
|
|
where TEnum : enum
|
|
|
|
{
|
|
|
|
return .();
|
|
|
|
}
|
|
|
|
|
2021-12-27 14:34:55 -05:00
|
|
|
public static EnumNamesEnumerator<TEnum> GetNames<TEnum>()
|
2021-12-27 13:45:52 -03:00
|
|
|
where TEnum : enum
|
|
|
|
{
|
|
|
|
return .();
|
|
|
|
}
|
|
|
|
|
2021-12-27 16:06:05 -03:00
|
|
|
private struct EnumFieldsEnumerator<TEnum>
|
2021-12-27 13:45:52 -03:00
|
|
|
where TEnum : enum
|
|
|
|
{
|
2021-12-27 16:06:05 -03:00
|
|
|
TypeInstance mTypeInstance;
|
|
|
|
int32 mIdx;
|
2021-12-27 13:45:52 -03:00
|
|
|
|
|
|
|
public this()
|
|
|
|
{
|
2021-12-27 16:06:05 -03:00
|
|
|
mTypeInstance = typeof(TEnum) as TypeInstance;
|
|
|
|
mIdx = -1;
|
2021-12-27 13:45:52 -03:00
|
|
|
}
|
|
|
|
|
2021-12-27 16:06:05 -03:00
|
|
|
public void Reset() mut
|
2021-12-27 13:45:52 -03:00
|
|
|
{
|
2021-12-27 16:06:05 -03:00
|
|
|
mIdx = -1;
|
2021-12-27 13:45:52 -03:00
|
|
|
}
|
|
|
|
|
2021-12-27 16:06:05 -03:00
|
|
|
public void Dispose()
|
2021-12-27 13:45:52 -03:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2021-12-27 16:06:05 -03:00
|
|
|
public bool MoveNext() mut
|
2021-12-27 13:45:52 -03:00
|
|
|
{
|
2021-12-27 16:06:05 -03:00
|
|
|
if (mTypeInstance == null)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
TypeInstance.FieldData* fieldData = null;
|
|
|
|
|
|
|
|
repeat
|
2021-12-27 13:45:52 -03:00
|
|
|
{
|
2021-12-27 16:06:05 -03:00
|
|
|
mIdx++;
|
|
|
|
if (mIdx == mTypeInstance.[Friend]mFieldDataCount)
|
|
|
|
return false;
|
|
|
|
fieldData = &mTypeInstance.[Friend]mFieldDataPtr[mIdx];
|
2021-12-27 13:45:52 -03:00
|
|
|
}
|
2021-12-27 16:06:05 -03:00
|
|
|
while (!fieldData.mFlags.HasFlag(.EnumCase));
|
|
|
|
|
|
|
|
return true;
|
2021-12-27 13:45:52 -03:00
|
|
|
}
|
|
|
|
|
2021-12-27 16:06:05 -03:00
|
|
|
public FieldInfo Current
|
2021-12-27 13:45:52 -03:00
|
|
|
{
|
2021-12-27 16:06:05 -03:00
|
|
|
get
|
|
|
|
{
|
|
|
|
var fieldData = &mTypeInstance.[Friend]mFieldDataPtr[mIdx];
|
|
|
|
return FieldInfo(mTypeInstance, fieldData);
|
|
|
|
}
|
2021-12-27 13:45:52 -03:00
|
|
|
}
|
|
|
|
|
2021-12-27 16:06:05 -03:00
|
|
|
public int32 Index
|
2021-12-27 13:45:52 -03:00
|
|
|
{
|
2021-12-27 16:06:05 -03:00
|
|
|
get
|
|
|
|
{
|
|
|
|
return mIdx;
|
|
|
|
}
|
2021-12-27 13:45:52 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
public Result<FieldInfo> GetNext() mut
|
|
|
|
{
|
|
|
|
if (!MoveNext())
|
|
|
|
return .Err;
|
|
|
|
return Current;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
{
|
2021-12-29 13:01:13 -05:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-27 16:06:05 -03:00
|
|
|
public struct EnumValuesEnumerator<TEnum> : EnumFieldsEnumerator<TEnum>, IEnumerator<TEnum>
|
2021-12-27 13:45:52 -03:00
|
|
|
where TEnum : enum
|
|
|
|
{
|
|
|
|
public new TEnum Current
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
2021-12-29 13:01:13 -05:00
|
|
|
return (.)*(int64*)&base.Current.[Friend]mFieldData.[Friend]mData;
|
2021-12-27 13:45:52 -03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public new Result<TEnum> GetNext() mut
|
|
|
|
{
|
|
|
|
if (!MoveNext())
|
|
|
|
return .Err;
|
|
|
|
return Current;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-27 16:06:05 -03:00
|
|
|
public struct EnumNamesEnumerator<TEnum> : EnumFieldsEnumerator<TEnum>, IEnumerator<StringView>
|
2021-12-27 13:45:52 -03:00
|
|
|
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
|
|
|
}
|
|
|
|
}
|