Std

Mainly a port of Rust's std.
git clone https://git.philomathiclife.com/repos/Std
Log | Files | Refs | README

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