(root)/
Python-3.12.0/
Objects/
rangeobject.c
       1  /* Range object implementation */
       2  
       3  #include "Python.h"
       4  #include "pycore_abstract.h"      // _PyIndex_Check()
       5  #include "pycore_range.h"
       6  #include "pycore_long.h"          // _PyLong_GetZero()
       7  #include "pycore_tuple.h"         // _PyTuple_ITEMS()
       8  #include "structmember.h"         // PyMemberDef
       9  
      10  /* Support objects whose length is > PY_SSIZE_T_MAX.
      11  
      12     This could be sped up for small PyLongs if they fit in a Py_ssize_t.
      13     This only matters on Win64.  Though we could use long long which
      14     would presumably help perf.
      15  */
      16  
      17  typedef struct {
      18      PyObject_HEAD
      19      PyObject *start;
      20      PyObject *stop;
      21      PyObject *step;
      22      PyObject *length;
      23  } rangeobject;
      24  
      25  /* Helper function for validating step.  Always returns a new reference or
      26     NULL on error.
      27  */
      28  static PyObject *
      29  validate_step(PyObject *step)
      30  {
      31      /* No step specified, use a step of 1. */
      32      if (!step)
      33          return PyLong_FromLong(1);
      34  
      35      step = PyNumber_Index(step);
      36      if (step && _PyLong_IsZero((PyLongObject *)step)) {
      37          PyErr_SetString(PyExc_ValueError,
      38                          "range() arg 3 must not be zero");
      39          Py_CLEAR(step);
      40      }
      41  
      42      return step;
      43  }
      44  
      45  static PyObject *
      46  compute_range_length(PyObject *start, PyObject *stop, PyObject *step);
      47  
      48  static rangeobject *
      49  make_range_object(PyTypeObject *type, PyObject *start,
      50                    PyObject *stop, PyObject *step)
      51  {
      52      rangeobject *obj = NULL;
      53      PyObject *length;
      54      length = compute_range_length(start, stop, step);
      55      if (length == NULL) {
      56          return NULL;
      57      }
      58      obj = PyObject_New(rangeobject, type);
      59      if (obj == NULL) {
      60          Py_DECREF(length);
      61          return NULL;
      62      }
      63      obj->start = start;
      64      obj->stop = stop;
      65      obj->step = step;
      66      obj->length = length;
      67      return obj;
      68  }
      69  
      70  /* XXX(nnorwitz): should we error check if the user passes any empty ranges?
      71     range(-10)
      72     range(0, -5)
      73     range(0, 5, -1)
      74  */
      75  static PyObject *
      76  range_from_array(PyTypeObject *type, PyObject *const *args, Py_ssize_t num_args)
      77  {
      78      rangeobject *obj;
      79      PyObject *start = NULL, *stop = NULL, *step = NULL;
      80  
      81      switch (num_args) {
      82          case 3:
      83              step = args[2];
      84              /* fallthrough */
      85          case 2:
      86              /* Convert borrowed refs to owned refs */
      87              start = PyNumber_Index(args[0]);
      88              if (!start) {
      89                  return NULL;
      90              }
      91              stop = PyNumber_Index(args[1]);
      92              if (!stop) {
      93                  Py_DECREF(start);
      94                  return NULL;
      95              }
      96              step = validate_step(step);  /* Caution, this can clear exceptions */
      97              if (!step) {
      98                  Py_DECREF(start);
      99                  Py_DECREF(stop);
     100                  return NULL;
     101              }
     102              break;
     103          case 1:
     104              stop = PyNumber_Index(args[0]);
     105              if (!stop) {
     106                  return NULL;
     107              }
     108              start = Py_NewRef(_PyLong_GetZero());
     109              step = Py_NewRef(_PyLong_GetOne());
     110              break;
     111          case 0:
     112              PyErr_SetString(PyExc_TypeError,
     113                              "range expected at least 1 argument, got 0");
     114              return NULL;
     115          default:
     116              PyErr_Format(PyExc_TypeError,
     117                           "range expected at most 3 arguments, got %zd",
     118                           num_args);
     119              return NULL;
     120      }
     121      obj = make_range_object(type, start, stop, step);
     122      if (obj != NULL) {
     123          return (PyObject *) obj;
     124      }
     125  
     126      /* Failed to create object, release attributes */
     127      Py_DECREF(start);
     128      Py_DECREF(stop);
     129      Py_DECREF(step);
     130      return NULL;
     131  }
     132  
     133  static PyObject *
     134  range_new(PyTypeObject *type, PyObject *args, PyObject *kw)
     135  {
     136      if (!_PyArg_NoKeywords("range", kw))
     137          return NULL;
     138  
     139      return range_from_array(type, _PyTuple_ITEMS(args), PyTuple_GET_SIZE(args));
     140  }
     141  
     142  
     143  static PyObject *
     144  range_vectorcall(PyTypeObject *type, PyObject *const *args,
     145                   size_t nargsf, PyObject *kwnames)
     146  {
     147      Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
     148      if (!_PyArg_NoKwnames("range", kwnames)) {
     149          return NULL;
     150      }
     151      return range_from_array(type, args, nargs);
     152  }
     153  
     154  PyDoc_STRVAR(range_doc,
     155  "range(stop) -> range object\n\
     156  range(start, stop[, step]) -> range object\n\
     157  \n\
     158  Return an object that produces a sequence of integers from start (inclusive)\n\
     159  to stop (exclusive) by step.  range(i, j) produces i, i+1, i+2, ..., j-1.\n\
     160  start defaults to 0, and stop is omitted!  range(4) produces 0, 1, 2, 3.\n\
     161  These are exactly the valid indices for a list of 4 elements.\n\
     162  When step is given, it specifies the increment (or decrement).");
     163  
     164  static void
     165  range_dealloc(rangeobject *r)
     166  {
     167      Py_DECREF(r->start);
     168      Py_DECREF(r->stop);
     169      Py_DECREF(r->step);
     170      Py_DECREF(r->length);
     171      PyObject_Free(r);
     172  }
     173  
     174  static unsigned long
     175  get_len_of_range(long lo, long hi, long step);
     176  
     177  /* Return the length as a long, -2 for an overflow and -1 for any other type of error
     178   *
     179   * In case of an overflow no error is set
     180   */
     181  static long compute_range_length_long(PyObject *start,
     182                  PyObject *stop, PyObject *step) {
     183      int overflow = 0;
     184  
     185      long long_start = PyLong_AsLongAndOverflow(start, &overflow);
     186      if (overflow) {
     187          return -2;
     188      }
     189      if (long_start == -1 && PyErr_Occurred()) {
     190          return -1;
     191      }
     192      long long_stop = PyLong_AsLongAndOverflow(stop, &overflow);
     193      if (overflow) {
     194          return -2;
     195      }
     196      if (long_stop == -1 && PyErr_Occurred()) {
     197          return -1;
     198      }
     199      long long_step = PyLong_AsLongAndOverflow(step, &overflow);
     200      if (overflow) {
     201          return -2;
     202      }
     203      if (long_step == -1 && PyErr_Occurred()) {
     204          return -1;
     205      }
     206  
     207      unsigned long ulen = get_len_of_range(long_start, long_stop, long_step);
     208      if (ulen > (unsigned long)LONG_MAX) {
     209          /* length too large for a long */
     210          return -2;
     211      }
     212      else {
     213          return (long)ulen;
     214      }
     215  }
     216  
     217  /* Return number of items in range (lo, hi, step) as a PyLong object,
     218   * when arguments are PyLong objects.  Arguments MUST return 1 with
     219   * PyLong_Check().  Return NULL when there is an error.
     220   */
     221  static PyObject*
     222  compute_range_length(PyObject *start, PyObject *stop, PyObject *step)
     223  {
     224      /* -------------------------------------------------------------
     225      Algorithm is equal to that of get_len_of_range(), but it operates
     226      on PyObjects (which are assumed to be PyLong objects).
     227      ---------------------------------------------------------------*/
     228      int cmp_result;
     229      PyObject *lo, *hi;
     230      PyObject *diff = NULL;
     231      PyObject *tmp1 = NULL, *tmp2 = NULL, *result;
     232                  /* holds sub-expression evaluations */
     233  
     234      PyObject *zero = _PyLong_GetZero();  // borrowed reference
     235      PyObject *one = _PyLong_GetOne();  // borrowed reference
     236  
     237      assert(PyLong_Check(start));
     238      assert(PyLong_Check(stop));
     239      assert(PyLong_Check(step));
     240  
     241      /* fast path when all arguments fit into a long integer */
     242      long len = compute_range_length_long(start, stop, step);
     243      if (len >= 0) {
     244          return PyLong_FromLong(len);
     245      }
     246      else if (len == -1) {
     247          /* unexpected error from compute_range_length_long, we propagate to the caller */
     248          return NULL;
     249      }
     250      assert(len == -2);
     251  
     252      cmp_result = PyObject_RichCompareBool(step, zero, Py_GT);
     253      if (cmp_result == -1)
     254          return NULL;
     255  
     256      if (cmp_result == 1) {
     257          lo = start;
     258          hi = stop;
     259          Py_INCREF(step);
     260      } else {
     261          lo = stop;
     262          hi = start;
     263          step = PyNumber_Negative(step);
     264          if (!step)
     265              return NULL;
     266      }
     267  
     268      /* if (lo >= hi), return length of 0. */
     269      cmp_result = PyObject_RichCompareBool(lo, hi, Py_GE);
     270      if (cmp_result != 0) {
     271          Py_DECREF(step);
     272          if (cmp_result < 0)
     273              return NULL;
     274          result = zero;
     275          return Py_NewRef(result);
     276      }
     277  
     278      if ((tmp1 = PyNumber_Subtract(hi, lo)) == NULL)
     279          goto Fail;
     280  
     281      if ((diff = PyNumber_Subtract(tmp1, one)) == NULL)
     282          goto Fail;
     283  
     284      if ((tmp2 = PyNumber_FloorDivide(diff, step)) == NULL)
     285          goto Fail;
     286  
     287      if ((result = PyNumber_Add(tmp2, one)) == NULL)
     288          goto Fail;
     289  
     290      Py_DECREF(tmp2);
     291      Py_DECREF(diff);
     292      Py_DECREF(step);
     293      Py_DECREF(tmp1);
     294      return result;
     295  
     296    Fail:
     297      Py_DECREF(step);
     298      Py_XDECREF(tmp2);
     299      Py_XDECREF(diff);
     300      Py_XDECREF(tmp1);
     301      return NULL;
     302  }
     303  
     304  static Py_ssize_t
     305  range_length(rangeobject *r)
     306  {
     307      return PyLong_AsSsize_t(r->length);
     308  }
     309  
     310  static PyObject *
     311  compute_item(rangeobject *r, PyObject *i)
     312  {
     313      PyObject *incr, *result;
     314      /* PyLong equivalent to:
     315       *    return r->start + (i * r->step)
     316       */
     317      if (r->step == _PyLong_GetOne()) {
     318          result = PyNumber_Add(r->start, i);
     319      }
     320      else {
     321          incr = PyNumber_Multiply(i, r->step);
     322          if (!incr) {
     323              return NULL;
     324          }
     325          result = PyNumber_Add(r->start, incr);
     326          Py_DECREF(incr);
     327      }
     328      return result;
     329  }
     330  
     331  static PyObject *
     332  compute_range_item(rangeobject *r, PyObject *arg)
     333  {
     334      PyObject *zero = _PyLong_GetZero();  // borrowed reference
     335      int cmp_result;
     336      PyObject *i, *result;
     337  
     338      /* PyLong equivalent to:
     339       *   if (arg < 0) {
     340       *     i = r->length + arg
     341       *   } else {
     342       *     i = arg
     343       *   }
     344       */
     345      cmp_result = PyObject_RichCompareBool(arg, zero, Py_LT);
     346      if (cmp_result == -1) {
     347          return NULL;
     348      }
     349      if (cmp_result == 1) {
     350          i = PyNumber_Add(r->length, arg);
     351          if (!i) {
     352            return NULL;
     353          }
     354      } else {
     355          i = Py_NewRef(arg);
     356      }
     357  
     358      /* PyLong equivalent to:
     359       *   if (i < 0 || i >= r->length) {
     360       *     <report index out of bounds>
     361       *   }
     362       */
     363      cmp_result = PyObject_RichCompareBool(i, zero, Py_LT);
     364      if (cmp_result == 0) {
     365          cmp_result = PyObject_RichCompareBool(i, r->length, Py_GE);
     366      }
     367      if (cmp_result == -1) {
     368         Py_DECREF(i);
     369         return NULL;
     370      }
     371      if (cmp_result == 1) {
     372          Py_DECREF(i);
     373          PyErr_SetString(PyExc_IndexError,
     374                          "range object index out of range");
     375          return NULL;
     376      }
     377  
     378      result = compute_item(r, i);
     379      Py_DECREF(i);
     380      return result;
     381  }
     382  
     383  static PyObject *
     384  range_item(rangeobject *r, Py_ssize_t i)
     385  {
     386      PyObject *res, *arg = PyLong_FromSsize_t(i);
     387      if (!arg) {
     388          return NULL;
     389      }
     390      res = compute_range_item(r, arg);
     391      Py_DECREF(arg);
     392      return res;
     393  }
     394  
     395  static PyObject *
     396  compute_slice(rangeobject *r, PyObject *_slice)
     397  {
     398      PySliceObject *slice = (PySliceObject *) _slice;
     399      rangeobject *result;
     400      PyObject *start = NULL, *stop = NULL, *step = NULL;
     401      PyObject *substart = NULL, *substop = NULL, *substep = NULL;
     402      int error;
     403  
     404      error = _PySlice_GetLongIndices(slice, r->length, &start, &stop, &step);
     405      if (error == -1)
     406          return NULL;
     407  
     408      substep = PyNumber_Multiply(r->step, step);
     409      if (substep == NULL) goto fail;
     410      Py_CLEAR(step);
     411  
     412      substart = compute_item(r, start);
     413      if (substart == NULL) goto fail;
     414      Py_CLEAR(start);
     415  
     416      substop = compute_item(r, stop);
     417      if (substop == NULL) goto fail;
     418      Py_CLEAR(stop);
     419  
     420      result = make_range_object(Py_TYPE(r), substart, substop, substep);
     421      if (result != NULL) {
     422          return (PyObject *) result;
     423      }
     424  fail:
     425      Py_XDECREF(start);
     426      Py_XDECREF(stop);
     427      Py_XDECREF(step);
     428      Py_XDECREF(substart);
     429      Py_XDECREF(substop);
     430      Py_XDECREF(substep);
     431      return NULL;
     432  }
     433  
     434  /* Assumes (PyLong_CheckExact(ob) || PyBool_Check(ob)) */
     435  static int
     436  range_contains_long(rangeobject *r, PyObject *ob)
     437  {
     438      PyObject *zero = _PyLong_GetZero();  // borrowed reference
     439      int cmp1, cmp2, cmp3;
     440      PyObject *tmp1 = NULL;
     441      PyObject *tmp2 = NULL;
     442      int result = -1;
     443  
     444      /* Check if the value can possibly be in the range. */
     445  
     446      cmp1 = PyObject_RichCompareBool(r->step, zero, Py_GT);
     447      if (cmp1 == -1)
     448          goto end;
     449      if (cmp1 == 1) { /* positive steps: start <= ob < stop */
     450          cmp2 = PyObject_RichCompareBool(r->start, ob, Py_LE);
     451          cmp3 = PyObject_RichCompareBool(ob, r->stop, Py_LT);
     452      }
     453      else { /* negative steps: stop < ob <= start */
     454          cmp2 = PyObject_RichCompareBool(ob, r->start, Py_LE);
     455          cmp3 = PyObject_RichCompareBool(r->stop, ob, Py_LT);
     456      }
     457  
     458      if (cmp2 == -1 || cmp3 == -1) /* TypeError */
     459          goto end;
     460      if (cmp2 == 0 || cmp3 == 0) { /* ob outside of range */
     461          result = 0;
     462          goto end;
     463      }
     464  
     465      /* Check that the stride does not invalidate ob's membership. */
     466      tmp1 = PyNumber_Subtract(ob, r->start);
     467      if (tmp1 == NULL)
     468          goto end;
     469      tmp2 = PyNumber_Remainder(tmp1, r->step);
     470      if (tmp2 == NULL)
     471          goto end;
     472      /* result = ((int(ob) - start) % step) == 0 */
     473      result = PyObject_RichCompareBool(tmp2, zero, Py_EQ);
     474    end:
     475      Py_XDECREF(tmp1);
     476      Py_XDECREF(tmp2);
     477      return result;
     478  }
     479  
     480  static int
     481  range_contains(rangeobject *r, PyObject *ob)
     482  {
     483      if (PyLong_CheckExact(ob) || PyBool_Check(ob))
     484          return range_contains_long(r, ob);
     485  
     486      return (int)_PySequence_IterSearch((PyObject*)r, ob,
     487                                         PY_ITERSEARCH_CONTAINS);
     488  }
     489  
     490  /* Compare two range objects.  Return 1 for equal, 0 for not equal
     491     and -1 on error.  The algorithm is roughly the C equivalent of
     492  
     493     if r0 is r1:
     494         return True
     495     if len(r0) != len(r1):
     496         return False
     497     if not len(r0):
     498         return True
     499     if r0.start != r1.start:
     500         return False
     501     if len(r0) == 1:
     502         return True
     503     return r0.step == r1.step
     504  */
     505  static int
     506  range_equals(rangeobject *r0, rangeobject *r1)
     507  {
     508      int cmp_result;
     509  
     510      if (r0 == r1)
     511          return 1;
     512      cmp_result = PyObject_RichCompareBool(r0->length, r1->length, Py_EQ);
     513      /* Return False or error to the caller. */
     514      if (cmp_result != 1)
     515          return cmp_result;
     516      cmp_result = PyObject_Not(r0->length);
     517      /* Return True or error to the caller. */
     518      if (cmp_result != 0)
     519          return cmp_result;
     520      cmp_result = PyObject_RichCompareBool(r0->start, r1->start, Py_EQ);
     521      /* Return False or error to the caller. */
     522      if (cmp_result != 1)
     523          return cmp_result;
     524      cmp_result = PyObject_RichCompareBool(r0->length, _PyLong_GetOne(), Py_EQ);
     525      /* Return True or error to the caller. */
     526      if (cmp_result != 0)
     527          return cmp_result;
     528      return PyObject_RichCompareBool(r0->step, r1->step, Py_EQ);
     529  }
     530  
     531  static PyObject *
     532  range_richcompare(PyObject *self, PyObject *other, int op)
     533  {
     534      int result;
     535  
     536      if (!PyRange_Check(other))
     537          Py_RETURN_NOTIMPLEMENTED;
     538      switch (op) {
     539      case Py_NE:
     540      case Py_EQ:
     541          result = range_equals((rangeobject*)self, (rangeobject*)other);
     542          if (result == -1)
     543              return NULL;
     544          if (op == Py_NE)
     545              result = !result;
     546          if (result)
     547              Py_RETURN_TRUE;
     548          else
     549              Py_RETURN_FALSE;
     550      case Py_LE:
     551      case Py_GE:
     552      case Py_LT:
     553      case Py_GT:
     554          Py_RETURN_NOTIMPLEMENTED;
     555      default:
     556          PyErr_BadArgument();
     557          return NULL;
     558      }
     559  }
     560  
     561  /* Hash function for range objects.  Rough C equivalent of
     562  
     563     if not len(r):
     564         return hash((len(r), None, None))
     565     if len(r) == 1:
     566         return hash((len(r), r.start, None))
     567     return hash((len(r), r.start, r.step))
     568  */
     569  static Py_hash_t
     570  range_hash(rangeobject *r)
     571  {
     572      PyObject *t;
     573      Py_hash_t result = -1;
     574      int cmp_result;
     575  
     576      t = PyTuple_New(3);
     577      if (!t)
     578          return -1;
     579      PyTuple_SET_ITEM(t, 0, Py_NewRef(r->length));
     580      cmp_result = PyObject_Not(r->length);
     581      if (cmp_result == -1)
     582          goto end;
     583      if (cmp_result == 1) {
     584          PyTuple_SET_ITEM(t, 1, Py_NewRef(Py_None));
     585          PyTuple_SET_ITEM(t, 2, Py_NewRef(Py_None));
     586      }
     587      else {
     588          PyTuple_SET_ITEM(t, 1, Py_NewRef(r->start));
     589          cmp_result = PyObject_RichCompareBool(r->length, _PyLong_GetOne(), Py_EQ);
     590          if (cmp_result == -1)
     591              goto end;
     592          if (cmp_result == 1) {
     593              PyTuple_SET_ITEM(t, 2, Py_NewRef(Py_None));
     594          }
     595          else {
     596              PyTuple_SET_ITEM(t, 2, Py_NewRef(r->step));
     597          }
     598      }
     599      result = PyObject_Hash(t);
     600    end:
     601      Py_DECREF(t);
     602      return result;
     603  }
     604  
     605  static PyObject *
     606  range_count(rangeobject *r, PyObject *ob)
     607  {
     608      if (PyLong_CheckExact(ob) || PyBool_Check(ob)) {
     609          int result = range_contains_long(r, ob);
     610          if (result == -1)
     611              return NULL;
     612          return PyLong_FromLong(result);
     613      } else {
     614          Py_ssize_t count;
     615          count = _PySequence_IterSearch((PyObject*)r, ob, PY_ITERSEARCH_COUNT);
     616          if (count == -1)
     617              return NULL;
     618          return PyLong_FromSsize_t(count);
     619      }
     620  }
     621  
     622  static PyObject *
     623  range_index(rangeobject *r, PyObject *ob)
     624  {
     625      int contains;
     626  
     627      if (!PyLong_CheckExact(ob) && !PyBool_Check(ob)) {
     628          Py_ssize_t index;
     629          index = _PySequence_IterSearch((PyObject*)r, ob, PY_ITERSEARCH_INDEX);
     630          if (index == -1)
     631              return NULL;
     632          return PyLong_FromSsize_t(index);
     633      }
     634  
     635      contains = range_contains_long(r, ob);
     636      if (contains == -1)
     637          return NULL;
     638  
     639      if (contains) {
     640          PyObject *idx = PyNumber_Subtract(ob, r->start);
     641          if (idx == NULL) {
     642              return NULL;
     643          }
     644  
     645          if (r->step == _PyLong_GetOne()) {
     646              return idx;
     647          }
     648  
     649          /* idx = (ob - r.start) // r.step */
     650          PyObject *sidx = PyNumber_FloorDivide(idx, r->step);
     651          Py_DECREF(idx);
     652          return sidx;
     653      }
     654  
     655      /* object is not in the range */
     656      PyErr_Format(PyExc_ValueError, "%R is not in range", ob);
     657      return NULL;
     658  }
     659  
     660  static PySequenceMethods range_as_sequence = {
     661      (lenfunc)range_length,      /* sq_length */
     662      0,                          /* sq_concat */
     663      0,                          /* sq_repeat */
     664      (ssizeargfunc)range_item,   /* sq_item */
     665      0,                          /* sq_slice */
     666      0,                          /* sq_ass_item */
     667      0,                          /* sq_ass_slice */
     668      (objobjproc)range_contains, /* sq_contains */
     669  };
     670  
     671  static PyObject *
     672  range_repr(rangeobject *r)
     673  {
     674      Py_ssize_t istep;
     675  
     676      /* Check for special case values for printing.  We don't always
     677         need the step value.  We don't care about overflow. */
     678      istep = PyNumber_AsSsize_t(r->step, NULL);
     679      if (istep == -1 && PyErr_Occurred()) {
     680          assert(!PyErr_ExceptionMatches(PyExc_OverflowError));
     681          return NULL;
     682      }
     683  
     684      if (istep == 1)
     685          return PyUnicode_FromFormat("range(%R, %R)", r->start, r->stop);
     686      else
     687          return PyUnicode_FromFormat("range(%R, %R, %R)",
     688                                      r->start, r->stop, r->step);
     689  }
     690  
     691  /* Pickling support */
     692  static PyObject *
     693  range_reduce(rangeobject *r, PyObject *args)
     694  {
     695      return Py_BuildValue("(O(OOO))", Py_TYPE(r),
     696                           r->start, r->stop, r->step);
     697  }
     698  
     699  static PyObject *
     700  range_subscript(rangeobject* self, PyObject* item)
     701  {
     702      if (_PyIndex_Check(item)) {
     703          PyObject *i, *result;
     704          i = PyNumber_Index(item);
     705          if (!i)
     706              return NULL;
     707          result = compute_range_item(self, i);
     708          Py_DECREF(i);
     709          return result;
     710      }
     711      if (PySlice_Check(item)) {
     712          return compute_slice(self, item);
     713      }
     714      PyErr_Format(PyExc_TypeError,
     715                   "range indices must be integers or slices, not %.200s",
     716                   Py_TYPE(item)->tp_name);
     717      return NULL;
     718  }
     719  
     720  
     721  static PyMappingMethods range_as_mapping = {
     722          (lenfunc)range_length,       /* mp_length */
     723          (binaryfunc)range_subscript, /* mp_subscript */
     724          (objobjargproc)0,            /* mp_ass_subscript */
     725  };
     726  
     727  static int
     728  range_bool(rangeobject* self)
     729  {
     730      return PyObject_IsTrue(self->length);
     731  }
     732  
     733  static PyNumberMethods range_as_number = {
     734      .nb_bool = (inquiry)range_bool,
     735  };
     736  
     737  static PyObject * range_iter(PyObject *seq);
     738  static PyObject * range_reverse(PyObject *seq, PyObject *Py_UNUSED(ignored));
     739  
     740  PyDoc_STRVAR(reverse_doc,
     741  "Return a reverse iterator.");
     742  
     743  PyDoc_STRVAR(count_doc,
     744  "rangeobject.count(value) -> integer -- return number of occurrences of value");
     745  
     746  PyDoc_STRVAR(index_doc,
     747  "rangeobject.index(value) -> integer -- return index of value.\n"
     748  "Raise ValueError if the value is not present.");
     749  
     750  static PyMethodDef range_methods[] = {
     751      {"__reversed__",    range_reverse,              METH_NOARGS, reverse_doc},
     752      {"__reduce__",      (PyCFunction)range_reduce,  METH_VARARGS},
     753      {"count",           (PyCFunction)range_count,   METH_O,      count_doc},
     754      {"index",           (PyCFunction)range_index,   METH_O,      index_doc},
     755      {NULL,              NULL}           /* sentinel */
     756  };
     757  
     758  static PyMemberDef range_members[] = {
     759      {"start",   T_OBJECT_EX,    offsetof(rangeobject, start),   READONLY},
     760      {"stop",    T_OBJECT_EX,    offsetof(rangeobject, stop),    READONLY},
     761      {"step",    T_OBJECT_EX,    offsetof(rangeobject, step),    READONLY},
     762      {0}
     763  };
     764  
     765  PyTypeObject PyRange_Type = {
     766          PyVarObject_HEAD_INIT(&PyType_Type, 0)
     767          "range",                /* Name of this type */
     768          sizeof(rangeobject),    /* Basic object size */
     769          0,                      /* Item size for varobject */
     770          (destructor)range_dealloc, /* tp_dealloc */
     771          0,                      /* tp_vectorcall_offset */
     772          0,                      /* tp_getattr */
     773          0,                      /* tp_setattr */
     774          0,                      /* tp_as_async */
     775          (reprfunc)range_repr,   /* tp_repr */
     776          &range_as_number,       /* tp_as_number */
     777          &range_as_sequence,     /* tp_as_sequence */
     778          &range_as_mapping,      /* tp_as_mapping */
     779          (hashfunc)range_hash,   /* tp_hash */
     780          0,                      /* tp_call */
     781          0,                      /* tp_str */
     782          PyObject_GenericGetAttr,  /* tp_getattro */
     783          0,                      /* tp_setattro */
     784          0,                      /* tp_as_buffer */
     785          Py_TPFLAGS_DEFAULT | Py_TPFLAGS_SEQUENCE,  /* tp_flags */
     786          range_doc,              /* tp_doc */
     787          0,                      /* tp_traverse */
     788          0,                      /* tp_clear */
     789          range_richcompare,      /* tp_richcompare */
     790          0,                      /* tp_weaklistoffset */
     791          range_iter,             /* tp_iter */
     792          0,                      /* tp_iternext */
     793          range_methods,          /* tp_methods */
     794          range_members,          /* tp_members */
     795          0,                      /* tp_getset */
     796          0,                      /* tp_base */
     797          0,                      /* tp_dict */
     798          0,                      /* tp_descr_get */
     799          0,                      /* tp_descr_set */
     800          0,                      /* tp_dictoffset */
     801          0,                      /* tp_init */
     802          0,                      /* tp_alloc */
     803          range_new,              /* tp_new */
     804          .tp_vectorcall = (vectorcallfunc)range_vectorcall
     805  };
     806  
     807  /*********************** range Iterator **************************/
     808  
     809  /* There are 2 types of iterators, one for C longs, the other for
     810     Python ints (ie, PyObjects).  This should make iteration fast
     811     in the normal case, but possible for any numeric value.
     812  */
     813  
     814  static PyObject *
     815  rangeiter_next(_PyRangeIterObject *r)
     816  {
     817      if (r->len > 0) {
     818          long result = r->start;
     819          r->start = result + r->step;
     820          r->len--;
     821          return PyLong_FromLong(result);
     822      }
     823      return NULL;
     824  }
     825  
     826  static PyObject *
     827  rangeiter_len(_PyRangeIterObject *r, PyObject *Py_UNUSED(ignored))
     828  {
     829      return PyLong_FromLong(r->len);
     830  }
     831  
     832  PyDoc_STRVAR(length_hint_doc,
     833               "Private method returning an estimate of len(list(it)).");
     834  
     835  static PyObject *
     836  rangeiter_reduce(_PyRangeIterObject *r, PyObject *Py_UNUSED(ignored))
     837  {
     838      PyObject *start=NULL, *stop=NULL, *step=NULL;
     839      PyObject *range;
     840  
     841      /* create a range object for pickling */
     842      start = PyLong_FromLong(r->start);
     843      if (start == NULL)
     844          goto err;
     845      stop = PyLong_FromLong(r->start + r->len * r->step);
     846      if (stop == NULL)
     847          goto err;
     848      step = PyLong_FromLong(r->step);
     849      if (step == NULL)
     850          goto err;
     851      range = (PyObject*)make_range_object(&PyRange_Type,
     852                                 start, stop, step);
     853      if (range == NULL)
     854          goto err;
     855      /* return the result */
     856      return Py_BuildValue("N(N)O", _PyEval_GetBuiltin(&_Py_ID(iter)),
     857                           range, Py_None);
     858  err:
     859      Py_XDECREF(start);
     860      Py_XDECREF(stop);
     861      Py_XDECREF(step);
     862      return NULL;
     863  }
     864  
     865  static PyObject *
     866  rangeiter_setstate(_PyRangeIterObject *r, PyObject *state)
     867  {
     868      long index = PyLong_AsLong(state);
     869      if (index == -1 && PyErr_Occurred())
     870          return NULL;
     871      /* silently clip the index value */
     872      if (index < 0)
     873          index = 0;
     874      else if (index > r->len)
     875          index = r->len; /* exhausted iterator */
     876      r->start += index * r->step;
     877      r->len -= index;
     878      Py_RETURN_NONE;
     879  }
     880  
     881  PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
     882  PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
     883  
     884  static PyMethodDef rangeiter_methods[] = {
     885      {"__length_hint__", (PyCFunction)rangeiter_len, METH_NOARGS,
     886          length_hint_doc},
     887      {"__reduce__", (PyCFunction)rangeiter_reduce, METH_NOARGS,
     888          reduce_doc},
     889      {"__setstate__", (PyCFunction)rangeiter_setstate, METH_O,
     890          setstate_doc},
     891      {NULL,              NULL}           /* sentinel */
     892  };
     893  
     894  PyTypeObject PyRangeIter_Type = {
     895          PyVarObject_HEAD_INIT(&PyType_Type, 0)
     896          "range_iterator",                       /* tp_name */
     897          sizeof(_PyRangeIterObject),             /* tp_basicsize */
     898          0,                                      /* tp_itemsize */
     899          /* methods */
     900          (destructor)PyObject_Del,               /* tp_dealloc */
     901          0,                                      /* tp_vectorcall_offset */
     902          0,                                      /* tp_getattr */
     903          0,                                      /* tp_setattr */
     904          0,                                      /* tp_as_async */
     905          0,                                      /* tp_repr */
     906          0,                                      /* tp_as_number */
     907          0,                                      /* tp_as_sequence */
     908          0,                                      /* tp_as_mapping */
     909          0,                                      /* tp_hash */
     910          0,                                      /* tp_call */
     911          0,                                      /* tp_str */
     912          PyObject_GenericGetAttr,                /* tp_getattro */
     913          0,                                      /* tp_setattro */
     914          0,                                      /* tp_as_buffer */
     915          Py_TPFLAGS_DEFAULT,                     /* tp_flags */
     916          0,                                      /* tp_doc */
     917          0,                                      /* tp_traverse */
     918          0,                                      /* tp_clear */
     919          0,                                      /* tp_richcompare */
     920          0,                                      /* tp_weaklistoffset */
     921          PyObject_SelfIter,                      /* tp_iter */
     922          (iternextfunc)rangeiter_next,           /* tp_iternext */
     923          rangeiter_methods,                      /* tp_methods */
     924          0,                                      /* tp_members */
     925  };
     926  
     927  /* Return number of items in range (lo, hi, step).  step != 0
     928   * required.  The result always fits in an unsigned long.
     929   */
     930  static unsigned long
     931  get_len_of_range(long lo, long hi, long step)
     932  {
     933      /* -------------------------------------------------------------
     934      If step > 0 and lo >= hi, or step < 0 and lo <= hi, the range is empty.
     935      Else for step > 0, if n values are in the range, the last one is
     936      lo + (n-1)*step, which must be <= hi-1.  Rearranging,
     937      n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives
     938      the proper value.  Since lo < hi in this case, hi-lo-1 >= 0, so
     939      the RHS is non-negative and so truncation is the same as the
     940      floor.  Letting M be the largest positive long, the worst case
     941      for the RHS numerator is hi=M, lo=-M-1, and then
     942      hi-lo-1 = M-(-M-1)-1 = 2*M.  Therefore unsigned long has enough
     943      precision to compute the RHS exactly.  The analysis for step < 0
     944      is similar.
     945      ---------------------------------------------------------------*/
     946      assert(step != 0);
     947      if (step > 0 && lo < hi)
     948          return 1UL + (hi - 1UL - lo) / step;
     949      else if (step < 0 && lo > hi)
     950          return 1UL + (lo - 1UL - hi) / (0UL - step);
     951      else
     952          return 0UL;
     953  }
     954  
     955  /* Initialize a rangeiter object.  If the length of the rangeiter object
     956     is not representable as a C long, OverflowError is raised. */
     957  
     958  static PyObject *
     959  fast_range_iter(long start, long stop, long step, long len)
     960  {
     961      _PyRangeIterObject *it = PyObject_New(_PyRangeIterObject, &PyRangeIter_Type);
     962      if (it == NULL)
     963          return NULL;
     964      it->start = start;
     965      it->step = step;
     966      it->len = len;
     967      return (PyObject *)it;
     968  }
     969  
     970  typedef struct {
     971      PyObject_HEAD
     972      PyObject *start;
     973      PyObject *step;
     974      PyObject *len;
     975  } longrangeiterobject;
     976  
     977  static PyObject *
     978  longrangeiter_len(longrangeiterobject *r, PyObject *no_args)
     979  {
     980      Py_INCREF(r->len);
     981      return r->len;
     982  }
     983  
     984  static PyObject *
     985  longrangeiter_reduce(longrangeiterobject *r, PyObject *Py_UNUSED(ignored))
     986  {
     987      PyObject *product, *stop=NULL;
     988      PyObject *range;
     989  
     990      /* create a range object for pickling.  Must calculate the "stop" value */
     991      product = PyNumber_Multiply(r->len, r->step);
     992      if (product == NULL)
     993          return NULL;
     994      stop = PyNumber_Add(r->start, product);
     995      Py_DECREF(product);
     996      if (stop ==  NULL)
     997          return NULL;
     998      range =  (PyObject*)make_range_object(&PyRange_Type,
     999                                 Py_NewRef(r->start), stop, Py_NewRef(r->step));
    1000      if (range == NULL) {
    1001          Py_DECREF(r->start);
    1002          Py_DECREF(stop);
    1003          Py_DECREF(r->step);
    1004          return NULL;
    1005      }
    1006  
    1007      /* return the result */
    1008      return Py_BuildValue("N(N)O", _PyEval_GetBuiltin(&_Py_ID(iter)),
    1009                           range, Py_None);
    1010  }
    1011  
    1012  static PyObject *
    1013  longrangeiter_setstate(longrangeiterobject *r, PyObject *state)
    1014  {
    1015      PyObject *zero = _PyLong_GetZero();  // borrowed reference
    1016      int cmp;
    1017  
    1018      /* clip the value */
    1019      cmp = PyObject_RichCompareBool(state, zero, Py_LT);
    1020      if (cmp < 0)
    1021          return NULL;
    1022      if (cmp > 0) {
    1023          state = zero;
    1024      }
    1025      else {
    1026          cmp = PyObject_RichCompareBool(r->len, state, Py_LT);
    1027          if (cmp < 0)
    1028              return NULL;
    1029          if (cmp > 0)
    1030              state = r->len;
    1031      }
    1032      PyObject *product = PyNumber_Multiply(state, r->step);
    1033      if (product == NULL)
    1034          return NULL;
    1035      PyObject *new_start = PyNumber_Add(r->start, product);
    1036      Py_DECREF(product);
    1037      if (new_start == NULL)
    1038          return NULL;
    1039      PyObject *new_len = PyNumber_Subtract(r->len, state);
    1040      if (new_len == NULL) {
    1041          Py_DECREF(new_start);
    1042          return NULL;
    1043      }
    1044      PyObject *tmp = r->start;
    1045      r->start = new_start;
    1046      Py_SETREF(r->len, new_len);
    1047      Py_DECREF(tmp);
    1048      Py_RETURN_NONE;
    1049  }
    1050  
    1051  static PyMethodDef longrangeiter_methods[] = {
    1052      {"__length_hint__", (PyCFunction)longrangeiter_len, METH_NOARGS,
    1053          length_hint_doc},
    1054      {"__reduce__", (PyCFunction)longrangeiter_reduce, METH_NOARGS,
    1055          reduce_doc},
    1056      {"__setstate__", (PyCFunction)longrangeiter_setstate, METH_O,
    1057          setstate_doc},
    1058      {NULL,              NULL}           /* sentinel */
    1059  };
    1060  
    1061  static void
    1062  longrangeiter_dealloc(longrangeiterobject *r)
    1063  {
    1064      Py_XDECREF(r->start);
    1065      Py_XDECREF(r->step);
    1066      Py_XDECREF(r->len);
    1067      PyObject_Free(r);
    1068  }
    1069  
    1070  static PyObject *
    1071  longrangeiter_next(longrangeiterobject *r)
    1072  {
    1073      if (PyObject_RichCompareBool(r->len, _PyLong_GetZero(), Py_GT) != 1)
    1074          return NULL;
    1075  
    1076      PyObject *new_start = PyNumber_Add(r->start, r->step);
    1077      if (new_start == NULL) {
    1078          return NULL;
    1079      }
    1080      PyObject *new_len = PyNumber_Subtract(r->len, _PyLong_GetOne());
    1081      if (new_len == NULL) {
    1082          Py_DECREF(new_start);
    1083          return NULL;
    1084      }
    1085      PyObject *result = r->start;
    1086      r->start = new_start;
    1087      Py_SETREF(r->len, new_len);
    1088      return result;
    1089  }
    1090  
    1091  PyTypeObject PyLongRangeIter_Type = {
    1092          PyVarObject_HEAD_INIT(&PyType_Type, 0)
    1093          "longrange_iterator",                   /* tp_name */
    1094          sizeof(longrangeiterobject),            /* tp_basicsize */
    1095          0,                                      /* tp_itemsize */
    1096          /* methods */
    1097          (destructor)longrangeiter_dealloc,      /* tp_dealloc */
    1098          0,                                      /* tp_vectorcall_offset */
    1099          0,                                      /* tp_getattr */
    1100          0,                                      /* tp_setattr */
    1101          0,                                      /* tp_as_async */
    1102          0,                                      /* tp_repr */
    1103          0,                                      /* tp_as_number */
    1104          0,                                      /* tp_as_sequence */
    1105          0,                                      /* tp_as_mapping */
    1106          0,                                      /* tp_hash */
    1107          0,                                      /* tp_call */
    1108          0,                                      /* tp_str */
    1109          PyObject_GenericGetAttr,                /* tp_getattro */
    1110          0,                                      /* tp_setattro */
    1111          0,                                      /* tp_as_buffer */
    1112          Py_TPFLAGS_DEFAULT,                     /* tp_flags */
    1113          0,                                      /* tp_doc */
    1114          0,                                      /* tp_traverse */
    1115          0,                                      /* tp_clear */
    1116          0,                                      /* tp_richcompare */
    1117          0,                                      /* tp_weaklistoffset */
    1118          PyObject_SelfIter,                      /* tp_iter */
    1119          (iternextfunc)longrangeiter_next,       /* tp_iternext */
    1120          longrangeiter_methods,                  /* tp_methods */
    1121          0,
    1122  };
    1123  
    1124  static PyObject *
    1125  range_iter(PyObject *seq)
    1126  {
    1127      rangeobject *r = (rangeobject *)seq;
    1128      longrangeiterobject *it;
    1129      long lstart, lstop, lstep;
    1130      unsigned long ulen;
    1131  
    1132      assert(PyRange_Check(seq));
    1133  
    1134      /* If all three fields and the length convert to long, use the int
    1135       * version */
    1136      lstart = PyLong_AsLong(r->start);
    1137      if (lstart == -1 && PyErr_Occurred()) {
    1138          PyErr_Clear();
    1139          goto long_range;
    1140      }
    1141      lstop = PyLong_AsLong(r->stop);
    1142      if (lstop == -1 && PyErr_Occurred()) {
    1143          PyErr_Clear();
    1144          goto long_range;
    1145      }
    1146      lstep = PyLong_AsLong(r->step);
    1147      if (lstep == -1 && PyErr_Occurred()) {
    1148          PyErr_Clear();
    1149          goto long_range;
    1150      }
    1151      ulen = get_len_of_range(lstart, lstop, lstep);
    1152      if (ulen > (unsigned long)LONG_MAX) {
    1153          goto long_range;
    1154      }
    1155      /* check for potential overflow of lstart + ulen * lstep */
    1156      if (ulen) {
    1157          if (lstep > 0) {
    1158              if (lstop > LONG_MAX - (lstep - 1))
    1159                  goto long_range;
    1160          }
    1161          else {
    1162              if (lstop < LONG_MIN + (-1 - lstep))
    1163                  goto long_range;
    1164          }
    1165      }
    1166      return fast_range_iter(lstart, lstop, lstep, (long)ulen);
    1167  
    1168    long_range:
    1169      it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
    1170      if (it == NULL)
    1171          return NULL;
    1172  
    1173      it->start = Py_NewRef(r->start);
    1174      it->step = Py_NewRef(r->step);
    1175      it->len = Py_NewRef(r->length);
    1176      return (PyObject *)it;
    1177  }
    1178  
    1179  static PyObject *
    1180  range_reverse(PyObject *seq, PyObject *Py_UNUSED(ignored))
    1181  {
    1182      rangeobject *range = (rangeobject*) seq;
    1183      longrangeiterobject *it;
    1184      PyObject *sum, *diff, *product;
    1185      long lstart, lstop, lstep, new_start, new_stop;
    1186      unsigned long ulen;
    1187  
    1188      assert(PyRange_Check(seq));
    1189  
    1190      /* reversed(range(start, stop, step)) can be expressed as
    1191         range(start+(n-1)*step, start-step, -step), where n is the number of
    1192         integers in the range.
    1193  
    1194         If each of start, stop, step, -step, start-step, and the length
    1195         of the iterator is representable as a C long, use the int
    1196         version.  This excludes some cases where the reversed range is
    1197         representable as a range_iterator, but it's good enough for
    1198         common cases and it makes the checks simple. */
    1199  
    1200      lstart = PyLong_AsLong(range->start);
    1201      if (lstart == -1 && PyErr_Occurred()) {
    1202          PyErr_Clear();
    1203          goto long_range;
    1204      }
    1205      lstop = PyLong_AsLong(range->stop);
    1206      if (lstop == -1 && PyErr_Occurred()) {
    1207          PyErr_Clear();
    1208          goto long_range;
    1209      }
    1210      lstep = PyLong_AsLong(range->step);
    1211      if (lstep == -1 && PyErr_Occurred()) {
    1212          PyErr_Clear();
    1213          goto long_range;
    1214      }
    1215      /* check for possible overflow of -lstep */
    1216      if (lstep == LONG_MIN)
    1217          goto long_range;
    1218  
    1219      /* check for overflow of lstart - lstep:
    1220  
    1221         for lstep > 0, need only check whether lstart - lstep < LONG_MIN.
    1222         for lstep < 0, need only check whether lstart - lstep > LONG_MAX
    1223  
    1224         Rearrange these inequalities as:
    1225  
    1226             lstart - LONG_MIN < lstep  (lstep > 0)
    1227             LONG_MAX - lstart < -lstep  (lstep < 0)
    1228  
    1229         and compute both sides as unsigned longs, to avoid the
    1230         possibility of undefined behaviour due to signed overflow. */
    1231  
    1232      if (lstep > 0) {
    1233           if ((unsigned long)lstart - LONG_MIN < (unsigned long)lstep)
    1234              goto long_range;
    1235      }
    1236      else {
    1237          if (LONG_MAX - (unsigned long)lstart < 0UL - lstep)
    1238              goto long_range;
    1239      }
    1240  
    1241      ulen = get_len_of_range(lstart, lstop, lstep);
    1242      if (ulen > (unsigned long)LONG_MAX)
    1243          goto long_range;
    1244  
    1245      new_stop = lstart - lstep;
    1246      new_start = (long)(new_stop + ulen * lstep);
    1247      return fast_range_iter(new_start, new_stop, -lstep, (long)ulen);
    1248  
    1249  long_range:
    1250      it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
    1251      if (it == NULL)
    1252          return NULL;
    1253      it->start = it->step = NULL;
    1254  
    1255      /* start + (len - 1) * step */
    1256      it->len = Py_NewRef(range->length);
    1257  
    1258      diff = PyNumber_Subtract(it->len, _PyLong_GetOne());
    1259      if (!diff)
    1260          goto create_failure;
    1261  
    1262      product = PyNumber_Multiply(diff, range->step);
    1263      Py_DECREF(diff);
    1264      if (!product)
    1265          goto create_failure;
    1266  
    1267      sum = PyNumber_Add(range->start, product);
    1268      Py_DECREF(product);
    1269      it->start = sum;
    1270      if (!it->start)
    1271          goto create_failure;
    1272  
    1273      it->step = PyNumber_Negative(range->step);
    1274      if (!it->step)
    1275          goto create_failure;
    1276  
    1277      return (PyObject *)it;
    1278  
    1279  create_failure:
    1280      Py_DECREF(it);
    1281      return NULL;
    1282  }