2 var InternalStateModule = require('../internals/internal-state');
3 var createIteratorConstructor = require('../internals/create-iterator-constructor');
4 var isObject = require('../internals/is-object');
5 var defineProperties = require('../internals/object-define-properties');
6 var DESCRIPTORS = require('../internals/descriptors');
8 var INCORRECT_RANGE = 'Incorrect Number.range arguments';
9 var RANGE_ITERATOR = 'RangeIterator';
11 var setInternalState = InternalStateModule.set;
12 var getInternalState = InternalStateModule.getterFor(RANGE_ITERATOR);
14 var $RangeIterator = createIteratorConstructor(function RangeIterator(start, end, option, type, zero, one) {
15 if (typeof start != type || (end !== Infinity && end !== -Infinity && typeof end != type)) {
16 throw new TypeError(INCORRECT_RANGE);
18 if (start === Infinity || start === -Infinity) {
19 throw new RangeError(INCORRECT_RANGE);
21 var ifIncrease = end > start;
22 var inclusiveEnd = false;
24 if (option === undefined) {
26 } else if (isObject(option)) {
28 inclusiveEnd = !!option.inclusive;
29 } else if (typeof option == type) {
32 throw new TypeError(INCORRECT_RANGE);
35 step = ifIncrease ? one : -one;
37 if (typeof step != type) {
38 throw new TypeError(INCORRECT_RANGE);
40 if (step === Infinity || step === -Infinity || (step === zero && start !== end)) {
41 throw new RangeError(INCORRECT_RANGE);
43 // eslint-disable-next-line no-self-compare
44 var hitsEnd = start != start || end != end || step != step || (end > start) !== (step > zero);
45 setInternalState(this, {
50 inclusiveEnd: inclusiveEnd,
59 this.inclusive = inclusiveEnd;
61 }, RANGE_ITERATOR, function next() {
62 var state = getInternalState(this);
63 if (state.hitsEnd) return { value: undefined, done: true };
64 var start = state.start;
66 var step = state.step;
67 var currentYieldingValue = start + (step * state.currentCount++);
68 if (currentYieldingValue === end) state.hitsEnd = true;
69 var inclusiveEnd = state.inclusiveEnd;
72 endCondition = inclusiveEnd ? currentYieldingValue > end : currentYieldingValue >= end;
74 endCondition = inclusiveEnd ? end > currentYieldingValue : end >= currentYieldingValue;
77 return { value: undefined, done: state.hitsEnd = true };
78 } return { value: currentYieldingValue, done: false };
81 var getter = function (fn) {
82 return { get: fn, set: function () { /* empty */ }, configurable: true, enumerable: false };
86 defineProperties($RangeIterator.prototype, {
87 start: getter(function () {
88 return getInternalState(this).start;
90 end: getter(function () {
91 return getInternalState(this).end;
93 inclusive: getter(function () {
94 return getInternalState(this).inclusiveEnd;
96 step: getter(function () {
97 return getInternalState(this).step;
102 module.exports = $RangeIterator;