| 'use strict'; |
| var InternalStateModule = require('../internals/internal-state'); |
| var createIteratorConstructor = require('../internals/create-iterator-constructor'); |
| var isObject = require('../internals/is-object'); |
| var defineProperties = require('../internals/object-define-properties'); |
| var DESCRIPTORS = require('../internals/descriptors'); |
| |
| var INCORRECT_RANGE = 'Incorrect Number.range arguments'; |
| var RANGE_ITERATOR = 'RangeIterator'; |
| |
| var setInternalState = InternalStateModule.set; |
| var getInternalState = InternalStateModule.getterFor(RANGE_ITERATOR); |
| |
| var $RangeIterator = createIteratorConstructor(function RangeIterator(start, end, option, type, zero, one) { |
| if (typeof start != type || (end !== Infinity && end !== -Infinity && typeof end != type)) { |
| throw new TypeError(INCORRECT_RANGE); |
| } |
| if (start === Infinity || start === -Infinity) { |
| throw new RangeError(INCORRECT_RANGE); |
| } |
| var ifIncrease = end > start; |
| var inclusiveEnd = false; |
| var step; |
| if (option === undefined) { |
| step = undefined; |
| } else if (isObject(option)) { |
| step = option.step; |
| inclusiveEnd = !!option.inclusive; |
| } else if (typeof option == type) { |
| step = option; |
| } else { |
| throw new TypeError(INCORRECT_RANGE); |
| } |
| if (step == null) { |
| step = ifIncrease ? one : -one; |
| } |
| if (typeof step != type) { |
| throw new TypeError(INCORRECT_RANGE); |
| } |
| if (step === Infinity || step === -Infinity || (step === zero && start !== end)) { |
| throw new RangeError(INCORRECT_RANGE); |
| } |
| // eslint-disable-next-line no-self-compare |
| var hitsEnd = start != start || end != end || step != step || (end > start) !== (step > zero); |
| setInternalState(this, { |
| type: RANGE_ITERATOR, |
| start: start, |
| end: end, |
| step: step, |
| inclusiveEnd: inclusiveEnd, |
| hitsEnd: hitsEnd, |
| currentCount: zero, |
| zero: zero |
| }); |
| if (!DESCRIPTORS) { |
| this.start = start; |
| this.end = end; |
| this.step = step; |
| this.inclusive = inclusiveEnd; |
| } |
| }, RANGE_ITERATOR, function next() { |
| var state = getInternalState(this); |
| if (state.hitsEnd) return { value: undefined, done: true }; |
| var start = state.start; |
| var end = state.end; |
| var step = state.step; |
| var currentYieldingValue = start + (step * state.currentCount++); |
| if (currentYieldingValue === end) state.hitsEnd = true; |
| var inclusiveEnd = state.inclusiveEnd; |
| var endCondition; |
| if (end > start) { |
| endCondition = inclusiveEnd ? currentYieldingValue > end : currentYieldingValue >= end; |
| } else { |
| endCondition = inclusiveEnd ? end > currentYieldingValue : end >= currentYieldingValue; |
| } |
| if (endCondition) { |
| return { value: undefined, done: state.hitsEnd = true }; |
| } return { value: currentYieldingValue, done: false }; |
| }); |
| |
| var getter = function (fn) { |
| return { get: fn, set: function () { /* empty */ }, configurable: true, enumerable: false }; |
| }; |
| |
| if (DESCRIPTORS) { |
| defineProperties($RangeIterator.prototype, { |
| start: getter(function () { |
| return getInternalState(this).start; |
| }), |
| end: getter(function () { |
| return getInternalState(this).end; |
| }), |
| inclusive: getter(function () { |
| return getInternalState(this).inclusiveEnd; |
| }), |
| step: getter(function () { |
| return getInternalState(this).step; |
| }) |
| }); |
| } |
| |
| module.exports = $RangeIterator; |