“use strict”; function arrayMove(src, srcIndex, dst, dstIndex, len) {

for (var j = 0; j < len; ++j) {
    dst[j + dstIndex] = src[j + srcIndex];
    src[j + srcIndex] = void 0;
}

}

function Queue(capacity) {

this._capacity = capacity;
this._length = 0;
this._front = 0;

}

Queue.prototype._willBeOverCapacity = function (size) {

return this._capacity < size;

};

Queue.prototype._pushOne = function (arg) {

var length = this.length();
this._checkCapacity(length + 1);
var i = (this._front + length) & (this._capacity - 1);
this[i] = arg;
this._length = length + 1;

};

Queue.prototype.push = function (fn, receiver, arg) {

var length = this.length() + 3;
if (this._willBeOverCapacity(length)) {
    this._pushOne(fn);
    this._pushOne(receiver);
    this._pushOne(arg);
    return;
}
var j = this._front + length - 3;
this._checkCapacity(length);
var wrapMask = this._capacity - 1;
this[(j + 0) & wrapMask] = fn;
this[(j + 1) & wrapMask] = receiver;
this[(j + 2) & wrapMask] = arg;
this._length = length;

};

Queue.prototype.shift = function () {

var front = this._front,
    ret = this[front];

this[front] = undefined;
this._front = (front + 1) & (this._capacity - 1);
this._length--;
return ret;

};

Queue.prototype.length = function () {

return this._length;

};

Queue.prototype._checkCapacity = function (size) {

if (this._capacity < size) {
    this._resizeTo(this._capacity << 1);
}

};

Queue.prototype._resizeTo = function (capacity) {

var oldCapacity = this._capacity;
this._capacity = capacity;
var front = this._front;
var length = this._length;
var moveItemsCount = (front + length) & (oldCapacity - 1);
arrayMove(this, 0, this, oldCapacity, moveItemsCount);

};

module.exports = Queue;