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.
		
		
		
		
		
			
		
			
				
					
					
						
							103 lines
						
					
					
						
							1.9 KiB
						
					
					
				
			
		
		
	
	
							103 lines
						
					
					
						
							1.9 KiB
						
					
					
				'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 | 
						|
 | 
						|
 |