BigIntRange constructor

BigIntRange([
  1. BigInt? a,
  2. BigInt? b,
  3. BigInt? c
])

Creates a virtual range of numbers containing an arithmetic progressions of BigInt values.

The constructor called without any arguments returns the empty range. For example, BigIntRange() yields <BigInt>[].

The constructor called with one argument returns the range of all numbers up to, but excluding the end. For example, BigIntRange(BigInt.from(3)) yields <BigInt>[BigInt.zero, BigInt.one, BigInt.two].

The constructor called with two arguments returns the range between the two numbers (including the start, but excluding the end). For example, BigIntRange(BigInt.from(3), BigInt.from(6)) yields <BigInt>[BigInt.from(3), BigInt.from(4), BigInt.from(5)].

The constructor called with three arguments returns the range between the first two numbers (including the start, but excluding the end) and the step value. For example, BigIntRange(BigInt.from(1), BigInt.from(7), BigInt.from(2)) yields <BigInt>[BigInt.from(1), BigInt.from(3), BigInt.from(5)].

Implementation

factory BigIntRange([BigInt? a, BigInt? b, BigInt? c]) {
  var start = BigInt.zero;
  var end = BigInt.zero;
  var step = BigInt.one;
  if (c != null) {
    start = a!;
    end = b!;
    step = c;
  } else if (b != null) {
    start = a!;
    end = b;
    step = start <= end ? BigInt.one : BigIntExtension.negativeOne;
  } else if (a != null) {
    end = a;
  }
  if (start < end) {
    if (step == BigInt.one) {
      return BigIntRange._(start, end, step, _toSafeLength(end - start));
    } else if (step > BigInt.one) {
      return BigIntRange._(start, end, step,
          _toSafeLength((end - start + step - BigInt.one) ~/ step));
    }
  } else if (start > end) {
    if (step == BigIntExtension.negativeOne) {
      return BigIntRange._(start, end, step, _toSafeLength(start - end));
    } else if (step < BigIntExtension.negativeOne) {
      return BigIntRange._(start, end, step,
          _toSafeLength((start - end - step - BigInt.one) ~/ -step));
    }
  } else {
    if (step != BigInt.zero) {
      return BigIntRange._(start, end, step, 0);
    }
  }
  throw ArgumentError.value(
      step, 'step', 'Invalid step size for range $start..$end');
}