You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

172 lines
5.0 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. namespace Apewer
  5. {
  6. /// <summary>数组构建器。</summary>
  7. public sealed class ArrayBuilder<T>
  8. {
  9. private T[] _array;
  10. private int _capacity;
  11. private int _count;
  12. private int _step;
  13. /// <summary>创建构建程序实例。</summary>
  14. /// <param name="step">每次扩容的增量,最小值:1,默认值:256。</param>
  15. /// <exception cref="ArgumentNullException"></exception>
  16. public ArrayBuilder(int step = 256)
  17. {
  18. if (step < 1) throw new ArgumentOutOfRangeException(nameof(step));
  19. _step = step;
  20. _capacity = step;
  21. _count = 0;
  22. _array = new T[step];
  23. }
  24. private ArrayBuilder(ArrayBuilder<T> old)
  25. {
  26. _step = old._step;
  27. _capacity = old._capacity;
  28. _count = old._count;
  29. _array = new T[_capacity];
  30. if (_count > 0) Array.Copy(old._array, _array, _count);
  31. }
  32. /// <summary>获取或设置指定位置的元素,索引器范围为 [0, Length)。</summary>
  33. /// <exception cref="ArgumentOutOfRangeException"></exception>
  34. public T this[int index]
  35. {
  36. get
  37. {
  38. if (index < 0 || index >= _count) throw new ArgumentOutOfRangeException("索引超出了当前数组的范围。");
  39. return _array[index];
  40. }
  41. set
  42. {
  43. if (index < 0 || index >= _count) throw new ArgumentOutOfRangeException("索引超出了当前数组的范围。");
  44. _array[index] = value;
  45. }
  46. }
  47. /// <summary>缓冲区的容量。</summary>
  48. public int Capacity { get => _capacity; }
  49. /// <summary>当前的元素数量。</summary>
  50. public int Length { get => _count; }
  51. /// <summary>当前的元素数量。</summary>
  52. public int Count { get => _count; }
  53. /// <summary>添加元素。</summary>
  54. public void Add(T item)
  55. {
  56. if (_capacity - _count < 1)
  57. {
  58. _capacity += _step;
  59. var temp = new T[_capacity];
  60. Array.Copy(_array, temp, _count);
  61. _array = temp;
  62. }
  63. _array[_count] = item;
  64. _count++;
  65. }
  66. /// <summary>添加多个元素。</summary>
  67. public void Add(params T[] items)
  68. {
  69. if (items == null) return;
  70. var length = items.Length;
  71. if (length < 1) return;
  72. if (_capacity - _count < length)
  73. {
  74. _capacity = _count + length;
  75. var temp = new T[_capacity];
  76. Array.Copy(_array, temp, _count);
  77. _array = temp;
  78. }
  79. Array.Copy(items, _array, length);
  80. _count += length;
  81. }
  82. /// <summary>添加多个元素。</summary>
  83. public void Add(ICollection<T> items)
  84. {
  85. if (items == null) return;
  86. var length = items.Count;
  87. if (length < 1) return;
  88. if (_capacity - _count < length)
  89. {
  90. _capacity = _count + length;
  91. var temp = new T[_capacity];
  92. Array.Copy(_array, temp, _count);
  93. _array = temp;
  94. }
  95. items.CopyTo(_array, _count);
  96. _count += length;
  97. }
  98. /// <summary>添加多个元素。</summary>
  99. public void Add(IEnumerable<T> items)
  100. {
  101. if (items == null) return;
  102. foreach (var item in items) Add(item);
  103. }
  104. /// <summary>清空所有元素。</summary>
  105. public void Clear()
  106. {
  107. _capacity = 0;
  108. _count = 0;
  109. _array = new T[0];
  110. }
  111. // 修剪数组,去除剩余空间。
  112. void Trim()
  113. {
  114. if (_count == 0)
  115. {
  116. if (_capacity > 0)
  117. {
  118. _capacity = 0;
  119. _array = new T[0];
  120. }
  121. return;
  122. }
  123. if (_count == _capacity) return;
  124. var array = new T[_count];
  125. Array.Copy(_array, array, _count);
  126. _capacity = _count;
  127. }
  128. /// <summary></summary>
  129. /// <param name="clear"></param>
  130. /// <returns></returns>
  131. public T[] Export(bool clear = false)
  132. {
  133. if (_count == 0) return new T[0];
  134. if (_count == _capacity) return _array;
  135. var array = new T[_count];
  136. Array.Copy(_array, array, _count);
  137. return array;
  138. }
  139. /// <summary>克隆当前实例,生成新实例。</summary>
  140. public ArrayBuilder<T> Clone() => new ArrayBuilder<T>(this);
  141. /// <summary>使用 Export 方法实现从 ArrayBuilder&lt;T&gt; 到 T[] 的隐式转换。</summary>
  142. public static implicit operator T[](ArrayBuilder<T> instance) => instance == null ? null : instance.Export();
  143. }
  144. }