Std

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

Chain.cs (4600B)


      1 using Std.Convert;
      2 using Std.Maybe;
      3 using static Std.Maybe.Maybe<ulong>;
      4 using Std.Num;
      5 using Std.Ops;
      6 using Std.Result;
      7 using static Std.Result.Result<Std.Unit, ulong>;
      8 using System;
      9 using System.Runtime.InteropServices;
     10 #region Namespaces
     11 namespace Std.Iter {
     12     #region Types
     13     [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 0)]
     14     public struct Chain<T, TIter, TIter2>: IInto<Chain<T, TIter, TIter2>>, IIterator<T> where T: notnull where TIter: notnull, IIterator<T> where TIter2: notnull, IIterator<T> {
     15 
     16         #region Type-level Constructors
     17         #endregion
     18 
     19         #region Instance Constructors
     20         public Chain() => throw new InvalidOperationException("Parameterless constructor is not allowed to be called!");
     21         internal Chain(TIter iter, TIter2 iter2) => (_iter, _iter2, _iterIsSome) = (iter, iter2, true);
     22         #endregion
     23 
     24         #region Type-level Fields
     25         #endregion
     26 
     27         #region Instance Fields
     28         [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0044:Add readonly modifier", Justification = "Can't be readonly since we call mutable methods on it.")]
     29         TIter _iter;
     30         [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0044:Add readonly modifier", Justification = "Can't be readonly since we call mutable methods on it.")]
     31         TIter2 _iter2;
     32         bool _iterIsSome;
     33         #endregion
     34 
     35         #region Type-level Properties
     36         #endregion
     37 
     38         #region Instance Properties
     39         #endregion
     40 
     41         #region Type-level Functions
     42         #endregion
     43 
     44         #region Instance Functions
     45         public Result<Unit, ulong> AdvanceBy(ulong n) {
     46 
     47             Result<Unit, ulong> res;
     48             var rem = n;
     49 
     50             if (_iterIsSome) {
     51                 res = _iter.AdvanceBy(n);
     52 
     53                 if (res.IsOK) {
     54                     return res;
     55                 } else {
     56                     rem -= res._err;
     57                     _iterIsSome = false;
     58                 }
     59             }
     60             res = _iter2.AdvanceBy(rem);
     61 
     62             if (res.IsOK) {
     63                 return res;
     64             } else {
     65                 rem -= res._err;
     66                 return rem == ulong.MinValue ? OK(new Unit()) : Err(n - rem);
     67             }
     68         }
     69         public ulong Count() => (_iterIsSome ? _iter.Count() : ulong.MinValue) + _iter2.Count();
     70         public TInit Fold<TInit>(TInit init, Fn<TInit, T, TInit> f) where TInit: notnull {
     71             
     72             if (_iterIsSome) {
     73                 init = _iter.Fold(init, f);
     74             }
     75             return _iter2.Fold(init, f);
     76         }
     77         public override readonly bool Equals(object? _) => false;
     78         public override readonly int GetHashCode() => 0;
     79         public readonly Chain<T, TIter, TIter2> Into() => this;
     80         public Maybe<T> Last() {
     81 
     82             var val = _iterIsSome ? _iter.Last() : Maybe<T>.None();
     83             return _iter2.Last().Or(val);
     84         }
     85         public Maybe<T> Next() {
     86 
     87             if (_iterIsSome) {
     88                 var val = _iter.Next();
     89 
     90                 if (val.IsNone) {
     91                     _iterIsSome = false;
     92                 }
     93                 return val;
     94             } else {
     95                 return _iter2.Next();
     96             }
     97         }
     98         public Prod<ulong, Maybe<ulong>> SizeHint() {
     99 
    100             if (_iterIsSome) {
    101                 (var min, var max) = _iter.SizeHint();
    102                 (var min2, var max2) = _iter2.SizeHint();
    103                 var lower = min.SaturatingAdd(min2);
    104                 var upper = max.IsSome && max2.IsSome ? max._some.CheckedAdd(max2._some) : None();
    105                 return new(lower, upper);
    106             } else {
    107                 return _iter2.SizeHint();
    108             }
    109         }
    110         public override readonly string ToString() => string.Empty;
    111         public Result<TInit, TErr> TryFold<TInit, TErr>(TInit init, Fn<TInit, T, Result<TInit, TErr>> f) where TInit: notnull where TErr: notnull {
    112 
    113             var res = Result<TInit, TErr>.OK(init);
    114 
    115             if (_iterIsSome) {
    116                 res = _iter.TryFold(init, f);
    117 
    118                 if (res.IsErr) {
    119                     return res;
    120                 } else {
    121                     _iterIsSome = false;
    122                 }
    123             }
    124             return _iter2.TryFold(res._ok, f);
    125         }
    126         readonly Result<Chain<T, TIter, TIter2>, Bottom> ITryInto<Chain<T, TIter, TIter2>, Bottom>.TryInto() => new(this);
    127         #endregion
    128 
    129         #region Operators
    130         #endregion
    131 
    132         #region Types
    133         #endregion
    134     }
    135     #endregion
    136 
    137     #region Namespaces
    138     #endregion
    139 }
    140 #endregion