blob: babf55b108b9abf89e6960ed3a34ac4194ef508f [file] [log] [blame]
Guido van Rossum12d12c51993-10-26 17:58:25 +00001/* Range object implementation */
2
Guido van Rossumc0b618a1997-05-02 03:12:38 +00003#include "Python.h"
Victor Stinner384621c2020-06-22 17:27:35 +02004#include "pycore_abstract.h" // _PyIndex_Check()
5#include "pycore_tuple.h" // _PyTuple_ITEMS()
Victor Stinner4a21e572020-04-15 02:35:41 +02006#include "structmember.h" // PyMemberDef
Thomas Woutersefafcea2001-07-09 12:30:54 +00007
Guido van Rossum805365e2007-05-07 22:24:25 +00008/* Support objects whose length is > PY_SSIZE_T_MAX.
9
Serhiy Storchaka6a7b3a72016-04-17 08:32:47 +030010 This could be sped up for small PyLongs if they fit in a Py_ssize_t.
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011 This only matters on Win64. Though we could use long long which
Guido van Rossum805365e2007-05-07 22:24:25 +000012 would presumably help perf.
13*/
14
Guido van Rossum12d12c51993-10-26 17:58:25 +000015typedef struct {
Guido van Rossum805365e2007-05-07 22:24:25 +000016 PyObject_HEAD
17 PyObject *start;
18 PyObject *stop;
19 PyObject *step;
Nick Coghlan37ee8502010-12-03 14:26:13 +000020 PyObject *length;
Guido van Rossum12d12c51993-10-26 17:58:25 +000021} rangeobject;
22
Hai Shi46874c22020-01-30 17:20:25 -060023_Py_IDENTIFIER(iter);
24
Guido van Rossum805365e2007-05-07 22:24:25 +000025/* Helper function for validating step. Always returns a new reference or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000026 NULL on error.
Guido van Rossum805365e2007-05-07 22:24:25 +000027*/
28static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +000029validate_step(PyObject *step)
30{
Guido van Rossum805365e2007-05-07 22:24:25 +000031 /* No step specified, use a step of 1. */
32 if (!step)
Christian Heimes217cfd12007-12-02 14:31:20 +000033 return PyLong_FromLong(1);
Guido van Rossum805365e2007-05-07 22:24:25 +000034
35 step = PyNumber_Index(step);
Serhiy Storchaka5d062d72016-06-18 09:51:55 +030036 if (step && _PyLong_Sign(step) == 0) {
37 PyErr_SetString(PyExc_ValueError,
38 "range() arg 3 must not be zero");
39 Py_CLEAR(step);
Guido van Rossum805365e2007-05-07 22:24:25 +000040 }
41
42 return step;
Raymond Hettingerc4c453f2002-06-05 23:12:45 +000043}
44
Nick Coghlan37ee8502010-12-03 14:26:13 +000045static PyObject *
46compute_range_length(PyObject *start, PyObject *stop, PyObject *step);
47
48static rangeobject *
49make_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
Guido van Rossum805365e2007-05-07 22:24:25 +000070/* 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*/
Raymond Hettingerc4c453f2002-06-05 23:12:45 +000075static PyObject *
Petr Viktorin6e35da92020-02-18 16:13:17 +010076range_from_array(PyTypeObject *type, PyObject *const *args, Py_ssize_t num_args)
Benjamin Petersona1864f32010-11-20 23:05:39 +000077{
Nick Coghlan37ee8502010-12-03 14:26:13 +000078 rangeobject *obj;
Guido van Rossum805365e2007-05-07 22:24:25 +000079 PyObject *start = NULL, *stop = NULL, *step = NULL;
Raymond Hettingerc4c453f2002-06-05 23:12:45 +000080
Pablo Galindo4b66fa62020-01-05 17:30:53 +000081 switch (num_args) {
82 case 3:
Petr Viktorin6e35da92020-02-18 16:13:17 +010083 step = args[2];
Pablo Galindo4b66fa62020-01-05 17:30:53 +000084 /* fallthrough */
85 case 2:
Petr Viktorin6e35da92020-02-18 16:13:17 +010086 /* Convert borrowed refs to owned refs */
87 start = PyNumber_Index(args[0]);
Pablo Galindo4b66fa62020-01-05 17:30:53 +000088 if (!start) {
89 return NULL;
90 }
Petr Viktorin6e35da92020-02-18 16:13:17 +010091 stop = PyNumber_Index(args[1]);
Pablo Galindo4b66fa62020-01-05 17:30:53 +000092 if (!stop) {
93 Py_DECREF(start);
94 return NULL;
95 }
Petr Viktorin6e35da92020-02-18 16:13:17 +010096 step = validate_step(step); /* Caution, this can clear exceptions */
Pablo Galindo4b66fa62020-01-05 17:30:53 +000097 if (!step) {
98 Py_DECREF(start);
99 Py_DECREF(stop);
100 return NULL;
101 }
102 break;
103 case 1:
Petr Viktorin6e35da92020-02-18 16:13:17 +0100104 stop = PyNumber_Index(args[0]);
Pablo Galindo4b66fa62020-01-05 17:30:53 +0000105 if (!stop) {
106 return NULL;
107 }
108 Py_INCREF(_PyLong_Zero);
109 start = _PyLong_Zero;
110 Py_INCREF(_PyLong_One);
111 step = _PyLong_One;
112 break;
113 case 0:
114 PyErr_SetString(PyExc_TypeError,
115 "range expected at least 1 argument, got 0");
Raymond Hettinger94f55832009-06-12 18:40:16 +0000116 return NULL;
Pablo Galindo4b66fa62020-01-05 17:30:53 +0000117 default:
Victor Stinner58ac7002020-02-07 03:04:21 +0100118 PyErr_Format(PyExc_TypeError,
Pablo Galindo4b66fa62020-01-05 17:30:53 +0000119 "range expected at most 3 arguments, got %zd",
120 num_args);
Raymond Hettinger94f55832009-06-12 18:40:16 +0000121 return NULL;
Guido van Rossum805365e2007-05-07 22:24:25 +0000122 }
Nick Coghlan37ee8502010-12-03 14:26:13 +0000123 obj = make_range_object(type, start, stop, step);
Petr Viktorin6e35da92020-02-18 16:13:17 +0100124 if (obj != NULL) {
Nick Coghlan37ee8502010-12-03 14:26:13 +0000125 return (PyObject *) obj;
Petr Viktorin6e35da92020-02-18 16:13:17 +0100126 }
Guido van Rossum805365e2007-05-07 22:24:25 +0000127
Nick Coghlan37ee8502010-12-03 14:26:13 +0000128 /* Failed to create object, release attributes */
Serhiy Storchakacfdfbb42016-06-18 09:44:03 +0300129 Py_DECREF(start);
130 Py_DECREF(stop);
131 Py_DECREF(step);
Guido van Rossum805365e2007-05-07 22:24:25 +0000132 return NULL;
Raymond Hettingerc4c453f2002-06-05 23:12:45 +0000133}
134
Petr Viktorin6e35da92020-02-18 16:13:17 +0100135static PyObject *
136range_new(PyTypeObject *type, PyObject *args, PyObject *kw)
137{
138 if (!_PyArg_NoKeywords("range", kw))
139 return NULL;
140
141 return range_from_array(type, _PyTuple_ITEMS(args), PyTuple_GET_SIZE(args));
142}
143
144
145static PyObject *
146range_vectorcall(PyTypeObject *type, PyObject *const *args,
147 size_t nargsf, PyObject *kwnames)
148{
149 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
Dong-hee Na87ec86c2020-03-16 23:06:20 +0900150 if (!_PyArg_NoKwnames("range", kwnames)) {
Petr Viktorin6e35da92020-02-18 16:13:17 +0100151 return NULL;
152 }
153 return range_from_array(type, args, nargs);
154}
155
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000156PyDoc_STRVAR(range_doc,
Chris Jerdonek83fe2e12012-10-07 14:48:36 -0700157"range(stop) -> range object\n\
158range(start, stop[, step]) -> range object\n\
Raymond Hettingerc4c453f2002-06-05 23:12:45 +0000159\n\
Benjamin Petersonac22c6b2015-04-22 09:16:07 -0400160Return an object that produces a sequence of integers from start (inclusive)\n\
161to stop (exclusive) by step. range(i, j) produces i, i+1, i+2, ..., j-1.\n\
162start defaults to 0, and stop is omitted! range(4) produces 0, 1, 2, 3.\n\
163These are exactly the valid indices for a list of 4 elements.\n\
164When step is given, it specifies the increment (or decrement).");
Raymond Hettingerc4c453f2002-06-05 23:12:45 +0000165
Guido van Rossum805365e2007-05-07 22:24:25 +0000166static void
Benjamin Petersona1864f32010-11-20 23:05:39 +0000167range_dealloc(rangeobject *r)
168{
Guido van Rossum805365e2007-05-07 22:24:25 +0000169 Py_DECREF(r->start);
170 Py_DECREF(r->stop);
171 Py_DECREF(r->step);
Nick Coghlan37ee8502010-12-03 14:26:13 +0000172 Py_DECREF(r->length);
Amaury Forgeot d'Arcb7f17e42007-11-15 20:52:21 +0000173 PyObject_Del(r);
Guido van Rossum805365e2007-05-07 22:24:25 +0000174}
175
Mark Dickinson732166d2009-06-28 22:08:40 +0000176/* Return number of items in range (lo, hi, step) as a PyLong object,
177 * when arguments are PyLong objects. Arguments MUST return 1 with
178 * PyLong_Check(). Return NULL when there is an error.
Guido van Rossum805365e2007-05-07 22:24:25 +0000179 */
180static PyObject*
Nick Coghlan37ee8502010-12-03 14:26:13 +0000181compute_range_length(PyObject *start, PyObject *stop, PyObject *step)
Benjamin Petersona1864f32010-11-20 23:05:39 +0000182{
Guido van Rossum805365e2007-05-07 22:24:25 +0000183 /* -------------------------------------------------------------
184 Algorithm is equal to that of get_len_of_range(), but it operates
Benjamin Petersona47af9c2009-06-24 21:14:38 +0000185 on PyObjects (which are assumed to be PyLong objects).
Guido van Rossum805365e2007-05-07 22:24:25 +0000186 ---------------------------------------------------------------*/
Mark Dickinson211c6252009-02-01 10:28:51 +0000187 int cmp_result;
Guido van Rossum805365e2007-05-07 22:24:25 +0000188 PyObject *lo, *hi;
Guido van Rossum805365e2007-05-07 22:24:25 +0000189 PyObject *diff = NULL;
Guido van Rossum805365e2007-05-07 22:24:25 +0000190 PyObject *tmp1 = NULL, *tmp2 = NULL, *result;
191 /* holds sub-expression evaluations */
192
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300193 cmp_result = PyObject_RichCompareBool(step, _PyLong_Zero, Py_GT);
Mark Dickinson211c6252009-02-01 10:28:51 +0000194 if (cmp_result == -1)
Guido van Rossum805365e2007-05-07 22:24:25 +0000195 return NULL;
196
Mark Dickinson211c6252009-02-01 10:28:51 +0000197 if (cmp_result == 1) {
Nick Coghlan37ee8502010-12-03 14:26:13 +0000198 lo = start;
199 hi = stop;
Guido van Rossum805365e2007-05-07 22:24:25 +0000200 Py_INCREF(step);
201 } else {
Nick Coghlan37ee8502010-12-03 14:26:13 +0000202 lo = stop;
203 hi = start;
204 step = PyNumber_Negative(step);
Guido van Rossum805365e2007-05-07 22:24:25 +0000205 if (!step)
206 return NULL;
207 }
208
209 /* if (lo >= hi), return length of 0. */
Serhiy Storchakafa494fd2015-05-30 17:45:22 +0300210 cmp_result = PyObject_RichCompareBool(lo, hi, Py_GE);
211 if (cmp_result != 0) {
Serhiy Storchakacfdfbb42016-06-18 09:44:03 +0300212 Py_DECREF(step);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +0300213 if (cmp_result < 0)
214 return NULL;
Guido van Rossum805365e2007-05-07 22:24:25 +0000215 return PyLong_FromLong(0);
216 }
217
Guido van Rossum805365e2007-05-07 22:24:25 +0000218 if ((tmp1 = PyNumber_Subtract(hi, lo)) == NULL)
219 goto Fail;
220
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300221 if ((diff = PyNumber_Subtract(tmp1, _PyLong_One)) == NULL)
Guido van Rossum805365e2007-05-07 22:24:25 +0000222 goto Fail;
223
224 if ((tmp2 = PyNumber_FloorDivide(diff, step)) == NULL)
225 goto Fail;
226
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300227 if ((result = PyNumber_Add(tmp2, _PyLong_One)) == NULL)
Guido van Rossum805365e2007-05-07 22:24:25 +0000228 goto Fail;
229
230 Py_DECREF(tmp2);
231 Py_DECREF(diff);
232 Py_DECREF(step);
233 Py_DECREF(tmp1);
Guido van Rossum805365e2007-05-07 22:24:25 +0000234 return result;
235
236 Fail:
Serhiy Storchakacfdfbb42016-06-18 09:44:03 +0300237 Py_DECREF(step);
Guido van Rossum805365e2007-05-07 22:24:25 +0000238 Py_XDECREF(tmp2);
239 Py_XDECREF(diff);
Guido van Rossum805365e2007-05-07 22:24:25 +0000240 Py_XDECREF(tmp1);
Guido van Rossum805365e2007-05-07 22:24:25 +0000241 return NULL;
Guido van Rossum12d12c51993-10-26 17:58:25 +0000242}
243
Martin v. Löwis18e16552006-02-15 17:27:45 +0000244static Py_ssize_t
Benjamin Petersona1864f32010-11-20 23:05:39 +0000245range_length(rangeobject *r)
246{
Nick Coghlan37ee8502010-12-03 14:26:13 +0000247 return PyLong_AsSsize_t(r->length);
Guido van Rossum805365e2007-05-07 22:24:25 +0000248}
249
Guido van Rossum805365e2007-05-07 22:24:25 +0000250static PyObject *
Nick Coghlane993b102011-01-12 03:15:52 +0000251compute_item(rangeobject *r, PyObject *i)
Benjamin Petersona1864f32010-11-20 23:05:39 +0000252{
Nick Coghlane993b102011-01-12 03:15:52 +0000253 PyObject *incr, *result;
254 /* PyLong equivalent to:
255 * return r->start + (i * r->step)
256 */
Dong-hee Na25492a52020-10-21 10:29:14 +0900257 if (r->step == _PyLong_One) {
258 result = PyNumber_Add(r->start, i);
259 }
260 else {
261 incr = PyNumber_Multiply(i, r->step);
262 if (!incr) {
263 return NULL;
264 }
265 result = PyNumber_Add(r->start, incr);
266 Py_DECREF(incr);
267 }
Guido van Rossum805365e2007-05-07 22:24:25 +0000268 return result;
Guido van Rossum7d6aa511993-12-21 22:50:31 +0000269}
270
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000271static PyObject *
Nick Coghlane993b102011-01-12 03:15:52 +0000272compute_range_item(rangeobject *r, PyObject *arg)
Benjamin Petersona1864f32010-11-20 23:05:39 +0000273{
Nick Coghlane993b102011-01-12 03:15:52 +0000274 int cmp_result;
275 PyObject *i, *result;
Tim Petersd976ab72004-08-08 06:29:10 +0000276
Nick Coghlane993b102011-01-12 03:15:52 +0000277 /* PyLong equivalent to:
278 * if (arg < 0) {
279 * i = r->length + arg
280 * } else {
281 * i = arg
282 * }
283 */
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300284 cmp_result = PyObject_RichCompareBool(arg, _PyLong_Zero, Py_LT);
Nick Coghlane993b102011-01-12 03:15:52 +0000285 if (cmp_result == -1) {
Nick Coghlan37ee8502010-12-03 14:26:13 +0000286 return NULL;
Guido van Rossum805365e2007-05-07 22:24:25 +0000287 }
Nick Coghlane993b102011-01-12 03:15:52 +0000288 if (cmp_result == 1) {
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300289 i = PyNumber_Add(r->length, arg);
290 if (!i) {
291 return NULL;
292 }
Nick Coghlane993b102011-01-12 03:15:52 +0000293 } else {
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300294 i = arg;
295 Py_INCREF(i);
Nick Coghlane993b102011-01-12 03:15:52 +0000296 }
297
298 /* PyLong equivalent to:
299 * if (i < 0 || i >= r->length) {
300 * <report index out of bounds>
301 * }
302 */
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300303 cmp_result = PyObject_RichCompareBool(i, _PyLong_Zero, Py_LT);
Nick Coghlane993b102011-01-12 03:15:52 +0000304 if (cmp_result == 0) {
305 cmp_result = PyObject_RichCompareBool(i, r->length, Py_GE);
306 }
307 if (cmp_result == -1) {
308 Py_DECREF(i);
309 return NULL;
310 }
311 if (cmp_result == 1) {
312 Py_DECREF(i);
313 PyErr_SetString(PyExc_IndexError,
314 "range object index out of range");
315 return NULL;
316 }
317
318 result = compute_item(r, i);
319 Py_DECREF(i);
320 return result;
321}
322
323static PyObject *
324range_item(rangeobject *r, Py_ssize_t i)
325{
Antoine Pitroua103b962012-05-16 14:37:54 +0200326 PyObject *res, *arg = PyLong_FromSsize_t(i);
Nick Coghlane993b102011-01-12 03:15:52 +0000327 if (!arg) {
328 return NULL;
329 }
Benjamin Peterson547d4852011-01-13 04:22:54 +0000330 res = compute_range_item(r, arg);
331 Py_DECREF(arg);
332 return res;
Nick Coghlane993b102011-01-12 03:15:52 +0000333}
334
Nick Coghlane993b102011-01-12 03:15:52 +0000335static PyObject *
336compute_slice(rangeobject *r, PyObject *_slice)
337{
338 PySliceObject *slice = (PySliceObject *) _slice;
339 rangeobject *result;
340 PyObject *start = NULL, *stop = NULL, *step = NULL;
341 PyObject *substart = NULL, *substop = NULL, *substep = NULL;
Mark Dickinsonffdb2c22012-11-17 19:18:10 +0000342 int error;
Nick Coghlane993b102011-01-12 03:15:52 +0000343
Mark Dickinsonffdb2c22012-11-17 19:18:10 +0000344 error = _PySlice_GetLongIndices(slice, r->length, &start, &stop, &step);
345 if (error == -1)
346 return NULL;
Nick Coghlane993b102011-01-12 03:15:52 +0000347
348 substep = PyNumber_Multiply(r->step, step);
349 if (substep == NULL) goto fail;
350 Py_CLEAR(step);
351
352 substart = compute_item(r, start);
353 if (substart == NULL) goto fail;
354 Py_CLEAR(start);
355
Mark Dickinsonffdb2c22012-11-17 19:18:10 +0000356 substop = compute_item(r, stop);
357 if (substop == NULL) goto fail;
Nick Coghlane993b102011-01-12 03:15:52 +0000358 Py_CLEAR(stop);
359
360 result = make_range_object(Py_TYPE(r), substart, substop, substep);
361 if (result != NULL) {
362 return (PyObject *) result;
363 }
364fail:
365 Py_XDECREF(start);
366 Py_XDECREF(stop);
367 Py_XDECREF(step);
368 Py_XDECREF(substart);
369 Py_XDECREF(substop);
370 Py_XDECREF(substep);
371 return NULL;
Alexandre Vassalotti75056072008-06-10 04:03:04 +0000372}
373
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000374/* Assumes (PyLong_CheckExact(ob) || PyBool_Check(ob)) */
375static int
Benjamin Petersona1864f32010-11-20 23:05:39 +0000376range_contains_long(rangeobject *r, PyObject *ob)
377{
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000378 int cmp1, cmp2, cmp3;
379 PyObject *tmp1 = NULL;
380 PyObject *tmp2 = NULL;
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000381 int result = -1;
382
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000383 /* Check if the value can possibly be in the range. */
384
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300385 cmp1 = PyObject_RichCompareBool(r->step, _PyLong_Zero, Py_GT);
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000386 if (cmp1 == -1)
387 goto end;
388 if (cmp1 == 1) { /* positive steps: start <= ob < stop */
389 cmp2 = PyObject_RichCompareBool(r->start, ob, Py_LE);
390 cmp3 = PyObject_RichCompareBool(ob, r->stop, Py_LT);
391 }
392 else { /* negative steps: stop < ob <= start */
393 cmp2 = PyObject_RichCompareBool(ob, r->start, Py_LE);
394 cmp3 = PyObject_RichCompareBool(r->stop, ob, Py_LT);
395 }
396
397 if (cmp2 == -1 || cmp3 == -1) /* TypeError */
398 goto end;
399 if (cmp2 == 0 || cmp3 == 0) { /* ob outside of range */
400 result = 0;
401 goto end;
402 }
403
404 /* Check that the stride does not invalidate ob's membership. */
405 tmp1 = PyNumber_Subtract(ob, r->start);
406 if (tmp1 == NULL)
407 goto end;
408 tmp2 = PyNumber_Remainder(tmp1, r->step);
409 if (tmp2 == NULL)
410 goto end;
Berker Peksaged6224e2016-09-12 07:47:04 +0300411 /* result = ((int(ob) - start) % step) == 0 */
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300412 result = PyObject_RichCompareBool(tmp2, _PyLong_Zero, Py_EQ);
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000413 end:
414 Py_XDECREF(tmp1);
415 Py_XDECREF(tmp2);
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000416 return result;
417}
418
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000419static int
Benjamin Petersona1864f32010-11-20 23:05:39 +0000420range_contains(rangeobject *r, PyObject *ob)
421{
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000422 if (PyLong_CheckExact(ob) || PyBool_Check(ob))
423 return range_contains_long(r, ob);
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000424
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000425 return (int)_PySequence_IterSearch((PyObject*)r, ob,
426 PY_ITERSEARCH_CONTAINS);
427}
428
Mark Dickinson36645682011-10-23 19:53:01 +0100429/* Compare two range objects. Return 1 for equal, 0 for not equal
430 and -1 on error. The algorithm is roughly the C equivalent of
431
432 if r0 is r1:
433 return True
434 if len(r0) != len(r1):
435 return False
436 if not len(r0):
437 return True
438 if r0.start != r1.start:
439 return False
440 if len(r0) == 1:
441 return True
442 return r0.step == r1.step
443*/
444static int
445range_equals(rangeobject *r0, rangeobject *r1)
446{
447 int cmp_result;
Mark Dickinson36645682011-10-23 19:53:01 +0100448
449 if (r0 == r1)
450 return 1;
451 cmp_result = PyObject_RichCompareBool(r0->length, r1->length, Py_EQ);
452 /* Return False or error to the caller. */
453 if (cmp_result != 1)
454 return cmp_result;
455 cmp_result = PyObject_Not(r0->length);
456 /* Return True or error to the caller. */
457 if (cmp_result != 0)
458 return cmp_result;
459 cmp_result = PyObject_RichCompareBool(r0->start, r1->start, Py_EQ);
460 /* Return False or error to the caller. */
461 if (cmp_result != 1)
462 return cmp_result;
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300463 cmp_result = PyObject_RichCompareBool(r0->length, _PyLong_One, Py_EQ);
Mark Dickinson36645682011-10-23 19:53:01 +0100464 /* Return True or error to the caller. */
465 if (cmp_result != 0)
466 return cmp_result;
467 return PyObject_RichCompareBool(r0->step, r1->step, Py_EQ);
468}
469
470static PyObject *
471range_richcompare(PyObject *self, PyObject *other, int op)
472{
473 int result;
474
475 if (!PyRange_Check(other))
476 Py_RETURN_NOTIMPLEMENTED;
477 switch (op) {
478 case Py_NE:
479 case Py_EQ:
480 result = range_equals((rangeobject*)self, (rangeobject*)other);
481 if (result == -1)
482 return NULL;
483 if (op == Py_NE)
484 result = !result;
485 if (result)
486 Py_RETURN_TRUE;
487 else
488 Py_RETURN_FALSE;
489 case Py_LE:
490 case Py_GE:
491 case Py_LT:
492 case Py_GT:
493 Py_RETURN_NOTIMPLEMENTED;
494 default:
495 PyErr_BadArgument();
496 return NULL;
497 }
498}
499
500/* Hash function for range objects. Rough C equivalent of
501
502 if not len(r):
503 return hash((len(r), None, None))
504 if len(r) == 1:
505 return hash((len(r), r.start, None))
506 return hash((len(r), r.start, r.step))
507*/
508static Py_hash_t
509range_hash(rangeobject *r)
510{
511 PyObject *t;
512 Py_hash_t result = -1;
513 int cmp_result;
514
515 t = PyTuple_New(3);
516 if (!t)
517 return -1;
518 Py_INCREF(r->length);
519 PyTuple_SET_ITEM(t, 0, r->length);
520 cmp_result = PyObject_Not(r->length);
521 if (cmp_result == -1)
522 goto end;
523 if (cmp_result == 1) {
524 Py_INCREF(Py_None);
525 Py_INCREF(Py_None);
526 PyTuple_SET_ITEM(t, 1, Py_None);
527 PyTuple_SET_ITEM(t, 2, Py_None);
528 }
529 else {
Mark Dickinson36645682011-10-23 19:53:01 +0100530 Py_INCREF(r->start);
531 PyTuple_SET_ITEM(t, 1, r->start);
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300532 cmp_result = PyObject_RichCompareBool(r->length, _PyLong_One, Py_EQ);
Mark Dickinson36645682011-10-23 19:53:01 +0100533 if (cmp_result == -1)
534 goto end;
535 if (cmp_result == 1) {
536 Py_INCREF(Py_None);
537 PyTuple_SET_ITEM(t, 2, Py_None);
538 }
539 else {
540 Py_INCREF(r->step);
541 PyTuple_SET_ITEM(t, 2, r->step);
542 }
543 }
544 result = PyObject_Hash(t);
545 end:
546 Py_DECREF(t);
547 return result;
548}
549
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000550static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +0000551range_count(rangeobject *r, PyObject *ob)
552{
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000553 if (PyLong_CheckExact(ob) || PyBool_Check(ob)) {
Georg Brandl7e5343b2010-11-20 22:40:10 +0000554 int result = range_contains_long(r, ob);
555 if (result == -1)
556 return NULL;
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300557 return PyLong_FromLong(result);
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000558 } else {
559 Py_ssize_t count;
560 count = _PySequence_IterSearch((PyObject*)r, ob, PY_ITERSEARCH_COUNT);
561 if (count == -1)
562 return NULL;
563 return PyLong_FromSsize_t(count);
564 }
565}
566
567static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +0000568range_index(rangeobject *r, PyObject *ob)
569{
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000570 int contains;
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000571
572 if (!PyLong_CheckExact(ob) && !PyBool_Check(ob)) {
573 Py_ssize_t index;
574 index = _PySequence_IterSearch((PyObject*)r, ob, PY_ITERSEARCH_INDEX);
575 if (index == -1)
576 return NULL;
577 return PyLong_FromSsize_t(index);
578 }
579
580 contains = range_contains_long(r, ob);
581 if (contains == -1)
582 return NULL;
583
Benjamin Peterson155614b2010-11-20 22:44:32 +0000584 if (contains) {
Dong-hee Nac0f22fb2020-10-21 11:29:56 +0900585 PyObject *idx = PyNumber_Subtract(ob, r->start);
586 if (idx == NULL) {
Benjamin Peterson155614b2010-11-20 22:44:32 +0000587 return NULL;
Dong-hee Nac0f22fb2020-10-21 11:29:56 +0900588 }
589
590 if (r->step == _PyLong_One) {
591 return idx;
592 }
593
Benjamin Peterson155614b2010-11-20 22:44:32 +0000594 /* idx = (ob - r.start) // r.step */
Dong-hee Nac0f22fb2020-10-21 11:29:56 +0900595 PyObject *sidx = PyNumber_FloorDivide(idx, r->step);
596 Py_DECREF(idx);
597 return sidx;
Benjamin Peterson155614b2010-11-20 22:44:32 +0000598 }
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000599
600 /* object is not in the range */
Benjamin Peterson155614b2010-11-20 22:44:32 +0000601 PyErr_Format(PyExc_ValueError, "%R is not in range", ob);
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000602 return NULL;
603}
604
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000605static PySequenceMethods range_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000606 (lenfunc)range_length, /* sq_length */
Nick Coghlan37ee8502010-12-03 14:26:13 +0000607 0, /* sq_concat */
608 0, /* sq_repeat */
609 (ssizeargfunc)range_item, /* sq_item */
610 0, /* sq_slice */
611 0, /* sq_ass_item */
612 0, /* sq_ass_slice */
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000613 (objobjproc)range_contains, /* sq_contains */
Guido van Rossum12d12c51993-10-26 17:58:25 +0000614};
615
Nick Coghlan37ee8502010-12-03 14:26:13 +0000616static PyObject *
617range_repr(rangeobject *r)
618{
619 Py_ssize_t istep;
620
621 /* Check for special case values for printing. We don't always
Alexey Izbyshev7ecae3c2018-08-24 07:39:45 +0300622 need the step value. We don't care about overflow. */
Nick Coghlan37ee8502010-12-03 14:26:13 +0000623 istep = PyNumber_AsSsize_t(r->step, NULL);
Alexey Izbyshev7ecae3c2018-08-24 07:39:45 +0300624 if (istep == -1 && PyErr_Occurred()) {
625 assert(!PyErr_ExceptionMatches(PyExc_OverflowError));
626 return NULL;
Nick Coghlan37ee8502010-12-03 14:26:13 +0000627 }
628
629 if (istep == 1)
630 return PyUnicode_FromFormat("range(%R, %R)", r->start, r->stop);
631 else
632 return PyUnicode_FromFormat("range(%R, %R, %R)",
633 r->start, r->stop, r->step);
634}
635
636/* Pickling support */
637static PyObject *
638range_reduce(rangeobject *r, PyObject *args)
639{
640 return Py_BuildValue("(O(OOO))", Py_TYPE(r),
641 r->start, r->stop, r->step);
642}
643
644static PyObject *
645range_subscript(rangeobject* self, PyObject* item)
646{
Victor Stinnera15e2602020-04-08 02:01:56 +0200647 if (_PyIndex_Check(item)) {
Nick Coghlane993b102011-01-12 03:15:52 +0000648 PyObject *i, *result;
649 i = PyNumber_Index(item);
650 if (!i)
Nick Coghlan37ee8502010-12-03 14:26:13 +0000651 return NULL;
Nick Coghlane993b102011-01-12 03:15:52 +0000652 result = compute_range_item(self, i);
653 Py_DECREF(i);
654 return result;
Nick Coghlan37ee8502010-12-03 14:26:13 +0000655 }
656 if (PySlice_Check(item)) {
Nick Coghlane993b102011-01-12 03:15:52 +0000657 return compute_slice(self, item);
Nick Coghlan37ee8502010-12-03 14:26:13 +0000658 }
659 PyErr_Format(PyExc_TypeError,
660 "range indices must be integers or slices, not %.200s",
Victor Stinner58ac7002020-02-07 03:04:21 +0100661 Py_TYPE(item)->tp_name);
Nick Coghlan37ee8502010-12-03 14:26:13 +0000662 return NULL;
663}
664
665
666static PyMappingMethods range_as_mapping = {
667 (lenfunc)range_length, /* mp_length */
668 (binaryfunc)range_subscript, /* mp_subscript */
669 (objobjargproc)0, /* mp_ass_subscript */
670};
671
4kir4e46fb862017-03-20 09:44:46 +0300672static int
673range_bool(rangeobject* self)
674{
675 return PyObject_IsTrue(self->length);
676}
677
678static PyNumberMethods range_as_number = {
679 .nb_bool = (inquiry)range_bool,
680};
681
Jeremy Hylton938ace62002-07-17 16:30:39 +0000682static PyObject * range_iter(PyObject *seq);
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530683static PyObject * range_reverse(PyObject *seq, PyObject *Py_UNUSED(ignored));
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000684
685PyDoc_STRVAR(reverse_doc,
Ezio Melotti5792ce12013-10-06 00:36:45 +0300686"Return a reverse iterator.");
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000687
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000688PyDoc_STRVAR(count_doc,
689"rangeobject.count(value) -> integer -- return number of occurrences of value");
690
691PyDoc_STRVAR(index_doc,
Srinivas Reddy Thatiparthy (శ్రీనివాస్ రెడ్డి తాటిపర్తి)22c52632019-05-03 17:52:12 +0530692"rangeobject.index(value) -> integer -- return index of value.\n"
Ezio Melotti5792ce12013-10-06 00:36:45 +0300693"Raise ValueError if the value is not present.");
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000694
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000695static PyMethodDef range_methods[] = {
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530696 {"__reversed__", range_reverse, METH_NOARGS, reverse_doc},
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000697 {"__reduce__", (PyCFunction)range_reduce, METH_VARARGS},
698 {"count", (PyCFunction)range_count, METH_O, count_doc},
699 {"index", (PyCFunction)range_index, METH_O, index_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000700 {NULL, NULL} /* sentinel */
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000701};
Raymond Hettinger48165d42002-06-05 20:08:48 +0000702
Benjamin Peterson878ce382011-11-05 15:17:52 -0400703static PyMemberDef range_members[] = {
704 {"start", T_OBJECT_EX, offsetof(rangeobject, start), READONLY},
705 {"stop", T_OBJECT_EX, offsetof(rangeobject, stop), READONLY},
706 {"step", T_OBJECT_EX, offsetof(rangeobject, step), READONLY},
707 {0}
708};
709
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000710PyTypeObject PyRange_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000711 PyVarObject_HEAD_INIT(&PyType_Type, 0)
712 "range", /* Name of this type */
713 sizeof(rangeobject), /* Basic object size */
714 0, /* Item size for varobject */
715 (destructor)range_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200716 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000717 0, /* tp_getattr */
718 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200719 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 (reprfunc)range_repr, /* tp_repr */
4kir4e46fb862017-03-20 09:44:46 +0300721 &range_as_number, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000722 &range_as_sequence, /* tp_as_sequence */
Nick Coghlan37ee8502010-12-03 14:26:13 +0000723 &range_as_mapping, /* tp_as_mapping */
Mark Dickinson36645682011-10-23 19:53:01 +0100724 (hashfunc)range_hash, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000725 0, /* tp_call */
726 0, /* tp_str */
727 PyObject_GenericGetAttr, /* tp_getattro */
728 0, /* tp_setattro */
729 0, /* tp_as_buffer */
730 Py_TPFLAGS_DEFAULT, /* tp_flags */
731 range_doc, /* tp_doc */
732 0, /* tp_traverse */
733 0, /* tp_clear */
Mark Dickinson36645682011-10-23 19:53:01 +0100734 range_richcompare, /* tp_richcompare */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000735 0, /* tp_weaklistoffset */
736 range_iter, /* tp_iter */
737 0, /* tp_iternext */
738 range_methods, /* tp_methods */
Benjamin Peterson878ce382011-11-05 15:17:52 -0400739 range_members, /* tp_members */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000740 0, /* tp_getset */
741 0, /* tp_base */
742 0, /* tp_dict */
743 0, /* tp_descr_get */
744 0, /* tp_descr_set */
745 0, /* tp_dictoffset */
746 0, /* tp_init */
747 0, /* tp_alloc */
748 range_new, /* tp_new */
Petr Viktorin6e35da92020-02-18 16:13:17 +0100749 .tp_vectorcall = (vectorcallfunc)range_vectorcall
Guido van Rossum12d12c51993-10-26 17:58:25 +0000750};
Raymond Hettinger48165d42002-06-05 20:08:48 +0000751
Walter Dörwald4ad94212007-05-21 18:01:17 +0000752/*********************** range Iterator **************************/
Raymond Hettinger48165d42002-06-05 20:08:48 +0000753
Guido van Rossum805365e2007-05-07 22:24:25 +0000754/* There are 2 types of iterators, one for C longs, the other for
Serhiy Storchaka95949422013-08-27 19:40:23 +0300755 Python ints (ie, PyObjects). This should make iteration fast
Guido van Rossum805365e2007-05-07 22:24:25 +0000756 in the normal case, but possible for any numeric value.
757*/
758
Raymond Hettinger48165d42002-06-05 20:08:48 +0000759typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000760 PyObject_HEAD
761 long index;
762 long start;
763 long step;
764 long len;
Raymond Hettinger48165d42002-06-05 20:08:48 +0000765} rangeiterobject;
766
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000767static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +0000768rangeiter_next(rangeiterobject *r)
769{
Guido van Rossum805365e2007-05-07 22:24:25 +0000770 if (r->index < r->len)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000771 /* cast to unsigned to avoid possible signed overflow
Mark Dickinsonb43dbc22009-11-15 12:56:08 +0000772 in intermediate calculations. */
773 return PyLong_FromLong((long)(r->start +
774 (unsigned long)(r->index++) * r->step));
Guido van Rossum805365e2007-05-07 22:24:25 +0000775 return NULL;
Raymond Hettinger48165d42002-06-05 20:08:48 +0000776}
777
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000778static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530779rangeiter_len(rangeiterobject *r, PyObject *Py_UNUSED(ignored))
Benjamin Petersona1864f32010-11-20 23:05:39 +0000780{
Christian Heimes217cfd12007-12-02 14:31:20 +0000781 return PyLong_FromLong(r->len - r->index);
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000782}
783
Guido van Rossum805365e2007-05-07 22:24:25 +0000784PyDoc_STRVAR(length_hint_doc,
785 "Private method returning an estimate of len(list(it)).");
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000786
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000787static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530788rangeiter_reduce(rangeiterobject *r, PyObject *Py_UNUSED(ignored))
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000789{
790 PyObject *start=NULL, *stop=NULL, *step=NULL;
791 PyObject *range;
Chris Jerdonek042fa652012-10-07 14:56:27 -0700792
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000793 /* create a range object for pickling */
794 start = PyLong_FromLong(r->start);
795 if (start == NULL)
796 goto err;
797 stop = PyLong_FromLong(r->start + r->len * r->step);
798 if (stop == NULL)
799 goto err;
800 step = PyLong_FromLong(r->step);
801 if (step == NULL)
802 goto err;
803 range = (PyObject*)make_range_object(&PyRange_Type,
804 start, stop, step);
805 if (range == NULL)
806 goto err;
807 /* return the result */
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200808 return Py_BuildValue("N(N)i", _PyEval_GetBuiltinId(&PyId_iter),
809 range, r->index);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000810err:
811 Py_XDECREF(start);
812 Py_XDECREF(stop);
813 Py_XDECREF(step);
814 return NULL;
815}
816
817static PyObject *
818rangeiter_setstate(rangeiterobject *r, PyObject *state)
819{
820 long index = PyLong_AsLong(state);
821 if (index == -1 && PyErr_Occurred())
822 return NULL;
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +0000823 /* silently clip the index value */
824 if (index < 0)
825 index = 0;
826 else if (index > r->len)
827 index = r->len; /* exhausted iterator */
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000828 r->index = index;
829 Py_RETURN_NONE;
830}
831
832PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
833PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
834
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000835static PyMethodDef rangeiter_methods[] = {
Guido van Rossum805365e2007-05-07 22:24:25 +0000836 {"__length_hint__", (PyCFunction)rangeiter_len, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000837 length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000838 {"__reduce__", (PyCFunction)rangeiter_reduce, METH_NOARGS,
839 reduce_doc},
840 {"__setstate__", (PyCFunction)rangeiter_setstate, METH_O,
841 setstate_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000842 {NULL, NULL} /* sentinel */
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000843};
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000844
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000845PyTypeObject PyRangeIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000846 PyVarObject_HEAD_INIT(&PyType_Type, 0)
847 "range_iterator", /* tp_name */
848 sizeof(rangeiterobject), /* tp_basicsize */
849 0, /* tp_itemsize */
850 /* methods */
851 (destructor)PyObject_Del, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200852 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000853 0, /* tp_getattr */
854 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200855 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000856 0, /* tp_repr */
857 0, /* tp_as_number */
858 0, /* tp_as_sequence */
859 0, /* tp_as_mapping */
860 0, /* tp_hash */
861 0, /* tp_call */
862 0, /* tp_str */
863 PyObject_GenericGetAttr, /* tp_getattro */
864 0, /* tp_setattro */
865 0, /* tp_as_buffer */
866 Py_TPFLAGS_DEFAULT, /* tp_flags */
867 0, /* tp_doc */
868 0, /* tp_traverse */
869 0, /* tp_clear */
870 0, /* tp_richcompare */
871 0, /* tp_weaklistoffset */
872 PyObject_SelfIter, /* tp_iter */
873 (iternextfunc)rangeiter_next, /* tp_iternext */
874 rangeiter_methods, /* tp_methods */
875 0, /* tp_members */
Guido van Rossum805365e2007-05-07 22:24:25 +0000876};
877
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000878/* Return number of items in range (lo, hi, step). step != 0
879 * required. The result always fits in an unsigned long.
Guido van Rossum805365e2007-05-07 22:24:25 +0000880 */
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000881static unsigned long
Benjamin Petersona1864f32010-11-20 23:05:39 +0000882get_len_of_range(long lo, long hi, long step)
883{
Guido van Rossum805365e2007-05-07 22:24:25 +0000884 /* -------------------------------------------------------------
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000885 If step > 0 and lo >= hi, or step < 0 and lo <= hi, the range is empty.
886 Else for step > 0, if n values are in the range, the last one is
Guido van Rossum805365e2007-05-07 22:24:25 +0000887 lo + (n-1)*step, which must be <= hi-1. Rearranging,
888 n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives
889 the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so
890 the RHS is non-negative and so truncation is the same as the
891 floor. Letting M be the largest positive long, the worst case
892 for the RHS numerator is hi=M, lo=-M-1, and then
893 hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000894 precision to compute the RHS exactly. The analysis for step < 0
895 is similar.
Guido van Rossum805365e2007-05-07 22:24:25 +0000896 ---------------------------------------------------------------*/
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000897 assert(step != 0);
898 if (step > 0 && lo < hi)
899 return 1UL + (hi - 1UL - lo) / step;
900 else if (step < 0 && lo > hi)
901 return 1UL + (lo - 1UL - hi) / (0UL - step);
902 else
903 return 0UL;
Guido van Rossum805365e2007-05-07 22:24:25 +0000904}
905
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000906/* Initialize a rangeiter object. If the length of the rangeiter object
907 is not representable as a C long, OverflowError is raised. */
908
Guido van Rossum805365e2007-05-07 22:24:25 +0000909static PyObject *
Nick Coghlan37ee8502010-12-03 14:26:13 +0000910fast_range_iter(long start, long stop, long step)
Benjamin Petersona1864f32010-11-20 23:05:39 +0000911{
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000912 rangeiterobject *it = PyObject_New(rangeiterobject, &PyRangeIter_Type);
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000913 unsigned long ulen;
Guido van Rossum805365e2007-05-07 22:24:25 +0000914 if (it == NULL)
915 return NULL;
916 it->start = start;
917 it->step = step;
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000918 ulen = get_len_of_range(start, stop, step);
919 if (ulen > (unsigned long)LONG_MAX) {
Benjamin Peterson36fbb732009-11-16 00:34:25 +0000920 Py_DECREF(it);
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000921 PyErr_SetString(PyExc_OverflowError,
922 "range too large to represent as a range_iterator");
923 return NULL;
924 }
925 it->len = (long)ulen;
Guido van Rossum805365e2007-05-07 22:24:25 +0000926 it->index = 0;
927 return (PyObject *)it;
928}
929
Nick Coghlan37ee8502010-12-03 14:26:13 +0000930typedef struct {
931 PyObject_HEAD
932 PyObject *index;
933 PyObject *start;
934 PyObject *step;
935 PyObject *len;
936} longrangeiterobject;
937
938static PyObject *
939longrangeiter_len(longrangeiterobject *r, PyObject *no_args)
940{
941 return PyNumber_Subtract(r->len, r->index);
Guido van Rossum805365e2007-05-07 22:24:25 +0000942}
943
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000944static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530945longrangeiter_reduce(longrangeiterobject *r, PyObject *Py_UNUSED(ignored))
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000946{
947 PyObject *product, *stop=NULL;
948 PyObject *range;
949
950 /* create a range object for pickling. Must calculate the "stop" value */
951 product = PyNumber_Multiply(r->len, r->step);
952 if (product == NULL)
953 return NULL;
954 stop = PyNumber_Add(r->start, product);
955 Py_DECREF(product);
956 if (stop == NULL)
957 return NULL;
958 Py_INCREF(r->start);
959 Py_INCREF(r->step);
960 range = (PyObject*)make_range_object(&PyRange_Type,
961 r->start, stop, r->step);
962 if (range == NULL) {
963 Py_DECREF(r->start);
964 Py_DECREF(stop);
965 Py_DECREF(r->step);
966 return NULL;
967 }
968
969 /* return the result */
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200970 return Py_BuildValue("N(N)O", _PyEval_GetBuiltinId(&PyId_iter),
971 range, r->index);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000972}
973
974static PyObject *
975longrangeiter_setstate(longrangeiterobject *r, PyObject *state)
976{
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +0000977 int cmp;
Serhiy Storchaka009b8112015-03-18 21:53:15 +0200978
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +0000979 /* clip the value */
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300980 cmp = PyObject_RichCompareBool(state, _PyLong_Zero, Py_LT);
981 if (cmp < 0)
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +0000982 return NULL;
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +0000983 if (cmp > 0) {
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300984 state = _PyLong_Zero;
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +0000985 }
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300986 else {
987 cmp = PyObject_RichCompareBool(r->len, state, Py_LT);
988 if (cmp < 0)
989 return NULL;
990 if (cmp > 0)
991 state = r->len;
992 }
Serhiy Storchaka4a1e70f2015-12-27 12:36:18 +0200993 Py_INCREF(state);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300994 Py_XSETREF(r->index, state);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000995 Py_RETURN_NONE;
996}
997
Guido van Rossum805365e2007-05-07 22:24:25 +0000998static PyMethodDef longrangeiter_methods[] = {
999 {"__length_hint__", (PyCFunction)longrangeiter_len, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001000 length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00001001 {"__reduce__", (PyCFunction)longrangeiter_reduce, METH_NOARGS,
1002 reduce_doc},
1003 {"__setstate__", (PyCFunction)longrangeiter_setstate, METH_O,
1004 setstate_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001005 {NULL, NULL} /* sentinel */
Guido van Rossum805365e2007-05-07 22:24:25 +00001006};
1007
1008static void
Benjamin Petersona1864f32010-11-20 23:05:39 +00001009longrangeiter_dealloc(longrangeiterobject *r)
1010{
Guido van Rossum805365e2007-05-07 22:24:25 +00001011 Py_XDECREF(r->index);
Guido van Rossum317e7742007-05-08 15:18:31 +00001012 Py_XDECREF(r->start);
1013 Py_XDECREF(r->step);
1014 Py_XDECREF(r->len);
Amaury Forgeot d'Arcb7f17e42007-11-15 20:52:21 +00001015 PyObject_Del(r);
Guido van Rossum805365e2007-05-07 22:24:25 +00001016}
1017
1018static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +00001019longrangeiter_next(longrangeiterobject *r)
1020{
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001021 PyObject *product, *new_index, *result;
Guido van Rossum805365e2007-05-07 22:24:25 +00001022 if (PyObject_RichCompareBool(r->index, r->len, Py_LT) != 1)
1023 return NULL;
1024
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001025 new_index = PyNumber_Add(r->index, _PyLong_One);
Benjamin Peterson36fbb732009-11-16 00:34:25 +00001026 if (!new_index)
1027 return NULL;
1028
1029 product = PyNumber_Multiply(r->index, r->step);
1030 if (!product) {
1031 Py_DECREF(new_index);
Guido van Rossum805365e2007-05-07 22:24:25 +00001032 return NULL;
1033 }
1034
1035 result = PyNumber_Add(r->start, product);
1036 Py_DECREF(product);
1037 if (result) {
Serhiy Storchaka57a01d32016-04-10 18:05:40 +03001038 Py_SETREF(r->index, new_index);
Guido van Rossum805365e2007-05-07 22:24:25 +00001039 }
Benjamin Peterson36fbb732009-11-16 00:34:25 +00001040 else {
1041 Py_DECREF(new_index);
1042 }
Guido van Rossum805365e2007-05-07 22:24:25 +00001043
1044 return result;
1045}
1046
Christian Heimesa22e8bd2007-11-29 22:35:39 +00001047PyTypeObject PyLongRangeIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001048 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1049 "longrange_iterator", /* tp_name */
1050 sizeof(longrangeiterobject), /* tp_basicsize */
1051 0, /* tp_itemsize */
1052 /* methods */
1053 (destructor)longrangeiter_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001054 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001055 0, /* tp_getattr */
1056 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001057 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001058 0, /* tp_repr */
1059 0, /* tp_as_number */
1060 0, /* tp_as_sequence */
1061 0, /* tp_as_mapping */
1062 0, /* tp_hash */
1063 0, /* tp_call */
1064 0, /* tp_str */
1065 PyObject_GenericGetAttr, /* tp_getattro */
1066 0, /* tp_setattro */
1067 0, /* tp_as_buffer */
1068 Py_TPFLAGS_DEFAULT, /* tp_flags */
1069 0, /* tp_doc */
1070 0, /* tp_traverse */
1071 0, /* tp_clear */
1072 0, /* tp_richcompare */
1073 0, /* tp_weaklistoffset */
1074 PyObject_SelfIter, /* tp_iter */
1075 (iternextfunc)longrangeiter_next, /* tp_iternext */
1076 longrangeiter_methods, /* tp_methods */
1077 0,
Raymond Hettinger48165d42002-06-05 20:08:48 +00001078};
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001079
1080static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +00001081range_iter(PyObject *seq)
1082{
Guido van Rossum805365e2007-05-07 22:24:25 +00001083 rangeobject *r = (rangeobject *)seq;
1084 longrangeiterobject *it;
Martin v. Löwis84451042007-12-20 22:57:23 +00001085 long lstart, lstop, lstep;
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001086 PyObject *int_it;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001087
Guido van Rossum805365e2007-05-07 22:24:25 +00001088 assert(PyRange_Check(seq));
Martin v. Löwis84451042007-12-20 22:57:23 +00001089
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001090 /* If all three fields and the length convert to long, use the int
1091 * version */
Martin v. Löwis84451042007-12-20 22:57:23 +00001092 lstart = PyLong_AsLong(r->start);
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001093 if (lstart == -1 && PyErr_Occurred()) {
1094 PyErr_Clear();
1095 goto long_range;
Martin v. Löwis84451042007-12-20 22:57:23 +00001096 }
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001097 lstop = PyLong_AsLong(r->stop);
1098 if (lstop == -1 && PyErr_Occurred()) {
1099 PyErr_Clear();
1100 goto long_range;
1101 }
1102 lstep = PyLong_AsLong(r->step);
1103 if (lstep == -1 && PyErr_Occurred()) {
1104 PyErr_Clear();
1105 goto long_range;
1106 }
Nick Coghlan37ee8502010-12-03 14:26:13 +00001107 int_it = fast_range_iter(lstart, lstop, lstep);
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001108 if (int_it == NULL && PyErr_ExceptionMatches(PyExc_OverflowError)) {
1109 PyErr_Clear();
1110 goto long_range;
1111 }
1112 return (PyObject *)int_it;
1113
1114 long_range:
Christian Heimesa22e8bd2007-11-29 22:35:39 +00001115 it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
Guido van Rossum805365e2007-05-07 22:24:25 +00001116 if (it == NULL)
1117 return NULL;
Guido van Rossum317e7742007-05-08 15:18:31 +00001118
Guido van Rossum805365e2007-05-07 22:24:25 +00001119 it->start = r->start;
Guido van Rossum317e7742007-05-08 15:18:31 +00001120 it->step = r->step;
Nick Coghlan37ee8502010-12-03 14:26:13 +00001121 it->len = r->length;
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001122 it->index = _PyLong_Zero;
Guido van Rossum317e7742007-05-08 15:18:31 +00001123 Py_INCREF(it->start);
1124 Py_INCREF(it->step);
Nick Coghlan37ee8502010-12-03 14:26:13 +00001125 Py_INCREF(it->len);
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001126 Py_INCREF(it->index);
Guido van Rossum805365e2007-05-07 22:24:25 +00001127 return (PyObject *)it;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001128}
1129
1130static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301131range_reverse(PyObject *seq, PyObject *Py_UNUSED(ignored))
Benjamin Petersona1864f32010-11-20 23:05:39 +00001132{
Guido van Rossum805365e2007-05-07 22:24:25 +00001133 rangeobject *range = (rangeobject*) seq;
1134 longrangeiterobject *it;
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001135 PyObject *sum, *diff, *product;
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001136 long lstart, lstop, lstep, new_start, new_stop;
1137 unsigned long ulen;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001138
Guido van Rossum805365e2007-05-07 22:24:25 +00001139 assert(PyRange_Check(seq));
Martin v. Löwis84451042007-12-20 22:57:23 +00001140
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001141 /* reversed(range(start, stop, step)) can be expressed as
1142 range(start+(n-1)*step, start-step, -step), where n is the number of
1143 integers in the range.
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001144
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001145 If each of start, stop, step, -step, start-step, and the length
1146 of the iterator is representable as a C long, use the int
1147 version. This excludes some cases where the reversed range is
1148 representable as a range_iterator, but it's good enough for
1149 common cases and it makes the checks simple. */
1150
1151 lstart = PyLong_AsLong(range->start);
1152 if (lstart == -1 && PyErr_Occurred()) {
1153 PyErr_Clear();
1154 goto long_range;
1155 }
1156 lstop = PyLong_AsLong(range->stop);
1157 if (lstop == -1 && PyErr_Occurred()) {
1158 PyErr_Clear();
1159 goto long_range;
1160 }
1161 lstep = PyLong_AsLong(range->step);
1162 if (lstep == -1 && PyErr_Occurred()) {
1163 PyErr_Clear();
1164 goto long_range;
1165 }
1166 /* check for possible overflow of -lstep */
1167 if (lstep == LONG_MIN)
1168 goto long_range;
1169
1170 /* check for overflow of lstart - lstep:
1171
1172 for lstep > 0, need only check whether lstart - lstep < LONG_MIN.
1173 for lstep < 0, need only check whether lstart - lstep > LONG_MAX
1174
1175 Rearrange these inequalities as:
1176
1177 lstart - LONG_MIN < lstep (lstep > 0)
1178 LONG_MAX - lstart < -lstep (lstep < 0)
1179
1180 and compute both sides as unsigned longs, to avoid the
1181 possibility of undefined behaviour due to signed overflow. */
1182
1183 if (lstep > 0) {
1184 if ((unsigned long)lstart - LONG_MIN < (unsigned long)lstep)
1185 goto long_range;
1186 }
1187 else {
1188 if (LONG_MAX - (unsigned long)lstart < 0UL - lstep)
1189 goto long_range;
1190 }
1191
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001192 ulen = get_len_of_range(lstart, lstop, lstep);
1193 if (ulen > (unsigned long)LONG_MAX)
1194 goto long_range;
1195
1196 new_stop = lstart - lstep;
1197 new_start = (long)(new_stop + ulen * lstep);
Nick Coghlan37ee8502010-12-03 14:26:13 +00001198 return fast_range_iter(new_start, new_stop, -lstep);
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001199
1200long_range:
Christian Heimesa22e8bd2007-11-29 22:35:39 +00001201 it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
Guido van Rossum805365e2007-05-07 22:24:25 +00001202 if (it == NULL)
1203 return NULL;
Zackery Spytzc9a61682018-10-31 03:13:16 -06001204 it->index = it->start = it->step = NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001205
Guido van Rossum805365e2007-05-07 22:24:25 +00001206 /* start + (len - 1) * step */
Nick Coghlan37ee8502010-12-03 14:26:13 +00001207 it->len = range->length;
1208 Py_INCREF(it->len);
Benjamin Peterson36fbb732009-11-16 00:34:25 +00001209
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001210 diff = PyNumber_Subtract(it->len, _PyLong_One);
Guido van Rossum805365e2007-05-07 22:24:25 +00001211 if (!diff)
1212 goto create_failure;
1213
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001214 product = PyNumber_Multiply(diff, range->step);
1215 Py_DECREF(diff);
Guido van Rossum805365e2007-05-07 22:24:25 +00001216 if (!product)
1217 goto create_failure;
1218
1219 sum = PyNumber_Add(range->start, product);
1220 Py_DECREF(product);
1221 it->start = sum;
1222 if (!it->start)
1223 goto create_failure;
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001224
Guido van Rossum805365e2007-05-07 22:24:25 +00001225 it->step = PyNumber_Negative(range->step);
Benjamin Peterson36fbb732009-11-16 00:34:25 +00001226 if (!it->step)
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001227 goto create_failure;
Guido van Rossum805365e2007-05-07 22:24:25 +00001228
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001229 it->index = _PyLong_Zero;
1230 Py_INCREF(it->index);
Guido van Rossum805365e2007-05-07 22:24:25 +00001231 return (PyObject *)it;
1232
1233create_failure:
Benjamin Peterson36fbb732009-11-16 00:34:25 +00001234 Py_DECREF(it);
Guido van Rossum805365e2007-05-07 22:24:25 +00001235 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001236}