1 | 'use strict';
|
---|
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');
|
---|
7 |
|
---|
8 | var INCORRECT_RANGE = 'Incorrect Number.range arguments';
|
---|
9 | var NUMERIC_RANGE_ITERATOR = 'NumericRangeIterator';
|
---|
10 |
|
---|
11 | var setInternalState = InternalStateModule.set;
|
---|
12 | var getInternalState = InternalStateModule.getterFor(NUMERIC_RANGE_ITERATOR);
|
---|
13 |
|
---|
14 | var $RangeIterator = createIteratorConstructor(function NumericRangeIterator(start, end, option, type, zero, one) {
|
---|
15 | if (typeof start != type || (end !== Infinity && end !== -Infinity && typeof end != type)) {
|
---|
16 | throw new TypeError(INCORRECT_RANGE);
|
---|
17 | }
|
---|
18 | if (start === Infinity || start === -Infinity) {
|
---|
19 | throw new RangeError(INCORRECT_RANGE);
|
---|
20 | }
|
---|
21 | var ifIncrease = end > start;
|
---|
22 | var inclusiveEnd = false;
|
---|
23 | var step;
|
---|
24 | if (option === undefined) {
|
---|
25 | step = undefined;
|
---|
26 | } else if (isObject(option)) {
|
---|
27 | step = option.step;
|
---|
28 | inclusiveEnd = !!option.inclusive;
|
---|
29 | } else if (typeof option == type) {
|
---|
30 | step = option;
|
---|
31 | } else {
|
---|
32 | throw new TypeError(INCORRECT_RANGE);
|
---|
33 | }
|
---|
34 | if (step == null) {
|
---|
35 | step = ifIncrease ? one : -one;
|
---|
36 | }
|
---|
37 | if (typeof step != type) {
|
---|
38 | throw new TypeError(INCORRECT_RANGE);
|
---|
39 | }
|
---|
40 | if (step === Infinity || step === -Infinity || (step === zero && start !== end)) {
|
---|
41 | throw new RangeError(INCORRECT_RANGE);
|
---|
42 | }
|
---|
43 | // eslint-disable-next-line no-self-compare -- NaN check
|
---|
44 | var hitsEnd = start != start || end != end || step != step || (end > start) !== (step > zero);
|
---|
45 | setInternalState(this, {
|
---|
46 | type: NUMERIC_RANGE_ITERATOR,
|
---|
47 | start: start,
|
---|
48 | end: end,
|
---|
49 | step: step,
|
---|
50 | inclusiveEnd: inclusiveEnd,
|
---|
51 | hitsEnd: hitsEnd,
|
---|
52 | currentCount: zero,
|
---|
53 | zero: zero
|
---|
54 | });
|
---|
55 | if (!DESCRIPTORS) {
|
---|
56 | this.start = start;
|
---|
57 | this.end = end;
|
---|
58 | this.step = step;
|
---|
59 | this.inclusive = inclusiveEnd;
|
---|
60 | }
|
---|
61 | }, NUMERIC_RANGE_ITERATOR, function next() {
|
---|
62 | var state = getInternalState(this);
|
---|
63 | if (state.hitsEnd) return { value: undefined, done: true };
|
---|
64 | var start = state.start;
|
---|
65 | var end = state.end;
|
---|
66 | var step = state.step;
|
---|
67 | var currentYieldingValue = start + (step * state.currentCount++);
|
---|
68 | if (currentYieldingValue === end) state.hitsEnd = true;
|
---|
69 | var inclusiveEnd = state.inclusiveEnd;
|
---|
70 | var endCondition;
|
---|
71 | if (end > start) {
|
---|
72 | endCondition = inclusiveEnd ? currentYieldingValue > end : currentYieldingValue >= end;
|
---|
73 | } else {
|
---|
74 | endCondition = inclusiveEnd ? end > currentYieldingValue : end >= currentYieldingValue;
|
---|
75 | }
|
---|
76 | if (endCondition) {
|
---|
77 | return { value: undefined, done: state.hitsEnd = true };
|
---|
78 | } return { value: currentYieldingValue, done: false };
|
---|
79 | });
|
---|
80 |
|
---|
81 | var getter = function (fn) {
|
---|
82 | return { get: fn, set: function () { /* empty */ }, configurable: true, enumerable: false };
|
---|
83 | };
|
---|
84 |
|
---|
85 | if (DESCRIPTORS) {
|
---|
86 | defineProperties($RangeIterator.prototype, {
|
---|
87 | start: getter(function () {
|
---|
88 | return getInternalState(this).start;
|
---|
89 | }),
|
---|
90 | end: getter(function () {
|
---|
91 | return getInternalState(this).end;
|
---|
92 | }),
|
---|
93 | inclusive: getter(function () {
|
---|
94 | return getInternalState(this).inclusiveEnd;
|
---|
95 | }),
|
---|
96 | step: getter(function () {
|
---|
97 | return getInternalState(this).step;
|
---|
98 | })
|
---|
99 | });
|
---|
100 | }
|
---|
101 |
|
---|
102 | module.exports = $RangeIterator;
|
---|