import Check from "./Check.js"; import defaultValue from "./defaultValue.js"; /** * A wrapper around arrays so that the internal length of the array can be manually managed. * * @alias ManagedArray * @constructor * @private * * @param {Number} [length=0] The initial length of the array. */ function ManagedArray(length) { length = defaultValue(length, 0); this._array = new Array(length); this._length = length; } Object.defineProperties(ManagedArray.prototype, { /** * Gets or sets the length of the array. * If the set length is greater than the length of the internal array, the internal array is resized. * * @memberof ManagedArray.prototype * @type Number */ length: { get: function () { return this._length; }, set: function (length) { //>>includeStart('debug', pragmas.debug); Check.typeOf.number.greaterThanOrEquals("length", length, 0); //>>includeEnd('debug'); var array = this._array; var originalLength = this._length; if (length < originalLength) { // Remove trailing references for (var i = length; i < originalLength; ++i) { array[i] = undefined; } } else if (length > array.length) { array.length = length; } this._length = length; }, }, /** * Gets the internal array. * * @memberof ManagedArray.prototype * @type Array * @readonly */ values: { get: function () { return this._array; }, }, }); /** * Gets the element at an index. * * @param {Number} index The index to get. */ ManagedArray.prototype.get = function (index) { //>>includeStart('debug', pragmas.debug); Check.typeOf.number.lessThan("index", index, this._array.length); //>>includeEnd('debug'); return this._array[index]; }; /** * Sets the element at an index. Resizes the array if index is greater than the length of the array. * * @param {Number} index The index to set. * @param {*} element The element to set at index. */ ManagedArray.prototype.set = function (index, element) { //>>includeStart('debug', pragmas.debug); Check.typeOf.number("index", index); //>>includeEnd('debug'); if (index >= this._length) { this.length = index + 1; } this._array[index] = element; }; /** * Returns the last element in the array without modifying the array. * * @returns {*} The last element in the array. */ ManagedArray.prototype.peek = function () { return this._array[this._length - 1]; }; /** * Push an element into the array. * * @param {*} element The element to push. */ ManagedArray.prototype.push = function (element) { var index = this.length++; this._array[index] = element; }; /** * Pop an element from the array. * * @returns {*} The last element in the array. */ ManagedArray.prototype.pop = function () { if (this._length === 0) { return undefined; } var element = this._array[this._length - 1]; --this.length; return element; }; /** * Resize the internal array if length > _array.length. * * @param {Number} length The length. */ ManagedArray.prototype.reserve = function (length) { //>>includeStart('debug', pragmas.debug); Check.typeOf.number.greaterThanOrEquals("length", length, 0); //>>includeEnd('debug'); if (length > this._array.length) { this._array.length = length; } }; /** * Resize the array. * * @param {Number} length The length. */ ManagedArray.prototype.resize = function (length) { //>>includeStart('debug', pragmas.debug); Check.typeOf.number.greaterThanOrEquals("length", length, 0); //>>includeEnd('debug'); this.length = length; }; /** * Trim the internal array to the specified length. Defaults to the current length. * * @param {Number} [length] The length. */ ManagedArray.prototype.trim = function (length) { length = defaultValue(length, this._length); this._array.length = length; }; export default ManagedArray;