HashMap.cs (19958B)
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 Std.Ops; 8 using Std.Result; 9 using System; 10 using System.Runtime.CompilerServices; 11 using System.Runtime.InteropServices; 12 using @base = Std.Hashbrown.HashMap; 13 #region Namespaces 14 namespace Std.Collections.HashMap { 15 #region Types 16 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 0)] 17 public struct HashMap<TKey, TValue, THasher, TBuildHasher>: IExtend<ProdMut<TKey, TValue>>, IIndex<TKey, TValue>, IInto<HashMap<TKey, TValue, THasher, TBuildHasher>>, IIntoIterator<ProdMut<TKey, TValue>, IntoIter<TKey, TValue>> where TKey: notnull, IEq<TKey>, IHashable where TValue: notnull where THasher: notnull, IHasher where TBuildHasher: notnull, IBuildHasher<THasher> { 18 19 #region Type-level Constructors 20 #endregion 21 22 #region Instance Constructors 23 public HashMap() => throw new InvalidOperationException("Parameterless constructor is not allowed to be called!"); 24 [MethodImpl(MethodImplOptions.AggressiveInlining)] 25 internal HashMap(@base::HashMap<TKey, TValue, THasher, TBuildHasher> @base) => _base = @base; 26 [MethodImpl(MethodImplOptions.AggressiveInlining)] 27 public HashMap(uint capacity, TBuildHasher hashBuilder) => _base = @base::HashMap<TKey, TValue, THasher, TBuildHasher>.WithCapacityAndHasher(capacity, hashBuilder); 28 [MethodImpl(MethodImplOptions.AggressiveInlining)] 29 public HashMap(TBuildHasher hashBuilder) => _base = @base::HashMap<TKey, TValue, THasher, TBuildHasher>.WithHasher(hashBuilder); 30 #endregion 31 32 #region Type-level Fields 33 #endregion 34 35 #region Instance Fields 36 internal @base::HashMap<TKey, TValue, THasher, TBuildHasher> _base; 37 #endregion 38 39 #region Type-level Properties 40 #endregion 41 42 #region Instance Properties 43 public readonly uint Capacity => (uint)_base.Capacity(); 44 public readonly bool IsEmpty => _base.IsEmpty(); 45 public readonly ref readonly TValue this[TKey key] => ref _base[key]; 46 public readonly uint Len => (uint)_base.Len(); 47 #endregion 48 49 #region Type-level Functions 50 [MethodImpl(MethodImplOptions.AggressiveInlining)] 51 public static HashMap<TKey, TValue, THasher, TBuildHasher> WithCapacityAndHasher(uint capacity, TBuildHasher hashBuilder) => new(@base::HashMap<TKey, TValue, THasher, TBuildHasher>.WithCapacityAndHasher(capacity, hashBuilder)); 52 [MethodImpl(MethodImplOptions.AggressiveInlining)] 53 public static HashMap<TKey, TValue, THasher, TBuildHasher> WithHasher(TBuildHasher hashBuilder) => new(@base::HashMap<TKey, TValue, THasher, TBuildHasher>.WithHasher(hashBuilder)); 54 #endregion 55 56 #region Instance Functions 57 [MethodImpl(MethodImplOptions.AggressiveInlining)] 58 public Unit Clear() => _base.Clear(); 59 [MethodImpl(MethodImplOptions.AggressiveInlining)] 60 public readonly bool ContainsKey(in TKey k) => _base.ContainsKey(in k); 61 public override readonly bool Equals(object? _) => false; 62 [MethodImpl(MethodImplOptions.AggressiveInlining)] 63 public Unit Extend<TIter>(TIter iter) where TIter: notnull, IIterator<ProdMut<TKey, TValue>> => _base.Extend(iter); 64 public Unit ExtendOne(ProdMut<TKey, TValue> val) { 65 _ = _base.Insert(val.Item0, val.Item1); 66 return new Unit(); 67 } 68 public Unit ExtendReserve(uint additional) => _base.Reserve(IsEmpty ? additional : (additional + 1u) / 2u); 69 [MethodImpl(MethodImplOptions.AggressiveInlining)] 70 public readonly Maybe<TValue> Get(in TKey k) => _base.Get(in k); 71 public override readonly int GetHashCode() => 0; 72 [MethodImpl(MethodImplOptions.AggressiveInlining)] 73 public readonly Maybe<ProdMut<TKey, TValue>> GetKeyValue(in TKey k) => _base.GetKeyValue(in k); 74 [MethodImpl(MethodImplOptions.AggressiveInlining)] 75 public readonly ref TValue GetMut(in TKey k, out bool exists) => ref _base.GetMut(in k, out exists); 76 [MethodImpl(MethodImplOptions.AggressiveInlining)] 77 public ref TValue GetOrInsert(TKey key, TValue v) => ref _base.GetOrInsert(key, v); 78 [MethodImpl(MethodImplOptions.AggressiveInlining)] 79 public ref TValue GetOrInsertWith(TKey key, Fn<TValue> f) => ref _base.GetOrInsertWith(key, f); 80 public readonly ref readonly TValue GetRef(in TKey k, out bool exists) => ref _base.GetRef(in k, out exists); 81 [MethodImpl(MethodImplOptions.AggressiveInlining)] 82 public readonly TBuildHasher Hasher() => _base.Hasher(); 83 [MethodImpl(MethodImplOptions.AggressiveInlining)] 84 public Maybe<TValue> Insert(TKey k, TValue v) => _base.Insert(k , v); 85 public readonly HashMap<TKey, TValue, THasher, TBuildHasher> Into() => this; 86 public readonly IntoIter<TKey, TValue> IntoIter() => new(_base.IntoIter()); 87 public readonly IntoKeys<TKey, TValue> IntoKeys() => new(IntoIter()); 88 public readonly IntoValues<TKey, TValue> IntoValues() => new(IntoIter()); 89 [MethodImpl(MethodImplOptions.AggressiveInlining)] 90 public Maybe<TValue> Remove(in TKey k) => _base.Remove(in k); 91 [MethodImpl(MethodImplOptions.AggressiveInlining)] 92 public Maybe<ProdMut<TKey, TValue>> RemoveEntry(in TKey k) => _base.RemoveEntry(in k); 93 [MethodImpl(MethodImplOptions.AggressiveInlining)] 94 public Unit Reserve(uint additional) => _base.Reserve(additional); 95 [MethodImpl(MethodImplOptions.AggressiveInlining)] 96 public readonly Unit Retain(FnRef<TKey, TValue, bool> f) => _base.Retain(f); 97 public Unit ShrinkTo(uint minCapacity) => _base.ShrinkTo(minCapacity); 98 public Unit ShrinkToFit() => _base.ShrinkToFit(); 99 public override readonly string ToString() => string.Empty; 100 readonly Result<HashMap<TKey, TValue, THasher, TBuildHasher>, Bottom> ITryInto<HashMap<TKey, TValue, THasher, TBuildHasher>, Bottom>.TryInto() => new(this); 101 #endregion 102 103 #region Operators 104 #endregion 105 106 #region Types 107 #endregion 108 } 109 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 0)] 110 public struct IntoIter<TKey, TValue>: IInto<IntoIter<TKey, TValue>>, IExactSizeIterator<ProdMut<TKey, TValue>>, IFusedIterator<ProdMut<TKey, TValue>> where TKey: notnull where TValue: notnull { 111 112 #region Type-level Constructors 113 #endregion 114 115 #region Instance Constructors 116 public IntoIter() => throw new InvalidOperationException("Parameterless constructor is not allowed to be called!"); 117 [MethodImpl(MethodImplOptions.AggressiveInlining)] 118 internal IntoIter(@base::IntoIter<TKey, TValue> @base) => _base = @base; 119 #endregion 120 121 #region Type-level Fields 122 #endregion 123 124 #region Instance Fields 125 @base::IntoIter<TKey, TValue> _base; 126 #endregion 127 128 #region Type-level Properties 129 #endregion 130 131 #region Instance Properties 132 #endregion 133 134 #region Type-level Functions 135 #endregion 136 137 #region Instance Functions 138 public Result<Unit, ulong> AdvanceBy(ulong n) => IIterator<ProdMut<TKey, TValue>>.AdvanceByDefault(ref this, n); 139 public ulong Count() => IIterator<ProdMut<TKey, TValue>>.CountDefault(ref this); 140 public TInit Fold<TInit>(TInit init, Fn<TInit, ProdMut<TKey, TValue>, TInit> f) where TInit: notnull => IIterator<ProdMut<TKey, TValue>>.FoldDefault(ref this, init, f); 141 public override readonly bool Equals(object? _) => false; 142 public override readonly int GetHashCode() => 0; 143 public readonly IntoIter<TKey, TValue> Into() => this; 144 public readonly bool IsEmpty() => _base.IsEmpty(); 145 public Maybe<ProdMut<TKey, TValue>> Last() => IIterator<ProdMut<TKey, TValue>>.LastDefault(ref this); 146 public readonly ulong Len() => _base.Len(); 147 [MethodImpl(MethodImplOptions.AggressiveInlining)] 148 public Maybe<ProdMut<TKey, TValue>> Next() => _base.Next(); 149 public readonly Prod<ulong, Maybe<ulong>> SizeHint() => _base.SizeHint(); 150 public override readonly string ToString() => string.Empty; 151 public Result<TInit, TErr> TryFold<TInit, TErr>(TInit init, Fn<TInit, ProdMut<TKey, TValue>, Result<TInit, TErr>> f) where TInit: notnull where TErr: notnull => IIterator<ProdMut<TKey, TValue>>.TryFoldDefault(ref this, init, f); 152 readonly Result<IntoIter<TKey, TValue>, Bottom> ITryInto<IntoIter<TKey, TValue>, Bottom>.TryInto() => new(this); 153 #endregion 154 155 #region Operators 156 #endregion 157 158 #region Types 159 #endregion 160 } 161 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 0)] 162 public struct IntoKeys<TKey, TValue>: IInto<IntoKeys<TKey, TValue>>, IExactSizeIterator<TKey>, IFusedIterator<TKey> where TKey: notnull where TValue: notnull { 163 164 #region Type-level Constructors 165 #endregion 166 167 #region Instance Constructors 168 public IntoKeys() => throw new InvalidOperationException("Parameterless constructor is not allowed to be called!"); 169 [MethodImpl(MethodImplOptions.AggressiveInlining)] 170 internal IntoKeys(IntoIter<TKey, TValue> inner) => _inner = inner; 171 #endregion 172 173 #region Type-level Fields 174 #endregion 175 176 #region Instance Fields 177 IntoIter<TKey, TValue> _inner; 178 #endregion 179 180 #region Type-level Properties 181 #endregion 182 183 #region Instance Properties 184 #endregion 185 186 #region Type-level Functions 187 #endregion 188 189 #region Instance Functions 190 public Result<Unit, ulong> AdvanceBy(ulong n) => IIterator<TKey>.AdvanceByDefault(ref this, n); 191 public ulong Count() => IIterator<TKey>.CountDefault(ref this); 192 public TInit Fold<TInit>(TInit init, Fn<TInit, TKey, TInit> f) where TInit: notnull => IIterator<TKey>.FoldDefault(ref this, init, f); 193 public override readonly bool Equals(object? _) => false; 194 public override readonly int GetHashCode() => 0; 195 public readonly IntoKeys<TKey, TValue> Into() => this; 196 public readonly bool IsEmpty() => _inner.IsEmpty(); 197 public Maybe<TKey> Last() => IIterator<TKey>.LastDefault(ref this); 198 public readonly ulong Len() => _inner.Len(); 199 [MethodImpl(MethodImplOptions.AggressiveInlining)] 200 public Maybe<TKey> Next() => _inner.Next().Map((tup) => tup.Item0); 201 public readonly Prod<ulong, Maybe<ulong>> SizeHint() => _inner.SizeHint(); 202 public override readonly string ToString() => string.Empty; 203 public Result<TInit, TErr> TryFold<TInit, TErr>(TInit init, Fn<TInit, TKey, Result<TInit, TErr>> f) where TInit: notnull where TErr: notnull => IIterator<TKey>.TryFoldDefault(ref this, init, f); 204 readonly Result<IntoKeys<TKey, TValue>, Bottom> ITryInto<IntoKeys<TKey, TValue>, Bottom>.TryInto() => new(this); 205 #endregion 206 207 #region Operators 208 #endregion 209 210 #region Types 211 #endregion 212 } 213 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 0)] 214 public struct IntoValues<TKey, TValue>: IInto<IntoValues<TKey, TValue>>, IExactSizeIterator<TValue>, IFusedIterator<TValue> where TKey: notnull where TValue: notnull { 215 216 #region Type-level Constructors 217 #endregion 218 219 #region Instance Constructors 220 public IntoValues() => throw new InvalidOperationException("Parameterless constructor is not allowed to be called!"); 221 [MethodImpl(MethodImplOptions.AggressiveInlining)] 222 internal IntoValues(IntoIter<TKey, TValue> inner) => _inner = inner; 223 #endregion 224 225 #region Type-level Fields 226 #endregion 227 228 #region Instance Fields 229 IntoIter<TKey, TValue> _inner; 230 #endregion 231 232 #region Type-level Properties 233 #endregion 234 235 #region Instance Properties 236 #endregion 237 238 #region Type-level Functions 239 #endregion 240 241 #region Instance Functions 242 public Result<Unit, ulong> AdvanceBy(ulong n) => IIterator<TValue>.AdvanceByDefault(ref this, n); 243 public ulong Count() => IIterator<TValue>.CountDefault(ref this); 244 public TInit Fold<TInit>(TInit init, Fn<TInit, TValue, TInit> f) where TInit: notnull => IIterator<TValue>.FoldDefault(ref this, init, f); 245 public override readonly bool Equals(object? _) => false; 246 public override readonly int GetHashCode() => 0; 247 public readonly IntoValues<TKey, TValue> Into() => this; 248 public readonly bool IsEmpty() => _inner.IsEmpty(); 249 public Maybe<TValue> Last() => IIterator<TValue>.LastDefault(ref this); 250 public readonly ulong Len() => _inner.Len(); 251 [MethodImpl(MethodImplOptions.AggressiveInlining)] 252 public Maybe<TValue> Next() => _inner.Next().Map((tup) => tup.Item1); 253 public readonly Prod<ulong, Maybe<ulong>> SizeHint() => _inner.SizeHint(); 254 public override readonly string ToString() => string.Empty; 255 public Result<TInit, TErr> TryFold<TInit, TErr>(TInit init, Fn<TInit, TValue, Result<TInit, TErr>> f) where TInit: notnull where TErr: notnull => IIterator<TValue>.TryFoldDefault(ref this, init, f); 256 readonly Result<IntoValues<TKey, TValue>, Bottom> ITryInto<IntoValues<TKey, TValue>, Bottom>.TryInto() => new(this); 257 #endregion 258 259 #region Operators 260 #endregion 261 262 #region Types 263 #endregion 264 } 265 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 0)] 266 public struct Iter<TKey, TValue>: IInto<Iter<TKey, TValue>>, IExactSizeIterator<ProdMut<TKey, TValue>>, IFusedIterator<ProdMut<TKey, TValue>> where TKey: notnull where TValue: notnull { 267 268 #region Type-level Constructors 269 #endregion 270 271 #region Instance Constructors 272 public Iter() => throw new InvalidOperationException("Parameterless constructor is not allowed to be called!"); 273 [MethodImpl(MethodImplOptions.AggressiveInlining)] 274 internal Iter(@base::Iter<TKey, TValue> @base) => _base = @base; 275 #endregion 276 277 #region Type-level Fields 278 #endregion 279 280 #region Instance Fields 281 @base::Iter<TKey, TValue> _base; 282 #endregion 283 284 #region Type-level Properties 285 #endregion 286 287 #region Instance Properties 288 #endregion 289 290 #region Type-level Functions 291 #endregion 292 293 #region Instance Functions 294 public Result<Unit, ulong> AdvanceBy(ulong n) => IIterator<ProdMut<TKey, TValue>>.AdvanceByDefault(ref this, n); 295 public ulong Count() => IIterator<ProdMut<TKey, TValue>>.CountDefault(ref this); 296 public TInit Fold<TInit>(TInit init, Fn<TInit, ProdMut<TKey, TValue>, TInit> f) where TInit: notnull => IIterator<ProdMut<TKey, TValue>>.FoldDefault(ref this, init, f); 297 public override readonly bool Equals(object? _) => false; 298 public override readonly int GetHashCode() => 0; 299 readonly Iter<TKey, TValue> IInto<Iter<TKey, TValue>>.Into() => this; 300 public readonly bool IsEmpty() => _base.IsEmpty(); 301 public Maybe<ProdMut<TKey, TValue>> Last() => IIterator<ProdMut<TKey, TValue>>.LastDefault(ref this); 302 public readonly ulong Len() => _base.Len(); 303 [MethodImpl(MethodImplOptions.AggressiveInlining)] 304 public Maybe<ProdMut<TKey, TValue>> Next() => _base.Next(); 305 public readonly Prod<ulong, Maybe<ulong>> SizeHint() => _base.SizeHint(); 306 public override readonly string ToString() => string.Empty; 307 public Result<TInit, TErr> TryFold<TInit, TErr>(TInit init, Fn<TInit, ProdMut<TKey, TValue>, Result<TInit, TErr>> f) where TInit: notnull where TErr: notnull => IIterator<ProdMut<TKey, TValue>>.TryFoldDefault(ref this, init, f); 308 readonly Result<Iter<TKey, TValue>, Bottom> ITryInto<Iter<TKey, TValue>, Bottom>.TryInto() => new(this); 309 #endregion 310 311 #region Operators 312 #endregion 313 314 #region Types 315 #endregion 316 } 317 public static class Functions { 318 319 #region Type-level Constructors 320 #endregion 321 322 #region Instance Constructors 323 #endregion 324 325 #region Type-level Fields 326 #endregion 327 328 #region Instance Fields 329 #endregion 330 331 #region Type-level Properties 332 #endregion 333 334 #region Instance Properties 335 #endregion 336 337 #region Type-level Functions 338 public static HashMap<TKey, TValue, THasher, TBuildHasher> Clone<TKey, TValue, THasher, TBuildHasher>(in this HashMap<TKey, TValue, THasher, TBuildHasher> self) where TKey: notnull, IClone<TKey>, IEq<TKey>, IHashable where TValue: notnull, IClone<TValue> where THasher: notnull, IHasher where TBuildHasher: notnull, IBuildHasher<THasher>, IClone<TBuildHasher> => new(@base.Functions.Clone(in self._base)); 339 public static bool Eq<TKey, TValue, THasher, TBuildHasher>(in this HashMap<TKey, TValue, THasher, TBuildHasher> self, in HashMap<TKey, TValue, THasher, TBuildHasher> other) where TKey: notnull, IEq<TKey>, IHashable where TValue: notnull, IPartialEq<TValue, TValue> where THasher: notnull, IHasher where TBuildHasher: notnull, IBuildHasher<THasher> { 340 341 Maybe<ProdMut<TKey, TValue>> val; 342 Maybe<ProdMut<TKey, TValue>> val2; 343 var iter = self.IntoIter(); 344 var iter2 = other.IntoIter(); 345 bool eq; 346 347 while ((val = iter.Next()).IsSome) { 348 val2 = iter2.Next(); 349 350 if (val2.IsNone) { 351 return false; 352 } else { 353 eq = val._some.Eq<ProdMut<TKey, TValue>, TKey, TValue>(val2._some); 354 355 if (!eq) { 356 return false; 357 } 358 } 359 } 360 return iter2.Next().IsNone; 361 } 362 public static bool EqualsEquatable<TKey, TValue, THasher, TBuildHasher>(in this HashMap<TKey, TValue, THasher, TBuildHasher> self, in HashMap<TKey, TValue, THasher, TBuildHasher> other) where TKey: notnull, IEq<TKey>, IHashable where TValue: notnull, IEquatable<TValue> where THasher: notnull, IHasher where TBuildHasher: notnull, IBuildHasher<THasher> { 363 364 Maybe<ProdMut<TKey, TValue>> val; 365 Maybe<ProdMut<TKey, TValue>> val2; 366 var iter = self.IntoIter(); 367 var iter2 = other.IntoIter(); 368 369 while ((val = iter.Next()).IsSome) { 370 val2 = iter2.Next(); 371 if (val2.IsNone || (!(val._some.Item0 == val2._some.Item0 && val._some.Item1.Equals(val2._some.Item1)))) { return false; } 372 } 373 return iter2.Next().IsNone; 374 } 375 public static bool Ne<TKey, TValue, THasher, TBuildHasher>(in this HashMap<TKey, TValue, THasher, TBuildHasher> self, in HashMap<TKey, TValue, THasher, TBuildHasher> other) where TKey: notnull, IEq<TKey>, IHashable where TValue: notnull, IPartialEq<TValue, TValue> where THasher: notnull, IHasher where TBuildHasher: notnull, IBuildHasher<THasher> { 376 377 Maybe<ProdMut<TKey, TValue>> val; 378 Maybe<ProdMut<TKey, TValue>> val2; 379 var iter = self.IntoIter(); 380 var iter2 = other.IntoIter(); 381 bool ne; 382 383 while ((val = iter.Next()).IsSome) { 384 val2 = iter2.Next(); 385 386 if (val2.IsNone) { 387 return true; 388 } else { 389 ne = val._some.Ne<ProdMut<TKey, TValue>, TKey, TValue>(val2._some); 390 391 if (ne) { 392 return true; 393 } 394 } 395 } 396 return iter2.Next().IsSome; 397 } 398 #endregion 399 400 #region Instance Functions 401 #endregion 402 403 #region Operators 404 #endregion 405 406 #region Types 407 #endregion 408 } 409 #endregion 410 411 #region Namespaces 412 #endregion 413 } 414 #endregion