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