TakeWhile.cs (3861B)
1 using Std.Convert; 2 using Std.Maybe; 3 using Std.Ops; 4 using Std.Result; 5 using System; 6 using System.Runtime.InteropServices; 7 #region Namespaces 8 namespace Std.Iter { 9 #region Types 10 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 0)] 11 public struct TakeWhile<T, TIter>: IInto<TakeWhile<T, TIter>>, IIterator<T> where T: notnull where TIter: notnull, IIterator<T> { 12 13 #region Type-level Constructors 14 #endregion 15 16 #region Instance Constructors 17 public TakeWhile() => throw new InvalidOperationException("Parameterless constructor is not allowed to be called!"); 18 internal TakeWhile(TIter iter, FnIn<T, bool> f) => (_iter, _f, _flag) = (iter, f, false); 19 #endregion 20 21 #region Type-level Fields 22 #endregion 23 24 #region Instance Fields 25 readonly FnIn<T, bool> _f; 26 [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0044:Add readonly modifier", Justification = "Can't be readonly since we call mutable methods on it.")] 27 TIter _iter; 28 bool _flag; 29 #endregion 30 31 #region Type-level Properties 32 #endregion 33 34 #region Instance Properties 35 #endregion 36 37 #region Type-level Functions 38 #endregion 39 40 #region Instance Functions 41 public Result<Unit, ulong> AdvanceBy(ulong n) => IIterator<T>.AdvanceByDefault(ref this, n); 42 public ulong Count() => IIterator<T>.CountDefault(ref this); 43 public override readonly bool Equals(object? _) => false; 44 public TInit Fold<TInit>(TInit init, Fn<TInit, T, TInit> f) where TInit: notnull { 45 46 static Fn<TInit, T, Result<TInit, Bottom>> fn(Fn<TInit, T, TInit> g) => (acc, x) => new(g(acc, x)); 47 return TryFold(init, fn(f))._ok; 48 } 49 public override readonly int GetHashCode() => 0; 50 public readonly TakeWhile<T, TIter> Into() => this; 51 public Maybe<T> Last() => IIterator<T>.LastDefault(ref this); 52 public Maybe<T> Next() { 53 54 if (_flag) { 55 return Maybe<T>.None(); 56 } else { 57 var x = _iter.Next(); 58 59 if (x.IsNone) { 60 return Maybe<T>.None(); 61 } else if (_f(in x._some)) { 62 return x; 63 } else { 64 _flag = true; 65 return Maybe<T>.None(); 66 } 67 } 68 } 69 public Prod<ulong, Maybe<ulong>> SizeHint() => _flag ? new(ulong.MinValue, new(ulong.MinValue)) : new(ulong.MinValue, _iter.SizeHint().Item1); 70 public override readonly string ToString() => string.Empty; 71 public Result<TInit, TErr> TryFold<TInit, TErr>(TInit init, Fn<TInit, T, Result<TInit, TErr>> f) where TInit: notnull where TErr: notnull { 72 73 if (_flag) { 74 return new(init); 75 } else { 76 var flag = _flag; 77 var p = _f; 78 Fn<TInit, T, Result<TInit, Result<TInit, TErr>>> check() => (acc, x) => { 79 80 if (p(in x)) { 81 var r = f(acc, x); 82 return r.IsErr ? new(new Result<TInit, TErr>(r._err)) : new(r._ok); 83 } else { 84 flag = true; 85 return new(new Result<TInit, TErr>(acc)); 86 } 87 }; 88 var res = _iter.TryFold(init, check()); 89 _flag = flag; 90 return res.IsErr ? res._err : new(res._ok); 91 } 92 } 93 readonly Result<TakeWhile<T, TIter>, Bottom> ITryInto<TakeWhile<T, TIter>, Bottom>.TryInto() => new(this); 94 #endregion 95 96 #region Operators 97 #endregion 98 99 #region Types 100 #endregion 101 } 102 #endregion 103 104 #region Namespaces 105 #endregion 106 } 107 #endregion