@@ -2776,7 +2776,11 @@ public string Empty
2776
2776
{
2777
2777
get
2778
2778
{
2779
+ #if UNITY_AOT
2780
+ return SR . EmptyEnumerable ;
2781
+ #else
2779
2782
return Strings . EmptyEnumerable ;
2783
+ #endif
2780
2784
}
2781
2785
}
2782
2786
}
@@ -2829,4 +2833,162 @@ public object[] Items
2829
2833
[ System . Diagnostics . DebuggerBrowsable ( System . Diagnostics . DebuggerBrowsableState . Never ) ]
2830
2834
private int count ;
2831
2835
}
2836
+
2837
+
2838
+ #if UNITY_AOT
2839
+ // <summary>
2840
+ /// An iterator that can produce an array or <see cref="List{TElement}"/> through an optimized path.
2841
+ /// </summary>
2842
+ internal interface IIListProvider < TElement > : IEnumerable < TElement >
2843
+ {
2844
+ /// <summary>
2845
+ /// Produce an array of the sequence through an optimized path.
2846
+ /// </summary>
2847
+ /// <returns>The array.</returns>
2848
+ TElement [ ] ToArray ( ) ;
2849
+
2850
+ /// <summary>
2851
+ /// Produce a <see cref="List{TElement}"/> of the sequence through an optimized path.
2852
+ /// </summary>
2853
+ /// <returns>The <see cref="List{TElement}"/>.</returns>
2854
+ List < TElement > ToList ( ) ;
2855
+
2856
+ /// <summary>
2857
+ /// Returns the count of elements in the sequence.
2858
+ /// </summary>
2859
+ /// <param name="onlyIfCheap">If true then the count should only be calculated if doing
2860
+ /// so is quick (sure or likely to be constant time), otherwise -1 should be returned.</param>
2861
+ /// <returns>The number of elements.</returns>
2862
+ int GetCount ( bool onlyIfCheap ) ;
2863
+ }
2864
+
2865
+ internal static partial class Error
2866
+ {
2867
+ internal static Exception ArgumentNull ( string s ) => new ArgumentNullException ( s ) ;
2868
+
2869
+ internal static Exception ArgumentOutOfRange ( string s ) => new ArgumentOutOfRangeException ( s ) ;
2870
+
2871
+ internal static Exception MoreThanOneElement ( ) => new InvalidOperationException ( SR . MoreThanOneElement ) ;
2872
+
2873
+ internal static Exception MoreThanOneMatch ( ) => new InvalidOperationException ( SR . MoreThanOneMatch ) ;
2874
+
2875
+ internal static Exception NoElements ( ) => new InvalidOperationException ( SR . NoElements ) ;
2876
+
2877
+ internal static Exception NoMatch ( ) => new InvalidOperationException ( SR . NoMatch ) ;
2878
+
2879
+ internal static Exception NotSupported ( ) => new NotSupportedException ( ) ;
2880
+ }
2881
+
2882
+ public static partial class Enumerable
2883
+ {
2884
+ public static IEnumerable < TSource > SkipLast < TSource > ( this IEnumerable < TSource > source , int count )
2885
+ {
2886
+ if ( source == null )
2887
+ {
2888
+ throw Error . ArgumentNull ( nameof ( source ) ) ;
2889
+ }
2890
+
2891
+ if ( count <= 0 )
2892
+ {
2893
+ return source . Skip ( 0 ) ;
2894
+ }
2895
+
2896
+ return SkipLastIterator ( source , count ) ;
2897
+ }
2898
+
2899
+ private static IEnumerable < TSource > SkipLastIterator < TSource > ( IEnumerable < TSource > source , int count )
2900
+ {
2901
+ var queue = new Queue < TSource > ( ) ;
2902
+
2903
+ using ( IEnumerator < TSource > e = source . GetEnumerator ( ) )
2904
+ {
2905
+ while ( e . MoveNext ( ) )
2906
+ {
2907
+ if ( queue . Count == count )
2908
+ {
2909
+ do
2910
+ {
2911
+ yield return queue . Dequeue ( ) ;
2912
+ queue . Enqueue ( e . Current ) ;
2913
+ }
2914
+ while ( e . MoveNext ( ) ) ;
2915
+ break ;
2916
+ }
2917
+ else
2918
+ {
2919
+ queue . Enqueue ( e . Current ) ;
2920
+ }
2921
+ }
2922
+ }
2923
+ }
2924
+
2925
+ public static IEnumerable < TSource > TakeLast < TSource > ( this IEnumerable < TSource > source , int count )
2926
+ {
2927
+ if ( source == null )
2928
+ {
2929
+ throw Error . ArgumentNull ( nameof ( source ) ) ;
2930
+ }
2931
+
2932
+ if ( count <= 0 )
2933
+ {
2934
+ return EmptyEnumerable < TSource > . Instance ;
2935
+ }
2936
+
2937
+ return TakeLastIterator ( source , count ) ;
2938
+ }
2939
+
2940
+ private static IEnumerable < TSource > TakeLastIterator < TSource > ( IEnumerable < TSource > source , int count )
2941
+ {
2942
+ Queue < TSource > queue ;
2943
+
2944
+ using ( IEnumerator < TSource > e = source . GetEnumerator ( ) )
2945
+ {
2946
+ if ( ! e . MoveNext ( ) )
2947
+ {
2948
+ yield break ;
2949
+ }
2950
+
2951
+ queue = new Queue < TSource > ( ) ;
2952
+ queue . Enqueue ( e . Current ) ;
2953
+
2954
+ while ( e . MoveNext ( ) )
2955
+ {
2956
+ if ( queue . Count < count )
2957
+ {
2958
+ queue . Enqueue ( e . Current ) ;
2959
+ }
2960
+ else
2961
+ {
2962
+ do
2963
+ {
2964
+ queue . Dequeue ( ) ;
2965
+ queue . Enqueue ( e . Current ) ;
2966
+ }
2967
+ while ( e . MoveNext ( ) ) ;
2968
+ break ;
2969
+ }
2970
+ }
2971
+ }
2972
+
2973
+ do
2974
+ {
2975
+ yield return queue . Dequeue ( ) ;
2976
+ }
2977
+ while ( queue . Count > 0 ) ;
2978
+ }
2979
+
2980
+ public static HashSet < TSource > ToHashSet < TSource > ( this IEnumerable < TSource > source ) => source . ToHashSet ( comparer : null ) ;
2981
+
2982
+ public static HashSet < TSource > ToHashSet < TSource > ( this IEnumerable < TSource > source , IEqualityComparer < TSource > comparer )
2983
+ {
2984
+ if ( source == null )
2985
+ {
2986
+ throw Error . ArgumentNull ( nameof ( source ) ) ;
2987
+ }
2988
+
2989
+ // Don't pre-allocate based on knowledge of size, as potentially many elements will be dropped.
2990
+ return new HashSet < TSource > ( source , comparer ) ;
2991
+ }
2992
+ }
2993
+ #endif
2832
2994
}
0 commit comments