-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #72 from SideQuestVR/dev
2.3.0 merge
- Loading branch information
Showing
65 changed files
with
2,303 additions
and
570 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,211 @@ | ||
#nullable enable | ||
using System; | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
|
||
namespace Banter.Utilities { | ||
/// <summary> | ||
/// Extensions for <see cref="IEnumerable{T}"/> that don't currently exist in <c>System.Linq</c>. | ||
/// </summary> | ||
public static class EnumerableExtensions | ||
{ | ||
/* | ||
/// <summary> | ||
/// Adds a value to the beginning of the sequence. | ||
/// </summary> | ||
/// <typeparam name="T">the type of the elements of <paramref name="seq"/></typeparam> | ||
/// <param name="seq">a sequence of values</param> | ||
/// <param name="prep">the value to prepend to <paramref name="seq"/></param> | ||
/// <returns>a new sequence beginning with <paramref name="prep"/></returns> | ||
public static IEnumerable<T> Prepend<T>(this IEnumerable<T> seq, T prep) | ||
=> new PrependEnumerable<T>(seq, prep); | ||
private sealed class PrependEnumerable<T> : IEnumerable<T> | ||
{ | ||
private readonly IEnumerable<T> rest; | ||
private readonly T first; | ||
public PrependEnumerable(IEnumerable<T> rest, T first) | ||
{ | ||
this.rest = rest; | ||
this.first = first; | ||
} | ||
public PrependEnumerator GetEnumerator() => new(this); | ||
public struct PrependEnumerator : IEnumerator<T> | ||
{ | ||
private readonly IEnumerator<T> restEnum; | ||
private readonly PrependEnumerable<T> enumerable; | ||
private int state; | ||
internal PrependEnumerator(PrependEnumerable<T> enumerable) | ||
{ | ||
this.enumerable = enumerable; | ||
restEnum = enumerable.rest.GetEnumerator(); | ||
state = 0; | ||
Current = default!; | ||
} | ||
public T Current { get; private set; } | ||
object? IEnumerator.Current => Current; | ||
public void Dispose() => restEnum.Dispose(); | ||
public bool MoveNext() | ||
{ | ||
switch (state) | ||
{ | ||
case 0: | ||
Current = enumerable.first; | ||
state++; | ||
return true; | ||
case 1: | ||
if (!restEnum.MoveNext()) | ||
{ | ||
state = 2; | ||
return false; | ||
} | ||
else | ||
Current = restEnum.Current; | ||
return true; | ||
case 2: | ||
default: | ||
return false; | ||
} | ||
} | ||
public void Reset() | ||
{ | ||
restEnum.Reset(); | ||
state = 0; | ||
} | ||
} | ||
IEnumerator<T> IEnumerable<T>.GetEnumerator() => new PrependEnumerator(this); | ||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); | ||
} | ||
/// <summary> | ||
/// Adds a value to the end of the sequence. | ||
/// </summary> | ||
/// <typeparam name="T">the type of the elements of <paramref name="seq"/></typeparam> | ||
/// <param name="seq">a sequence of values</param> | ||
/// <param name="app">the value to append to <paramref name="seq"/></param> | ||
/// <returns>a new sequence ending with <paramref name="app"/></returns> | ||
public static IEnumerable<T> Append<T>(this IEnumerable<T> seq, T app) | ||
=> new AppendEnumerable<T>(seq, app); | ||
private sealed class AppendEnumerable<T> : IEnumerable<T> | ||
{ | ||
private readonly IEnumerable<T> rest; | ||
private readonly T last; | ||
public AppendEnumerable(IEnumerable<T> rest, T last) | ||
{ | ||
this.rest = rest; | ||
this.last = last; | ||
} | ||
public AppendEnumerator GetEnumerator() => new(this); | ||
public struct AppendEnumerator : IEnumerator<T> | ||
{ | ||
private readonly IEnumerator<T> restEnum; | ||
private readonly AppendEnumerable<T> enumerable; | ||
private int state; | ||
internal AppendEnumerator(AppendEnumerable<T> enumerable) | ||
{ | ||
this.enumerable = enumerable; | ||
restEnum = enumerable.rest.GetEnumerator(); | ||
state = 0; | ||
Current = default!; | ||
} | ||
public T Current { get; private set; } | ||
object? IEnumerator.Current => Current; | ||
public void Dispose() => restEnum.Dispose(); | ||
public bool MoveNext() | ||
{ | ||
switch (state) | ||
{ | ||
case 0: | ||
if (!restEnum.MoveNext()) | ||
{ | ||
state = 1; | ||
goto case 1; | ||
} | ||
else | ||
Current = restEnum.Current; | ||
return true; | ||
case 1: | ||
Current = enumerable.last; | ||
state++; | ||
return true; | ||
case 2: | ||
default: | ||
return false; | ||
} | ||
} | ||
public void Reset() | ||
{ | ||
restEnum.Reset(); | ||
state = 0; | ||
} | ||
} | ||
IEnumerator<T> IEnumerable<T>.GetEnumerator() => GetEnumerator(); | ||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); | ||
} | ||
*/ | ||
|
||
/// <summary> | ||
/// LINQ-style extension method that filters <see langword="null"/> elements out of an enumeration. | ||
/// </summary> | ||
/// <typeparam name="T">the type of the enumeration</typeparam> | ||
/// <param name="self">the enumeration to filter</param> | ||
/// <returns>a filtered enumerable</returns> | ||
public static IEnumerable<T> NonNull<T>(this IEnumerable<T?> self) where T : class | ||
=> self.Where(o => o != null)!; | ||
|
||
/// <summary> | ||
/// LINQ-style extension method that filters <see langword="null"/> elements out of an enumeration based on a converter. | ||
/// </summary> | ||
/// <typeparam name="T">the type of the enumeration</typeparam> | ||
/// <typeparam name="U">the type to compare to null</typeparam> | ||
/// <param name="self">the enumeration to filter</param> | ||
/// <param name="pred">the predicate to select for filtering</param> | ||
/// <returns>a filtered enumerable</returns> | ||
public static IEnumerable<T> NonNull<T, U>(this IEnumerable<T> self, Func<T, U?> pred) where U : class | ||
=> self.Where(o => pred(o) != null); | ||
|
||
/// <summary> | ||
/// LINQ-style extension method that filters <see langword="null"/> elements from an enumeration of nullable types. | ||
/// </summary> | ||
/// <typeparam name="T">the underlying type of the nullable enumeration</typeparam> | ||
/// <param name="self">the enumeration to filter</param> | ||
/// <returns>a filtered enumerable</returns> | ||
public static IEnumerable<T> NonNull<T>(this IEnumerable<T?> self) where T : struct | ||
=> self.Where(o => o != null).Select(o => o!.Value); | ||
|
||
/// <summary> | ||
/// LINQ-style extension method that filters <see langword="null"/> elements out of an enumeration based on a converter to a nullable type. | ||
/// </summary> | ||
/// <typeparam name="T">the type of the enumeration</typeparam> | ||
/// <typeparam name="U">the type of the predicate's resulting nullable</typeparam> | ||
/// <param name="self">the enumeration to filter</param> | ||
/// <param name="pred">the predicate to select for filtering</param> | ||
/// <returns>a filtered enumerable</returns> | ||
public static IEnumerable<T> NonNull<T, U>(this IEnumerable<T> self, Func<T, U?> pred) where U : struct | ||
=> self.Where(o => pred(o) != null); | ||
} | ||
|
||
} |
2 changes: 1 addition & 1 deletion
2
...s/Utils/UnityMainThreadDispatcher.cs.meta → ...dParty/BSIPA/EnumerableExtensions.cs.meta
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.