Std

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

Take.cs (4097B)


      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 Take<T, TIter>: IInto<Take<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 Take() => throw new InvalidOperationException("Parameterless constructor is not allowed to be called!");
     18         internal Take(TIter iter, ulong n) => (_iter, _n) = (iter, n);
     19         #endregion
     20 
     21         #region Type-level Fields
     22         #endregion
     23 
     24         #region Instance Fields
     25         ulong _n;
     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         #endregion
     29 
     30         #region Type-level Properties
     31         #endregion
     32 
     33         #region Instance Properties
     34         #endregion
     35 
     36         #region Type-level Functions
     37         #endregion
     38 
     39         #region Instance Functions
     40         public Result<Unit, ulong> AdvanceBy(ulong n) {
     41 
     42             if (_n >= n) {
     43                 _n -= n;
     44                 return _iter.AdvanceBy(n);
     45             } else if (_n == ulong.MinValue) {
     46                 return new(ulong.MinValue);
     47             } else {
     48                 var res = _iter.AdvanceBy(_n);
     49                 n = _n;
     50                 _n = ulong.MinValue;
     51                 return res.IsErr ? res : new(n);
     52             }
     53         }
     54         public ulong Count() => IIterator<T>.CountDefault(ref this);
     55         public override readonly bool Equals(object? _) => false;
     56         public TInit Fold<TInit>(TInit init, Fn<TInit, T, TInit> f) where TInit: notnull {
     57 
     58             static Fn<TInit, T, Result<TInit, Bottom>> fn(Fn<TInit, T, TInit> g) => (acc, x) => new(g(acc, x));
     59             return TryFold(init, fn(f))._ok;
     60         }
     61         public override readonly int GetHashCode() => 0;
     62         public readonly Take<T, TIter> Into() => this;
     63         public Maybe<T> Last() {
     64 
     65             var n = _n;
     66             _n = ulong.MinValue;
     67 
     68             if (n > ulong.MinValue) {
     69                 var res = _iter.AdvanceBy(n);
     70 
     71                 if (res.IsErr) {
     72                     return Maybe<T>.None();
     73                 }
     74             }
     75             return _iter.Last();
     76         }
     77         public Maybe<T> Next() {
     78 
     79             if (_n != ulong.MinValue) {
     80                 _n -= 1ul;
     81                 return _iter.Next();
     82             } else {
     83                 return Maybe<T>.None();
     84             }
     85         }
     86         public Prod<ulong, Maybe<ulong>> SizeHint() {
     87 
     88             if (_n == ulong.MinValue) { return new(ulong.MinValue, new(ulong.MinValue)); }
     89             var val = _iter.SizeHint();
     90             return new(val.Item0 <= _n ? val.Item0 : _n, val.Item1.IsSome && val.Item1._some < _n ? val.Item1 : new(_n)); ;
     91         }
     92         public override readonly string ToString() => string.Empty;
     93         public Result<TInit, TErr> TryFold<TInit, TErr>(TInit init, Fn<TInit, T, Result<TInit, TErr>> f) where TInit: notnull where TErr: notnull {
     94 
     95             if (_n == ulong.MinValue) {
     96                 return new(init);
     97             } else {
     98                 var n = _n;
     99                 Fn<TInit, T, Result<TInit, Result<TInit, TErr>>> check() => (acc, x) => {
    100                     n -= 1ul;
    101                     var r = f(acc, x);
    102                     return n == ulong.MinValue ? new(r) : (r.IsErr ? new(r) : new(r._ok));
    103                 };
    104                 var res = _iter.TryFold(init, check());
    105                 _n = n;
    106                 return res.IsErr ? res._err : new(res._ok);
    107             }
    108         }
    109         readonly Result<Take<T, TIter>, Bottom> ITryInto<Take<T, TIter>, Bottom>.TryInto() => new(this);
    110         #endregion
    111 
    112         #region Operators
    113         #endregion
    114 
    115         #region Types
    116         #endregion
    117     }
    118     #endregion
    119 
    120     #region Namespaces
    121     #endregion
    122 }
    123 #endregion