| #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member | 
|   | 
| using System; | 
| using System.Collections.Generic; | 
| using System.Runtime.CompilerServices; | 
|   | 
| namespace Cysharp.Threading.Tasks.Internal | 
| { | 
|     internal static class ArrayUtil | 
|     { | 
|         [MethodImpl(MethodImplOptions.AggressiveInlining)] | 
|         public static void EnsureCapacity<T>(ref T[] array, int index) | 
|         { | 
|             if (array.Length <= index) | 
|             { | 
|                 EnsureCore(ref array, index); | 
|             } | 
|         } | 
|   | 
|         // rare case, no inlining. | 
|         [MethodImpl(MethodImplOptions.NoInlining)] | 
|         static void EnsureCore<T>(ref T[] array, int index) | 
|         { | 
|             var newSize = array.Length * 2; | 
|             var newArray = new T[(index < newSize) ? newSize : (index * 2)]; | 
|             Array.Copy(array, 0, newArray, 0, array.Length); | 
|   | 
|             array = newArray; | 
|         } | 
|   | 
|         /// <summary> | 
|         /// Optimizing utility to avoid .ToArray() that creates buffer copy(cut to just size). | 
|         /// </summary> | 
|         public static (T[] array, int length) Materialize<T>(IEnumerable<T> source) | 
|         { | 
|             if (source is T[] array) | 
|             { | 
|                 return (array, array.Length); | 
|             } | 
|   | 
|             var defaultCount = 4; | 
|             if (source is ICollection<T> coll) | 
|             { | 
|                 defaultCount = coll.Count; | 
|                 var buffer = new T[defaultCount]; | 
|                 coll.CopyTo(buffer, 0); | 
|                 return (buffer, defaultCount); | 
|             } | 
|             else if (source is IReadOnlyCollection<T> rcoll) | 
|             { | 
|                 defaultCount = rcoll.Count; | 
|             } | 
|   | 
|             if (defaultCount == 0) | 
|             { | 
|                 return (Array.Empty<T>(), 0); | 
|             } | 
|   | 
|             { | 
|                 var index = 0; | 
|                 var buffer = new T[defaultCount]; | 
|                 foreach (var item in source) | 
|                 { | 
|                     EnsureCapacity(ref buffer, index); | 
|                     buffer[index++] = item; | 
|                 } | 
|   | 
|                 return (buffer, index); | 
|             } | 
|         } | 
|     } | 
| } |