From d6a4986674cbf184fea8901c660048bd5065906f Mon Sep 17 00:00:00 2001 From: Andrei Sergeev Date: Tue, 24 Dec 2024 23:20:54 +0400 Subject: [PATCH] OptionalLinq: Refactor inner implementation --- .../ElementAtOrAbsent.cs | 4 +- .../OptionalLinqExtensions/FirstOrAbsent.cs | 4 +- .../GetValueOrAbsent.cs | 10 +-- ...actories.cs => InnerExceptionFactories.cs} | 0 .../InnerElementAtOrAbsent.cs | 49 +++++++++++++++ .../InnerElementAtOrAbsent_IEnumerable.cs | 39 ++++++++++++ ...erElementAtOrAbsent_IEnumerable_FromEnd.cs | 46 ++++++++++++++ .../InnerElementAtOrAbsent_IList.cs | 17 +++++ .../InnerElementAtOrAbsent_IReadOnlyList.cs | 17 +++++ .../InnerFirstOrAbsent.cs | 47 ++++++++++++++ .../InnerFirstOrAbsent_IEnumerable.cs | 37 +++++++++++ .../InnerFirstOrAbsent_IList.cs | 34 ++++++++++ .../InnerFirstOrAbsent_IReadOnlyList.cs | 34 ++++++++++ .../InnerLastOrAbsent.cs | 47 ++++++++++++++ .../InnerLastOrAbsent_IEnumerable.cs | 62 +++++++++++++++++++ .../InnerLastOrAbsent_IList.cs | 34 ++++++++++ .../InnerLastOrAbsent_IReadOnlyList.cs | 34 ++++++++++ .../InnerSingleOrAbsent.cs | 49 +++++++++++++++ .../InnerSingleOrAbsent_IEnumerable.cs | 61 ++++++++++++++++++ .../InnerSingleOrAbsent_IList.cs | 51 +++++++++++++++ .../InnerSingleOrAbsent_IReadOnlyList.cs | 51 +++++++++++++++ .../InnerValueOrAbsent.cs | 33 ++++++++++ .../Inner/InnerElementAtOrAbsent.cs | 43 ------------- .../InnerElementAtOrAbsent_IEnumerable.cs | 34 ---------- ...erElementAtOrAbsent_IEnumerable_FromEnd.cs | 41 ------------ .../Inner/InnerElementAtOrAbsent_IList.cs | 12 ---- .../InnerElementAtOrAbsent_IReadOnlyList.cs | 12 ---- .../Inner/InnerFirstOrAbsent.cs | 41 ------------ .../Inner/InnerFirstOrAbsent_IEnumerable.cs | 31 ---------- .../Inner/InnerFirstOrAbsent_IList.cs | 28 --------- .../Inner/InnerFirstOrAbsent_IReadOnlyList.cs | 28 --------- .../Inner/InnerGetValueOrAbsent.cs | 27 -------- .../Inner/InnerLastOrAbsent.cs | 41 ------------ .../Inner/InnerLastOrAbsent_IEnumerable.cs | 56 ----------------- .../Inner/InnerLastOrAbsent_IList.cs | 28 --------- .../Inner/InnerLastOrAbsent_IReadOnlyList.cs | 28 --------- .../Inner/InnerSingleOrAbsent.cs | 43 ------------- .../Inner/InnerSingleOrAbsent_IEnumerable.cs | 55 ---------------- .../Inner/InnerSingleOrAbsent_IList.cs | 45 -------------- .../InnerSingleOrAbsent_IReadOnlyList.cs | 45 -------------- .../OptionalLinqExtensions/LastOrAbsent.cs | 4 +- .../OptionalLinqExtensions/SingleOrAbsent.cs | 8 +-- 42 files changed, 757 insertions(+), 653 deletions(-) rename src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.ExceptionFactories/{Inner.ExceptionFactories.cs => InnerExceptionFactories.cs} (100%) create mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerElementAtOrAbsent.cs create mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerElementAtOrAbsent_IEnumerable.cs create mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerElementAtOrAbsent_IEnumerable_FromEnd.cs create mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerElementAtOrAbsent_IList.cs create mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerElementAtOrAbsent_IReadOnlyList.cs create mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerFirstOrAbsent.cs create mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerFirstOrAbsent_IEnumerable.cs create mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerFirstOrAbsent_IList.cs create mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerFirstOrAbsent_IReadOnlyList.cs create mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerLastOrAbsent.cs create mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerLastOrAbsent_IEnumerable.cs create mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerLastOrAbsent_IList.cs create mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerLastOrAbsent_IReadOnlyList.cs create mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerSingleOrAbsent.cs create mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerSingleOrAbsent_IEnumerable.cs create mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerSingleOrAbsent_IList.cs create mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerSingleOrAbsent_IReadOnlyList.cs create mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerValueOrAbsent.cs delete mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerElementAtOrAbsent.cs delete mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerElementAtOrAbsent_IEnumerable.cs delete mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerElementAtOrAbsent_IEnumerable_FromEnd.cs delete mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerElementAtOrAbsent_IList.cs delete mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerElementAtOrAbsent_IReadOnlyList.cs delete mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerFirstOrAbsent.cs delete mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerFirstOrAbsent_IEnumerable.cs delete mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerFirstOrAbsent_IList.cs delete mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerFirstOrAbsent_IReadOnlyList.cs delete mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerGetValueOrAbsent.cs delete mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerLastOrAbsent.cs delete mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerLastOrAbsent_IEnumerable.cs delete mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerLastOrAbsent_IList.cs delete mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerLastOrAbsent_IReadOnlyList.cs delete mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerSingleOrAbsent.cs delete mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerSingleOrAbsent_IEnumerable.cs delete mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerSingleOrAbsent_IList.cs delete mode 100644 src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerSingleOrAbsent_IReadOnlyList.cs diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/ElementAtOrAbsent.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/ElementAtOrAbsent.cs index 73566a88..4be23d65 100644 --- a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/ElementAtOrAbsent.cs +++ b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/ElementAtOrAbsent.cs @@ -8,7 +8,7 @@ public static Optional ElementAtOrAbsent( this IEnumerable source, Index index) => - InnerElementAtOrAbsent( + InnerElementAtOrAbsent.Get( source ?? throw new ArgumentNullException(nameof(source)), index); @@ -16,7 +16,7 @@ public static Optional ElementAtOrAbsent( this IEnumerable source, int index) => - InnerElementAtOrAbsent( + InnerElementAtOrAbsent.Get( source ?? throw new ArgumentNullException(nameof(source)), index); } diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/FirstOrAbsent.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/FirstOrAbsent.cs index 38817202..11d64450 100644 --- a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/FirstOrAbsent.cs +++ b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/FirstOrAbsent.cs @@ -7,14 +7,14 @@ partial class OptionalLinqExtensions public static Optional FirstOrAbsent( this IEnumerable source) => - InnerFirstOrAbsent( + InnerFirstOrAbsent.Get( source ?? throw new ArgumentNullException(nameof(source))); public static Optional FirstOrAbsent( this IEnumerable source, Func predicate) => - InnerFirstOrAbsent( + InnerFirstOrAbsent.Get( source ?? throw new ArgumentNullException(nameof(source)), predicate ?? throw new ArgumentNullException(nameof(predicate))); } diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/GetValueOrAbsent.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/GetValueOrAbsent.cs index 1febfeb9..c8b2237f 100644 --- a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/GetValueOrAbsent.cs +++ b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/GetValueOrAbsent.cs @@ -9,14 +9,10 @@ public static Optional GetValueOrAbsent( this IEnumerable> pairs, TKey key) => - InnerGetValueOrAbsent( + InnerValueOrAbsent.Get( pairs ?? throw new ArgumentNullException(nameof(pairs)), key); - private const string NotIntendedMessage_TryGetValueOrAbsent - = - "This method is not intended for use. Call GetValueOrAbsent instead."; - [Obsolete(NotIntendedMessage_TryGetValueOrAbsent, error: true)] [DoesNotReturn] public static Optional TryGetValueOrAbsent( @@ -24,4 +20,8 @@ public static Optional TryGetValueOrAbsent( TKey key) => throw new NotImplementedException(NotIntendedMessage_TryGetValueOrAbsent); + + private const string NotIntendedMessage_TryGetValueOrAbsent + = + $"This method is not intended for use. Call {nameof(GetValueOrAbsent)} instead."; } diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.ExceptionFactories/Inner.ExceptionFactories.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.ExceptionFactories/InnerExceptionFactories.cs similarity index 100% rename from src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.ExceptionFactories/Inner.ExceptionFactories.cs rename to src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.ExceptionFactories/InnerExceptionFactories.cs diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerElementAtOrAbsent.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerElementAtOrAbsent.cs new file mode 100644 index 00000000..db117cbf --- /dev/null +++ b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerElementAtOrAbsent.cs @@ -0,0 +1,49 @@ +using System.Collections.Generic; +using System.Runtime.CompilerServices; + +namespace System.Linq; + +partial class OptionalLinqExtensions +{ + private static partial class InnerElementAtOrAbsent + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static Optional Get( + IEnumerable source, + Index index) + => + source switch + { + IReadOnlyList list + => + InnerGet(list, index.GetOffset(list.Count)), + + IList list + => + InnerGet(list, index.GetOffset(list.Count)), + + _ => index.IsFromEnd is false + ? InnerGet(source, index.Value) + : InnerGetFromEnd(source, index.Value) + }; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static Optional Get( + IEnumerable source, + int index) + => + source switch + { + IReadOnlyList list + => + InnerGet(list, index), + + IList list + => + InnerGet(list, index), + + _ => + InnerGet(source, index) + }; + } +} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerElementAtOrAbsent_IEnumerable.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerElementAtOrAbsent_IEnumerable.cs new file mode 100644 index 00000000..73c29ff4 --- /dev/null +++ b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerElementAtOrAbsent_IEnumerable.cs @@ -0,0 +1,39 @@ +using System.Collections.Generic; +using System.Runtime.CompilerServices; + +namespace System.Linq; + +partial class OptionalLinqExtensions +{ + partial class InnerElementAtOrAbsent + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Optional InnerGet( + IEnumerable source, + int index) + { + if (index >= 0) + { + using var enumerator = source.GetEnumerator(); + + if (enumerator.MoveNext()) + { + var countdownIndex = index; + + do + { + if (countdownIndex == 0) + { + return new(enumerator.Current); + } + + countdownIndex--; + } + while (enumerator.MoveNext()); + } + } + + return default; + } + } +} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerElementAtOrAbsent_IEnumerable_FromEnd.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerElementAtOrAbsent_IEnumerable_FromEnd.cs new file mode 100644 index 00000000..a0428734 --- /dev/null +++ b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerElementAtOrAbsent_IEnumerable_FromEnd.cs @@ -0,0 +1,46 @@ +using System.Collections.Generic; +using System.Runtime.CompilerServices; + +namespace System.Linq; + +partial class OptionalLinqExtensions +{ + partial class InnerElementAtOrAbsent + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Optional InnerGetFromEnd( + IEnumerable source, + int indexFromEnd) + { + if (indexFromEnd > 0) + { + using var enumerator = source.GetEnumerator(); + + if (enumerator.MoveNext() is not true) + { + return default; + } + + Queue queue = new(); + queue.Enqueue(enumerator.Current); + + while (enumerator.MoveNext()) + { + if (queue.Count == indexFromEnd) + { + _ = queue.Dequeue(); + } + + queue.Enqueue(enumerator.Current); + } + + if (queue.Count == indexFromEnd) + { + return queue.Dequeue(); + } + } + + return default; + } + } +} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerElementAtOrAbsent_IList.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerElementAtOrAbsent_IList.cs new file mode 100644 index 00000000..3275ba5b --- /dev/null +++ b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerElementAtOrAbsent_IList.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using System.Runtime.CompilerServices; + +namespace System.Linq; + +partial class OptionalLinqExtensions +{ + partial class InnerElementAtOrAbsent + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Optional InnerGet( + IList source, + int index) + => + index >= 0 && index < source.Count ? new(source[index]) : default; + } +} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerElementAtOrAbsent_IReadOnlyList.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerElementAtOrAbsent_IReadOnlyList.cs new file mode 100644 index 00000000..f2355023 --- /dev/null +++ b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerElementAtOrAbsent_IReadOnlyList.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using System.Runtime.CompilerServices; + +namespace System.Linq; + +partial class OptionalLinqExtensions +{ + partial class InnerElementAtOrAbsent + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Optional InnerGet( + IReadOnlyList source, + int index) + => + index >= 0 && index < source.Count ? new(source[index]) : default; + } +} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerFirstOrAbsent.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerFirstOrAbsent.cs new file mode 100644 index 00000000..8cc6d114 --- /dev/null +++ b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerFirstOrAbsent.cs @@ -0,0 +1,47 @@ +using System.Collections.Generic; +using System.Runtime.CompilerServices; + +namespace System.Linq; + +partial class OptionalLinqExtensions +{ + private static partial class InnerFirstOrAbsent + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static Optional Get( + IEnumerable source) + => + source switch + { + IReadOnlyList list + => + InnerGet(list), + + IList list + => + InnerGet(list), + + _ => + InnerGet(source) + }; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static Optional Get( + IEnumerable source, + Func predicate) + => + source switch + { + IReadOnlyList list + => + InnerGet(list, predicate), + + IList list + => + InnerGet(list, predicate), + + _ => + InnerGet(source, predicate) + }; + } +} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerFirstOrAbsent_IEnumerable.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerFirstOrAbsent_IEnumerable.cs new file mode 100644 index 00000000..e837d638 --- /dev/null +++ b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerFirstOrAbsent_IEnumerable.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; +using System.Runtime.CompilerServices; + +namespace System.Linq; + +partial class OptionalLinqExtensions +{ + partial class InnerFirstOrAbsent + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Optional InnerGet( + IEnumerable source) + { + using var enumerator = source.GetEnumerator(); + + return enumerator.MoveNext() + ? new(enumerator.Current) + : default; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Optional InnerGet( + IEnumerable source, + Func predicate) + { + foreach (var current in source) + { + if (predicate.Invoke(current)) + { + return new(current); + } + } + + return default; + } + } +} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerFirstOrAbsent_IList.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerFirstOrAbsent_IList.cs new file mode 100644 index 00000000..a63c9800 --- /dev/null +++ b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerFirstOrAbsent_IList.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; +using System.Runtime.CompilerServices; + +namespace System.Linq; + +partial class OptionalLinqExtensions +{ + partial class InnerFirstOrAbsent + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Optional InnerGet( + IList source) + => + source.Count > 0 ? new(source[0]) : default; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Optional InnerGet( + IList source, + Func predicate) + { + for (var i = 0; i < source.Count; i++) + { + var current = source[i]; + + if (predicate.Invoke(current)) + { + return new(current); + } + } + + return default; + } + } +} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerFirstOrAbsent_IReadOnlyList.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerFirstOrAbsent_IReadOnlyList.cs new file mode 100644 index 00000000..025dd1d8 --- /dev/null +++ b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerFirstOrAbsent_IReadOnlyList.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; +using System.Runtime.CompilerServices; + +namespace System.Linq; + +partial class OptionalLinqExtensions +{ + partial class InnerFirstOrAbsent + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Optional InnerGet( + IReadOnlyList source) + => + source.Count > 0 ? new(source[0]) : default; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Optional InnerGet( + IReadOnlyList source, + Func predicate) + { + for (var i = 0; i < source.Count; i++) + { + var current = source[i]; + + if (predicate.Invoke(current)) + { + return new(current); + } + } + + return default; + } + } +} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerLastOrAbsent.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerLastOrAbsent.cs new file mode 100644 index 00000000..f7571315 --- /dev/null +++ b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerLastOrAbsent.cs @@ -0,0 +1,47 @@ +using System.Collections.Generic; +using System.Runtime.CompilerServices; + +namespace System.Linq; + +partial class OptionalLinqExtensions +{ + private static partial class InnerLastOrAbsent + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static Optional Get( + IEnumerable source) + => + source switch + { + IReadOnlyList list + => + InnerGet(list), + + IList list + => + InnerGet(list), + + _ => + InnerGet(source) + }; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static Optional Get( + IEnumerable source, + Func predicate) + => + source switch + { + IReadOnlyList list + => + InnerGet(list, predicate), + + IList list + => + InnerGet(list, predicate), + + _ => + InnerGet(source, predicate) + }; + } +} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerLastOrAbsent_IEnumerable.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerLastOrAbsent_IEnumerable.cs new file mode 100644 index 00000000..022c48ac --- /dev/null +++ b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerLastOrAbsent_IEnumerable.cs @@ -0,0 +1,62 @@ +using System.Collections.Generic; +using System.Runtime.CompilerServices; + +namespace System.Linq; + +partial class OptionalLinqExtensions +{ + partial class InnerLastOrAbsent + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Optional InnerGet( + IEnumerable source) + { + using var enumerator = source.GetEnumerator(); + + if (enumerator.MoveNext()) + { + TSource current; + + do + { + current = enumerator.Current; + } + while (enumerator.MoveNext()); + + return new(current); + } + + return default; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Optional InnerGet( + IEnumerable source, + Func predicate) + { + using var enumerator = source.GetEnumerator(); + + while (enumerator.MoveNext()) + { + var current = enumerator.Current; + + if (predicate.Invoke(current)) + { + while (enumerator.MoveNext()) + { + TSource next = enumerator.Current; + + if (predicate.Invoke(next)) + { + current = next; + } + } + + return new(current); + } + } + + return default; + } + } +} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerLastOrAbsent_IList.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerLastOrAbsent_IList.cs new file mode 100644 index 00000000..cd31c959 --- /dev/null +++ b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerLastOrAbsent_IList.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; +using System.Runtime.CompilerServices; + +namespace System.Linq; + +partial class OptionalLinqExtensions +{ + partial class InnerLastOrAbsent + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Optional InnerGet( + IList source) + => + source.Count > 0 ? new(source[^1]) : default; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Optional InnerGet( + IList source, + Func predicate) + { + for (var i = source.Count - 1; i >= 0; i--) + { + var current = source[i]; + + if (predicate.Invoke(current)) + { + return new(current); + } + } + + return default; + } + } +} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerLastOrAbsent_IReadOnlyList.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerLastOrAbsent_IReadOnlyList.cs new file mode 100644 index 00000000..3efdbc3d --- /dev/null +++ b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerLastOrAbsent_IReadOnlyList.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; +using System.Runtime.CompilerServices; + +namespace System.Linq; + +partial class OptionalLinqExtensions +{ + partial class InnerLastOrAbsent + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Optional InnerGet( + IReadOnlyList source) + => + source.Count > 0 ? new(source[^1]) : default; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Optional InnerGet( + IReadOnlyList source, + Func predicate) + { + for (var i = source.Count - 1; i >= 0; i--) + { + var current = source[i]; + + if (predicate.Invoke(current)) + { + return new(current); + } + } + + return default; + } + } +} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerSingleOrAbsent.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerSingleOrAbsent.cs new file mode 100644 index 00000000..7d675c06 --- /dev/null +++ b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerSingleOrAbsent.cs @@ -0,0 +1,49 @@ +using System.Collections.Generic; +using System.Runtime.CompilerServices; + +namespace System.Linq; + +partial class OptionalLinqExtensions +{ + private static partial class InnerSingleOrAbsent + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static Optional Get( + IEnumerable source, + Func moreThanOneElementExceptionFactory) + => + source switch + { + IReadOnlyList list + => + InnerGet(list, moreThanOneElementExceptionFactory), + + IList list + => + InnerGet(list, moreThanOneElementExceptionFactory), + + _ => + InnerGet(source, moreThanOneElementExceptionFactory) + }; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static Optional Get( + IEnumerable source, + Func predicate, + Func moreThanOneMatchExceptionFactory) + => + source switch + { + IReadOnlyList list + => + InnerGet(list, predicate, moreThanOneMatchExceptionFactory), + + IList list + => + InnerGet(list, predicate, moreThanOneMatchExceptionFactory), + + _ => + InnerGet(source, predicate, moreThanOneMatchExceptionFactory) + }; + } +} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerSingleOrAbsent_IEnumerable.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerSingleOrAbsent_IEnumerable.cs new file mode 100644 index 00000000..507f7f40 --- /dev/null +++ b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerSingleOrAbsent_IEnumerable.cs @@ -0,0 +1,61 @@ +using System.Collections.Generic; +using System.Runtime.CompilerServices; + +namespace System.Linq; + +partial class OptionalLinqExtensions +{ + partial class InnerSingleOrAbsent + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Optional InnerGet( + IEnumerable source, + Func moreThanOneElementExceptionFactory) + { + using var enumerator = source.GetEnumerator(); + + if (enumerator.MoveNext()) + { + var current = enumerator.Current; + + if (enumerator.MoveNext()) + { + throw moreThanOneElementExceptionFactory.Invoke(); + } + + return new(current); + } + + return default; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Optional InnerGet( + IEnumerable source, + Func predicate, + Func moreThanOneMatchExceptionFactory) + { + using var enumerator = source.GetEnumerator(); + + while (enumerator.MoveNext()) + { + var current = enumerator.Current; + + if (predicate.Invoke(current)) + { + while (enumerator.MoveNext()) + { + if (predicate.Invoke(enumerator.Current)) + { + throw moreThanOneMatchExceptionFactory.Invoke(); + } + } + + return new(current); + } + } + + return default; + } + } +} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerSingleOrAbsent_IList.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerSingleOrAbsent_IList.cs new file mode 100644 index 00000000..2c41f7be --- /dev/null +++ b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerSingleOrAbsent_IList.cs @@ -0,0 +1,51 @@ +using System.Collections.Generic; +using System.Runtime.CompilerServices; + +namespace System.Linq; + +partial class OptionalLinqExtensions +{ + partial class InnerSingleOrAbsent + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Optional InnerGet( + IList source, + Func moreThanOneElementExceptionFactory) + => + source.Count switch + { + > 1 => throw moreThanOneElementExceptionFactory.Invoke(), + + 1 => new(source[0]), + + _ => default + }; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Optional InnerGet( + IList source, + Func predicate, + Func moreThanOneMatchExceptionFactory) + { + for (var i = 0; i < source.Count; i++) + { + var current = source[i]; + + if (predicate.Invoke(current)) + { + for (var j = i + 1; j < source.Count; j++) + { + if (predicate.Invoke(source[j])) + { + throw moreThanOneMatchExceptionFactory.Invoke(); + } + } + + return new(current); + } + } + + return default; + } + } +} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerSingleOrAbsent_IReadOnlyList.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerSingleOrAbsent_IReadOnlyList.cs new file mode 100644 index 00000000..4dc6d54a --- /dev/null +++ b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerSingleOrAbsent_IReadOnlyList.cs @@ -0,0 +1,51 @@ +using System.Collections.Generic; +using System.Runtime.CompilerServices; + +namespace System.Linq; + +partial class OptionalLinqExtensions +{ + partial class InnerSingleOrAbsent + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Optional InnerGet( + IReadOnlyList source, + Func moreThanOneElementExceptionFactory) + => + source.Count switch + { + > 1 => throw moreThanOneElementExceptionFactory.Invoke(), + + 1 => new(source[0]), + + _ => default + }; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Optional InnerGet( + IReadOnlyList source, + Func predicate, + Func moreThanOneMatchExceptionFactory) + { + for (var i = 0; i < source.Count; i++) + { + var current = source[i]; + + if (predicate.Invoke(current)) + { + for (var j = i + 1; j < source.Count; j++) + { + if (predicate.Invoke(source[j])) + { + throw moreThanOneMatchExceptionFactory.Invoke(); + } + } + + return new(current); + } + } + + return default; + } + } +} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerValueOrAbsent.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerValueOrAbsent.cs new file mode 100644 index 00000000..fd709b42 --- /dev/null +++ b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner.Implementations/InnerValueOrAbsent.cs @@ -0,0 +1,33 @@ +using System.Collections.Generic; +using System.Runtime.CompilerServices; + +namespace System.Linq; + +partial class OptionalLinqExtensions +{ + private static class InnerValueOrAbsent + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static Optional Get( + IEnumerable> pairs, + TKey key) + => + pairs switch + { + IReadOnlyDictionary dictionary + => + dictionary.TryGetValue(key, out var value) ? new(value) : default, + + IDictionary dictionary + => + dictionary.TryGetValue(key, out var value) ? new(value) : default, + + _ => + InnerFirstOrAbsent.Get( + pairs, + pair => EqualityComparer.Default.Equals(pair.Key, key)) + .Map( + pair => pair.Value) + }; + } +} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerElementAtOrAbsent.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerElementAtOrAbsent.cs deleted file mode 100644 index 00388d9a..00000000 --- a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerElementAtOrAbsent.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System.Collections.Generic; - -namespace System.Linq; - -partial class OptionalLinqExtensions -{ - private static Optional InnerElementAtOrAbsent( - this IEnumerable source, - Index index) - => - source switch - { - IReadOnlyList list - => - list.InnerElementAtOrAbsent_IReadOnlyList(index.GetOffset(list.Count)), - - IList list - => - list.InnerElementAtOrAbsent_IList(index.GetOffset(list.Count)), - - _ => index.IsFromEnd is false - ? source.InnerElementAtOrAbsent_IEnumerable(index.Value) - : source.InnerElementAtOrAbsent_IEnumerable_FromEnd(index.Value) - }; - - private static Optional InnerElementAtOrAbsent( - this IEnumerable source, - int index) - => - source switch - { - IReadOnlyList list - => - list.InnerElementAtOrAbsent_IReadOnlyList(index), - - IList list - => - list.InnerElementAtOrAbsent_IList(index), - - _ => - source.InnerElementAtOrAbsent_IEnumerable(index) - }; -} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerElementAtOrAbsent_IEnumerable.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerElementAtOrAbsent_IEnumerable.cs deleted file mode 100644 index f400f876..00000000 --- a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerElementAtOrAbsent_IEnumerable.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Collections.Generic; - -namespace System.Linq; - -partial class OptionalLinqExtensions -{ - private static Optional InnerElementAtOrAbsent_IEnumerable( - this IEnumerable source, - int index) - { - if (index >= 0) - { - using var enumerator = source.GetEnumerator(); - - if (enumerator.MoveNext()) - { - var countdownIndex = index; - - do - { - if (countdownIndex == 0) - { - return new(enumerator.Current); - } - - countdownIndex--; - } - while (enumerator.MoveNext()); - } - } - - return default; - } -} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerElementAtOrAbsent_IEnumerable_FromEnd.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerElementAtOrAbsent_IEnumerable_FromEnd.cs deleted file mode 100644 index 54f9bf37..00000000 --- a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerElementAtOrAbsent_IEnumerable_FromEnd.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System.Collections.Generic; - -namespace System.Linq; - -partial class OptionalLinqExtensions -{ - private static Optional InnerElementAtOrAbsent_IEnumerable_FromEnd( - this IEnumerable source, - int indexFromEnd) - { - if (indexFromEnd > 0) - { - using var enumerator = source.GetEnumerator(); - - if (enumerator.MoveNext() is not true) - { - return default; - } - - Queue queue = new(); - queue.Enqueue(enumerator.Current); - - while (enumerator.MoveNext()) - { - if (queue.Count == indexFromEnd) - { - _ = queue.Dequeue(); - } - - queue.Enqueue(enumerator.Current); - } - - if (queue.Count == indexFromEnd) - { - return queue.Dequeue(); - } - } - - return default; - } -} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerElementAtOrAbsent_IList.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerElementAtOrAbsent_IList.cs deleted file mode 100644 index e572dea1..00000000 --- a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerElementAtOrAbsent_IList.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Collections.Generic; - -namespace System.Linq; - -partial class OptionalLinqExtensions -{ - private static Optional InnerElementAtOrAbsent_IList( - this IList source, - int index) - => - index >= 0 && index < source.Count ? new(source[index]) : default; -} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerElementAtOrAbsent_IReadOnlyList.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerElementAtOrAbsent_IReadOnlyList.cs deleted file mode 100644 index a1d8e9e4..00000000 --- a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerElementAtOrAbsent_IReadOnlyList.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Collections.Generic; - -namespace System.Linq; - -partial class OptionalLinqExtensions -{ - private static Optional InnerElementAtOrAbsent_IReadOnlyList( - this IReadOnlyList source, - int index) - => - index >= 0 && index < source.Count ? new(source[index]) : default; -} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerFirstOrAbsent.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerFirstOrAbsent.cs deleted file mode 100644 index 88362430..00000000 --- a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerFirstOrAbsent.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System.Collections.Generic; - -namespace System.Linq; - -partial class OptionalLinqExtensions -{ - private static Optional InnerFirstOrAbsent( - this IEnumerable source) - => - source switch - { - IReadOnlyList list - => - list.InnerFirstOrAbsent_IReadOnlyList(), - - IList list - => - list.InnerFirstOrAbsent_IList(), - - _ => - source.InnerFirstOrAbsent_IEnumerable() - }; - - private static Optional InnerFirstOrAbsent( - this IEnumerable source, - Func predicate) - => - source switch - { - IReadOnlyList list - => - list.InnerFirstOrAbsent_IReadOnlyList(predicate), - - IList list - => - list.InnerFirstOrAbsent_IList(predicate), - - _ => - source.InnerFirstOrAbsent_IEnumerable(predicate) - }; -} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerFirstOrAbsent_IEnumerable.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerFirstOrAbsent_IEnumerable.cs deleted file mode 100644 index ec28f76b..00000000 --- a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerFirstOrAbsent_IEnumerable.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Collections.Generic; - -namespace System.Linq; - -partial class OptionalLinqExtensions -{ - private static Optional InnerFirstOrAbsent_IEnumerable( - this IEnumerable source) - { - using var enumerator = source.GetEnumerator(); - - return enumerator.MoveNext() - ? new(enumerator.Current) - : default; - } - - private static Optional InnerFirstOrAbsent_IEnumerable( - this IEnumerable source, - Func predicate) - { - foreach (var current in source) - { - if (predicate.Invoke(current)) - { - return new(current); - } - } - - return default; - } -} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerFirstOrAbsent_IList.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerFirstOrAbsent_IList.cs deleted file mode 100644 index f3619f6d..00000000 --- a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerFirstOrAbsent_IList.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Collections.Generic; - -namespace System.Linq; - -partial class OptionalLinqExtensions -{ - private static Optional InnerFirstOrAbsent_IList( - this IList source) - => - source.Count > 0 ? new(source[0]) : default; - - private static Optional InnerFirstOrAbsent_IList( - this IList source, - Func predicate) - { - for (var i = 0; i < source.Count; i++) - { - var current = source[i]; - - if (predicate.Invoke(current)) - { - return new(current); - } - } - - return default; - } -} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerFirstOrAbsent_IReadOnlyList.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerFirstOrAbsent_IReadOnlyList.cs deleted file mode 100644 index cc9c1aac..00000000 --- a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerFirstOrAbsent_IReadOnlyList.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Collections.Generic; - -namespace System.Linq; - -partial class OptionalLinqExtensions -{ - private static Optional InnerFirstOrAbsent_IReadOnlyList( - this IReadOnlyList source) - => - source.Count > 0 ? new(source[0]) : default; - - private static Optional InnerFirstOrAbsent_IReadOnlyList( - this IReadOnlyList source, - Func predicate) - { - for (var i = 0; i < source.Count; i++) - { - var current = source[i]; - - if (predicate.Invoke(current)) - { - return new(current); - } - } - - return default; - } -} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerGetValueOrAbsent.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerGetValueOrAbsent.cs deleted file mode 100644 index 6c05759b..00000000 --- a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerGetValueOrAbsent.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Collections.Generic; - -namespace System.Linq; - -partial class OptionalLinqExtensions -{ - private static Optional InnerGetValueOrAbsent( - this IEnumerable> pairs, - TKey key) - => - pairs switch - { - IReadOnlyDictionary dictionary - => - dictionary.TryGetValue(key, out var value) ? new(value) : default, - - IDictionary dictionary - => - dictionary.TryGetValue(key, out var value) ? new(value) : default, - - _ => - pairs.InnerFirstOrAbsent( - pair => EqualityComparer.Default.Equals(pair.Key, key)) - .Map( - pair => pair.Value) - }; -} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerLastOrAbsent.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerLastOrAbsent.cs deleted file mode 100644 index 2abb11b3..00000000 --- a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerLastOrAbsent.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System.Collections.Generic; - -namespace System.Linq; - -partial class OptionalLinqExtensions -{ - private static Optional InnerLastOrAbsent( - this IEnumerable source) - => - source switch - { - IReadOnlyList list - => - list.InnerLastOrAbsent_IReadOnlyList(), - - IList list - => - list.InnerLastOrAbsent_IList(), - - _ => - source.InnerLastOrAbsent_IEnumerable() - }; - - private static Optional InnerLastOrAbsent( - this IEnumerable source, - Func predicate) - => - source switch - { - IReadOnlyList list - => - list.InnerLastOrAbsent_IReadOnlyList(predicate), - - IList list - => - list.InnerLastOrAbsent_IList(predicate), - - _ => - source.InnerLastOrAbsent_IEnumerable(predicate) - }; -} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerLastOrAbsent_IEnumerable.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerLastOrAbsent_IEnumerable.cs deleted file mode 100644 index e9d0c140..00000000 --- a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerLastOrAbsent_IEnumerable.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System.Collections.Generic; - -namespace System.Linq; - -partial class OptionalLinqExtensions -{ - private static Optional InnerLastOrAbsent_IEnumerable( - this IEnumerable source) - { - using var enumerator = source.GetEnumerator(); - - if (enumerator.MoveNext()) - { - TSource current; - - do - { - current = enumerator.Current; - } - while (enumerator.MoveNext()); - - return new(current); - } - - return default; - } - - private static Optional InnerLastOrAbsent_IEnumerable( - this IEnumerable source, - Func predicate) - { - using var enumerator = source.GetEnumerator(); - - while (enumerator.MoveNext()) - { - var current = enumerator.Current; - - if (predicate.Invoke(current)) - { - while (enumerator.MoveNext()) - { - TSource next = enumerator.Current; - - if (predicate.Invoke(next)) - { - current = next; - } - } - - return new(current); - } - } - - return default; - } -} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerLastOrAbsent_IList.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerLastOrAbsent_IList.cs deleted file mode 100644 index 19b5b350..00000000 --- a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerLastOrAbsent_IList.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Collections.Generic; - -namespace System.Linq; - -partial class OptionalLinqExtensions -{ - private static Optional InnerLastOrAbsent_IList( - this IList source) - => - source.Count > 0 ? new(source[^1]) : default; - - private static Optional InnerLastOrAbsent_IList( - this IList source, - Func predicate) - { - for (var i = source.Count - 1; i >= 0; i--) - { - var current = source[i]; - - if (predicate.Invoke(current)) - { - return new(current); - } - } - - return default; - } -} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerLastOrAbsent_IReadOnlyList.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerLastOrAbsent_IReadOnlyList.cs deleted file mode 100644 index e317fef8..00000000 --- a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerLastOrAbsent_IReadOnlyList.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Collections.Generic; - -namespace System.Linq; - -partial class OptionalLinqExtensions -{ - private static Optional InnerLastOrAbsent_IReadOnlyList( - this IReadOnlyList source) - => - source.Count > 0 ? new(source[^1]) : default; - - private static Optional InnerLastOrAbsent_IReadOnlyList( - this IReadOnlyList source, - Func predicate) - { - for (var i = source.Count - 1; i >= 0; i--) - { - var current = source[i]; - - if (predicate.Invoke(current)) - { - return new(current); - } - } - - return default; - } -} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerSingleOrAbsent.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerSingleOrAbsent.cs deleted file mode 100644 index 9ee91b2e..00000000 --- a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerSingleOrAbsent.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System.Collections.Generic; - -namespace System.Linq; - -partial class OptionalLinqExtensions -{ - private static Optional InnerSingleOrAbsent( - this IEnumerable source, - Func moreThanOneElementExceptionFactory) - => - source switch - { - IReadOnlyList list - => - list.InnerSingleOrAbsent_IReadOnlyList(moreThanOneElementExceptionFactory), - - IList list - => - list.InnerSingleOrAbsent_IList(moreThanOneElementExceptionFactory), - - _ => - source.InnerSingleOrAbsent_IEnumerable(moreThanOneElementExceptionFactory) - }; - - private static Optional InnerSingleOrAbsent( - this IEnumerable source, - Func predicate, - Func moreThanOneMatchExceptionFactory) - => - source switch - { - IReadOnlyList list - => - list.InnerSingleOrAbsent_IReadOnlyList(predicate, moreThanOneMatchExceptionFactory), - - IList list - => - list.InnerSingleOrAbsent_IList(predicate, moreThanOneMatchExceptionFactory), - - _ => - source.InnerSingleOrAbsent_IEnumerable(predicate, moreThanOneMatchExceptionFactory) - }; -} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerSingleOrAbsent_IEnumerable.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerSingleOrAbsent_IEnumerable.cs deleted file mode 100644 index 1bf50bea..00000000 --- a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerSingleOrAbsent_IEnumerable.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System.Collections.Generic; - -namespace System.Linq; - -partial class OptionalLinqExtensions -{ - private static Optional InnerSingleOrAbsent_IEnumerable( - this IEnumerable source, - Func moreThanOneElementExceptionFactory) - { - using var enumerator = source.GetEnumerator(); - - if (enumerator.MoveNext()) - { - var current = enumerator.Current; - - if (enumerator.MoveNext()) - { - throw moreThanOneElementExceptionFactory.Invoke(); - } - - return new(current); - } - - return default; - } - - private static Optional InnerSingleOrAbsent_IEnumerable( - this IEnumerable source, - Func predicate, - Func moreThanOneMatchExceptionFactory) - { - using var enumerator = source.GetEnumerator(); - - while (enumerator.MoveNext()) - { - var current = enumerator.Current; - - if (predicate.Invoke(current)) - { - while (enumerator.MoveNext()) - { - if (predicate.Invoke(enumerator.Current)) - { - throw moreThanOneMatchExceptionFactory.Invoke(); - } - } - - return new(current); - } - } - - return default; - } -} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerSingleOrAbsent_IList.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerSingleOrAbsent_IList.cs deleted file mode 100644 index aafcadf2..00000000 --- a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerSingleOrAbsent_IList.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System.Collections.Generic; - -namespace System.Linq; - -partial class OptionalLinqExtensions -{ - private static Optional InnerSingleOrAbsent_IList( - this IList source, - Func moreThanOneElementExceptionFactory) - => - source.Count switch - { - > 1 => throw moreThanOneElementExceptionFactory.Invoke(), - - 1 => new(source[0]), - - _ => default - }; - - private static Optional InnerSingleOrAbsent_IList( - this IList source, - Func predicate, - Func moreThanOneMatchExceptionFactory) - { - for (var i = 0; i < source.Count; i++) - { - var current = source[i]; - - if (predicate.Invoke(current)) - { - for (var j = i + 1; j < source.Count; j++) - { - if (predicate.Invoke(source[j])) - { - throw moreThanOneMatchExceptionFactory.Invoke(); - } - } - - return new(current); - } - } - - return default; - } -} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerSingleOrAbsent_IReadOnlyList.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerSingleOrAbsent_IReadOnlyList.cs deleted file mode 100644 index bb1ecc33..00000000 --- a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/Inner/InnerSingleOrAbsent_IReadOnlyList.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System.Collections.Generic; - -namespace System.Linq; - -partial class OptionalLinqExtensions -{ - private static Optional InnerSingleOrAbsent_IReadOnlyList( - this IReadOnlyList source, - Func moreThanOneElementExceptionFactory) - => - source.Count switch - { - > 1 => throw moreThanOneElementExceptionFactory.Invoke(), - - 1 => new(source[0]), - - _ => default - }; - - private static Optional InnerSingleOrAbsent_IReadOnlyList( - this IReadOnlyList source, - Func predicate, - Func moreThanOneMatchExceptionFactory) - { - for (var i = 0; i < source.Count; i++) - { - var current = source[i]; - - if (predicate.Invoke(current)) - { - for (var j = i + 1; j < source.Count; j++) - { - if (predicate.Invoke(source[j])) - { - throw moreThanOneMatchExceptionFactory.Invoke(); - } - } - - return new(current); - } - } - - return default; - } -} diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/LastOrAbsent.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/LastOrAbsent.cs index 7ec7d7fe..2c25d38d 100644 --- a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/LastOrAbsent.cs +++ b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/LastOrAbsent.cs @@ -7,14 +7,14 @@ partial class OptionalLinqExtensions public static Optional LastOrAbsent( this IEnumerable source) => - InnerLastOrAbsent( + InnerLastOrAbsent.Get( source ?? throw new ArgumentNullException(nameof(source))); public static Optional LastOrAbsent( this IEnumerable source, Func predicate) => - InnerLastOrAbsent( + InnerLastOrAbsent.Get( source ?? throw new ArgumentNullException(nameof(source)), predicate ?? throw new ArgumentNullException(nameof(predicate))); } diff --git a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/SingleOrAbsent.cs b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/SingleOrAbsent.cs index e700875b..0505b701 100644 --- a/src/core-taggeds-optional/Optional/OptionalLinqExtensions/SingleOrAbsent.cs +++ b/src/core-taggeds-optional/Optional/OptionalLinqExtensions/SingleOrAbsent.cs @@ -7,7 +7,7 @@ partial class OptionalLinqExtensions public static Optional SingleOrAbsent( this IEnumerable source) => - InnerSingleOrAbsent( + InnerSingleOrAbsent.Get( source ?? throw new ArgumentNullException(nameof(source)), InnerCreateMoreThanOneElementException); @@ -15,7 +15,7 @@ public static Optional SingleOrAbsent( this IEnumerable source, Func moreThanOneElementExceptionFactory) => - InnerSingleOrAbsent( + InnerSingleOrAbsent.Get( source ?? throw new ArgumentNullException(nameof(source)), moreThanOneElementExceptionFactory ?? throw new ArgumentNullException(nameof(moreThanOneElementExceptionFactory))); @@ -23,7 +23,7 @@ public static Optional SingleOrAbsent( this IEnumerable source, Func predicate) => - InnerSingleOrAbsent( + InnerSingleOrAbsent.Get( source ?? throw new ArgumentNullException(nameof(source)), predicate ?? throw new ArgumentNullException(nameof(predicate)), InnerCreateMoreThanOneMatchException); @@ -33,7 +33,7 @@ public static Optional SingleOrAbsent( Func predicate, Func moreThanOneMatchExceptionFactory) => - InnerSingleOrAbsent( + InnerSingleOrAbsent.Get( source ?? throw new ArgumentNullException(nameof(source)), predicate ?? throw new ArgumentNullException(nameof(predicate)), moreThanOneMatchExceptionFactory ?? throw new ArgumentNullException(nameof(moreThanOneMatchExceptionFactory)));