--- /dev/null
+'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;