#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6)) #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member using System; using System.Collections.Generic; using System.Runtime.CompilerServices; namespace UniRx.Async.Internal { internal static class ArrayPoolUtil { [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void EnsureCapacity(ref T[] array, int index, ArrayPool pool) { if (array.Length <= index) { EnsureCapacityCore(ref array, index, pool); } } [MethodImpl(MethodImplOptions.NoInlining)] static void EnsureCapacityCore(ref T[] array, int index, ArrayPool pool) { if (array.Length <= index) { var newSize = array.Length * 2; var newArray = pool.Rent((index < newSize) ? newSize : (index * 2)); Array.Copy(array, 0, newArray, 0, array.Length); pool.Return(array, clearArray: !RuntimeHelpersAbstraction.IsWellKnownNoReferenceContainsType()); array = newArray; } } public static RentArray Materialize(IEnumerable source) { if (source is T[] array) { return new RentArray(array, array.Length, null); } var defaultCount = 4; if (source is ICollection coll) { defaultCount = coll.Count; var pool = ArrayPool.Shared; var buffer = pool.Rent(defaultCount); coll.CopyTo(buffer, 0); return new RentArray(buffer, coll.Count, pool); } else if (source is IReadOnlyCollection rcoll) { defaultCount = rcoll.Count; } if (defaultCount == 0) { return new RentArray(Array.Empty(), 0, null); } { var pool = ArrayPool.Shared; var index = 0; var buffer = pool.Rent(defaultCount); foreach (var item in source) { EnsureCapacity(ref buffer, index, pool); buffer[index++] = item; } return new RentArray(buffer, index, pool); } } public struct RentArray : IDisposable { public readonly T[] Array; public readonly int Length; ArrayPool pool; public RentArray(T[] array, int length, ArrayPool pool) { this.Array = array; this.Length = length; this.pool = pool; } public void Dispose() { DisposeManually(!RuntimeHelpersAbstraction.IsWellKnownNoReferenceContainsType()); } public void DisposeManually(bool clearArray) { if (pool != null) { if (clearArray) { System.Array.Clear(Array, 0, Length); } pool.Return(Array, clearArray: false); pool = null; } } } } } #endif