11// ReSharper disable once CheckNamespace
22
33using System ;
4- using System . Buffers ;
54using System . Runtime . CompilerServices ;
65
76// ReSharper disable once CheckNamespace
@@ -10,108 +9,102 @@ namespace StructLinq
109 public static partial class StructEnumerable
1110 {
1211 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
13- private static ref T RefInnerLast < T , TEnumerator > ( TEnumerator enumerator )
12+ private static bool RefTryInnerLast < T , TEnumerator > ( ref TEnumerator enumerator , ref T last )
1413 where TEnumerator : struct , IRefStructEnumerator < T >
1514 {
1615 if ( enumerator . MoveNext ( ) )
1716 {
18- var rent = ArrayPool < T > . Shared . Rent ( 1 ) ;
1917 do
2018 {
21- ref var elt = ref rent [ 0 ] ;
2219 ref var current = ref enumerator . Current ;
23- elt = current ;
20+ last = current ;
2421 }
2522 while ( enumerator . MoveNext ( ) ) ;
2623 enumerator . Dispose ( ) ;
27- ref var result = ref rent [ 0 ] ;
28- ArrayPool < T > . Shared . Return ( rent ) ;
29- return ref result ;
24+ return true ;
3025 }
31- enumerator . Dispose ( ) ;
32- throw new Exception ( "No Elements" ) ;
26+ return false ;
3327 }
3428
3529 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
36- private static ref T RefInnerLast < T , TEnumerator > ( TEnumerator enumerator , Func < T , bool > predicate )
30+ private static bool TryRefInnerLast < T , TEnumerator > ( ref TEnumerator enumerator , Func < T , bool > predicate , ref T last )
3731 where TEnumerator : struct , IRefStructEnumerator < T >
3832 {
39- var rent = ArrayPool < T > . Shared . Rent ( 1 ) ;
33+ bool found = false ;
4034 while ( enumerator . MoveNext ( ) )
4135 {
4236 ref var current = ref enumerator . Current ;
4337 if ( predicate ( current ) )
4438 {
45- ref var elt = ref rent [ 0 ] ;
46- elt = current ;
39+ last = current ;
40+ found = true ;
4741 }
4842 }
4943 enumerator . Dispose ( ) ;
50- ref var result = ref rent [ 0 ] ;
51- ArrayPool < T > . Shared . Return ( rent ) ;
52- return ref result ;
44+ return found ;
5345 }
5446
5547 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
56- private static ref T RefInnerLast < T , TEnumerator , TFunc > ( TEnumerator enumerator , ref TFunc predicate )
48+ private static bool TryRefInnerLast < T , TEnumerator , TFunc > ( ref TEnumerator enumerator , ref TFunc predicate , ref T last )
5749 where TEnumerator : struct , IRefStructEnumerator < T >
5850 where TFunc : struct , IInFunction < T , bool >
5951 {
52+ bool found = false ;
6053 while ( enumerator . MoveNext ( ) )
6154 {
6255 ref var current = ref enumerator . Current ;
6356 if ( predicate . Eval ( in current ) )
6457 {
65- enumerator . Dispose ( ) ;
66- return ref current ;
58+ last = current ;
59+ found = true ;
6760 }
6861 }
6962 enumerator . Dispose ( ) ;
70- throw new Exception ( "No Match" ) ;
63+ return found ;
7164 }
7265
7366 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
74- public static ref T Last < T , TEnumerable , TEnumerator > ( this TEnumerable enumerable , Func < TEnumerable , IRefStructEnumerable < T , TEnumerator > > _ )
67+ public static bool TryLast < T , TEnumerable , TEnumerator > ( this TEnumerable enumerable , ref T last , Func < TEnumerable , IRefStructEnumerable < T , TEnumerator > > _ )
7568 where TEnumerator : struct , IRefStructEnumerator < T >
7669 where TEnumerable : IRefStructEnumerable < T , TEnumerator >
7770 {
7871 var enumerator = enumerable . GetEnumerator ( ) ;
79- return ref RefInnerLast < T , TEnumerator > ( enumerator ) ;
72+ return RefTryInnerLast < T , TEnumerator > ( ref enumerator , ref last ) ;
8073 }
8174
8275 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
83- public static ref T Last < T , TEnumerator > ( this IRefStructEnumerable < T , TEnumerator > enumerable )
76+ public static bool TryLast < T , TEnumerator > ( this IRefStructEnumerable < T , TEnumerator > enumerable , ref T last )
8477 where TEnumerator : struct , IRefStructEnumerator < T >
8578 {
8679 var enumerator = enumerable . GetEnumerator ( ) ;
87- return ref RefInnerLast < T , TEnumerator > ( enumerator ) ;
80+ return RefTryInnerLast < T , TEnumerator > ( ref enumerator , ref last ) ;
8881 }
8982
9083 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
91- public static ref T Last < T , TEnumerable , TEnumerator > ( this TEnumerable enumerable , Func < T , bool > predicate , Func < TEnumerable , IRefStructEnumerable < T , TEnumerator > > _ )
84+ public static bool TryLast < T , TEnumerable , TEnumerator > ( this TEnumerable enumerable , Func < T , bool > predicate , ref T last , Func < TEnumerable , IRefStructEnumerable < T , TEnumerator > > _ )
9285 where TEnumerator : struct , IRefStructEnumerator < T >
9386 where TEnumerable : IRefStructEnumerable < T , TEnumerator >
9487 {
9588 var enumerator = enumerable . GetEnumerator ( ) ;
96- return ref RefInnerLast ( enumerator , predicate ) ;
89+ return TryRefInnerLast ( ref enumerator , predicate , ref last ) ;
9790 }
9891
9992 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
100- public static ref T Last < T , TEnumerator > ( this IRefStructEnumerable < T , TEnumerator > enumerable , Func < T , bool > predicate )
93+ public static bool TryLast < T , TEnumerator > ( this IRefStructEnumerable < T , TEnumerator > enumerable , Func < T , bool > predicate , ref T last )
10194 where TEnumerator : struct , IRefStructEnumerator < T >
10295 {
10396 var enumerator = enumerable . GetEnumerator ( ) ;
104- return ref RefInnerLast < T , TEnumerator > ( enumerator , predicate ) ;
97+ return TryRefInnerLast ( ref enumerator , predicate , ref last ) ;
10598 }
10699
107100 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
108- public static ref T Last < T , TEnumerable , TEnumerator , TFunc > ( this TEnumerable enumerable , ref TFunc predicate , Func < TEnumerable , IRefStructEnumerable < T , TEnumerator > > _ )
101+ public static bool TryLast < T , TEnumerable , TEnumerator , TFunc > ( this TEnumerable enumerable , ref TFunc predicate , ref T last , Func < TEnumerable , IRefStructEnumerable < T , TEnumerator > > _ )
109102 where TEnumerator : struct , IRefStructEnumerator < T >
110103 where TEnumerable : IRefStructEnumerable < T , TEnumerator >
111104 where TFunc : struct , IInFunction < T , bool >
112105 {
113106 var enumerator = enumerable . GetEnumerator ( ) ;
114- return ref RefInnerLast < T , TEnumerator , TFunc > ( enumerator , ref predicate ) ;
107+ return TryRefInnerLast ( ref enumerator , ref predicate , ref last ) ;
115108 }
116109 }
117110}
0 commit comments