6
6
using System . Runtime . CompilerServices ;
7
7
using System . Text ;
8
8
using System . Threading ;
9
+ using System . Collections ;
9
10
10
11
namespace ImTools . Experimental
11
12
{
@@ -351,18 +352,59 @@ public override Entry GetEntryOrDefault(int hash) =>
351
352
/// <inheritdoc />
352
353
public override IEnumerable < ValueEntry > Enumerate ( )
353
354
{
354
- if ( Entry0 is ValueEntry v0 )
355
- yield return v0 ;
356
- else foreach ( var x in ( ( ConflictsEntry ) Entry0 ) . Conflicts )
357
- yield return x ;
358
- if ( Entry1 is ValueEntry v1 )
359
- yield return v1 ;
360
- else foreach ( var x in ( ( ConflictsEntry ) Entry1 ) . Conflicts )
361
- yield return x ;
362
- if ( Entry2 is ValueEntry v2 )
363
- yield return v2 ;
364
- else foreach ( var x in ( ( ConflictsEntry ) Entry2 ) . Conflicts )
365
- yield return x ;
355
+ return new Enumerable ( this ) ;
356
+
357
+ // if (Entry0 is ValueEntry v0)
358
+ // yield return v0;
359
+ // else foreach (var x in ((ConflictsEntry)Entry0).Conflicts)
360
+ // yield return x;
361
+ // if (Entry1 is ValueEntry v1)
362
+ // yield return v1;
363
+ // else foreach (var x in ((ConflictsEntry)Entry1).Conflicts)
364
+ // yield return x;
365
+ // if (Entry2 is ValueEntry v2)
366
+ // yield return v2;
367
+ // else foreach (var x in ((ConflictsEntry)Entry2).Conflicts)
368
+ // yield return x;
369
+ }
370
+
371
+
372
+ private readonly struct Enumerable : IEnumerable < ValueEntry >
373
+ {
374
+ private readonly Leaf3 _l ;
375
+ public Enumerable ( Leaf3 l ) => _l = l ;
376
+ public Enumerator GetEnumerator ( ) => new Enumerator ( _l , 0 ) ;
377
+ IEnumerator IEnumerable . GetEnumerator ( ) => GetEnumerator ( ) ;
378
+ IEnumerator < ValueEntry > IEnumerable < ValueEntry > . GetEnumerator ( ) => GetEnumerator ( ) ;
379
+ }
380
+
381
+ private struct Enumerator : IEnumerator < ValueEntry >
382
+ {
383
+ private readonly Leaf3 _l ;
384
+ private byte _i ;
385
+ public Enumerator ( Leaf3 l , byte i )
386
+ {
387
+ _l = l ;
388
+ _i = i ;
389
+ }
390
+
391
+ public ValueEntry Current
392
+ {
393
+ [ MethodImpl ( ( MethodImplOptions ) 256 ) ]
394
+ get
395
+ {
396
+ var i = _i ;
397
+ return ( ValueEntry ) (
398
+ i == 1 ? _l . Entry0 :
399
+ i == 2 ? _l . Entry1 :
400
+ _l . Entry2 ) ;
401
+ }
402
+ }
403
+ object IEnumerator . Current => Current ;
404
+ public bool MoveNext ( ) => ++ _i < 4 ;
405
+
406
+ public void Dispose ( ) { }
407
+ public void Reset ( ) => _i = 0 ;
366
408
}
367
409
368
410
/// <inheritdoc />
@@ -450,7 +492,6 @@ public override IEnumerable<ValueEntry> Enumerate()
450
492
var e1 = l . Entry1 ;
451
493
var e2 = l . Entry2 ;
452
494
453
- // [2*, 3, 4]
454
495
if ( ph < e0 . Hash )
455
496
{
456
497
if ( p is ValueEntry v )
@@ -707,7 +748,7 @@ public override ImHashMap234<K, V> RemoveEntry(int hash, K key)
707
748
}
708
749
709
750
/// <summary>Leaf with 5 entries</summary>
710
- public sealed class Leaf5 : ImHashMap234 < K , V >
751
+ public sealed class Leaf5 : ImHashMap234 < K , V > , IEnumerable < ValueEntry >
711
752
{
712
753
/// <summary>Left entry</summary>
713
754
public readonly Entry Entry0 ;
@@ -751,26 +792,75 @@ public override Entry GetEntryOrDefault(int hash) =>
751
792
/// <inheritdoc />
752
793
public override IEnumerable < ValueEntry > Enumerate ( )
753
794
{
754
- if ( Entry0 is ValueEntry v0 )
755
- yield return v0 ;
756
- else foreach ( var x in ( ( ConflictsEntry ) Entry0 ) . Conflicts )
757
- yield return x ;
758
- if ( Entry1 is ValueEntry v1 )
759
- yield return v1 ;
760
- else foreach ( var x in ( ( ConflictsEntry ) Entry1 ) . Conflicts )
761
- yield return x ;
762
- if ( Entry2 is ValueEntry v2 )
763
- yield return v2 ;
764
- else foreach ( var x in ( ( ConflictsEntry ) Entry2 ) . Conflicts )
765
- yield return x ;
766
- if ( Entry3 is ValueEntry v3 )
767
- yield return v3 ;
768
- else foreach ( var x in ( ( ConflictsEntry ) Entry3 ) . Conflicts )
769
- yield return x ;
770
- if ( Entry4 is ValueEntry v4 )
771
- yield return v4 ;
772
- else foreach ( var x in ( ( ConflictsEntry ) Entry4 ) . Conflicts )
773
- yield return x ;
795
+ return this ;
796
+ // if (Entry0 is ValueEntry v0)
797
+ // yield return v0;
798
+ // else foreach (var x in ((ConflictsEntry)Entry0).Conflicts)
799
+ // yield return x;
800
+ // if (Entry1 is ValueEntry v1)
801
+ // yield return v1;
802
+ // else foreach (var x in ((ConflictsEntry)Entry1).Conflicts)
803
+ // yield return x;
804
+ // if (Entry2 is ValueEntry v2)
805
+ // yield return v2;
806
+ // else foreach (var x in ((ConflictsEntry)Entry2).Conflicts)
807
+ // yield return x;
808
+ // if (Entry3 is ValueEntry v3)
809
+ // yield return v3;
810
+ // else foreach (var x in ((ConflictsEntry)Entry3).Conflicts)
811
+ // yield return x;
812
+ // if (Entry4 is ValueEntry v4)
813
+ // yield return v4;
814
+ // else foreach (var x in ((ConflictsEntry)Entry4).Conflicts)
815
+ // yield return x;
816
+ }
817
+
818
+ /// <summary>Returns the left-to-right enumerator</summary>
819
+ public IEnumerator < ValueEntry > GetEnumerator ( ) => new Enumerator ( this ) ;
820
+ IEnumerator < ValueEntry > IEnumerable < ValueEntry > . GetEnumerator ( ) => GetEnumerator ( ) ;
821
+ IEnumerator IEnumerable . GetEnumerator ( ) => GetEnumerator ( ) ;
822
+
823
+ private struct Enumerator : IEnumerator < ValueEntry >
824
+ {
825
+ private readonly Leaf5 _m ;
826
+ private byte _i , _j ;
827
+ public Enumerator ( Leaf5 m )
828
+ {
829
+ _m = m ;
830
+ _i = 0 ;
831
+ _j = 0 ;
832
+ Current = null ;
833
+ }
834
+
835
+ public ValueEntry Current { get ; private set ; }
836
+ object IEnumerator . Current => Current ;
837
+ public bool MoveNext ( )
838
+ {
839
+ for ( var i = _i ; i < 5 ; ++ _i )
840
+ {
841
+ var e = i == 0 ? _m . Entry0 : i == 1 ? _m . Entry1 : i == 2 ? _m . Entry2 : i == 3 ? _m . Entry3 : _m . Entry4 ;
842
+ if ( _j == 0 && e is ValueEntry v0 )
843
+ {
844
+ Current = v0 ;
845
+ ++ _i ;
846
+ return true ;
847
+ }
848
+
849
+ var ee = ( ( ConflictsEntry ) e ) . Conflicts ;
850
+ if ( _j < ( uint ) ee . Length )
851
+ {
852
+ Current = ee [ _j ++ ] ;
853
+ return true ;
854
+ }
855
+
856
+ _j = 0 ;
857
+ }
858
+
859
+ return false ;
860
+ }
861
+
862
+ public void Dispose ( ) { }
863
+ public void Reset ( ) { }
774
864
}
775
865
776
866
/// <inheritdoc />
@@ -2123,4 +2213,12 @@ public static void AddOrUpdate<K, V>(this ImHashMap234<K, V>[] parts, K key, V v
2123
2213
public static void RefAddOrUpdatePart < K , V > ( ref ImHashMap234 < K , V > part , int hash , K key , V value ) =>
2124
2214
Ref . Swap ( ref part , hash , key , value , ( x , h , k , v ) => x . AddOrUpdate ( h , k , v ) ) ;
2125
2215
}
2216
+
2217
+ /// <summary>Funny enumerable</summary>
2218
+ public interface IEnumerable < out T , out TEnumerator > : IEnumerable < T >
2219
+ where TEnumerator : IEnumerator < T >
2220
+ {
2221
+ /// <summary>Funny enumerator</summary>
2222
+ new TEnumerator GetEnumerator ( ) ;
2223
+ }
2126
2224
}
0 commit comments