AutoResizeArrayCore.cs 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. using System.Runtime.CompilerServices;
  2. using System.Runtime.InteropServices;
  3. namespace Lua.Internal;
  4. internal struct AutoResizeArrayCore<T>
  5. {
  6. T[]? array;
  7. int size;
  8. public int Size => size;
  9. public int Capacity => array == null ? 0 : array.Length;
  10. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  11. public void Add(T item)
  12. {
  13. this[size] = item;
  14. }
  15. public ref T this[int index]
  16. {
  17. get
  18. {
  19. EnsureCapacity(index);
  20. size = Math.Max(size, index + 1);
  21. #if NET6_0_OR_GREATER
  22. ref var reference = ref MemoryMarshal.GetArrayDataReference(array!);
  23. #else
  24. ref var reference = ref MemoryMarshal.GetReference(array.AsSpan());
  25. #endif
  26. return ref Unsafe.Add(ref reference, index);
  27. }
  28. }
  29. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  30. public Span<T> AsSpan()
  31. {
  32. return array.AsSpan(0, size);
  33. }
  34. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  35. public T[] GetInternalArray()
  36. {
  37. return array ?? [];
  38. }
  39. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  40. public void Clear()
  41. {
  42. array.AsSpan().Clear();
  43. }
  44. public void EnsureCapacity(int newCapacity, bool overrideSize = false)
  45. {
  46. var capacity = 64;
  47. while (capacity <= newCapacity)
  48. {
  49. capacity = MathEx.NewArrayCapacity(capacity);
  50. }
  51. if (array == null)
  52. {
  53. array = new T[capacity];
  54. }
  55. else
  56. {
  57. Array.Resize(ref array, capacity);
  58. }
  59. if (overrideSize)
  60. {
  61. size = newCapacity;
  62. }
  63. }
  64. public void Shrink(int newSize)
  65. {
  66. if (array != null && array.Length > newSize)
  67. {
  68. array.AsSpan(newSize).Clear();
  69. }
  70. size = newSize;
  71. }
  72. }