using System.Reflection; using System.Collections; namespace System { struct Enum { public static void EnumToString(Type type, String strBuffer, int64 iVal) { for (var field in type.GetFields()) { if (field.[Friend]mFieldData.mFlags.HasFlag(.EnumCase) && *(int64*)&field.[Friend]mFieldData.[Friend]mData == iVal) { strBuffer.Append(field.Name); return; } } iVal.ToString(strBuffer); } public static Result Parse(StringView str, bool ignoreCase = false) where T : enum { for (var (name, data) in GetEnumerator()) { if (str.Equals(name, ignoreCase)) return .Ok(data); if (int64.Parse(str) case .Ok(let val) && val == (.)data) return .Ok(data); } return .Err; } public static bool IsDefined(T value) where T : enum { for (var data in GetValues()) { if (data == (.)value) return true; } return false; } public static EnumEnumerator GetEnumerator() where TEnum : enum { return .(); } public static EnumValuesEnumerator GetValues() where TEnum : enum { return .(); } public static EnumNamesEnumerator GetNames() where TEnum : enum { return .(); } private struct EnumFieldsEnumerator where TEnum : enum { TypeInstance mTypeInstance; int32 mIdx; public this() { mTypeInstance = typeof(TEnum) as TypeInstance; mIdx = -1; } public void Reset() mut { mIdx = -1; } public void Dispose() { } public bool MoveNext() mut { if (mTypeInstance == null) return false; TypeInstance.FieldData* fieldData = null; repeat { mIdx++; if (mIdx == mTypeInstance.[Friend]mFieldDataCount) return false; fieldData = &mTypeInstance.[Friend]mFieldDataPtr[mIdx]; } while (!fieldData.mFlags.HasFlag(.EnumCase)); return true; } public FieldInfo Current { get { var fieldData = &mTypeInstance.[Friend]mFieldDataPtr[mIdx]; return FieldInfo(mTypeInstance, fieldData); } } public int32 Index { get { return mIdx; } } public Result GetNext() mut { if (!MoveNext()) return .Err; return Current; } } public struct EnumEnumerator : EnumFieldsEnumerator, 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); } } public new Result<(StringView name, TEnum value)> GetNext() mut { if (!MoveNext()) return .Err; return Current; } } public struct EnumValuesEnumerator : EnumFieldsEnumerator, IEnumerator where TEnum : enum { public new TEnum Current { get { return (.)*(int64*)&base.Current.[Friend]mFieldData.[Friend]mData; } } public new Result GetNext() mut { if (!MoveNext()) return .Err; return Current; } } public struct EnumNamesEnumerator : EnumFieldsEnumerator, IEnumerator where TEnum : enum { public new StringView Current { get { return (.)base.Current.[Friend]mFieldData.[Friend]mName; } } public new Result GetNext() mut { if (!MoveNext()) return .Err; return Current; } } } }