IIterator.cs (6397B)
1 using Std.Maybe; 2 using static Std.Maybe.Maybe<ulong>; 3 using Std.Ops; 4 using Std.Result; 5 using static Std.Result.Result<Std.Unit, ulong>; 6 using System.Runtime.CompilerServices; 7 #region Namespaces 8 namespace Std.Iter { 9 #region Types 10 public interface IIterator<T> where T: notnull { 11 12 #region Type-level Constructors 13 #endregion 14 15 #region Instance Constructors 16 #endregion 17 18 #region Type-level Fields 19 #endregion 20 21 #region Instance Fields 22 #endregion 23 24 #region Type-level Properties 25 #endregion 26 27 #region Instance Properties 28 #endregion 29 30 #region Type-level Functions 31 protected static Result<Unit, ulong> AdvanceByDefault<TSelf>(TSelf self, ulong n) where TSelf: notnull, IIterator<T> { 32 33 for (var i = ulong.MinValue; i < n; i++) { if (self.Next().IsNone) { return Err(i); } } 34 return OK(new Unit()); 35 } 36 protected static Result<Unit, ulong> AdvanceByDefault<TSelf>(ref TSelf self, ulong n) where TSelf: struct, IIterator<T> { 37 38 for (var i = ulong.MinValue; i < n; i++) { if (self.Next().IsNone) { return Err(i); } } 39 return OK(new Unit()); 40 } 41 public static bool All<TSelf>(ref TSelf self, Fn<T, bool> f) where TSelf: notnull, IIterator<T> => self.TryFold(new Unit(), (_, val) => f(val) ? Result<Unit, Unit>.OK(new Unit()) : Result<Unit, Unit>.Err(new Unit())).IsOK; 42 public static bool Any<TSelf>(ref TSelf self, Fn<T, bool> f) where TSelf: notnull, IIterator<T> => self.TryFold(new Unit(), (_, val) => f(val) ? Result<Unit, Unit>.Err(new Unit()) : Result<Unit, Unit>.OK(new Unit())).IsErr; 43 protected static ulong CountDefault<TSelf>(TSelf self) where TSelf: notnull, IIterator<T> => self.Fold(ulong.MinValue, (count, _) => count + 1ul); 44 protected static ulong CountDefault<TSelf>(ref TSelf self) where TSelf: struct, IIterator<T> => self.Fold(ulong.MinValue, (count, _) => count + 1ul); 45 public static Maybe<T> Find<TSelf>(ref TSelf self, FnIn<T, bool> f) where TSelf: notnull, IIterator<T> { 46 47 var res = self.TryFold(new Unit(), (_, val) => f(in val) ? Result<Unit, T>.Err(val) : Result<Unit, T>.OK(new Unit())); 48 return res.IsErr ? Maybe<T>.Some(res._err) : Maybe<T>.None(); 49 } 50 public static Maybe<T2> FindMap<TSelf, T2>(ref TSelf self, Fn<T, Maybe<T2>> f) where TSelf: notnull, IIterator<T> where T2: notnull { 51 52 var res = self.TryFold(new Unit(), (_, x) => { var val = f(x); return val.IsSome ? Result<Unit, Maybe<T2>>.Err(val) : Result<Unit, Maybe<T2>>.OK(new Unit()); }); 53 return res.IsErr ? res._err : Maybe<T2>.None(); 54 } 55 protected static TInit FoldDefault<TSelf, TInit>(TSelf self, TInit init, Fn<TInit, T, TInit> f) where TSelf: notnull, IIterator<T> where TInit: notnull { 56 57 Maybe<T> val; 58 while ((val = self.Next()).IsSome) { init = f(init, val._some); } 59 return init; 60 } 61 protected static TInit FoldDefault<TSelf, TInit>(ref TSelf self, TInit init, Fn<TInit, T, TInit> f) where TSelf: struct, IIterator<T> where TInit: notnull { 62 63 Maybe<T> val; 64 while ((val = self.Next()).IsSome) { init = f(init, val._some); } 65 return init; 66 } 67 protected static Maybe<T> LastDefault<TSelf>(TSelf self) where TSelf: notnull, IIterator<T> => self.Fold(Maybe<T>.None(), (_, val) => Maybe<T>.Some(val)); 68 protected static Maybe<T> LastDefault<TSelf>(ref TSelf self) where TSelf: struct, IIterator<T> => self.Fold(Maybe<T>.None(), (_, val) => Maybe<T>.Some(val)); 69 public static Maybe<T> Nth<TSelf>(ref TSelf self, ulong n) where TSelf: notnull, IIterator<T> => self.AdvanceBy(n).IsErr ? Maybe<T>.None() : self.Next(); 70 public static Maybe<ulong> Position<TSelf>(ref TSelf self, Fn<T, bool> f) where TSelf: notnull, IIterator<T> { 71 72 var res = self.TryFold(ulong.MinValue, (i, val) => f(val) ? Result<ulong, ulong>.Err(i) : Result<ulong, ulong>.OK(i + 1ul)); 73 return res.IsErr ? Some(res._err) : None(); 74 } 75 protected static Result<TInit, TErr> TryFoldDefault<TSelf, TInit, TErr>(TSelf self, TInit init, Fn<TInit, T, Result<TInit, TErr>> f) where TSelf: notnull, IIterator<T> where TInit: notnull where TErr: notnull { 76 77 Result<TInit, TErr> res = new(init); 78 Maybe<T> val; 79 80 while ((val = self.Next()).IsSome) { 81 init = res._ok; 82 res = f(init, val._some); 83 if (res.IsErr) { break; } 84 } 85 return res; 86 } 87 protected static Result<TInit, TErr> TryFoldDefault<TSelf, TInit, TErr>(ref TSelf self, TInit init, Fn<TInit, T, Result<TInit, TErr>> f) where TSelf: struct, IIterator<T> where TInit: notnull where TErr: notnull { 88 89 Result<TInit, TErr> res = new(init); 90 Maybe<T> val; 91 92 while ((val = self.Next()).IsSome) { 93 init = res._ok; 94 res = f(init, val._some); 95 if (res.IsErr) { break; } 96 } 97 return res; 98 } 99 public static Result<Unit, TErr> TryForEach<TSelf, TErr>(ref TSelf self, Fn<T, Result<Unit, TErr>> f) where TSelf: notnull, IIterator<T> where TErr: notnull => self.TryFold(new Unit(), (_, val) => f(val)); 100 #endregion 101 102 #region Instance Functions 103 public abstract Result<Unit, ulong> AdvanceBy(ulong n); 104 public abstract ulong Count(); 105 public abstract TInit Fold<TInit>(TInit init, Fn<TInit, T, TInit> f) where TInit: notnull; 106 public abstract Maybe<T> Last(); 107 [MethodImpl(MethodImplOptions.AggressiveInlining)] 108 [System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1716:Identifiers should not match keywords", Justification = "Collision with keyword is unlikely since it's an instance method.")] 109 public abstract Maybe<T> Next(); 110 public virtual Prod<ulong, Maybe<ulong>> SizeHint() => new(ulong.MinValue, None()); 111 public abstract Result<TInit, TErr> TryFold<TInit, TErr>(TInit init, Fn<TInit, T, Result<TInit, TErr>> f) where TInit: notnull where TErr: notnull; 112 #endregion 113 114 #region Operators 115 #endregion 116 117 #region Types 118 #endregion 119 } 120 #endregion 121 122 #region Namespaces 123 #endregion 124 } 125 #endregion