@@ -2776,7 +2776,11 @@ public string Empty
27762776 {
27772777 get
27782778 {
2779+ #if UNITY_AOT
2780+ return SR . EmptyEnumerable ;
2781+ #else
27792782 return Strings . EmptyEnumerable ;
2783+ #endif
27802784 }
27812785 }
27822786 }
@@ -2829,4 +2833,162 @@ public object[] Items
28292833 [ System . Diagnostics . DebuggerBrowsable ( System . Diagnostics . DebuggerBrowsableState . Never ) ]
28302834 private int count ;
28312835 }
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
28322994}
0 commit comments