1+ // ReSharper disable once CheckNamespace
2+
3+ using System ;
4+ using System . Buffers ;
5+ using System . Runtime . CompilerServices ;
6+
7+ // ReSharper disable once CheckNamespace
8+ namespace StructLinq
9+ {
10+ public static partial class StructEnumerable
11+ {
12+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
13+ private static ref T RefInnerLast < T , TEnumerator > ( TEnumerator enumerator )
14+ where TEnumerator : struct , IRefStructEnumerator < T >
15+ {
16+ if ( enumerator . MoveNext ( ) )
17+ {
18+ var rent = ArrayPool < T > . Shared . Rent ( 1 ) ;
19+ do
20+ {
21+ ref var elt = ref rent [ 0 ] ;
22+ ref var current = ref enumerator . Current ;
23+ elt = current ;
24+ }
25+ while ( enumerator . MoveNext ( ) ) ;
26+ enumerator . Dispose ( ) ;
27+ ref var result = ref rent [ 0 ] ;
28+ ArrayPool < T > . Shared . Return ( rent ) ;
29+ return ref result ;
30+ }
31+ enumerator . Dispose ( ) ;
32+ throw new Exception ( "No Elements" ) ;
33+ }
34+
35+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
36+ private static ref T RefInnerLast < T , TEnumerator > ( TEnumerator enumerator , Func < T , bool > predicate )
37+ where TEnumerator : struct , IRefStructEnumerator < T >
38+ {
39+ var rent = ArrayPool < T > . Shared . Rent ( 1 ) ;
40+ while ( enumerator . MoveNext ( ) )
41+ {
42+ ref var current = ref enumerator . Current ;
43+ if ( predicate ( current ) )
44+ {
45+ ref var elt = ref rent [ 0 ] ;
46+ elt = current ;
47+ }
48+ }
49+ enumerator . Dispose ( ) ;
50+ ref var result = ref rent [ 0 ] ;
51+ ArrayPool < T > . Shared . Return ( rent ) ;
52+ return ref result ;
53+ }
54+
55+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
56+ private static ref T RefInnerLast < T , TEnumerator , TFunc > ( TEnumerator enumerator , ref TFunc predicate )
57+ where TEnumerator : struct , IRefStructEnumerator < T >
58+ where TFunc : struct , IInFunction < T , bool >
59+ {
60+ while ( enumerator . MoveNext ( ) )
61+ {
62+ ref var current = ref enumerator . Current ;
63+ if ( predicate . Eval ( in current ) )
64+ {
65+ enumerator . Dispose ( ) ;
66+ return ref current ;
67+ }
68+ }
69+ enumerator . Dispose ( ) ;
70+ throw new Exception ( "No Match" ) ;
71+ }
72+
73+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
74+ public static ref T Last < T , TEnumerable , TEnumerator > ( this TEnumerable enumerable , Func < TEnumerable , IRefStructEnumerable < T , TEnumerator > > _ )
75+ where TEnumerator : struct , IRefStructEnumerator < T >
76+ where TEnumerable : IRefStructEnumerable < T , TEnumerator >
77+ {
78+ var enumerator = enumerable . GetEnumerator ( ) ;
79+ return ref RefInnerLast < T , TEnumerator > ( enumerator ) ;
80+ }
81+
82+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
83+ public static ref T Last < T , TEnumerator > ( this IRefStructEnumerable < T , TEnumerator > enumerable )
84+ where TEnumerator : struct , IRefStructEnumerator < T >
85+ {
86+ var enumerator = enumerable . GetEnumerator ( ) ;
87+ return ref RefInnerLast < T , TEnumerator > ( enumerator ) ;
88+ }
89+
90+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
91+ public static ref T Last < T , TEnumerable , TEnumerator > ( this TEnumerable enumerable , Func < T , bool > predicate , Func < TEnumerable , IRefStructEnumerable < T , TEnumerator > > _ )
92+ where TEnumerator : struct , IRefStructEnumerator < T >
93+ where TEnumerable : IRefStructEnumerable < T , TEnumerator >
94+ {
95+ var enumerator = enumerable . GetEnumerator ( ) ;
96+ return ref RefInnerLast ( enumerator , predicate ) ;
97+ }
98+
99+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
100+ public static ref T Last < T , TEnumerator > ( this IRefStructEnumerable < T , TEnumerator > enumerable , Func < T , bool > predicate )
101+ where TEnumerator : struct , IRefStructEnumerator < T >
102+ {
103+ var enumerator = enumerable . GetEnumerator ( ) ;
104+ return ref RefInnerLast < T , TEnumerator > ( enumerator , predicate ) ;
105+ }
106+
107+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
108+ public static ref T Last < T , TEnumerable , TEnumerator , TFunc > ( this TEnumerable enumerable , ref TFunc predicate , Func < TEnumerable , IRefStructEnumerable < T , TEnumerator > > _ )
109+ where TEnumerator : struct , IRefStructEnumerator < T >
110+ where TEnumerable : IRefStructEnumerable < T , TEnumerator >
111+ where TFunc : struct , IInFunction < T , bool >
112+ {
113+ var enumerator = enumerable . GetEnumerator ( ) ;
114+ return ref RefInnerLast < T , TEnumerator , TFunc > ( enumerator , ref predicate ) ;
115+ }
116+ }
117+ }
0 commit comments