Std

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

FlatMapInternal.cs (3782B)


      1 using Std.Maybe;
      2 using Std.Ops;
      3 using Std.Result;
      4 using System;
      5 using System.Runtime.InteropServices;
      6 #region Namespaces
      7 namespace Std.Iter {
      8     #region Types
      9     [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 0)]
     10     struct FlatMapInternal<T, TInnerIter, TIter>: IFusedIterator<T> where T: notnull where TInnerIter: notnull, IIterator<T> where TIter: notnull, IIterator<TInnerIter> {
     11 
     12         #region Type-level Constructors
     13         #endregion
     14 
     15         #region Instance Constructors
     16         public FlatMapInternal() => throw new InvalidOperationException("Parameterless constructor is not allowed to be called!");
     17         internal FlatMapInternal(TIter iter) => (_iter, _inner, _innerIsSome) = (iter.Fuse<TIter, TInnerIter>(), default!, false);
     18         #endregion
     19 
     20         #region Type-level Fields
     21         #endregion
     22 
     23         #region Instance Fields
     24         Fuse<TInnerIter, TIter> _iter;
     25         TInnerIter _inner;
     26         bool _innerIsSome;
     27         #endregion
     28 
     29         #region Type-level Properties
     30         #endregion
     31 
     32         #region Instance Properties
     33         #endregion
     34 
     35         #region Type-level Functions
     36         #endregion
     37 
     38         #region Instance Functions
     39         public Result<Unit, ulong> AdvanceBy(ulong n) => IIterator<T>.AdvanceByDefault(ref this, n);
     40         public ulong Count() => IIterator<T>.CountDefault(ref this);
     41         public TInit Fold<TInit>(TInit init, Fn<TInit, T, TInit> f) where TInit: notnull {
     42             static Fn<TInit, TInnerIter, TInit> flatten(Fn<TInit, T, TInit> fold) => (acc, x) => x.Fold(acc, fold);
     43             return (_innerIsSome ? new Maybe<TInnerIter>(_inner!) : Maybe<TInnerIter>.None()).IntoIter().Chain<Maybe.IntoIterator<TInnerIter>, TInnerIter, Fuse<TInnerIter, TIter>>(_iter).Fold(init, flatten(f));
     44         }
     45         public Maybe<T> Last() => IIterator<T>.LastDefault(ref this);
     46         public Maybe<T> Next() {
     47 
     48             while (true) {
     49 
     50                 if (_innerIsSome) {
     51                     var val = _inner!.Next();
     52 
     53                     if (val.IsSome) {
     54                         return val;
     55                     } else {
     56                         _innerIsSome = false;
     57                     }
     58                 } else {
     59                     var val = _iter.Next();
     60                     _innerIsSome = val.IsSome;
     61                     if (_innerIsSome) { _inner = val._some; } else { return Maybe<T>.None(); }
     62                 }
     63             }
     64         }
     65         public Prod<ulong, Maybe<ulong>> SizeHint() {
     66 
     67             var inner = _innerIsSome ? _inner!.SizeHint() : new(ulong.MinValue, new(ulong.MinValue));
     68             var (low, high) = _iter.SizeHint();
     69             return low == ulong.MinValue && high.IsSome && high._some == ulong.MinValue ? inner : (new(inner.Item0, Maybe<ulong>.None()));
     70         }
     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             Result<TInit, TErr> res;
     74 
     75             if (_innerIsSome) {
     76                 res = _inner!.TryFold(init, f);
     77 
     78                 if (res.IsErr) {
     79                     return res;
     80                 } else {
     81                     init = res._ok;
     82                     _innerIsSome = false;
     83                 }
     84             }
     85             var inner = _inner;
     86             Fn<TInit, TInnerIter, Result<TInit, TErr>> flatten(Fn<TInit, T, Result<TInit, TErr>> fold) => (acc, x) => { var r = x.TryFold(acc, fold); inner = x; return r; };
     87             res = _iter.TryFold(init, flatten(f));
     88             (_inner, _innerIsSome) = (inner, res.IsErr);
     89             return res;
     90         }
     91         #endregion
     92 
     93         #region Operators
     94         #endregion
     95 
     96         #region Types
     97         #endregion
     98     }
     99     #endregion
    100 
    101     #region Namespaces
    102     #endregion
    103 }
    104 #endregion