|
|
'use strict'
class Hoopy extends Array { constructor (size) { let index, isIndexOverflowed
if (! isPositiveInteger(size)) { throw new TypeError('Argument `size` must be a positive integer.') }
super(size)
this.grow = by => { if (! isPositiveInteger(by)) { throw new TypeError('Argument `by` must be a positive integer.') }
let i const newSize = size + by
for (i = size; i < newSize; ++i) { this[i] = undefined }
if (isIndexOverflowed) { for (i = 0; i <= index; ++i) { let j = size + i if (j >= newSize) { j %= newSize } this[j] = this[i] this[i] = undefined } }
size = newSize }
return new Proxy(this, { get (target, key) { if (isInteger(key)) { return target[getIndex(key, size)] }
return target[key] },
set (target, key, value) { if (isInteger(key)) { index = getIndex(key, size) target[index] = value
if (Math.abs(key) >= size) { isIndexOverflowed = true } else { isIndexOverflowed = false } } else { target[key] = value } return true } }) } }
function isPositiveInteger (thing) { return isInteger(thing) && thing > 0 }
function isInteger (thing) { try { return +thing % 1 === 0 } catch (error) { // Coercing symbols to numbers throws an error
}
return false }
function getIndex (key, size) { if (key === 0) { return 0 }
if (key < 0) { return (size - Math.abs(key)) % size }
return key % size }
function nop () { throw new Error('Not implemented') }
Hoopy.prototype.push = nop Hoopy.prototype.pop = nop Hoopy.prototype.shift = nop Hoopy.prototype.unshift = nop
module.exports = Hoopy
|