From 0b3f24208200df276b109bef3139bbedee13ce95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20L=C3=BCbe=C3=9F?= Date: Sun, 1 Jan 2023 18:18:27 +0100 Subject: [PATCH] Added Submodule "Beef.Linq" --- .gitmodules | 3 + BeefSpace.toml | 4 +- GlitchyEngine/BeefProj.toml | 2 +- .../System/Collections/IEnumerable.bf | 2871 ----------------- GlitchyEngine/vendor/Beef.Linq | 1 + 5 files changed, 7 insertions(+), 2874 deletions(-) delete mode 100644 GlitchyEngine/src/Extension/System/Collections/IEnumerable.bf create mode 160000 GlitchyEngine/vendor/Beef.Linq diff --git a/.gitmodules b/.gitmodules index 309fdb7..4c735e8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -28,3 +28,6 @@ [submodule "GlitchyEngine/vendor/box2D"] path = GlitchyEngine/vendor/box2D url = https://github.com/jazzbre/box2d-beef.git +[submodule "GlitchyEngine/vendor/Beef.Linq"] + path = GlitchyEngine/vendor/Beef.Linq + url = https://github.com/aharabada/Beef.Linq.git diff --git a/BeefSpace.toml b/BeefSpace.toml index 3bc76be..ae0a15c 100644 --- a/BeefSpace.toml +++ b/BeefSpace.toml @@ -1,6 +1,6 @@ FileVersion = 1 -Projects = {Sandbox = {Path = "Sandbox"}, GlitchyEngine = {Path = "GlitchyEngine"}, GlitchLog = {Path = "GlitchLog"}, DirectX = {Path = "GlitchyEngine/vendor/directx/DirectX"}, LodePng = {Path = "vendor/lodepng-beef/lodepng-beef"}, FreeType = {Path = "GlitchyEngine/vendor/freetype"}, cgltf-beef = {Path = "GlitchyEngine/vendor/gltf/cgltf-beef"}, GlitchyEditor = {Path = "GlitchyEditor"}, msdfgen-beef = {Path = "GlitchyEngine/vendor/msdfgen/msdfgen-beef"}, ImGui = {Path = "GlitchyEngine/vendor/imgui/ImGui"}, ImGuiImplDX11 = {Path = "GlitchyEngine/vendor/imgui/ImGuiImplDX11"}, ImGuiImplWin32 = {Path = "GlitchyEngine/vendor/imgui/ImGuiImplWin32"}, ImGuizmo = {Path = "GlitchyEngine/vendor/imgui/ImGuizmo"}, GlitchyEngineHelper = {Path = "GlitchyEngineHelper"}, bon = {Path = "GlitchyEngine/vendor/bon"}, box2d-beef = {Path = "GlitchyEngine/vendor/box2D"}} -WorkspaceFolders = {GlitchyEngine = ["GlitchyEngine", "GlitchLog", "GlitchyEngineHelper"], "GlitchyEngine/Dependencies" = ["cgltf-beef", "DirectX", "FreeType", "ImGui", "ImGuiImplDX11", "ImGuiImplWin32", "ImGuizmo", "LodePng", "msdfgen-beef", "bon", "box2d-beef"]} +Projects = {Sandbox = {Path = "Sandbox"}, GlitchyEngine = {Path = "GlitchyEngine"}, GlitchLog = {Path = "GlitchLog"}, DirectX = {Path = "GlitchyEngine/vendor/directx/DirectX"}, LodePng = {Path = "vendor/lodepng-beef/lodepng-beef"}, FreeType = {Path = "GlitchyEngine/vendor/freetype"}, cgltf-beef = {Path = "GlitchyEngine/vendor/gltf/cgltf-beef"}, GlitchyEditor = {Path = "GlitchyEditor"}, msdfgen-beef = {Path = "GlitchyEngine/vendor/msdfgen/msdfgen-beef"}, ImGui = {Path = "GlitchyEngine/vendor/imgui/ImGui"}, ImGuiImplDX11 = {Path = "GlitchyEngine/vendor/imgui/ImGuiImplDX11"}, ImGuiImplWin32 = {Path = "GlitchyEngine/vendor/imgui/ImGuiImplWin32"}, ImGuizmo = {Path = "GlitchyEngine/vendor/imgui/ImGuizmo"}, GlitchyEngineHelper = {Path = "GlitchyEngineHelper"}, bon = {Path = "GlitchyEngine/vendor/bon"}, box2d-beef = {Path = "GlitchyEngine/vendor/box2D"}, "Beef.Linq" = {Path = "GlitchyEngine/vendor/Beef.Linq/src"}} +WorkspaceFolders = {GlitchyEngine = ["GlitchyEngine", "GlitchLog", "GlitchyEngineHelper"], "GlitchyEngine/Dependencies" = ["cgltf-beef", "DirectX", "FreeType", "ImGui", "ImGuiImplDX11", "ImGuiImplWin32", "ImGuizmo", "LodePng", "msdfgen-beef", "bon", "box2d-beef", "Beef.Linq"]} [Workspace] StartupProject = "GlitchyEditor" diff --git a/GlitchyEngine/BeefProj.toml b/GlitchyEngine/BeefProj.toml index 35c9304..2a9211d 100644 --- a/GlitchyEngine/BeefProj.toml +++ b/GlitchyEngine/BeefProj.toml @@ -1,5 +1,5 @@ FileVersion = 1 -Dependencies = {GlitchLog = "*", corlib = "*", DirectX = "*", FreeType = "*", cgltf-beef = "*", msdfgen-beef = "*", ImGui = "*", ImGuiImplDX11 = "*", ImGuiImplWin32 = "*", ImGuizmo = "*", Beefy2D = "*", LodePng = "*", GlitchyEngineHelper = "*", bon = "*", box2d-beef = "*"} +Dependencies = {GlitchLog = "*", corlib = "*", DirectX = "*", FreeType = "*", cgltf-beef = "*", msdfgen-beef = "*", ImGui = "*", ImGuiImplDX11 = "*", ImGuiImplWin32 = "*", ImGuizmo = "*", Beefy2D = "*", LodePng = "*", GlitchyEngineHelper = "*", bon = "*", box2d-beef = "*", "Beef.Linq" = "*"} [Project] Name = "GlitchyEngine" diff --git a/GlitchyEngine/src/Extension/System/Collections/IEnumerable.bf b/GlitchyEngine/src/Extension/System/Collections/IEnumerable.bf deleted file mode 100644 index f80469d..0000000 --- a/GlitchyEngine/src/Extension/System/Collections/IEnumerable.bf +++ /dev/null @@ -1,2871 +0,0 @@ -using System.Collections; -using System; -using internal System.Linq; - -namespace System.Linq -{ - public static - { - public static class Enumerable - { - public struct EmptyEnumerable : IEnumerable - { - public Enumerator GetEnumerator() => .(); - - public struct Enumerator : IEnumerator - { - public Result GetNext() - { - return .Err; - } - } - } - - public static EmptyEnumerable Empty() => .(); - - public struct RangeEnumerable : IEnumerable where TSource : operator TSource + int - { - TSource mStart; - TSource mEnd; - - public this(TSource start, TSource end) - { - mStart = start; - mEnd = end; - } - - public Enumerator GetEnumerator() => .(mStart, mEnd); - - public struct Enumerator : IEnumerator - { - TSource mCurrent; - TSource mEnd; - - public this(TSource start, TSource end) - { - mCurrent = start; - mEnd = end; - } - - public Result GetNext() mut - { - if (mCurrent == mEnd) - return .Err; - - let next = mCurrent; - mCurrent = mCurrent + 1; - return .Ok(next); - } - } - } - - public static RangeEnumerable - Range(TSource count) - where TSource : operator TSource + int - { - return .(default, count); - } - - public static RangeEnumerable - Range(TSource start, TSource end) - where TSource : operator TSource + int - where TSource : operator TSource + TSource - { - return .(start, end); - } - - public struct RepeatEnumerable : IEnumerable - { - TSource mValue; - int mCount; - - public this(TSource value, int count) - { - mValue = value; - mCount = count; - } - - public Enumerator GetEnumerator() => .(mValue, mCount); - - public struct Enumerator : IEnumerator - { - TSource mValue; - int mCount; - - public this(TSource value, int count) - { - mValue = value; - mCount = count; - } - - public Result GetNext() mut - { - if (--mCount >= 0) - return .Ok(mValue); - - return .Err; - } - } - } - - public static RepeatEnumerable - Repeat(TSource value, int count) - { - return .(value, count); - } - } - - - #region Matching - public static bool All(this TEnum items, TPredicate predicate) - where TEnum : concrete, IEnumerator - where TPredicate : delegate bool(TSource) - { - return InternalAll(items, predicate); - } - - public static bool All(this TCollection items, TPredicate predicate) - where TCollection : concrete, IEnumerable - where TPredicate : delegate bool(TSource) - { - return InternalAll(items.GetEnumerator(), predicate); - } - - static bool InternalAll(TEnum items, TPredicate predicate) - where TEnum : concrete, IEnumerator - where TPredicate : delegate bool(TSource) - { - using (var iterator = Iterator.Wrap(items)) - { - var enumerator = iterator.mEnum; - switch (enumerator.GetNext()) - { - case .Ok(let val): if (!predicate(val)) return false; - case .Err: return false; - } - - while (enumerator.GetNext() case .Ok(let val)) - if (!predicate(val)) - return false; - - return true; - } - } - - public static bool Any(this TCollection items) - where TCollection : concrete, IEnumerable - { - for (var it in items) - return true; - - return false; - } - - public static bool Any(this TCollection items, TPredicate predicate) - where TCollection : concrete, IEnumerable - where TPredicate : delegate bool(TSource) - { - for (var it in items) - if (predicate(it)) - return true; - - return false; - } - - public static bool Any(this TEnum items) - where TEnum : concrete, IEnumerator - { - for (var it in items) - return true; - - return false; - } - - public static bool Any(this TEnum items, TPredicate predicate) - where TEnum : concrete, IEnumerator - where TPredicate : delegate bool(TSource) - { - for (var it in items) - if (predicate(it)) - return true; - - return false; - } - - public static bool Contains(this TCollection items, TSource source) - where TCollection : concrete, IEnumerable - where bool : operator TSource == TSource - { - for (var it in items) - if (it == source) - return true; - - return false; - } - - public static bool Contains(this TEnum items, TSource source) - where TEnum : concrete, IEnumerator - where bool : operator TSource == TSource - { - for (var it in items) - if (it == source) - return true; - - return false; - } - - - public static bool SequenceEquals(this TLeft left, TRight right) - where TLeft : concrete, IEnumerable - where TRight : concrete, IEnumerable - where bool : operator TSource == TSource - { - return InternalSequenceEquals< - decltype(default(TLeft).GetEnumerator()), - decltype(default(TRight).GetEnumerator()), - TSource>(left.GetEnumerator(), right.GetEnumerator()); - } - - public static bool SequenceEquals(this TLeft left, TRight right) - where TLeft : concrete, IEnumerable - where TRight : concrete, IEnumerator - where bool : operator TSource == TSource - { - return InternalSequenceEquals< - decltype(default(TLeft).GetEnumerator()), - TRight, - TSource>(left.GetEnumerator(), right); - } - - public static bool SequenceEquals(this TLeft left, TRight right) - where TLeft : concrete, IEnumerator - where TRight : concrete, IEnumerable - where bool : operator TSource == TSource - { - return InternalSequenceEquals< - TLeft, - decltype(default(TRight).GetEnumerator()), - TSource>(left, right.GetEnumerator()); - } - - public static bool SequenceEquals(this TLeft left, TRight right) - where TLeft : concrete, IEnumerator - where TRight : concrete, IEnumerator - where bool : operator TSource == TSource - { - return InternalSequenceEquals(left, right); - } - - static bool InternalSequenceEquals(TLeft left, TRight right) - where TLeft : concrete, IEnumerator - where TRight : concrete, IEnumerator - where bool : operator TSource == TSource - { - using (var iterator0 = Iterator.Wrap(left)) - { - var e0 = iterator0.mEnum; - using (var iterator1 = Iterator.Wrap(right)) - { - var e1 = iterator1.mEnum; - while (true) - { - switch (e0.GetNext()) - { - case .Ok(let i0): - switch (e1.GetNext()) - { - case .Ok(let i1): - if (i0 != i1) - return false; - case .Err: - return false; - } - case .Err: - return e1.GetNext() case .Err; - } - } - } - } - } - - #endregion - - #region Aggregates - - public static TSource Average(this TCollection items) - where TCollection : concrete, IEnumerable - where TSource : operator TSource / int - where TSource : operator TSource + TSource - { - return InternalAverage(items.GetEnumerator()); - } - - public static TSource Average(this TEnum items) - where TEnum : concrete, IEnumerator - where TSource : operator TSource / int - where TSource : operator TSource + TSource - { - return InternalAverage(items); - } - - static TSource InternalAverage(TEnum items) - where TEnum : concrete, IEnumerator - where TSource : operator TSource / int - where TSource : operator TSource + TSource - { - var count = 0; - TSource sum = ?; - using (var iterator = Iterator.Wrap(items)) - { - var enumerator = iterator.mEnum; - - switch (enumerator.GetNext()) - { - case .Ok(let val): - sum = val; - count++; - case .Err: return default; - } - - while (enumerator.GetNext() case .Ok(let val)) - { - sum += val; - count++; - } - - return sum / count; - } - } - - public static TSource Max(this TCollection items) - where TCollection : concrete, IEnumerable - where bool : operator TSource < TSource - { - return InternalMax(items.GetEnumerator()); - } - - public static TSource Max(this TEnum items) - where TEnum : concrete, IEnumerator - where bool : operator TSource < TSource - { - return InternalMax(items); - } - - static TSource InternalMax(TEnum items) - where TEnum : concrete, IEnumerator - where bool : operator TSource < TSource - { - TSource max = ?; - using (var iterator = Iterator.Wrap(items)) - { - var enumerator = iterator.mEnum; - switch (enumerator.GetNext()) - { - case .Ok(let val): max = val; - case .Err: return default; - } - - while (enumerator.GetNext() case .Ok(let val)) - { - let next = val; - if (max < next) - max = next; - } - } - return max; - } - - public static TSource Min(this TCollection items) - where TCollection : concrete, IEnumerable - where bool : operator TSource < TSource - { - return InternalMin(items.GetEnumerator()); - } - - public static TSource Min(this TEnum items) - where TEnum : concrete, IEnumerator - where bool : operator TSource < TSource - { - return InternalMin(items); - } - - static TSource InternalMin(TEnum items) - where TEnum : concrete, IEnumerator - where bool : operator TSource < TSource - { - TSource min = ?; - using (var iterator = Iterator.Wrap(items)) - { - var enumerator = iterator.mEnum; - switch (enumerator.GetNext()) - { - case .Ok(let val): min = val; - case .Err: return default; - } - - while (enumerator.GetNext() case .Ok(let val)) - { - let next = val; - if (next < min) - min = next; - } - } - return min; - } - - public static TSource Sum(this TCollection items) - where TCollection : concrete, IEnumerable - where TPredicate : delegate bool(TSource) - where TSource : operator TSource + TSource - { - return InternalSum(items.GetEnumerator()); - } - - public static TSource Sum(this TEnum items) - where TEnum : concrete, IEnumerator - where TPredicate : delegate bool(TSource) - where TSource : operator TSource + TSource - { - return InternalSum(items); - } - - static TSource InternalSum(TEnum items) - where TEnum : concrete, IEnumerator - where TPredicate : delegate bool(TSource) - where TSource : operator TSource + TSource - { - TSource sum = ?; - using (var iterator = Iterator.Wrap(items)) - { - var enumerator = iterator.mEnum; - switch (enumerator.GetNext()) - { - case .Ok(let val): sum = val; - case .Err: return default; - } - - while (enumerator.GetNext() case .Ok(let val)) - sum += val; - } - return sum; - } - - public static int Count(this TCollection items) - where TCollection : concrete, IEnumerable - { - if (typeof(TCollection) == typeof(List)) - return (items as List).Count; - if (typeof(TCollection) == typeof(TSource[])) - return (items as TSource[]).Count; - - return InternalCount(items.GetEnumerator()); - } - - - public static int Count(this TEnum items) - where TEnum : concrete, IEnumerator - { - return InternalCount(items); - } - - public static int InternalCount(TEnum items) - where TEnum : concrete, IEnumerator - { - var count = 0; - using (var iterator = Iterator.Wrap(items)) - { - var enumerator = iterator.mEnum; - while (enumerator.GetNext() case .Ok) - count++; - } - return count; - } - - #endregion - - #region Find in enumerable - - internal static bool InternalElementAt(TEnum items, int index, out TSource val) - where TEnum : concrete, IEnumerator - { - var index; - using (var iterator = Iterator.Wrap(items)) - { - var enumerator = iterator.mEnum; - while (--index > 0) - { - if (enumerator.GetNext() case .Err) - break; - } - - if (index == 0 && enumerator.GetNext() case .Ok(out val)) - return true; - } - val = default; - return false; - } - - public static TSource ElementAt(this TCollection items, int index) - where TCollection : concrete, IEnumerable - { - if (InternalElementAt(items.GetEnumerator(), index, let val)) - return val; - - Runtime.FatalError("Not enough elements in the sequence."); - } - - public static TSource ElementAt(this TEnum items, int index) - where TEnum : concrete, IEnumerator - { - if (InternalElementAt(items, index, let val)) - return val; - - Runtime.FatalError("Not enough elements in the sequence."); - } - - public static TSource ElementAtOrDefault(this TCollection items, int index) - where TCollection : concrete, IEnumerable - { - if (InternalElementAt(items.GetEnumerator(), index, let val)) - return val; - - return default; - } - - public static TSource ElementAtOrDefault(this TEnum items, int index) - where TEnum : concrete, IEnumerator - { - if (InternalElementAt(items, index, let val)) - return val; - - return default; - } - - public static bool InternalFirst(TEnum items, out TSource val) - where TEnum : concrete, IEnumerator - { - val = default; - using (var iterator = Iterator.Wrap(items)) - { - var enumerator = iterator.mEnum; - if (enumerator.GetNext() case .Ok(out val)) - return true; - } - - return false; - } - - public static TSource First(this TCollection items) - where TCollection : concrete, IEnumerable - { - if (InternalFirst(items.GetEnumerator(), let val)) - return val; - Runtime.FatalError("Sequence contained no elements."); - } - - public static TSource First(this TEnum items) - where TEnum : concrete, IEnumerator - { - if (InternalFirst(items, let val)) - return val; - Runtime.FatalError("Sequence contained no elements."); - } - - public static TSource FirstOrDefault(this TCollection items) - where TCollection : concrete, IEnumerable - { - if (InternalFirst(items.GetEnumerator(), let val)) - return val; - - return default; - } - - public static TSource FirstOrDefault(this TEnum items) - where TEnum : concrete, IEnumerator - { - if (InternalFirst(items, let val)) - return val; - - return default; - } - - internal static bool InternalLast(TEnum items, out TSource val) - where TEnum : concrete, IEnumerator - { - val = default; - var found = false; - using (var iterator = Iterator.Wrap(items)) - { - var enumerator = iterator.mEnum; - if (enumerator.GetNext() case .Ok(out val)) - found = true; - - while (enumerator.GetNext() case .Ok(let temp)) - val = temp; - } - - return found; - } - - public static TSource Last(this TCollection items) - where TCollection : concrete, IEnumerable - { - if (InternalLast(items.GetEnumerator(), let val)) - return val; - - Runtime.FatalError("Sequence contained no elements."); - } - - public static TSource Last(this TEnum items) - where TEnum : concrete, IEnumerator - { - if (InternalLast(items, let val)) - return val; - - Runtime.FatalError("Sequence contained no elements."); - } - - public static TSource LastOrDefault(this TCollection items) - where TCollection : concrete, IEnumerable - { - if (InternalLast(items.GetEnumerator(), let val)) - return val; - - return default; - } - - public static TSource LastOrDefault(this TEnum items) - where TEnum : concrete, IEnumerator - { - if (InternalLast(items, let val)) - return val; - - return default; - } - - internal static bool InternalSingle(TEnum items, out TSource val) - where TEnum : concrete, IEnumerator - { - val = default; - using (var iterator = Iterator.Wrap(items)) - { - var enumerator = iterator.mEnum; - - if (enumerator.GetNext() case .Ok(out val)) - { - if (enumerator.GetNext() case .Err) - return true; - - Runtime.FatalError("Sequence matched more than one element."); - } - } - - return false; - } - - public static TSource Single(this TCollection items) - where TCollection : concrete, IEnumerable - { - if (InternalSingle(items.GetEnumerator(), let val)) - return val; - - Runtime.FatalError("Sequence contained no elements."); - } - - public static TSource Single(this TEnum items) - where TEnum : concrete, IEnumerator - { - if (InternalSingle(items, let val)) - return val; - - Runtime.FatalError("Sequence contained no elements."); - } - - public static TSource SingleOrDefault(this TCollection items) - where TCollection : concrete, IEnumerable - { - if (InternalSingle(items.GetEnumerator(), let val)) - return val; - - return default; - } - - public static TSource SingleOrDefault(this TEnum items) - where TEnum : concrete, IEnumerator - { - if (InternalSingle(items, let val)) - return val; - - return default; - } - - #endregion - -#region Enumerable Chains - struct Iterator - { - public static Iterator Wrap(TEnum items) - where TEnum : concrete, IEnumerator - { - return .(items); - } - - public static Iterator Wrap(TCollection items) - where TCollection : concrete, IEnumerable - { - return .(items.GetEnumerator()); - } - } - - struct Iterator : IDisposable - where TEnum : concrete, IEnumerator - { - internal TEnum mEnum; - - public this(TEnum items) - { - mEnum = items; - } - - [SkipCall] - public void Dispose() mut { } - - public static implicit operator Iterator(TEnum enumerator) => .(enumerator); - } - - extension Iterator : IDisposable where TEnum : IDisposable - { - public void Dispose() mut => mEnum.Dispose(); - } - - struct SelectEnumerable : Iterator, IEnumerable - where TSelect : delegate TResult(TSource) - where TEnum : concrete, IEnumerator - { - TSelect mDlg; - - public this(TEnum e, TSelect dlg) : base(e) - { - mDlg = dlg; - } - - Result GetNext() mut - { - if (mEnum.GetNext() case .Ok(let val)) - return mDlg(val); - - return .Err; - } - - public Enumerator GetEnumerator() => .(this); - - public struct Enumerator : IEnumerator - { - SelfOuter mEnum; - public this(SelfOuter enumerator) - { - mEnum = enumerator; - } - public Result GetNext() mut => mEnum.GetNext(); - } - } - - public static SelectEnumerable - Select(this TCollection items, TSelect select) - where TCollection : concrete, IEnumerable - where TSelect : delegate TResult(TSource) - { - return .(items.GetEnumerator(), select); - } - - public static SelectEnumerable - Select(this TEnum items, TSelect select) - where TEnum : concrete, IEnumerator - where TSelect : delegate TResult(TSource) - { - return .(items, select); - } - - struct WhereEnumerable : IEnumerable, IDisposable - where TPredicate : delegate bool(TSource) - where TEnum : concrete, IEnumerator - { - TPredicate mPredicate; - Iterator mIterator; - - public this(TEnum enumerator, TPredicate predicate) - { - mIterator = enumerator; - mPredicate = predicate; - } - - Result GetNext() mut - { - while (mIterator.mEnum.GetNext() case .Ok(let val)) - if (mPredicate(val)) - return .Ok(val); - - return .Err; - } - - public Enumerator GetEnumerator() => .(this); - - public struct Enumerator : IEnumerator, IDisposable - { - SelfOuter mSelf; - public this(SelfOuter self) - { - mSelf = self; - } - public Result GetNext() mut => mSelf.GetNext(); - - public void Dispose() mut - { - mSelf.Dispose(); - } - } - - public void Dispose() mut - { - mIterator.Dispose(); - } - } - - public static WhereEnumerable - Where(this TCollection items, TPredicate predicate) - where TCollection : concrete, IEnumerable - where TPredicate : delegate bool(TSource) - { - return .(items.GetEnumerator(), predicate); - } - - public static WhereEnumerable - Where(this TEnum items, TPredicate predicate) - where TEnum : concrete, IEnumerator - where TPredicate : delegate bool(TSource) - { - return .(items, predicate); - } - - struct TakeEnumerable : Iterator, IEnumerable - where TEnum : concrete, IEnumerator - { - int mCount; - - public this(TEnum enumerator, int count) : base(enumerator) - { - mCount = count; - } - - public Result GetNext() mut - { - while (mCount-- > 0 && mEnum.GetNext() case .Ok(let val)) - return val; - - return .Err; - } - - public Enumerator GetEnumerator() => .(this); - - public struct Enumerator : IEnumerator - { - SelfOuter mEnum; - public this(SelfOuter enumerator) - { - mEnum = enumerator; - } - public Result GetNext() mut => mEnum.GetNext(); - } - } - - public static TakeEnumerable - Take(this TCollection items, int count) - where TCollection : concrete, IEnumerable - { - return .(items.GetEnumerator(), count); - } - - public static TakeEnumerable - Take(this TEnum items, int count) - where TEnum : concrete, IEnumerator - { - return .(items, count); - } - - struct TakeWhileEnumerable : Iterator, IEnumerable - where TEnum : concrete, IEnumerator - where TPredicate : delegate bool(TSource) - { - TPredicate mPredicate; - - public this(TEnum enumerator, TPredicate predicate) : base(enumerator) - { - mPredicate = predicate; - } - - Result GetNext() mut - { - if (mEnum.GetNext() case .Ok(let val)) - if (mPredicate(val)) - return .Ok(val); - - return .Err; - } - - public Enumerator GetEnumerator() => .(this); - - public struct Enumerator : IEnumerator - { - SelfOuter mEnum; - public this(SelfOuter enumerator) - { - mEnum = enumerator; - } - public Result GetNext() mut => mEnum.GetNext(); - } - } - - public static TakeWhileEnumerable - TakeWhile(this TCollection items, TPredicate predicate) - where TCollection : concrete, IEnumerable - where TPredicate : delegate bool(TSource) - { - return .(items.GetEnumerator(), predicate); - } - - public static TakeWhileEnumerable - TakeWhile(this TEnum items, TPredicate predicate) - where TEnum : concrete, IEnumerator - where TPredicate : delegate bool(TSource) - { - return .(items, predicate); - } - - struct SkipEnumerable : Iterator, IEnumerable - where TEnum : concrete, IEnumerator - { - int mCount; - - public this(TEnum enumerator, int count) : base(enumerator) - { - mCount = count; - } - - public Result GetNext() mut - { - while (mCount-- > 0 && mEnum.GetNext() case .Ok(?)) { } - - while (mEnum.GetNext() case .Ok(let val)) - return val; - - return .Err; - } - - public Enumerator GetEnumerator() => .(this); - - public struct Enumerator : IEnumerator - { - SelfOuter mEnum; - public this(SelfOuter enumerator) - { - mEnum = enumerator; - } - public Result GetNext() mut => mEnum.GetNext(); - } - } - - public static SkipEnumerable - Skip(this TCollection items, int count) - where TCollection : concrete, IEnumerable - { - return .(items.GetEnumerator(), count); - } - - public static SkipEnumerable - Skip(this TEnum items, int count) - where TEnum : concrete, IEnumerator - { - return .(items, count); - } - - struct SkipWhileEnumerable : Iterator, IEnumerable - where TEnum : concrete, IEnumerator - where TPredicate : delegate bool(TSource) - { - TPredicate mPredicate; - int mState = 0; - - public this(TEnum enumerator, TPredicate predicate) : base(enumerator) - { - mPredicate = predicate; - } - - public Result GetNext() mut - { - switch (mState) { - case 0: - while (mEnum.GetNext() case .Ok(let val)) - { - if (!mPredicate(val)) - { - mState = 1; - return .Ok(val); - } - } - case 1: - return mEnum.GetNext(); - } - - return .Err; - } - - public Enumerator GetEnumerator() => .(this); - - public struct Enumerator : IEnumerator - { - SelfOuter mEnum; - public this(SelfOuter enumerator) - { - mEnum = enumerator; - } - public Result GetNext() mut => mEnum.GetNext(); - } - } - - public static SkipWhileEnumerable - SkipWhile(this TCollection items, TPredicate predicate) - where TCollection : concrete, IEnumerable - where TPredicate : delegate bool(TSource) - { - return .(items.GetEnumerator(), predicate); - } - - public static SkipWhileEnumerable - SkipWhile(this TEnum items, TPredicate predicate) - where TEnum : concrete, IEnumerator - where TPredicate : delegate bool(TSource) - { - return .(items, predicate); - } - - struct DefaultIfEmptyEnumerable : Iterator, IEnumerable - where TEnum : concrete, IEnumerator - { - TSource mDefaultValue; - int mState = 0; - - public this(TEnum enumerator, TSource defaultValue) : base(enumerator) - { - mDefaultValue = defaultValue; - } - - public Result GetNext() mut - { - switch (mState) { - case 0: - if (mEnum.GetNext() case .Ok(let val)) - { - mState = 1; - return .Ok(val); - } - - mState = 2; - return .Ok(mDefaultValue); - case 1: - return mEnum.GetNext(); - } - - return .Err; - } - - public Enumerator GetEnumerator() => .(this); - - public struct Enumerator : IEnumerator - { - SelfOuter mEnum; - public this(SelfOuter enumerator) - { - mEnum = enumerator; - } - public Result GetNext() mut => mEnum.GetNext(); - } - } - - public static DefaultIfEmptyEnumerable - DefaultIfEmpty(this TCollection items) - where TCollection : concrete, IEnumerable - { - return .(items.GetEnumerator(), default); - } - - public static DefaultIfEmptyEnumerable - DefaultIfEmpty(this TEnum items) - where TEnum : concrete, IEnumerator - { - return .(items, default); - } - - public static DefaultIfEmptyEnumerable - DefaultIfEmpty(this TCollection items, TSource defaultValue = default) - where TCollection : concrete, IEnumerable - { - return .(items.GetEnumerator(), defaultValue); - } - - public static DefaultIfEmptyEnumerable - DefaultIfEmpty(this TEnum items, TSource defaultValue = default) - where TEnum : concrete, IEnumerator - { - return .(items, defaultValue); - } - - struct DistinctEnumerable : IEnumerable, IDisposable - where TEnum : concrete, IEnumerator - where TSource : IHashable - { - HashSet mDistinctValues; - HashSet.Enumerator mEnum; - Iterator mIterator; - int mState = 0; - - public this(TEnum enumerator) - { - mIterator = .(enumerator); - mDistinctValues = new .(); - mEnum = default; - } - - public Result GetNext() mut - { - switch (mState) { - case 0: - var enumerator = mIterator.mEnum; - while (enumerator.GetNext() case .Ok(let val)) - mDistinctValues.Add(val); - - mIterator.Dispose(); - mIterator = default; - mEnum = mDistinctValues.GetEnumerator(); - mState = 1; - fallthrough; - case 1: - return mEnum.GetNext(); - } - - return .Err; - } - - public void Dispose() mut - { - mEnum.Dispose(); - DeleteAndNullify!(mDistinctValues); - } - - public Enumerator GetEnumerator() => .(this); - - public struct Enumerator : IEnumerator, IDisposable - { - SelfOuter mEnum; - public this(SelfOuter enumerator) - { - mEnum = enumerator; - } - public Result GetNext() mut => mEnum.GetNext(); - - public void Dispose() mut => mEnum.Dispose(); - } - } - - public static DistinctEnumerable - Distinct(this TCollection items) - where TCollection : concrete, IEnumerable - where TSource : IHashable - { - return .(items.GetEnumerator()); - } - - public static DistinctEnumerable - Distinct(this TEnum items) - where TEnum : concrete, IEnumerator - where TSource : IHashable - { - return .(items); - } - - struct ReverseEnumerable : IEnumerable, IDisposable - where TEnum : concrete, IEnumerator - { - List mCopyValues; - List.Enumerator mEnum; - Iterator mIterator; - int mIndex = -1; - - public this(TEnum enumerator) - { - mIterator = .(enumerator); - mCopyValues = new .(); - mEnum = default; - } - - public Result GetNext() mut - { - switch (mIndex) { - case -1: - var enumerator = mIterator.mEnum; - while (enumerator.GetNext() case .Ok(let val)) - mCopyValues.Add(val); - - mIterator.Dispose(); - mIterator = default; - mEnum = mCopyValues.GetEnumerator(); - mIndex = mCopyValues.Count; - fallthrough; - default: - if (--mIndex >= 0) - return .Ok(mCopyValues[mIndex]); - - return .Err; - } - } - - public void Dispose() mut - { - mEnum.Dispose(); - DeleteAndNullify!(mCopyValues); - } - - public Enumerator GetEnumerator() => .(this); - - public struct Enumerator : IEnumerator, IDisposable - { - SelfOuter mSelf; - public this(SelfOuter self) - { - mSelf = self; - } - public Result GetNext() mut => mSelf.GetNext(); - - public void Dispose() mut - { - mSelf.Dispose(); - } - } - } - - public static ReverseEnumerable - Reverse(this TCollection items) - where TCollection : concrete, IEnumerable - { - return .(items.GetEnumerator()); - } - - struct MapEnumerable : Iterator, IEnumerator, IEnumerable - where bool : operator TSource < TSource - where TSource : operator TSource - TSource - where TResult : operator TResult + TResult - where TResult : operator TResult - TResult - where float : operator float / TSource - where float : operator TSource * float - where float : operator float / TResult - where TResult : operator explicit float - where TEnum : concrete, IEnumerator - { - int mState = 0; - float mScale = 0f, mMapScale; - TSource mMin = default; - TResult mMapMin; - - public this(TEnum enumerator, TResult mapMin, TResult mapMax) : base(enumerator) - { - mMapMin = mapMin; - mMapScale = 1f / (mapMax - mapMin); - } - - public Result GetNext() mut - { - switch (mState) { - case 0: - var copyEnum = mEnum; - switch (copyEnum.GetNext()) { - case .Ok(let first): - var min = first; - var max = first; - - while (copyEnum.GetNext() case .Ok(let next)) - { - if (next < min) min = next; - if (max < next) max = next; - } - - mMin = min; - mScale = 1f / (max - min); - if (mScale == default) - { - mState = 2; - return .Ok(default); - } - - mState = 1; - case .Err: return .Err; - } - fallthrough; - case 1: - if (mEnum.GetNext() case .Ok(let val)) - return (TResult)(((val - mMin) * mScale) / mMapScale) + mMapMin; - case 2: - if (mEnum.GetNext() case .Ok(let val)) - return .Ok(default); - } - - return .Err; - } - - /*typealias SelfOuter = MapEnumerable; - public Enumerator GetEnumerator() => .(this); - - public struct Enumerator: IEnumerator - { - SelfOuter mEnum; - public this(SelfOuter enumerator) - { - mEnum = enumerator; - } - public Result GetNext() mut => mEnum.GetNext(); - }*/ - - public Self GetEnumerator() => this; - } - - public static MapEnumerable - Map(this TCollection items, TResult min, TResult max) - where TCollection : concrete, IEnumerable - where bool : operator TSource < TSource - where TSource : operator TSource - TSource - where TResult : operator TResult + TResult - where TResult : operator TResult - TResult - where float : operator float / TSource - where float : operator TSource * float - where float : operator float / TResult - where TResult : operator explicit float - { - return .(items.GetEnumerator(), min, max); - } - - public static MapEnumerable - Map(this TEnum items, TResult min, TResult max) - where TEnum : concrete, IEnumerator - where bool : operator TSource < TSource - where TSource : operator TSource - TSource - where TResult : operator TResult + TResult - where TResult : operator TResult - TResult - where float : operator float / TSource - where float : operator TSource * float - where float : operator float / TResult - where TResult : operator explicit float - { - return .(items, min, max); - } -#endregion - -#region ToXYZ methods - public static void ToDictionary(this TCollection items, TKeyDlg keyDlg, TValueDlg valueDlg, Dictionary output) - where TCollection : concrete, IEnumerable - where TKey : IHashable - where TKeyDlg : delegate TKey(TSource) - where TValueDlg : delegate TValue(TSource) - { - for (var it in items) - output.Add(keyDlg(it), valueDlg(it)); - } - - public static void ToDictionary(this TEnum items, TKeyDlg keyDlg, TValueDlg valueDlg, Dictionary output) - where TEnum : concrete, IEnumerator - where TKey : IHashable - where TKeyDlg : delegate TKey(TSource) - where TValueDlg : delegate TValue(TSource) - { - for (var it in items) - output.Add(keyDlg(it), valueDlg(it)); - } - - public static void ToDictionary(this TCollection items, TKeyDlg keyDlg, Dictionary output) - where TCollection : concrete, IEnumerable - where TKey : IHashable - where TKeyDlg : delegate TKey(TSource) - { - for (var it in items) - output.Add(keyDlg(it), it); - } - - public static void ToDictionary(this TEnum items, TKeyDlg keyDlg, Dictionary output) - where TEnum : concrete, IEnumerator - where TKey : IHashable - where TKeyDlg : delegate TKey(TSource) - { - for (var it in items) - output.Add(keyDlg(it), it); - } - - public static void ToHashSet(this TCollection items, HashSet output) - where TCollection : concrete, IEnumerable - where TSource : IHashable - { - for (var it in items) - output.Add(it); - } - - public static void ToHashSet(this TEnum items, HashSet output) - where TEnum : concrete, IEnumerator - where TSource : IHashable - { - for (var it in items) - output.Add(it); - } - - public static void ToList(this TCollection items, List output) - where TCollection : concrete, IEnumerable - { - for (var it in items) - output.Add(it); - } - - public static void ToList(this TEnum items, List output) - where TEnum : concrete, IEnumerator - { - for (var it in items) - output.Add(it); - } -#endregion - -#region Aggregates - public static TSource - Aggregate(this TCollection items, TAccumulate accumulate) - where TCollection : concrete, IEnumerable - where TAccumulate : delegate TSource(TSource, TSource) - { - if (InternalAggregate(items.GetEnumerator(), accumulate, let result)) - return result; - - Runtime.FatalError("No elements in the sequence."); - } - - public static TSource - Aggregate(this TEnum items, TAccumulate accumulate) - where TEnum : concrete, IEnumerator - where TAccumulate : delegate TSource(TSource, TSource) - { - if (InternalAggregate(items, accumulate, let result)) - return result; - - Runtime.FatalError("No elements in the sequence."); - } - - public static TAccumulate - Aggregate(this TCollection items, TAccumulate seed, TAccDlg accumulate) - where TCollection : concrete, IEnumerable - where TAccDlg : delegate TAccumulate(TAccumulate, TSource) - { - if (InternalAggregate(items.GetEnumerator(), seed, accumulate, let result)) - return result; - - return seed; - } - - public static TAccumulate - Aggregate(this TEnum items, TAccumulate seed, TAccDlg accumulate) - where TEnum : concrete, IEnumerator - where TAccDlg : delegate TAccumulate(TAccumulate, TSource) - { - if (InternalAggregate(items, seed, accumulate, let result)) - return result; - - return seed; - } - - public static TResult - Aggregate(this TCollection items, TAccDlg accumulate, TResDlg resultSelector) - where TCollection : concrete, IEnumerable - where TAccDlg : delegate TSource(TSource, TSource) - where TResDlg : delegate TResult(TSource) - { - if (InternalAggregate(items.GetEnumerator(), accumulate, let result)) - return resultSelector(result); - - return resultSelector(default); - } - - public static TResult - Aggregate(this TEnum items, TAccDlg accumulate, TResDlg resultSelector) - where TEnum : concrete, IEnumerator - where TAccDlg : delegate TSource(TSource, TSource) - where TResDlg : delegate TResult(TSource) - { - if (InternalAggregate(items, accumulate, let result)) - return resultSelector(result); - - return resultSelector(default); - } - - public static TResult - Aggregate(this TCollection items, TAccumulate seed, TAccDlg accumulate, TResDlg resultSelector) - where TCollection : concrete, IEnumerable - where TAccDlg : delegate TAccumulate(TAccumulate, TSource) - where TResDlg : delegate TResult(TAccumulate) - { - if (InternalAggregate(items.GetEnumerator(), seed, accumulate, let result)) - return resultSelector(result); - - return resultSelector(seed); - } - - public static TResult - Aggregate(this TEnum items, TAccumulate seed, TAccDlg accumulate, TResDlg resultSelector) - where TEnum : concrete, IEnumerator - where TAccDlg : delegate TAccumulate(TAccumulate, TSource) - where TResDlg : delegate TResult(TAccumulate) - { - if (InternalAggregate(items, seed, accumulate, let result)) - return resultSelector(result); - - return resultSelector(seed); - } - - static bool InternalAggregate(TEnum items, TAccDlg accumulate, out TSource aggregate) - where TEnum : concrete, IEnumerator - where TAccDlg : delegate TSource(TSource, TSource) - { - aggregate = default; - using (var iterator = Iterator.Wrap(items)) - { - var enumerator = iterator.mEnum; - - //I guess we need at least 2 elements to do an accumulation without a seed? - if (!(enumerator.GetNext() case .Ok(out aggregate))) - return false; - - while (enumerator.GetNext() case .Ok(let val)) - aggregate = accumulate(aggregate, val); - } - return true; - } - - - static bool InternalAggregate(TEnum items, TAccumulate seed, TAccDlg func, out TAccumulate result) - where TEnum : concrete, IEnumerator - where TAccDlg : delegate TAccumulate(TAccumulate, TSource) - { - TAccumulate sum = seed; - var accumulated = false; - using (var iterator = Iterator.Wrap(items)) - { - var enumerator = iterator.mEnum; - - if (enumerator.GetNext() case .Ok(let val)) - { - sum = func(sum, val); - accumulated = true; - } - - if (accumulated) - while (enumerator.GetNext() case .Ok(let val)) - sum = func(sum, val); - } - - result = sum; - return accumulated; - } - #endregion - -#region GroupBy - - struct DynamicArray : IDisposable - { - TValue[] mPtr = default; - Span mSpan = default; - int mLength = 0; - int mSize = 4; - int mIndex = 0; - - public int Length => mLength; - - public this() - { - this.mPtr = new TValue[mSize]; - this.mLength = 0; - } - - public ref TValue this[int index] => ref mPtr[index]; - - public void Dispose() mut - { - DeleteAndNullify!(mPtr); - mPtr = null; - } - public void Add(TValue value) mut - { - if (mLength + 1 > mSize) - { - var newSize = mSize * 3 / 2; - var dst = new TValue[newSize]; - Array.Copy(mPtr, dst, mLength); - Swap!(mPtr, dst); - delete dst; - mSize = newSize; - } - mPtr[mLength++] = value; - } - - public Span.Enumerator GetEnumerator() mut - { - mSpan = .(mPtr, 0, mLength); - return mSpan.GetEnumerator(); - } - - public static implicit operator Span(Self it) => .(it.mPtr, 0, it.mLength); - } - - public extension DynamicArray : IDisposable - where TValue : IDisposable - { - public void Dispose() mut - { - for (var it in mPtr) - it.Dispose(); - - base.Dispose(); - } - } - - public struct Grouping : IEnumerable, IDisposable, IResettable - { - List mValues; - int mIndex = 0; - public readonly TKey Key; - - public this(TKey key) - { - Key = key; - mValues = new .(); - } - - public void Reset() mut - { - mIndex = 0; - } - - public List.Enumerator GetEnumerator() - { - return mValues.GetEnumerator(); - } - - public void Add(TValue value) mut - { - mValues.Add(value); - } - - public void Dispose() mut - { - DeleteAndNullify!(mValues); - } - } - - public class GroupByResult : IEnumerable> - where bool : operator TKey == TKey//where TKey : IHashable - { - DynamicArray> mResults = .() ~ mResults.Dispose(); - - public int Count => mResults.Length; - - public void Add(Grouping group) - { - mResults.Add(group); - } - - public ref Grouping this[int index] => ref mResults[index]; - - public Enumerator GetEnumerator() => .(this); - - public struct Enumerator : IRefEnumerator*>, IEnumerator>, IResettable - { - SelfOuter mSelf; - Span> mSpan; - int mIndex = 0; - - public this(SelfOuter self) - { - mSelf = self; - mSpan = self.mResults; - } - - public Result> GetNext() mut - { - if (mIndex < mSpan.Length) - return .Ok(mSpan[mIndex++]); - - return .Err; - } - - public Result*> GetNextRef() mut - { - if (mIndex < mSpan.Length) - return .Ok(&mSpan[mIndex++]); - - return .Err; - } - - public void Reset() mut - { - mIndex = 0; - } - } - } - - public struct GroupByEnumerable : IEnumerable>, IDisposable - where TEnum : concrete, IEnumerator - where bool : operator TKey == TKey//where TKey : IHashable - where TKeyDlg : delegate TKey(TSource) - where TValueDlg : delegate TValue(TSource) - { - GroupByResult mResults; - TKeyDlg mKeyDlg; - TValueDlg mValueDlg; - Iterator mIterator; - int mIndex = -1; - bool mDeleteResult; - - public this(GroupByResult results, TEnum enumerator, TKeyDlg keyDlg, TValueDlg valueDlg, bool deleteResult) - { - mResults = results; - mIterator = .(enumerator); - mKeyDlg = keyDlg; - mValueDlg = valueDlg; - mDeleteResult = deleteResult; - } - - Result> GetNext() mut - { - if (mIndex == -1) - { - while (mIterator.mEnum.GetNext() case .Ok(let val)) - { - let k = mKeyDlg(val); - let v = mValueDlg(val); - var added = false; - for (var it in ref mResults) - { - if (it.Key == k) - { - it.Add(v); - added = true; - } - } - - if (!added) - { - var group = mResults.Add(.. .(k)); - group.Add(v); - } - } - mIndex = 0; - } - - if (mIndex < mResults.Count) - return mResults[mIndex++]; - - return .Err; - } - - public void Dispose() mut - { - mIterator.Dispose(); - if (mDeleteResult) - DeleteAndNullify!(mResults); - } - - public Enumerator GetEnumerator() => .(this); - - public struct Enumerator : IEnumerator>, IDisposable - { - SelfOuter mSelf; - - public this(SelfOuter self) - { - mSelf = self; - } - - public Result> GetNext() mut => mSelf.GetNext(); - - public void Dispose() mut => mSelf.Dispose(); - } - } - - extension GroupByEnumerable - where TValueDlg : Object - { - public void Dispose() mut - { - base.Dispose(); - DeleteAndNullify!(mValueDlg); - } - } - - public static GroupByEnumerable - GroupBy(this TCollection items, TKeyDlg key) - where TCollection : concrete, IEnumerable - where TKeyDlg : delegate TKey(TSource) - where TKey : IHashable - { - //guess we could optimize out this scope with some code duplication - return .(new .(), items.GetEnumerator(), key, new (val) => val, true); - } - - public static GroupByEnumerable - GroupBy(this TEnum items, TKeyDlg key) - where TEnum : concrete, IEnumerator - where TKeyDlg : delegate TKey(TSource) - where TKey : IHashable - { - //guess we could optimize out this scope with some code duplication - return .(new .(), items, key, new (val) => val, true); - } - - public static GroupByEnumerable - GroupBy(this TCollection items, TKeyDlg key, GroupByResult results) - where TCollection : concrete, IEnumerable - where TKeyDlg : delegate TKey(TSource) - where TKey : IHashable - { - //guess we could optimize out this scope with some code duplication - return .(results, items.GetEnumerator(), key, new (val) => val, false); - } - - public static GroupByEnumerable - GroupBy(this TEnum items, TKeyDlg key, GroupByResult results) - where TEnum : concrete, IEnumerator - where TKeyDlg : delegate TKey(TSource) - where TKey : IHashable - { - //guess we could optimize out this scope with some code duplication - return .(results, items, key, new (val) => val, false); - } - - /*public static GroupByEnumerable GroupBy(this TCollection items, TKeyDlg - key, GroupByResult results) where TCollection : concrete, IEnumerable where TKeyDlg : - delegate TKey(TSource) where TKey : IHashable - { - //guess we could optimize out this scope with some code duplication - return .(results, items.GetEnumerator(), key, scope (val) => val); - }*/ -#endregion - struct UnionEnumerable : IEnumerable, IDisposable - where TEnum : concrete, IEnumerator - where TEnum2 : concrete, IEnumerator - where TSource : IHashable - { - HashSet mDistinctValues; - Iterator mSource; - Iterator mOther; - int mState = 0; - - public this(TEnum sourceEnumerator, TEnum2 otherEnumerator) - { - mSource = sourceEnumerator; - mOther = otherEnumerator; - - mDistinctValues = new .(); - } - - Result GetNext() mut - { - switch (mState) { - case 0: - var e = mSource.mEnum; - while (e.GetNext() case .Ok(let val)) - if (mDistinctValues.Add(val)) - return .Ok(val); - - mState++; - fallthrough; - case 1: - var e = mOther.mEnum; - while (e.GetNext() case .Ok(let val)) - if (mDistinctValues.Add(val)) - return .Ok(val); - - mState++; - } - - return .Err; - } - - public Enumerator GetEnumerator() => .(this); - - public struct Enumerator : IEnumerator, IDisposable - { - SelfOuter mSelf; - - public this(SelfOuter self) - { - mSelf = self; - } - - public Result GetNext() mut => mSelf.GetNext(); - - public void Dispose() mut => mSelf.Dispose(); - } - - public void Dispose() mut - { - mSource.Dispose(); - mOther.Dispose(); - DeleteAndNullify!(mDistinctValues); - } - } - - public static UnionEnumerable - Union(this TCollection items, TCollection2 other) - where TCollection : concrete, IEnumerable - where TCollection2 : concrete, IEnumerable - where TSource : IHashable - { - return .(items.GetEnumerator(), other.GetEnumerator()); - } - - public static UnionEnumerable - Union(this TEnum items, TCollection2 other) - where TEnum : concrete, IEnumerator - where TCollection2 : concrete, IEnumerable - where TSource : IHashable - { - return .(items, other.GetEnumerator()); - } - - public static UnionEnumerable - Union(this TCollection items, TEnum other) - where TCollection : concrete, IEnumerable - where TEnum : concrete, IEnumerator - where TSource : IHashable - { - return .(items.GetEnumerator(), other); - } - - public static UnionEnumerable - Union(this TEnum items, TEnum2 other) - where TEnum : concrete, IEnumerator - where TEnum2 : concrete, IEnumerator - where TSource : IHashable - { - return .(items, other); - } - - struct ExceptEnumerable : IEnumerable, IDisposable - where TEnum : concrete, IEnumerator - where TEnum2 : concrete, IEnumerator - where TSource : IHashable - { - HashSet mDistinctValues; - Iterator mSource; - Iterator mOther; - int mState = 0; - - public this(TEnum sourceEnumerator, TEnum2 otherEnumerator) - { - mSource = sourceEnumerator; - mOther = otherEnumerator; - - mDistinctValues = new .(); - } - - Result GetNext() mut - { - switch (mState) { - case 0: - var e = mOther.mEnum; - while (e.GetNext() case .Ok(let val)) - mDistinctValues.Add(val); - - mState++; - fallthrough; - case 1: - var e = mSource.mEnum; - while (e.GetNext() case .Ok(let val)) - if (mDistinctValues.Add(val)) - return .Ok(val); - - mState++; - } - - return .Err; - } - - public Enumerator GetEnumerator() => .(this); - - public struct Enumerator : IEnumerator, IDisposable - { - SelfOuter mSelf; - - public this(SelfOuter self) - { - mSelf = self; - } - - public Result GetNext() mut => mSelf.GetNext(); - - public void Dispose() mut => mSelf.Dispose(); - } - - public void Dispose() mut - { - mSource.Dispose(); - mOther.Dispose(); - DeleteAndNullify!(mDistinctValues); - } - } - - public static ExceptEnumerable - Except(this TCollection items, TCollection2 other) - where TCollection : concrete, IEnumerable - where TCollection2 : concrete, IEnumerable - where TSource : IHashable - { - return .(items.GetEnumerator(), other.GetEnumerator()); - } - - public static ExceptEnumerable - Except(this TEnum items, TCollection2 other) - where TEnum : concrete, IEnumerator - where TCollection2 : concrete, IEnumerable - where TSource : IHashable - { - return .(items, other.GetEnumerator()); - } - - public static ExceptEnumerable - Except(this TCollection items, TEnum other) - where TCollection : concrete, IEnumerable - where TEnum : concrete, IEnumerator - where TSource : IHashable - { - return .(items.GetEnumerator(), other); - } - - public static ExceptEnumerable - Except(this TEnum items, TEnum2 other) - where TEnum : concrete, IEnumerator - where TEnum2 : concrete, IEnumerator - where TSource : IHashable - { - return .(items, other); - } - - struct IntersectEnumerable : IEnumerable, IDisposable - where TEnum : concrete, IEnumerator - where TEnum2 : concrete, IEnumerator - where TSource : IHashable - { - HashSet mDistinctValues; - Iterator mSource; - Iterator mIntersect; - int mState = 0; - - public this(TEnum sourceEnumerator, TEnum2 intersectEnumerator) - { - mSource = .(sourceEnumerator); - mIntersect = .(intersectEnumerator); - mDistinctValues = new .(); - } - - Result GetNext() mut - { - switch (mState) - { - case 0: - var e = mSource.mEnum; - while (e.GetNext() case .Ok(let val)) - mDistinctValues.Add(val); - - mState++; - fallthrough; - case 1: - var e = mIntersect.mEnum; - while (e.GetNext() case .Ok(let val)) - if (mDistinctValues.Remove(val)) - return .Ok(val); - - mState++; - } - - return .Err; - } - - public Enumerator GetEnumerator() => .(this); - - public struct Enumerator : IEnumerator, IDisposable - { - SelfOuter mSelf; - - public this(SelfOuter self) - { - mSelf = self; - } - - public Result GetNext() mut => mSelf.GetNext(); - - public void Dispose() mut => mSelf.Dispose(); - } - - public void Dispose() mut - { - mSource.Dispose(); - mIntersect.Dispose(); - DeleteAndNullify!(mDistinctValues); - } - } - - public static IntersectEnumerable - Intersect(this TCollection items, TCollection2 other) - where TCollection : concrete, IEnumerable - where TCollection2 : concrete, IEnumerable - where TSource : IHashable - { - return .(items.GetEnumerator(), other.GetEnumerator()); - } - - public static IntersectEnumerable - Intersect(this TEnum items, TCollection2 other) - where TEnum : concrete, IEnumerator - where TCollection2 : concrete, IEnumerable - where TSource : IHashable - { - return .(items, other.GetEnumerator()); - } - - public static IntersectEnumerable - Intersect(this TCollection items, TEnum other) - where TCollection : concrete, IEnumerable - where TEnum : concrete, IEnumerator - where TSource : IHashable - { - return .(items.GetEnumerator(), other); - } - - public static IntersectEnumerable - Intersect(this TEnum items, TEnum2 other) - where TEnum : concrete, IEnumerator - where TEnum2 : concrete, IEnumerator - where TSource : IHashable - { - return .(items, other); - } - - struct ZipEnumerable : IEnumerable, IDisposable - where TEnum : concrete, IEnumerator - where TEnum2 : concrete, IEnumerator - where TSelect : delegate TResult(TSource first, TSource second) - { - Iterator mSource; - Iterator mOther; - TSelect mSelect; - - public this(TEnum sourceEnumerator, TEnum2 otherEnumerator, TSelect select) - { - mSource = sourceEnumerator; - mOther = otherEnumerator; - mSelect = select; - } - - Result GetNext() mut - { - if (mSource.mEnum.GetNext() case .Ok(let first)) - if (mOther.mEnum.GetNext() case .Ok(let second)) - return mSelect(first, second); - - return .Err; - } - - public Enumerator GetEnumerator() => .(this); - - public struct Enumerator : IEnumerator, IDisposable - { - SelfOuter mSelf; - - public this(SelfOuter self) - { - mSelf = self; - } - - public Result GetNext() mut => mSelf.GetNext(); - - public void Dispose() mut => mSelf.Dispose(); - } - - - public void Dispose() mut - { - mSource.Dispose(); - mOther.Dispose(); - } - } - - public static ZipEnumerable - Zip(this TCollection items, TCollection2 other, TSelect select) - where TCollection : concrete, IEnumerable - where TCollection2 : concrete, IEnumerable - where TSelect : delegate TResult(TSource first, TSource second) - { - return .(items.GetEnumerator(), other.GetEnumerator(), select); - } - - public static ZipEnumerable - Zip(this TEnum items, TCollection2 other, TSelect select) - where TEnum : concrete, IEnumerator - where TCollection2 : concrete, IEnumerable - where TSelect : delegate TResult(TSource first, TSource second) - { - return .(items, other.GetEnumerator(), select); - } - - public static ZipEnumerable - Zip(this TCollection items, TEnum other, TSelect select) - where TCollection : concrete, IEnumerable - where TEnum : concrete, IEnumerator - where TSelect : delegate TResult(TSource first, TSource second) - { - return .(items.GetEnumerator(), other, select); - } - - public static ZipEnumerable - Zip(this TEnum items, TEnum2 other, TSelect select) - where TEnum : concrete, IEnumerator - where TEnum2 : concrete, IEnumerator - where TSelect : delegate TResult(TSource first, TSource second) - { - return .(items, other, select); - } - - struct ConcatEnumerable : IEnumerable, IDisposable - where TEnum : concrete, IEnumerator - where TEnum2 : concrete, IEnumerator - { - Iterator mFirst; - Iterator mSecond; - int mState = 0; - - public this(TEnum firstEnumerator, TEnum2 secondEnumerator) - { - mFirst = firstEnumerator; - mSecond = secondEnumerator; - } - - Result GetNext() mut - { - switch (mState) { - case 0: - if (mFirst.mEnum.GetNext() case .Ok(let val)) - return .Ok(val); - - mState++; - fallthrough; - case 1: - if (mSecond.mEnum.GetNext() case .Ok(let val)) - return .Ok(val); - - mState++; - } - - return .Err; - } - - public Enumerator GetEnumerator() => .(this); - - public struct Enumerator : IEnumerator, IDisposable - { - SelfOuter mSelf; - - public this(SelfOuter self) - { - mSelf = self; - } - - public Result GetNext() mut => mSelf.GetNext(); - - public void Dispose() mut => mSelf.Dispose(); - } - - public void Dispose() mut - { - mFirst.Dispose(); - mSecond.Dispose(); - } - } - - - - public static ConcatEnumerable - Concat(this TCollection items, TCollection2 other) - where TCollection : concrete, IEnumerable - where TCollection2 : concrete, IEnumerable - { - return .(items.GetEnumerator(), other.GetEnumerator()); - } - - public static ConcatEnumerable - Concat(this TEnum items, TCollection2 other) - where TEnum : concrete, IEnumerator - where TCollection2 : concrete, IEnumerable - { - return .(items, other.GetEnumerator()); - } - - public static ConcatEnumerable - Concat(this TCollection items, TEnum other) - where TCollection : concrete, IEnumerable - where TEnum : concrete, IEnumerator - { - return .(items.GetEnumerator(), other); - } - - public static ConcatEnumerable - Concat(this TEnum items, TEnum2 other) - where TEnum : concrete, IEnumerator - where TEnum2 : concrete, IEnumerator - { - return .(items, other); - } - - public static ConcatEnumerable - Append(this TCollection items, TCollection2 other) - where TCollection : concrete, IEnumerable - where TCollection2 : concrete, IEnumerable - { - return .(items.GetEnumerator(), other.GetEnumerator()); - } - - public static ConcatEnumerable - Append(this TEnum items, TCollection2 other) - where TEnum : concrete, IEnumerator - where TCollection2 : concrete, IEnumerable - { - return .(items, other.GetEnumerator()); - } - - public static ConcatEnumerable - Append(this TCollection items, TEnum other) - where TCollection : concrete, IEnumerable - where TEnum : concrete, IEnumerator - { - return .(items.GetEnumerator(), other); - } - - public static ConcatEnumerable - Append(this TEnum items, TEnum2 other) - where TEnum : concrete, IEnumerator - where TEnum2 : concrete, IEnumerator - { - return .(items, other); - } - - public static ConcatEnumerable - Prepend(this TCollection items, TCollection2 other) - where TCollection : concrete, IEnumerable - where TCollection2 : concrete, IEnumerable - { - return .(other.GetEnumerator(), items.GetEnumerator()); - } - - public static ConcatEnumerable - Prepend(this TEnum items, TCollection2 other) - where TEnum : concrete, IEnumerator - where TCollection2 : concrete, IEnumerable - { - return .(other.GetEnumerator(), items); - } - - public static ConcatEnumerable - Prepend(this TCollection items, TEnum other) - where TCollection : concrete, IEnumerable - where TEnum : concrete, IEnumerator - { - return .(other, items.GetEnumerator()); - } - - public static ConcatEnumerable - Prepend(this TEnum items, TEnum2 other) - where TEnum : concrete, IEnumerator - where TEnum2 : concrete, IEnumerator - { - return .(other, items); - } - - - - static class OrderByComparison - where int : operator T <=> T - { - typealias TCompare = delegate int(T lhs, T rhs); - public readonly static TCompare Comparison = (new (lhs, rhs) => lhs <=> rhs) ~ delete _; - } - - struct SortedEnumerable : IEnumerator<(TKey key, TSource value)>, IDisposable - where TEnum : concrete, IEnumerator - where TKeyDlg : delegate TKey(TSource) - where TCompare : delegate int(TKey lhs, TKey rhs) - { - List<(TKey key, TSource value)> mOrderedList; - Iterator mIterator; - TKeyDlg mKey; - TCompare mCompare; - int mIndex; - int mCount = 0; - bool mDescending; - - public this(TEnum firstEnumerator, TKeyDlg key, TCompare compare, bool descending) - { - mOrderedList = new .(); - mKey = key; - mIterator = firstEnumerator; - mCompare = compare; - mIndex = -1; - mDescending = descending; - } - - public Result<(TKey key, TSource value)> GetNext() mut - { - if (mIndex == -1) - { - while (mIterator.mEnum.GetNext() case .Ok(let val)) - mOrderedList.Add((mKey(val), val)); - - mOrderedList.Sort(scope (l, r) => mCompare(l.key, r.key)); - mCount = mOrderedList.Count;//keeping vars local - mIndex = mDescending ? mCount : 0; - } - - if (mDescending) - { - if (mIndex > 0) - return .Ok(mOrderedList[--mIndex]); - } - else if (mIndex < mCount) - return .Ok(mOrderedList[mIndex++]); - - return .Err; - } - - - public Enumerator GetEnumerator() => .(this); - public struct Enumerator : IEnumerator<(TKey key, TSource value)>, IDisposable - { - SelfOuter mSelf; - - public this(SelfOuter self) - { - mSelf = self; - } - - public Result<(TKey key, TSource value)> GetNext() mut => mSelf.GetNext(); - - public void Dispose() mut => mSelf.Dispose(); - } - - - public void Dispose() mut - { - mIterator.Dispose(); - DeleteAndNullify!(mOrderedList); - } - } - - //if the data is a large struct, this could get pretty slow with all the copies - //we may need to investigate the ability to use ptrs instead if the type is a struct? - struct OrderByEnumerable : IEnumerable, IDisposable - where TEnum : concrete, IEnumerator - { - typealias TCompare = delegate int(TSource lhs, TSource rhs); - - struct Comparer - { - public TCompare comparer; - public bool descending; - } - - DynamicArray mValues; - int[] mMap; - //List mOrderedList; - List mCompares = default; - Iterator mIterator; - int mIndex; - - public this(TEnum enumerator, TCompare compare, bool descending) - { - mCompares = new .(); - var add = mCompares.GrowUnitialized(1); - add.comparer = compare; - add.descending = descending; - - mValues = ?; - mMap = null; - mIterator = enumerator; - mIndex = -1; - } - - void QuickSort(int left, int right) { - var left; - var right; -#unwarn - repeat { - int i = left; - int j = right; - int x = mMap[i + ((j - i) >> 1)]; - repeat { - while (i < mMap.Count && CompareKeys(x, mMap[i]) > 0) i++; - while (j >= 0 && CompareKeys(x, mMap[j]) < 0) j--; - if (i > j) break; - if (i < j) { - int temp = mMap[i]; - mMap[i] = mMap[j]; - mMap[j] = temp; - } - i++; - j--; - } while (i <= j); - if (j - left <= right - i) { - if (left < j) QuickSort(left, j); - left = i; - } - else { - if (i < right) QuickSort(i, right); - right = j; - } - } while (left < right); - } - - [Inline] - int CompareKeys(int index1, int index2) - { - for(var cmp in ref mCompares) - { - int c = cmp.comparer(mValues[index1], mValues[index2]); - if (c != 0) - return cmp.descending ? -c : c; - } - - return index1 - index2; - } - - Result GetNext() mut - { - if (mIndex == -1) - { - mIndex = 0; - mValues = .(); - while (mIterator.mEnum.GetNext() case .Ok(let val)) - mValues.Add(val); - - let count = mValues.Length; - mMap = new int[count]; - for (int i = 0; i < count; i++) mMap[i] = i; - QuickSort( 0, count - 1); - } - - if (mIndex < mValues.Length) - return .Ok(mValues[mMap[mIndex++]]); - - return .Err; - } - - public Enumerator GetEnumerator() => .(this); - - public struct Enumerator : IEnumerator, IDisposable - { - SelfOuter mSelf; - - public this(SelfOuter self) - { - mSelf = self; - } - - public Result GetNext() mut => mSelf.GetNext(); - - public void Dispose() mut => mSelf.Dispose(); - } - - public void Dispose() mut - { - mIterator.Dispose(); - - for(var it in mCompares) - delete it.comparer; - DeleteAndNullify!(mCompares); - DeleteAndNullify!(mMap); - mValues.Dispose(); - } - - public Self ThenBy(TKeyDlg2 keySelect, TCompare2 comparison) mut - where TKeyDlg2 : delegate TKey2(TSource) - where TCompare2 : delegate int(TKey2 lhs, TKey2 rhs) - { - var add = mCompares.GrowUnitialized(1); - add.comparer = new (l, r) => comparison(keySelect(l), keySelect(r)); - add.descending = false; - return this; - } - - public Self ThenBy(TKeyDlg2 keySelect) - where TKeyDlg2 : delegate TKey2(TSource) - where int : operator TKey2 <=> TKey2 - { - let comparison = OrderByComparison.Comparison; - var add = mCompares.GrowUnitialized(1); - add.comparer = new (l, r) => comparison(keySelect(l), keySelect(r)); - add.descending = false; - return this; - } - - - public Self ThenByDescending(TKeyDlg2 keySelect, TCompare2 comparison) mut - where TKeyDlg2 : delegate TKey2(TSource) - where TCompare2 : delegate int(TKey2 lhs, TKey2 rhs) - { - var add = mCompares.GrowUnitialized(1); - add.comparer = new (l, r) => comparison(keySelect(l), keySelect(r)); - add.descending = true; - return this; - } - - public Self ThenByDescending(TKeyDlg2 keySelect) - where TKeyDlg2 : delegate TKey2(TSource) - where int : operator TKey2 <=> TKey2 - { - let comparison = OrderByComparison.Comparison; - var add = mCompares.GrowUnitialized(1); - add.comparer = new (l, r) => comparison(keySelect(l), keySelect(r)); - add.descending = true; - return this; - } - } - - public static OrderByEnumerable - OrderBy(this TCollection items, TKeyDlg keySelect) - where TCollection : concrete, IEnumerable - where TKeyDlg : delegate TKey(TSource) - where int : operator TKey <=> TKey - { - let comparison = OrderByComparison.Comparison; - return .(items.GetEnumerator(), new (l, r) => comparison(keySelect(l), keySelect(r)), false); - } - - public static OrderByEnumerable - OrderBy(this TEnum items, TKeyDlg keySelect) - where TEnum : concrete, IEnumerator - where TKeyDlg : delegate TKey(TSource) - where int : operator TKey <=> TKey - { - let comparison = OrderByComparison.Comparison; - return .(items, new (l, r) => comparison(keySelect(l), keySelect(r)), false); - } - - public static OrderByEnumerable - OrderBy(this TCollection items, TKeyDlg keySelect, TCompare comparison) - where TCollection : concrete, IEnumerable - where TKeyDlg : delegate TKey(TSource) - where TCompare : delegate int(TKey lhs, TKey rhs) - { - return .(items.GetEnumerator(), new (l, r) => comparison(keySelect(l), keySelect(r)), false); - } - - public static OrderByEnumerable - OrderBy(this TEnum items, TKeyDlg keySelect, TCompare comparison) - where TEnum : concrete, IEnumerator - where TKeyDlg : delegate TKey(TSource) - where TCompare : delegate int(TKey lhs, TKey rhs) - { - return .(items, new (l, r) => comparison(keySelect(l), keySelect(r)), false); - } - - public static OrderByEnumerable - OrderByDescending(this TCollection items, TKeyDlg keySelect) - where TCollection : concrete, IEnumerable - where TKeyDlg : delegate TKey(TSource) - where int : operator TKey <=> TKey - { - let comparison = OrderByComparison.Comparison; - return .(items.GetEnumerator(), new (l, r) => comparison(keySelect(l), keySelect(r)), true); - } - - public static OrderByEnumerable - OrderByDescending(this TEnum items, TKeyDlg keySelect) - where TEnum : concrete, IEnumerator - where TKeyDlg : delegate TKey(TSource) - where int : operator TKey <=> TKey - { - let comparison = OrderByComparison.Comparison; - return .(items, new (l, r) => comparison(keySelect(l), keySelect(r)), true); - } - - public static OrderByEnumerable - OrderByDescending(this TCollection items, TKeyDlg keySelect, TCompare comparison) - where TCollection : concrete, IEnumerable - where TKeyDlg : delegate TKey(TSource) - where TCompare : delegate int(TKey lhs, TKey rhs) - { - return .(items.GetEnumerator(),new (l, r) => comparison(keySelect(l), keySelect(r)), true); - } - - public static OrderByEnumerable - OrderByDescending(this TEnum items, TKeyDlg keySelect, TCompare comparison) - where TEnum : concrete, IEnumerator - where TKeyDlg : delegate TKey(TSource) - where TCompare : delegate int(TKey lhs, TKey rhs) - { - return .(items, new (l, r) => comparison(keySelect(l), keySelect(r)), true); - } - - struct SelectManyEnumerable : IEnumerable, IDisposable - where TEnum : concrete, IEnumerator - where TEnum2 : concrete, IEnumerator - where TSelect : delegate TEnum2(TSource) - { - public readonly static String SelectManyEnum = new String() ~ delete _; - - Iterator mItems; - Iterator mCurrent = default; - TSelect mSelect; - int mState = -1; - - public this(TEnum firstEnumerator, TSelect select) - { - mItems = firstEnumerator; - mSelect = select; - } - - Result GetNext(out bool moveNext) mut - { - if (mState < 1) - { - if (mState == 0) - mCurrent.Dispose(); - - if (mItems.mEnum.GetNext() case .Ok(var val)) - { - mCurrent = mSelect(val); - mState = 1; - } - else - { - //no more elements - moveNext = false; - return .Err; - } - } - - if (mCurrent.mEnum.GetNext() case .Ok(let val)) - { - moveNext = false; - return .Ok(val); - } - - //done with current enumerator - mState = 0; - moveNext = true; - return .Err; - } - - Result GetNext() mut - { - var moveNext = true; - while (moveNext) - { - let result = GetNext(out moveNext); - if (!moveNext) - return result; - } - - return .Err; - } - - public Enumerator GetEnumerator() => .(this); - - public struct Enumerator : IEnumerator, IDisposable - { - SelfOuter mSelf; - - public this(SelfOuter self) - { - mSelf = self; - } - - public Result GetNext() mut => mSelf.GetNext(); - - public void Dispose() mut => mSelf.Dispose(); - } - - public void Dispose() mut - { - mItems.Dispose(); - } - } - extension SelectManyEnumerable - where TSelect : Object - { - public void Dispose() mut - { - base.Dispose(); - DeleteAndNullify!(mSelect); - } - } - - public static SelectManyEnumerable - SelectMany(this TCollection items, TSelect select) - where TCollection : concrete, IEnumerable - where TCollection2 : concrete, IEnumerable - where TSelect : delegate TCollection2(TSource) - { - return .(items.GetEnumerator(), new (x) => select(x).GetEnumerator()); - } - - public static SelectManyEnumerable - SelectMany(this TCollection items, TSelect select) - where TCollection : concrete, IEnumerable - where TEnum2 : concrete, IEnumerator - where TSelect : delegate TEnum2(TSource) - { - return .(items.GetEnumerator(), select); - } - - /*struct OfTypeEnumerable : Iterator, IEnumerator, IEnumerable - where TEnum : concrete, IEnumerator - where TSource : class - { - public this(TEnum enumerator) : base(enumerator) - { - } - - public Result GetNext() mut - { - while (mEnum.GetNext() case .Ok(let val)) - { - if (val is TOf) - return .Ok(*(TOf*)Internal.UnsafeCastToPtr(val)); - } - return .Err; - } - - public Self GetEnumerator() - { - return this; - } - } - - public static OfTypeEnumerable - OfType(this TCollection items) - where TCollection : concrete, IEnumerable - where TSource : class - { - return .(items.GetEnumerator()); - }*/ - - - } -} diff --git a/GlitchyEngine/vendor/Beef.Linq b/GlitchyEngine/vendor/Beef.Linq new file mode 160000 index 0000000..4e4ed61 --- /dev/null +++ b/GlitchyEngine/vendor/Beef.Linq @@ -0,0 +1 @@ +Subproject commit 4e4ed6158b7602928cfc7ba391bd097b19ef2892