numeric-range-iterator.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. 'use strict';
  2. var InternalStateModule = require('../internals/internal-state');
  3. var createIteratorConstructor = require('../internals/iterator-create-constructor');
  4. var createIterResultObject = require('../internals/create-iter-result-object');
  5. var isNullOrUndefined = require('../internals/is-null-or-undefined');
  6. var isObject = require('../internals/is-object');
  7. var defineBuiltInAccessor = require('../internals/define-built-in-accessor');
  8. var DESCRIPTORS = require('../internals/descriptors');
  9. var INCORRECT_RANGE = 'Incorrect Iterator.range arguments';
  10. var NUMERIC_RANGE_ITERATOR = 'NumericRangeIterator';
  11. var setInternalState = InternalStateModule.set;
  12. var getInternalState = InternalStateModule.getterFor(NUMERIC_RANGE_ITERATOR);
  13. var $RangeError = RangeError;
  14. var $TypeError = TypeError;
  15. var $RangeIterator = createIteratorConstructor(function NumericRangeIterator(start, end, option, type, zero, one) {
  16. // TODO: Drop the first `typeof` check after removing legacy methods in `core-js@4`
  17. if (typeof start != type || (end !== Infinity && end !== -Infinity && typeof end != type)) {
  18. throw new $TypeError(INCORRECT_RANGE);
  19. }
  20. if (start === Infinity || start === -Infinity) {
  21. throw new $RangeError(INCORRECT_RANGE);
  22. }
  23. var ifIncrease = end > start;
  24. var inclusiveEnd = false;
  25. var step;
  26. if (option === undefined) {
  27. step = undefined;
  28. } else if (isObject(option)) {
  29. step = option.step;
  30. inclusiveEnd = !!option.inclusive;
  31. } else if (typeof option == type) {
  32. step = option;
  33. } else {
  34. throw new $TypeError(INCORRECT_RANGE);
  35. }
  36. if (isNullOrUndefined(step)) {
  37. step = ifIncrease ? one : -one;
  38. }
  39. if (typeof step != type) {
  40. throw new $TypeError(INCORRECT_RANGE);
  41. }
  42. if (step === Infinity || step === -Infinity || (step === zero && start !== end)) {
  43. throw new $RangeError(INCORRECT_RANGE);
  44. }
  45. // eslint-disable-next-line no-self-compare -- NaN check
  46. var hitsEnd = start !== start || end !== end || step !== step || (end > start) !== (step > zero);
  47. setInternalState(this, {
  48. type: NUMERIC_RANGE_ITERATOR,
  49. start: start,
  50. end: end,
  51. step: step,
  52. inclusive: inclusiveEnd,
  53. hitsEnd: hitsEnd,
  54. currentCount: zero,
  55. zero: zero
  56. });
  57. if (!DESCRIPTORS) {
  58. this.start = start;
  59. this.end = end;
  60. this.step = step;
  61. this.inclusive = inclusiveEnd;
  62. }
  63. }, NUMERIC_RANGE_ITERATOR, function next() {
  64. var state = getInternalState(this);
  65. if (state.hitsEnd) return createIterResultObject(undefined, true);
  66. var start = state.start;
  67. var end = state.end;
  68. var step = state.step;
  69. var currentYieldingValue = start + (step * state.currentCount++);
  70. if (currentYieldingValue === end) state.hitsEnd = true;
  71. var inclusiveEnd = state.inclusive;
  72. var endCondition;
  73. if (end > start) {
  74. endCondition = inclusiveEnd ? currentYieldingValue > end : currentYieldingValue >= end;
  75. } else {
  76. endCondition = inclusiveEnd ? end > currentYieldingValue : end >= currentYieldingValue;
  77. }
  78. if (endCondition) {
  79. state.hitsEnd = true;
  80. return createIterResultObject(undefined, true);
  81. } return createIterResultObject(currentYieldingValue, false);
  82. });
  83. var addGetter = function (key) {
  84. defineBuiltInAccessor($RangeIterator.prototype, key, {
  85. get: function () {
  86. return getInternalState(this)[key];
  87. },
  88. set: function () { /* empty */ },
  89. configurable: true,
  90. enumerable: false
  91. });
  92. };
  93. if (DESCRIPTORS) {
  94. addGetter('start');
  95. addGetter('end');
  96. addGetter('inclusive');
  97. addGetter('step');
  98. }
  99. module.exports = $RangeIterator;