@@ -46,8 +46,11 @@ namespace FastExpressionCompiler.ImTools;
4646using System . Runtime . InteropServices ;
4747using System . Diagnostics . CodeAnalysis ;
4848
49- using static SmallMap ;
49+ #if NET8_0_OR_GREATER
5050using System . Runtime . Intrinsics ;
51+ #endif
52+
53+ using static SmallMap ;
5154
5255/// <summary>Helpers and polyfills for the missing things in the old .NET versions</summary>
5356public static class RefTools < T >
@@ -216,6 +219,7 @@ internal static ref T ThrowIndexOutOfBounds<T>(int index, int capacity) =>
216219 throw new IndexOutOfRangeException ( $ "Index { index } is out of range for Stack{ capacity } <{ typeof ( T ) } ,..>.") ;
217220}
218221
222+ /// <summary>Stack with the Size information to check the Capacity in the compile time</summary>
219223public interface IStack < T , TSize , TStack > : IStack < T , TStack >
220224 where TSize : struct , ISize
221225 where TStack : struct , IStack < T , TSize , TStack >
@@ -248,7 +252,11 @@ public interface IStack<T, TStack>
248252
249253// todo: @wip
250254/// <summary>Base marker for collection or container holding some number of items</summary>
251- public interface ISize { }
255+ public interface ISize
256+ {
257+ /// <summary>Returns the size of the collection or container</summary>
258+ int Size { get ; }
259+ }
252260/// <summary>Marker for collection or container holding 2 or items</summary>
253261public interface ISize2Plus : ISize { }
254262/// <summary>Marker for collection or container holding 4 or more items</summary>
@@ -811,13 +819,9 @@ public int GetHashCode((A, B, C) key) =>
811819 Hasher . Combine ( RuntimeHelpers . GetHashCode ( key . Item1 ) , Hasher . Combine ( RuntimeHelpers . GetHashCode ( key . Item2 ) , RuntimeHelpers . GetHashCode ( key . Item3 ) ) ) ;
812820}
813821
814- /// <summary>Add the Infer parameter to `T Method<T>(..., Infer{T} _)` to enable type inference for T,
815- /// by calling it as `var t = Method(..., default(Infer{T}))`</summary>
816- public class Use < T >
817- {
818- public static readonly Use < T > It = new Use < T > ( ) ;
819- private Use ( ) { }
820- }
822+ /// <summary>Add the Infer parameter to `T Method{T}(..., Use{T} _)` to enable type inference for T,
823+ /// by calling it as `var t = Method(..., default(Use{T}))`</summary>
824+ public interface Use < T > { }
821825
822826/// <summary>Configuration and the tools for the SmallMap and friends</summary>
823827public static class SmallMap
@@ -974,7 +978,7 @@ public static ref TEntry TryGetEntryRef_loop<K, TEntry, TEq, TStackHashes, TStac
974978 /// <summary>Lookup for the K in the TStackEntries, first by calculating it hash with TEq and searching the hash in the TStackHashes</summary>
975979 public static ref TEntry TryGetEntryRef_ILP < K , TEntry , TEq , TStackHashes , TStackEntries , TCap > (
976980 this ref TStackEntries entries , ref TStackHashes hashes , K key , out bool found ,
977- TEq eq = default , Use < TEntry > _ = default , Use < TCap > _cap = default )
981+ TEq eq = default , TCap cap = default , Use < TEntry > _ = default )
978982 where TEntry : struct , IEntry < K >
979983 where TEq : struct , IEq < K >
980984 where TStackHashes : struct , IStack < int , TCap , TStackHashes >
@@ -983,7 +987,7 @@ public static ref TEntry TryGetEntryRef_ILP<K, TEntry, TEq, TStackHashes, TStack
983987 {
984988 var hash = eq . GetHashCode ( key ) ;
985989
986- for ( var i = 0 ; i < hashes . Capacity ; i += 4 )
990+ for ( var i = 0 ; i < cap . Size ; i += 4 )
987991 {
988992 ref var h0 = ref hashes . GetSurePresentItemRef ( i ) ;
989993 ref var h1 = ref hashes . GetSurePresentItemRef ( i + 1 ) ;
@@ -1032,21 +1036,19 @@ public static ref TEntry TryGetEntryRef_ILP<K, TEntry, TEq, TStackHashes, TStack
10321036 }
10331037
10341038 /// <summary>Lookup for the K in the TStackEntries, first by calculating it hash with TEq and searching the hash in the TStackHashes</summary>
1035- public static ref TEntry TryGetEntryRef < K , TEntry , TEq , TStackHashes , TStackEntries > (
1039+ public static ref TEntry TryGetEntryRef < K , TEntry , TEq , TCap , TStackHashes , TStackEntries > (
10361040 this ref TStackEntries entries , ref TStackHashes hashes , K key , out bool found ,
1037- TEq eq = default , Use < TEntry > _ = default )
1041+ TEq eq = default , TCap cap = default , Use < TEntry > _ = default )
10381042 where TEntry : struct , IEntry < K >
10391043 where TEq : struct , IEq < K >
1040- where TStackHashes : struct , IStack < int , TStackHashes >
1041- where TStackEntries : struct , IStack < TEntry , TStackEntries >
1044+ where TStackHashes : struct , IStack < int , TCap , TStackHashes >
1045+ where TStackEntries : struct , IStack < TEntry , TCap , TStackEntries >
1046+ where TCap : struct , ISize2Plus
10421047 {
1043- Debug . Assert ( hashes . Capacity == entries . Capacity ,
1044- "Expecting that the hashes and entries stacks have the same capacity" ) ;
1045-
10461048 var hash = eq . GetHashCode ( key ) ;
10471049
10481050#if NET8_0_OR_GREATER
1049- if ( hashes . Capacity >= 8 & Vector256 . IsHardwareAccelerated )
1051+ if ( cap . Size >= 8 & Vector256 . IsHardwareAccelerated )
10501052 {
10511053 var vHash = Vector256 . Create ( hash ) ;
10521054 var vHashes = MemoryMarshal . Cast < int , Vector256 < int > > ( hashes . AsSpan ( ) ) ;
@@ -1076,7 +1078,7 @@ public static ref TEntry TryGetEntryRef<K, TEntry, TEq, TStackHashes, TStackEntr
10761078 }
10771079#endif
10781080
1079- if ( hashes . Capacity >= 4 )
1081+ if ( cap . Size >= 4 )
10801082 {
10811083 for ( var i = 0 ; i < hashes . Capacity ; i += 4 )
10821084 {
@@ -1122,7 +1124,7 @@ public static ref TEntry TryGetEntryRef<K, TEntry, TEq, TStackHashes, TStackEntr
11221124 }
11231125 }
11241126 }
1125- else if ( hashes . Capacity == 2 )
1127+ else
11261128 {
11271129 ref var h0 = ref hashes . GetSurePresentItemRef ( 0 ) ;
11281130 ref var h1 = ref hashes . GetSurePresentItemRef ( 1 ) ;
0 commit comments