IDoubleEndedIterator.cs (4411B)
1 using Std.Maybe; 2 using static Std.Maybe.Maybe<ulong>; 3 using Std.Ops; 4 using Std.Result; 5 using System.Runtime.CompilerServices; 6 #region Namespaces 7 namespace Std.Iter { 8 #region Types 9 public interface IDoubleEndedIterator<T>: IIterator<T> where T: notnull { 10 11 #region Type-level Constructors 12 #endregion 13 14 #region Instance Constructors 15 #endregion 16 17 #region Type-level Fields 18 #endregion 19 20 #region Instance Fields 21 #endregion 22 23 #region Type-level Properties 24 #endregion 25 26 #region Instance Properties 27 #endregion 28 29 #region Type-level Functions 30 protected static Result<Unit, ulong> AdvanceBackByDefault<TSelf>(TSelf self, ulong n) where TSelf: notnull, IDoubleEndedIterator<T> { 31 32 for (var i = ulong.MinValue; i < n; i++) { if (self.NextBack().IsNone) { return new(i); } } 33 return new(new Unit()); 34 } 35 protected static Result<Unit, ulong> AdvanceBackByDefault<TSelf>(ref TSelf self, ulong n) where TSelf: struct, IDoubleEndedIterator<T> { 36 37 for (var i = ulong.MinValue; i < n; i++) { if (self.NextBack().IsNone) { return new(i); } } 38 return new(new Unit()); 39 } 40 public static Maybe<T> NthBack<TSelf>(ref TSelf self, ulong n) where TSelf: notnull, IDoubleEndedIterator<T> => self.AdvanceBackBy(n).IsErr ? Maybe<T>.None() : self.NextBack(); 41 public static Maybe<T> RFind<TSelf>(ref TSelf self, FnIn<T, bool> f) where TSelf: notnull, IDoubleEndedIterator<T> { 42 43 var res = self.TryRFold(new Unit(), (_, val) => f(in val) ? Result<Unit, T>.Err(val) : Result<Unit, T>.OK(new Unit())); 44 return res.IsErr ? Maybe<T>.Some(res._err) : Maybe<T>.None(); 45 } 46 protected static TInit RFoldDefault<TSelf, TInit>(TSelf self, TInit init, Fn<TInit, T, TInit> f) where TSelf: notnull, IDoubleEndedIterator<T> where TInit: notnull { 47 48 Maybe<T> val; 49 while ((val = self.NextBack()).IsSome) { init = f(init, val._some); } 50 return init; 51 } 52 protected static TInit RFoldDefault<TSelf, TInit>(ref TSelf self, TInit init, Fn<TInit, T, TInit> f) where TSelf: struct, IDoubleEndedIterator<T> where TInit: notnull { 53 54 Maybe<T> val; 55 while ((val = self.NextBack()).IsSome) { init = f(init, val._some); } 56 return init; 57 } 58 public static Maybe<ulong> RPosition<TSelf>(ref TSelf self, Fn<T, bool> f) where TSelf: notnull, IDoubleEndedIterator<T>, IExactSizeIterator<T> { 59 60 var res = self.TryRFold(ulong.MinValue, (i, val) => f(val) ? Result<ulong, ulong>.Err(i) : Result<ulong, ulong>.OK(i + 1ul)); 61 return res.IsErr ? Some(res._err) : None(); 62 } 63 protected static Result<TInit, TErr> TryRFoldDefault<TSelf, TInit, TErr>(TSelf self, TInit init, Fn<TInit, T, Result<TInit, TErr>> f) where TSelf: notnull, IDoubleEndedIterator<T> where TInit: notnull where TErr: notnull { 64 65 Result<TInit, TErr> res = new(init); 66 Maybe<T> val; 67 68 while ((val = self.NextBack()).IsSome) { 69 res = f(res._ok, val._some); 70 if (res.IsErr) { break; } 71 } 72 return res; 73 } 74 protected static Result<TInit, TErr> TryRFoldDefault<TSelf, TInit, TErr>(ref TSelf self, TInit init, Fn<TInit, T, Result<TInit, TErr>> f) where TSelf: struct, IDoubleEndedIterator<T> where TInit: notnull where TErr: notnull { 75 76 Result<TInit, TErr> res = new(init); 77 Maybe<T> val; 78 79 while ((val = self.NextBack()).IsSome) { 80 res = f(res._ok, val._some); 81 if (res.IsErr) { break; } 82 } 83 return res; 84 } 85 #endregion 86 87 #region Instance Functions 88 public abstract Result<Unit, ulong> AdvanceBackBy(ulong n); 89 [MethodImpl(MethodImplOptions.AggressiveInlining)] 90 public abstract Maybe<T> NextBack(); 91 public abstract TInit RFold<TInit>(TInit init, Fn<TInit, T, TInit> f) where TInit: notnull; 92 public abstract Result<TInit, TErr> TryRFold<TInit, TErr>(TInit init, Fn<TInit, T, Result<TInit, TErr>> f) where TInit: notnull where TErr: notnull; 93 #endregion 94 95 #region Operators 96 #endregion 97 98 #region Types 99 #endregion 100 } 101 #endregion 102 103 #region Namespaces 104 #endregion 105 } 106 #endregion