Vec.cs (19042B)
1 using Std.Clone; 2 using Std.Cmp; 3 using Std.Convert; 4 using Std.Hashing; 5 using Std.Iter; 6 using Std.Maybe; 7 using static Std.Maybe.Maybe<ulong>; 8 using Std.Num; 9 using Std.Ops; 10 using Std.Result; 11 using System; 12 using System.Runtime.CompilerServices; 13 using System.Runtime.InteropServices; 14 #region Namespaces 15 namespace Std.Vec { 16 #region Types 17 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 0)] 18 public struct IntoIterator<T>: IDoubleEndedIterator<T>, IExactSizeIterator<T>, IFusedIterator<T>, IInto<IntoIterator<T>>, IIntoIterator<T, IntoIterator<T>> where T: notnull { 19 20 #region Type-level Constructors 21 #endregion 22 23 #region Instance Constructors 24 public IntoIterator() => throw new InvalidOperationException("Parameterless constructor is not allowed to be called!"); 25 internal IntoIterator(Vec<T> vec) => (_vec, _index, _indexBack) = (vec, 0, (int)vec.Len - 1); 26 #endregion 27 28 #region Type-level Fields 29 #endregion 30 31 #region Instance Fields 32 Vec<T> _vec; 33 int _index; 34 int _indexBack; 35 #endregion 36 37 #region Type-level Properties 38 #endregion 39 40 #region Instance Properties 41 #endregion 42 43 #region Type-level Functions 44 #endregion 45 46 #region Instance Functions 47 public Result<Unit, ulong> AdvanceBy(ulong n) { 48 49 if (n == ulong.MinValue) { 50 return new(new Unit()); 51 } else { 52 var val = _indexBack - _index + 1; 53 54 if (n > (ulong)val) { 55 _index = _indexBack + 1; 56 return new((ulong)val); 57 } else { 58 _index += (int)n; 59 return new(new Unit()); 60 } 61 } 62 } 63 public Result<Unit, ulong> AdvanceBackBy(ulong n) { 64 65 if (n == ulong.MinValue) { 66 return new(new Unit()); 67 } else { 68 var val = _indexBack - _index + 1; 69 70 if (n > (ulong)val) { 71 _indexBack = _index - 1; 72 return new((ulong)val); 73 } else { 74 _indexBack -= (int)n; 75 return new(new Unit()); 76 } 77 } 78 } 79 public readonly ReadOnlySpan<T> AsSlice() => _index <= _indexBack ? _vec.AsSlice()[_index..(_indexBack + 1)] : ReadOnlySpan<T>.Empty; 80 public readonly ulong Count() => Len(); 81 public override readonly bool Equals(object? _) => false; 82 public TInit Fold<TInit>(TInit init, Fn<TInit, T, TInit> f) where TInit: notnull { 83 84 while (_index <= _indexBack) { init = f(init, _vec[(uint)_index++]); } 85 return init; 86 } 87 public override readonly int GetHashCode() => 0; 88 public readonly IntoIterator<T> Into() => this; 89 public readonly IntoIterator<T> IntoIter() => this; 90 public readonly bool IsEmpty() => Len() == ulong.MinValue; 91 public readonly Maybe<T> Last() => _index > _indexBack ? Maybe<T>.None() : new(_vec[(uint)_indexBack]); 92 public readonly ulong Len() => (ulong)(1 + _indexBack - _index); 93 [MethodImpl(MethodImplOptions.AggressiveInlining)] 94 public Maybe<T> Next() => _index > _indexBack ? Maybe<T>.None() : Maybe<T>.Some(_vec[(uint)_index++]); 95 public Maybe<T> NextBack() => _indexBack < _index ? Maybe<T>.None() : Maybe<T>.Some(_vec[(uint)_indexBack--]); 96 public TInit RFold<TInit>(TInit init, Fn<TInit, T, TInit> f) where TInit: notnull { 97 98 while (_index <= _indexBack) { init = f(init, _vec[(uint)_indexBack--]); } 99 return init; 100 } 101 public readonly Prod<ulong, Maybe<ulong>> SizeHint() => new(Len(), Some(Len())); 102 public override readonly string ToString() => string.Empty; 103 public Result<TInit, TErr> TryFold<TInit, TErr>(TInit init, Fn<TInit, T, Result<TInit, TErr>> f) where TInit: notnull where TErr: notnull { 104 105 while (_index <= _indexBack) { 106 var res = f(init, _vec[(uint)_index++]); 107 108 if (res.IsErr) { 109 return res; 110 } else { 111 init = res._ok; 112 } 113 } 114 return new(init); 115 } 116 readonly Result<IntoIterator<T>, Bottom> ITryInto<IntoIterator<T>, Bottom>.TryInto() => new(this); 117 public Result<TInit, TErr> TryRFold<TInit, TErr>(TInit init, Fn<TInit, T, Result<TInit, TErr>> f) where TInit: notnull where TErr: notnull { 118 119 while (_index <= _indexBack) { 120 var res = f(init, _vec[(uint)_indexBack--]); 121 122 if (res.IsErr) { 123 return res; 124 } else { 125 init = res._ok; 126 } 127 } 128 return new(init); 129 } 130 #endregion 131 132 #region Operators 133 #endregion 134 135 #region Types 136 #endregion 137 } 138 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 0)] 139 public struct Vec<T>: IFromIterator<Vec<T>, T>, IExtend<T>, IIndex<uint, T>, IIndexMut<uint, T>, IInto<Vec<T>>, IIntoIterator<T, IntoIterator<T>> where T: notnull { 140 141 #region Type-level Constructors 142 #endregion 143 144 #region Instance Constructors 145 [MethodImpl(MethodImplOptions.AggressiveInlining)] 146 public Vec() => (_arr, _len) = (System.Array.Empty<T>(), uint.MinValue); 147 [MethodImpl(MethodImplOptions.AggressiveInlining)] 148 public Vec(uint capacity) => (_arr, _len) = (capacity == uint.MinValue ? System.Array.Empty<T>() : new T[(int)capacity], uint.MinValue); 149 [MethodImpl(MethodImplOptions.AggressiveInlining)] 150 internal Vec(T[] arr, uint len) => (_arr, _len) = (arr, len); 151 #endregion 152 153 #region Type-level Fields 154 static T? _dummy = default; 155 #endregion 156 157 #region Instance Fields 158 T[] _arr; 159 [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0032:Use auto property", Justification = "Want to make public property readonly.")] 160 uint _len; 161 #endregion 162 163 #region Type-level Properties 164 #endregion 165 166 #region Instance Properties 167 public readonly uint Capacity => (uint)_arr.Length; 168 public readonly bool IsEmpty => _len == uint.MinValue; 169 public readonly ref readonly T this[uint index] { 170 [MethodImpl(MethodImplOptions.AggressiveInlining)] 171 get { 172 173 if (index < _len) { 174 return ref _arr[(int)index]; 175 } else { 176 throw new InvalidOperationException($"The index, {index.ToString()}, is greater than or equal to the length, {_len.ToString()}, of the vector."); 177 } 178 } 179 } 180 public readonly uint Len => _len; 181 internal readonly T[] Array => _arr; 182 #endregion 183 184 #region Type-level Functions 185 public static Vec<T> New() => new(uint.MinValue); 186 public static Vec<T> WithCapacity(uint capacity) => new(capacity); 187 public static Vec<T> FromIter<TIter>(TIter iter) where TIter: notnull, IIterator<T> { 188 189 var vec = new Vec<T>(); 190 _ = vec.Extend(iter); 191 return vec; 192 } 193 #endregion 194 195 #region Instance Functions 196 public Unit Append(ref Vec<T> other) { 197 198 _ = Reserve(other._len); 199 System.Array.Copy(other._arr, 0L, _arr, _len, other._len); 200 _len += other._len; 201 other._len = uint.MinValue; 202 return new(); 203 } 204 public readonly T[] AsArray() => _arr; 205 [MethodImpl(MethodImplOptions.AggressiveInlining)] 206 public readonly Span<T> AsMutSlice() => _arr.AsSpan()[..(int)_len]; 207 [MethodImpl(MethodImplOptions.AggressiveInlining)] 208 public readonly ReadOnlySpan<T> AsSlice() => _arr.AsSpan()[..(int)_len]; 209 public Unit Clear() => Truncate(uint.MinValue); 210 public Unit DeDupBy(FnRef<T, T, bool> f) { 211 212 var len = _len; 213 214 if (len == uint.MinValue) { return new(); } 215 Span<T> span = new(_arr, 0, (int)len); 216 var nextRead = 1u; 217 var nextWrite = 1u; 218 T val0; 219 T val1; 220 221 while (nextRead < len) { 222 val0 = span[(int)nextRead]; 223 val1 = span[(int)(nextWrite - 1)]; 224 225 if (!f(ref val0, ref val1)) { 226 if (nextRead != nextWrite) { _ = span.Swap(nextRead, nextWrite); } 227 nextWrite++; 228 } 229 nextRead++; 230 } 231 return Truncate(nextWrite); 232 } 233 public Unit DeDupByKey<T2>(FnRef<T, T2> f) where T2: notnull, IPartialEq<T2, T2> => DeDupBy((ref T a, ref T b) => f(ref a) == f(ref b)); 234 public override readonly bool Equals(object? _) => false; 235 public Unit Extend<TIter>(TIter iter) where TIter: notnull, IIterator<T> { 236 237 var cap = iter.SizeHint().Item0; 238 _ = Reserve(cap > uint.MaxValue ? uint.MaxValue : (uint)cap); 239 var val = iter.Next(); 240 241 while (val.IsSome) { 242 243 if ((uint)_arr.Length <= _len + 1u) { 244 var tmp = new T[2 * _arr.Length]; 245 System.Array.Copy(_arr, 0L, tmp, 0L, _arr.Length); 246 _arr = tmp; 247 } 248 _arr[(int)_len++] = val._some; 249 val = iter.Next(); 250 } 251 return new(); 252 } 253 [MethodImpl(MethodImplOptions.AggressiveInlining)] 254 public Unit ExtendFromSlice(ReadOnlySpan<T> other) { 255 256 _ = Reserve((uint)other.Length); 257 other.CopyTo(new(_arr, (int)_len, other.Length)); 258 _len += (uint)other.Length; 259 return new(); 260 } 261 public Unit ExtendOne(T val) => Push(val); 262 public Unit ExtendReserve(uint additional) => Reserve(additional); 263 [MethodImpl(MethodImplOptions.AggressiveInlining)] 264 public readonly Maybe<T> Get(uint index) => index < _len ? new(this[index]) : Maybe<T>.None(); 265 public override readonly int GetHashCode() => 0; 266 [MethodImpl(MethodImplOptions.AggressiveInlining)] 267 public readonly ref T GetMut(uint index, out bool exists) { 268 269 if (index < _len) { 270 exists = true; 271 return ref _arr[(int)index]; 272 } else { 273 exists = false; 274 return ref _dummy!; 275 } 276 } 277 public Unit Insert(uint index, T elem) { 278 279 if (index <= _len) { 280 _ = Reserve(1u); 281 System.Array.Copy(_arr, index, _arr, 1L + index, _len - index); 282 _len++; 283 _arr[index] = elem; 284 return new(); 285 } else { 286 throw new InvalidOperationException($"The index, {index.ToString()}, is greater than the length, {_len.ToString()}, of the vector."); 287 } 288 } 289 public readonly Vec<T> Into() => this; 290 public readonly IntoIterator<T> IntoIter() => new(this); 291 public readonly ref T ItemMut(uint index) { 292 293 if (index < _len) { 294 return ref _arr[(int)index]; 295 } else { 296 throw new InvalidOperationException($"The index, {index.ToString()}, is greater than or equal to the length, {_len.ToString()}, of the vector."); 297 } 298 } 299 public readonly Prod<T[], uint> IntoRawParts() => new(_arr, _len); 300 [MethodImpl(MethodImplOptions.AggressiveInlining)] 301 public Maybe<T> Pop() => _len == uint.MinValue ? Maybe<T>.None() : new(_arr[(int)--_len]); 302 [MethodImpl(MethodImplOptions.AggressiveInlining)] 303 public Unit Push(T val) { 304 305 _ = Reserve(1u); 306 _arr[(int)_len++] = val; 307 return new(); 308 } 309 public T Remove(uint index) { 310 311 if (index >= _len) { 312 throw new InvalidOperationException($"The index, {index.ToString()}, is greater than or equal to the length, {_len.ToString()}, of the vector."); 313 } else { 314 var val = _arr[index]; 315 System.Array.Copy(_arr, index + 1L, _arr, index, (--_len) - index); 316 return val; 317 } 318 } 319 public Unit Reserve(uint additional) { 320 321 additional += _len; 322 if ((uint)_arr.Length < additional) { System.Array.Resize(ref _arr, (int)additional.NextPowerOfTwo()); } 323 return new(); 324 } 325 public Unit ReserveExact(uint additional) { 326 327 additional += _len; 328 if ((uint)_arr.Length < additional) { System.Array.Resize(ref _arr, (int)additional); } 329 return new(); 330 } 331 public Unit ResizeWith(uint newLen, Fn<T> f) { 332 333 var len = _len; 334 335 if (newLen > len) { 336 _ = Reserve(newLen - len); 337 for (var i = len; i < newLen; i++) { _arr[i] = f(); } 338 _len = newLen; 339 return new(); 340 } else { 341 return Truncate(newLen); 342 } 343 } 344 public Unit Retain(FnIn<T, bool> f) { 345 346 var len = _len; 347 var del = uint.MinValue; 348 Span<T> span = new(_arr, 0, (int)len); 349 T val; 350 351 for (var i = uint.MinValue; i < len; i++) { 352 val = span[(int)i]; 353 354 if (!f(in val)) { 355 del += 1u; 356 } else if (del > uint.MinValue) { 357 _ = span.Swap(i - del, i); 358 } 359 } 360 return del > uint.MinValue ? Truncate(len - del) : new(); 361 } 362 public Unit SetLenUnsafe(uint newLen) { 363 364 _len = newLen; 365 return new(); 366 } 367 public Unit ShrinkTo(uint min) { 368 369 min = min >= _len ? min : _len; 370 371 if ((uint)_arr.Length > min) { 372 System.Array.Resize(ref _arr, (int)min); 373 } else if ((uint)_arr.Length < min) { 374 throw new InvalidOperationException($"The current capacity, {_arr.Length.ToString()}, is smaller than the minimum value, {min.ToString()}, that was passed."); 375 } 376 return new(); 377 } 378 public Unit ShrinkToFit() { 379 380 if ((uint)_arr.Length > _len) { 381 System.Array.Resize(ref _arr, (int)_len); 382 } 383 return new(); 384 } 385 public Vec<T> SplitOff(uint at) { 386 387 if (at < uint.MinValue) { 388 var otherLen = _len - at; 389 Vec<T> other = new(otherLen); 390 _len = at; 391 other._len = otherLen; 392 System.Array.Copy(_arr, (int)at, other._arr, 0, (int)otherLen); 393 return other; 394 } else if (at == uint.MinValue) { 395 _arr = new T[_arr.Length]; 396 _len = uint.MinValue; 397 return new(_arr, _len); 398 } else { 399 throw new InvalidOperationException($"The index to split at, {at.ToString()}, must be less than or equal to the length, {_len.ToString()}."); 400 } 401 } 402 public T SwapRemove(uint index) { 403 404 var val = this[index]; 405 _arr[(int)index] = _arr[(int)(--_len)]; 406 return val; 407 } 408 public override readonly string ToString() => string.Empty; 409 public Unit Truncate(uint len) { 410 _len = len < _len ? len : _len; 411 return new(); 412 } 413 readonly Result<Vec<T>, Bottom> ITryInto<Vec<T>, Bottom>.TryInto() => new(this); 414 #endregion 415 416 #region Operators 417 #endregion 418 419 #region Types 420 #endregion 421 } 422 public static class Functions { 423 424 #region Type-level Constructors 425 #endregion 426 427 #region Instance Constructors 428 #endregion 429 430 #region Type-level Fields 431 #endregion 432 433 #region Instance Fields 434 #endregion 435 436 #region Type-level Properties 437 #endregion 438 439 #region Instance Properties 440 #endregion 441 442 #region Type-level Functions 443 public static Vec<T> Clone<T>(in this Vec<T> self) where T: notnull, IClone<T> => new(Std.Functions.Clone(self.Array), self.Len); 444 public static Ordering Cmp<T>(in this Vec<T> self, in Vec<T> other) where T: notnull, IOrd<T> => self.AsSlice().Cmp(other.AsSlice()); 445 public static int CompareToComparable<T>(in this Vec<T> self, in Vec<T> other) where T: notnull, IComparable<T> => self.AsSlice().CompareToComparable(other.AsSlice()); 446 public static bool Eq<T0, T1>(in this Vec<T0> self, in Vec<T1> other) where T0: notnull, IPartialEq<T0, T1> where T1: notnull, IPartialEq<T1, T0> => self.AsSlice().Eq(other.AsSlice()); 447 public static bool EqualsEquatable<T>(in this Vec<T> self, in Vec<T> other) where T: notnull, IEquatable<T> => self.AsSlice().EqualsEquatable(other.AsSlice()); 448 public static bool Ge<T0, T1>(in this Vec<T0> self, in Vec<T1> other) where T0: notnull, IPartialOrd<T0, T1> where T1: notnull, IPartialOrd<T1, T0> => self.AsSlice().Ge(other.AsSlice()); 449 public static int GetHashCodeEquatable<T>(in this Vec<T> self) where T: notnull, IEquatable<T> => self.AsSlice().GetHashCodeEquatable(); 450 public static bool Gt<T0, T1>(in this Vec<T0> self, in Vec<T1> other) where T0: notnull, IPartialOrd<T0, T1> where T1: notnull, IPartialOrd<T1, T0> => self.AsSlice().Gt(other.AsSlice()); 451 public static Unit Hash<T, THasher>(in this Vec<T> self, ref THasher hasher) where T: notnull, IHashable where THasher: notnull, IHasher => self.AsSlice().Hash(ref hasher); 452 public static string LowerHex(in this Vec<byte> self) => self.AsSlice().LowerHex(); 453 public static bool Le<T0, T1>(in this Vec<T0> self, in Vec<T1> other) where T0: notnull, IPartialOrd<T0, T1> where T1: notnull, IPartialOrd<T1, T0> => self.AsSlice().Le(other.AsSlice()); 454 public static bool Lt<T0, T1>(in this Vec<T0> self, in Vec<T1> other) where T0: notnull, IPartialOrd<T0, T1> where T1: notnull, IPartialOrd<T1, T0> => self.AsSlice().Lt(other.AsSlice()); 455 public static bool Ne<T0, T1>(in this Vec<T0> self, in Vec<T1> other) where T0: notnull, IPartialEq<T0, T1> where T1: notnull, IPartialEq<T1, T0> => self.AsSlice().Ne(other.AsSlice()); 456 public static Maybe<Ordering> PartialCmp<T0, T1>(in this Vec<T0> self, in Vec<T1> other) where T0: notnull, IPartialOrd<T0, T1> where T1: notnull, IPartialOrd<T1, T0> => self.AsSlice().PartialCmp(other.AsSlice()); 457 public static string ToArrayString<T>(in this Vec<T> self) where T: notnull => self.AsSlice().ToArrayString(); 458 public static string UpperHex(in this Vec<byte> self) => self.AsSlice().UpperHex(); 459 #endregion 460 461 #region Instance Functions 462 #endregion 463 464 #region Operators 465 #endregion 466 467 #region Types 468 #endregion 469 } 470 #endregion 471 472 #region Namespaces 473 #endregion 474 } 475 #endregion