ManagedArray.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. import Check from "./Check.js";
  2. import defaultValue from "./defaultValue.js";
  3. /**
  4. * A wrapper around arrays so that the internal length of the array can be manually managed.
  5. *
  6. * @alias ManagedArray
  7. * @constructor
  8. * @private
  9. *
  10. * @param {number} [length=0] The initial length of the array.
  11. */
  12. function ManagedArray(length) {
  13. length = defaultValue(length, 0);
  14. this._array = new Array(length);
  15. this._length = length;
  16. }
  17. Object.defineProperties(ManagedArray.prototype, {
  18. /**
  19. * Gets or sets the length of the array.
  20. * If the set length is greater than the length of the internal array, the internal array is resized.
  21. *
  22. * @memberof ManagedArray.prototype
  23. * @type {number}
  24. */
  25. length: {
  26. get: function () {
  27. return this._length;
  28. },
  29. set: function (length) {
  30. //>>includeStart('debug', pragmas.debug);
  31. Check.typeOf.number.greaterThanOrEquals("length", length, 0);
  32. //>>includeEnd('debug');
  33. const array = this._array;
  34. const originalLength = this._length;
  35. if (length < originalLength) {
  36. // Remove trailing references
  37. for (let i = length; i < originalLength; ++i) {
  38. array[i] = undefined;
  39. }
  40. } else if (length > array.length) {
  41. array.length = length;
  42. }
  43. this._length = length;
  44. },
  45. },
  46. /**
  47. * Gets the internal array.
  48. *
  49. * @memberof ManagedArray.prototype
  50. * @type {Array}
  51. * @readonly
  52. */
  53. values: {
  54. get: function () {
  55. return this._array;
  56. },
  57. },
  58. });
  59. /**
  60. * Gets the element at an index.
  61. *
  62. * @param {number} index The index to get.
  63. */
  64. ManagedArray.prototype.get = function (index) {
  65. //>>includeStart('debug', pragmas.debug);
  66. Check.typeOf.number.lessThan("index", index, this._array.length);
  67. //>>includeEnd('debug');
  68. return this._array[index];
  69. };
  70. /**
  71. * Sets the element at an index. Resizes the array if index is greater than the length of the array.
  72. *
  73. * @param {number} index The index to set.
  74. * @param {*} element The element to set at index.
  75. */
  76. ManagedArray.prototype.set = function (index, element) {
  77. //>>includeStart('debug', pragmas.debug);
  78. Check.typeOf.number("index", index);
  79. //>>includeEnd('debug');
  80. if (index >= this._length) {
  81. this.length = index + 1;
  82. }
  83. this._array[index] = element;
  84. };
  85. /**
  86. * Returns the last element in the array without modifying the array.
  87. *
  88. * @returns {*} The last element in the array.
  89. */
  90. ManagedArray.prototype.peek = function () {
  91. return this._array[this._length - 1];
  92. };
  93. /**
  94. * Push an element into the array.
  95. *
  96. * @param {*} element The element to push.
  97. */
  98. ManagedArray.prototype.push = function (element) {
  99. const index = this.length++;
  100. this._array[index] = element;
  101. };
  102. /**
  103. * Pop an element from the array.
  104. *
  105. * @returns {*} The last element in the array.
  106. */
  107. ManagedArray.prototype.pop = function () {
  108. if (this._length === 0) {
  109. return undefined;
  110. }
  111. const element = this._array[this._length - 1];
  112. --this.length;
  113. return element;
  114. };
  115. /**
  116. * Resize the internal array if length > _array.length.
  117. *
  118. * @param {number} length The length.
  119. */
  120. ManagedArray.prototype.reserve = function (length) {
  121. //>>includeStart('debug', pragmas.debug);
  122. Check.typeOf.number.greaterThanOrEquals("length", length, 0);
  123. //>>includeEnd('debug');
  124. if (length > this._array.length) {
  125. this._array.length = length;
  126. }
  127. };
  128. /**
  129. * Resize the array.
  130. *
  131. * @param {number} length The length.
  132. */
  133. ManagedArray.prototype.resize = function (length) {
  134. //>>includeStart('debug', pragmas.debug);
  135. Check.typeOf.number.greaterThanOrEquals("length", length, 0);
  136. //>>includeEnd('debug');
  137. this.length = length;
  138. };
  139. /**
  140. * Trim the internal array to the specified length. Defaults to the current length.
  141. *
  142. * @param {number} [length] The length.
  143. */
  144. ManagedArray.prototype.trim = function (length) {
  145. length = defaultValue(length, this._length);
  146. this._array.length = length;
  147. };
  148. export default ManagedArray;