Std

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

Cycle.cs (4138B)


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