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