12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- #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);
- }
- }
- }
- }
|