blob: 5bd178b20279e7168afafabf75812b9f53941a40 [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"
Benjamin Peterson878ce382011-11-05 15:17:52 -04004#include "structmember.h"
Petr Viktorin6e35da92020-02-18 16:13:17 +01005#include "pycore_tupleobject.h"
Thomas Woutersefafcea2001-07-09 12:30:54 +00006
Guido van Rossum805365e2007-05-07 22:24:25 +00007/* Support objects whose length is > PY_SSIZE_T_MAX.
8
Serhiy Storchaka6a7b3a72016-04-17 08:32:47 +03009 This could be sped up for small PyLongs if they fit in a Py_ssize_t.
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010 This only matters on Win64. Though we could use long long which
Guido van Rossum805365e2007-05-07 22:24:25 +000011 would presumably help perf.
12*/
13
Guido van Rossum12d12c51993-10-26 17:58:25 +000014typedef struct {
Guido van Rossum805365e2007-05-07 22:24:25 +000015 PyObject_HEAD
16 PyObject *start;
17 PyObject *stop;
18 PyObject *step;
Nick Coghlan37ee8502010-12-03 14:26:13 +000019 PyObject *length;
Guido van Rossum12d12c51993-10-26 17:58:25 +000020} rangeobject;
21
Hai Shi46874c22020-01-30 17:20:25 -060022_Py_IDENTIFIER(iter);
23
Guido van Rossum805365e2007-05-07 22:24:25 +000024/* Helper function for validating step. Always returns a new reference or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000025 NULL on error.
Guido van Rossum805365e2007-05-07 22:24:25 +000026*/
27static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +000028validate_step(PyObject *step)
29{
Guido van Rossum805365e2007-05-07 22:24:25 +000030 /* No step specified, use a step of 1. */
31 if (!step)
Christian Heimes217cfd12007-12-02 14:31:20 +000032 return PyLong_FromLong(1);
Guido van Rossum805365e2007-05-07 22:24:25 +000033
34 step = PyNumber_Index(step);
Serhiy Storchaka5d062d72016-06-18 09:51:55 +030035 if (step && _PyLong_Sign(step) == 0) {
36 PyErr_SetString(PyExc_ValueError,
37 "range() arg 3 must not be zero");
38 Py_CLEAR(step);
Guido van Rossum805365e2007-05-07 22:24:25 +000039 }
40
41 return step;
Raymond Hettingerc4c453f2002-06-05 23:12:45 +000042}
43
Nick Coghlan37ee8502010-12-03 14:26:13 +000044static PyObject *
45compute_range_length(PyObject *start, PyObject *stop, PyObject *step);
46
47static rangeobject *
48make_range_object(PyTypeObject *type, PyObject *start,
49 PyObject *stop, PyObject *step)
50{
51 rangeobject *obj = NULL;
52 PyObject *length;
53 length = compute_range_length(start, stop, step);
54 if (length == NULL) {
55 return NULL;
56 }
57 obj = PyObject_New(rangeobject, type);
58 if (obj == NULL) {
59 Py_DECREF(length);
60 return NULL;
61 }
62 obj->start = start;
63 obj->stop = stop;
64 obj->step = step;
65 obj->length = length;
66 return obj;
67}
68
Guido van Rossum805365e2007-05-07 22:24:25 +000069/* XXX(nnorwitz): should we error check if the user passes any empty ranges?
70 range(-10)
71 range(0, -5)
72 range(0, 5, -1)
73*/
Raymond Hettingerc4c453f2002-06-05 23:12:45 +000074static PyObject *
Petr Viktorin6e35da92020-02-18 16:13:17 +010075range_from_array(PyTypeObject *type, PyObject *const *args, Py_ssize_t num_args)
Benjamin Petersona1864f32010-11-20 23:05:39 +000076{
Nick Coghlan37ee8502010-12-03 14:26:13 +000077 rangeobject *obj;
Guido van Rossum805365e2007-05-07 22:24:25 +000078 PyObject *start = NULL, *stop = NULL, *step = NULL;
Raymond Hettingerc4c453f2002-06-05 23:12:45 +000079
Pablo Galindo4b66fa62020-01-05 17:30:53 +000080 switch (num_args) {
81 case 3:
Petr Viktorin6e35da92020-02-18 16:13:17 +010082 step = args[2];
Pablo Galindo4b66fa62020-01-05 17:30:53 +000083 /* fallthrough */
84 case 2:
Petr Viktorin6e35da92020-02-18 16:13:17 +010085 /* Convert borrowed refs to owned refs */
86 start = PyNumber_Index(args[0]);
Pablo Galindo4b66fa62020-01-05 17:30:53 +000087 if (!start) {
88 return NULL;
89 }
Petr Viktorin6e35da92020-02-18 16:13:17 +010090 stop = PyNumber_Index(args[1]);
Pablo Galindo4b66fa62020-01-05 17:30:53 +000091 if (!stop) {
92 Py_DECREF(start);
93 return NULL;
94 }
Petr Viktorin6e35da92020-02-18 16:13:17 +010095 step = validate_step(step); /* Caution, this can clear exceptions */
Pablo Galindo4b66fa62020-01-05 17:30:53 +000096 if (!step) {
97 Py_DECREF(start);
98 Py_DECREF(stop);
99 return NULL;
100 }
101 break;
102 case 1:
Petr Viktorin6e35da92020-02-18 16:13:17 +0100103 stop = PyNumber_Index(args[0]);
Pablo Galindo4b66fa62020-01-05 17:30:53 +0000104 if (!stop) {
105 return NULL;
106 }
107 Py_INCREF(_PyLong_Zero);
108 start = _PyLong_Zero;
109 Py_INCREF(_PyLong_One);
110 step = _PyLong_One;
111 break;
112 case 0:
113 PyErr_SetString(PyExc_TypeError,
114 "range expected at least 1 argument, got 0");
Raymond Hettinger94f55832009-06-12 18:40:16 +0000115 return NULL;
Pablo Galindo4b66fa62020-01-05 17:30:53 +0000116 default:
Victor Stinner58ac7002020-02-07 03:04:21 +0100117 PyErr_Format(PyExc_TypeError,
Pablo Galindo4b66fa62020-01-05 17:30:53 +0000118 "range expected at most 3 arguments, got %zd",
119 num_args);
Raymond Hettinger94f55832009-06-12 18:40:16 +0000120 return NULL;
Guido van Rossum805365e2007-05-07 22:24:25 +0000121 }
Nick Coghlan37ee8502010-12-03 14:26:13 +0000122 obj = make_range_object(type, start, stop, step);
Petr Viktorin6e35da92020-02-18 16:13:17 +0100123 if (obj != NULL) {
Nick Coghlan37ee8502010-12-03 14:26:13 +0000124 return (PyObject *) obj;
Petr Viktorin6e35da92020-02-18 16:13:17 +0100125 }
Guido van Rossum805365e2007-05-07 22:24:25 +0000126
Nick Coghlan37ee8502010-12-03 14:26:13 +0000127 /* Failed to create object, release attributes */
Serhiy Storchakacfdfbb42016-06-18 09:44:03 +0300128 Py_DECREF(start);
129 Py_DECREF(stop);
130 Py_DECREF(step);
Guido van Rossum805365e2007-05-07 22:24:25 +0000131 return NULL;
Raymond Hettingerc4c453f2002-06-05 23:12:45 +0000132}
133
Petr Viktorin6e35da92020-02-18 16:13:17 +0100134static PyObject *
135range_new(PyTypeObject *type, PyObject *args, PyObject *kw)
136{
137 if (!_PyArg_NoKeywords("range", kw))
138 return NULL;
139
140 return range_from_array(type, _PyTuple_ITEMS(args), PyTuple_GET_SIZE(args));
141}
142
143
144static PyObject *
145range_vectorcall(PyTypeObject *type, PyObject *const *args,
146 size_t nargsf, PyObject *kwnames)
147{
148 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
Dong-hee Na87ec86c2020-03-16 23:06:20 +0900149 if (!_PyArg_NoKwnames("range", kwnames)) {
Petr Viktorin6e35da92020-02-18 16:13:17 +0100150 return NULL;
151 }
152 return range_from_array(type, args, nargs);
153}
154
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000155PyDoc_STRVAR(range_doc,
Chris Jerdonek83fe2e12012-10-07 14:48:36 -0700156"range(stop) -> range object\n\
157range(start, stop[, step]) -> range object\n\
Raymond Hettingerc4c453f2002-06-05 23:12:45 +0000158\n\
Benjamin Petersonac22c6b2015-04-22 09:16:07 -0400159Return an object that produces a sequence of integers from start (inclusive)\n\
160to stop (exclusive) by step. range(i, j) produces i, i+1, i+2, ..., j-1.\n\
161start defaults to 0, and stop is omitted! range(4) produces 0, 1, 2, 3.\n\
162These are exactly the valid indices for a list of 4 elements.\n\
163When step is given, it specifies the increment (or decrement).");
Raymond Hettingerc4c453f2002-06-05 23:12:45 +0000164
Guido van Rossum805365e2007-05-07 22:24:25 +0000165static void
Benjamin Petersona1864f32010-11-20 23:05:39 +0000166range_dealloc(rangeobject *r)
167{
Guido van Rossum805365e2007-05-07 22:24:25 +0000168 Py_DECREF(r->start);
169 Py_DECREF(r->stop);
170 Py_DECREF(r->step);
Nick Coghlan37ee8502010-12-03 14:26:13 +0000171 Py_DECREF(r->length);
Amaury Forgeot d'Arcb7f17e42007-11-15 20:52:21 +0000172 PyObject_Del(r);
Guido van Rossum805365e2007-05-07 22:24:25 +0000173}
174
Mark Dickinson732166d2009-06-28 22:08:40 +0000175/* Return number of items in range (lo, hi, step) as a PyLong object,
176 * when arguments are PyLong objects. Arguments MUST return 1 with
177 * PyLong_Check(). Return NULL when there is an error.
Guido van Rossum805365e2007-05-07 22:24:25 +0000178 */
179static PyObject*
Nick Coghlan37ee8502010-12-03 14:26:13 +0000180compute_range_length(PyObject *start, PyObject *stop, PyObject *step)
Benjamin Petersona1864f32010-11-20 23:05:39 +0000181{
Guido van Rossum805365e2007-05-07 22:24:25 +0000182 /* -------------------------------------------------------------
183 Algorithm is equal to that of get_len_of_range(), but it operates
Benjamin Petersona47af9c2009-06-24 21:14:38 +0000184 on PyObjects (which are assumed to be PyLong objects).
Guido van Rossum805365e2007-05-07 22:24:25 +0000185 ---------------------------------------------------------------*/
Mark Dickinson211c6252009-02-01 10:28:51 +0000186 int cmp_result;
Guido van Rossum805365e2007-05-07 22:24:25 +0000187 PyObject *lo, *hi;
Guido van Rossum805365e2007-05-07 22:24:25 +0000188 PyObject *diff = NULL;
Guido van Rossum805365e2007-05-07 22:24:25 +0000189 PyObject *tmp1 = NULL, *tmp2 = NULL, *result;
190 /* holds sub-expression evaluations */
191
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300192 cmp_result = PyObject_RichCompareBool(step, _PyLong_Zero, Py_GT);
Mark Dickinson211c6252009-02-01 10:28:51 +0000193 if (cmp_result == -1)
Guido van Rossum805365e2007-05-07 22:24:25 +0000194 return NULL;
195
Mark Dickinson211c6252009-02-01 10:28:51 +0000196 if (cmp_result == 1) {
Nick Coghlan37ee8502010-12-03 14:26:13 +0000197 lo = start;
198 hi = stop;
Guido van Rossum805365e2007-05-07 22:24:25 +0000199 Py_INCREF(step);
200 } else {
Nick Coghlan37ee8502010-12-03 14:26:13 +0000201 lo = stop;
202 hi = start;
203 step = PyNumber_Negative(step);
Guido van Rossum805365e2007-05-07 22:24:25 +0000204 if (!step)
205 return NULL;
206 }
207
208 /* if (lo >= hi), return length of 0. */
Serhiy Storchakafa494fd2015-05-30 17:45:22 +0300209 cmp_result = PyObject_RichCompareBool(lo, hi, Py_GE);
210 if (cmp_result != 0) {
Serhiy Storchakacfdfbb42016-06-18 09:44:03 +0300211 Py_DECREF(step);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +0300212 if (cmp_result < 0)
213 return NULL;
Guido van Rossum805365e2007-05-07 22:24:25 +0000214 return PyLong_FromLong(0);
215 }
216
Guido van Rossum805365e2007-05-07 22:24:25 +0000217 if ((tmp1 = PyNumber_Subtract(hi, lo)) == NULL)
218 goto Fail;
219
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300220 if ((diff = PyNumber_Subtract(tmp1, _PyLong_One)) == NULL)
Guido van Rossum805365e2007-05-07 22:24:25 +0000221 goto Fail;
222
223 if ((tmp2 = PyNumber_FloorDivide(diff, step)) == NULL)
224 goto Fail;
225
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300226 if ((result = PyNumber_Add(tmp2, _PyLong_One)) == NULL)
Guido van Rossum805365e2007-05-07 22:24:25 +0000227 goto Fail;
228
229 Py_DECREF(tmp2);
230 Py_DECREF(diff);
231 Py_DECREF(step);
232 Py_DECREF(tmp1);
Guido van Rossum805365e2007-05-07 22:24:25 +0000233 return result;
234
235 Fail:
Serhiy Storchakacfdfbb42016-06-18 09:44:03 +0300236 Py_DECREF(step);
Guido van Rossum805365e2007-05-07 22:24:25 +0000237 Py_XDECREF(tmp2);
238 Py_XDECREF(diff);
Guido van Rossum805365e2007-05-07 22:24:25 +0000239 Py_XDECREF(tmp1);
Guido van Rossum805365e2007-05-07 22:24:25 +0000240 return NULL;
Guido van Rossum12d12c51993-10-26 17:58:25 +0000241}
242
Martin v. Löwis18e16552006-02-15 17:27:45 +0000243static Py_ssize_t
Benjamin Petersona1864f32010-11-20 23:05:39 +0000244range_length(rangeobject *r)
245{
Nick Coghlan37ee8502010-12-03 14:26:13 +0000246 return PyLong_AsSsize_t(r->length);
Guido van Rossum805365e2007-05-07 22:24:25 +0000247}
248
Guido van Rossum805365e2007-05-07 22:24:25 +0000249static PyObject *
Nick Coghlane993b102011-01-12 03:15:52 +0000250compute_item(rangeobject *r, PyObject *i)
Benjamin Petersona1864f32010-11-20 23:05:39 +0000251{
Nick Coghlane993b102011-01-12 03:15:52 +0000252 PyObject *incr, *result;
253 /* PyLong equivalent to:
254 * return r->start + (i * r->step)
255 */
256 incr = PyNumber_Multiply(i, r->step);
Guido van Rossum805365e2007-05-07 22:24:25 +0000257 if (!incr)
258 return NULL;
259 result = PyNumber_Add(r->start, incr);
260 Py_DECREF(incr);
261 return result;
Guido van Rossum7d6aa511993-12-21 22:50:31 +0000262}
263
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000264static PyObject *
Nick Coghlane993b102011-01-12 03:15:52 +0000265compute_range_item(rangeobject *r, PyObject *arg)
Benjamin Petersona1864f32010-11-20 23:05:39 +0000266{
Nick Coghlane993b102011-01-12 03:15:52 +0000267 int cmp_result;
268 PyObject *i, *result;
Tim Petersd976ab72004-08-08 06:29:10 +0000269
Nick Coghlane993b102011-01-12 03:15:52 +0000270 /* PyLong equivalent to:
271 * if (arg < 0) {
272 * i = r->length + arg
273 * } else {
274 * i = arg
275 * }
276 */
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300277 cmp_result = PyObject_RichCompareBool(arg, _PyLong_Zero, Py_LT);
Nick Coghlane993b102011-01-12 03:15:52 +0000278 if (cmp_result == -1) {
Nick Coghlan37ee8502010-12-03 14:26:13 +0000279 return NULL;
Guido van Rossum805365e2007-05-07 22:24:25 +0000280 }
Nick Coghlane993b102011-01-12 03:15:52 +0000281 if (cmp_result == 1) {
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300282 i = PyNumber_Add(r->length, arg);
283 if (!i) {
284 return NULL;
285 }
Nick Coghlane993b102011-01-12 03:15:52 +0000286 } else {
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300287 i = arg;
288 Py_INCREF(i);
Nick Coghlane993b102011-01-12 03:15:52 +0000289 }
290
291 /* PyLong equivalent to:
292 * if (i < 0 || i >= r->length) {
293 * <report index out of bounds>
294 * }
295 */
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300296 cmp_result = PyObject_RichCompareBool(i, _PyLong_Zero, Py_LT);
Nick Coghlane993b102011-01-12 03:15:52 +0000297 if (cmp_result == 0) {
298 cmp_result = PyObject_RichCompareBool(i, r->length, Py_GE);
299 }
300 if (cmp_result == -1) {
301 Py_DECREF(i);
302 return NULL;
303 }
304 if (cmp_result == 1) {
305 Py_DECREF(i);
306 PyErr_SetString(PyExc_IndexError,
307 "range object index out of range");
308 return NULL;
309 }
310
311 result = compute_item(r, i);
312 Py_DECREF(i);
313 return result;
314}
315
316static PyObject *
317range_item(rangeobject *r, Py_ssize_t i)
318{
Antoine Pitroua103b962012-05-16 14:37:54 +0200319 PyObject *res, *arg = PyLong_FromSsize_t(i);
Nick Coghlane993b102011-01-12 03:15:52 +0000320 if (!arg) {
321 return NULL;
322 }
Benjamin Peterson547d4852011-01-13 04:22:54 +0000323 res = compute_range_item(r, arg);
324 Py_DECREF(arg);
325 return res;
Nick Coghlane993b102011-01-12 03:15:52 +0000326}
327
Nick Coghlane993b102011-01-12 03:15:52 +0000328static PyObject *
329compute_slice(rangeobject *r, PyObject *_slice)
330{
331 PySliceObject *slice = (PySliceObject *) _slice;
332 rangeobject *result;
333 PyObject *start = NULL, *stop = NULL, *step = NULL;
334 PyObject *substart = NULL, *substop = NULL, *substep = NULL;
Mark Dickinsonffdb2c22012-11-17 19:18:10 +0000335 int error;
Nick Coghlane993b102011-01-12 03:15:52 +0000336
Mark Dickinsonffdb2c22012-11-17 19:18:10 +0000337 error = _PySlice_GetLongIndices(slice, r->length, &start, &stop, &step);
338 if (error == -1)
339 return NULL;
Nick Coghlane993b102011-01-12 03:15:52 +0000340
341 substep = PyNumber_Multiply(r->step, step);
342 if (substep == NULL) goto fail;
343 Py_CLEAR(step);
344
345 substart = compute_item(r, start);
346 if (substart == NULL) goto fail;
347 Py_CLEAR(start);
348
Mark Dickinsonffdb2c22012-11-17 19:18:10 +0000349 substop = compute_item(r, stop);
350 if (substop == NULL) goto fail;
Nick Coghlane993b102011-01-12 03:15:52 +0000351 Py_CLEAR(stop);
352
353 result = make_range_object(Py_TYPE(r), substart, substop, substep);
354 if (result != NULL) {
355 return (PyObject *) result;
356 }
357fail:
358 Py_XDECREF(start);
359 Py_XDECREF(stop);
360 Py_XDECREF(step);
361 Py_XDECREF(substart);
362 Py_XDECREF(substop);
363 Py_XDECREF(substep);
364 return NULL;
Alexandre Vassalotti75056072008-06-10 04:03:04 +0000365}
366
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000367/* Assumes (PyLong_CheckExact(ob) || PyBool_Check(ob)) */
368static int
Benjamin Petersona1864f32010-11-20 23:05:39 +0000369range_contains_long(rangeobject *r, PyObject *ob)
370{
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000371 int cmp1, cmp2, cmp3;
372 PyObject *tmp1 = NULL;
373 PyObject *tmp2 = NULL;
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000374 int result = -1;
375
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000376 /* Check if the value can possibly be in the range. */
377
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300378 cmp1 = PyObject_RichCompareBool(r->step, _PyLong_Zero, Py_GT);
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000379 if (cmp1 == -1)
380 goto end;
381 if (cmp1 == 1) { /* positive steps: start <= ob < stop */
382 cmp2 = PyObject_RichCompareBool(r->start, ob, Py_LE);
383 cmp3 = PyObject_RichCompareBool(ob, r->stop, Py_LT);
384 }
385 else { /* negative steps: stop < ob <= start */
386 cmp2 = PyObject_RichCompareBool(ob, r->start, Py_LE);
387 cmp3 = PyObject_RichCompareBool(r->stop, ob, Py_LT);
388 }
389
390 if (cmp2 == -1 || cmp3 == -1) /* TypeError */
391 goto end;
392 if (cmp2 == 0 || cmp3 == 0) { /* ob outside of range */
393 result = 0;
394 goto end;
395 }
396
397 /* Check that the stride does not invalidate ob's membership. */
398 tmp1 = PyNumber_Subtract(ob, r->start);
399 if (tmp1 == NULL)
400 goto end;
401 tmp2 = PyNumber_Remainder(tmp1, r->step);
402 if (tmp2 == NULL)
403 goto end;
Berker Peksaged6224e2016-09-12 07:47:04 +0300404 /* result = ((int(ob) - start) % step) == 0 */
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300405 result = PyObject_RichCompareBool(tmp2, _PyLong_Zero, Py_EQ);
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000406 end:
407 Py_XDECREF(tmp1);
408 Py_XDECREF(tmp2);
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000409 return result;
410}
411
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000412static int
Benjamin Petersona1864f32010-11-20 23:05:39 +0000413range_contains(rangeobject *r, PyObject *ob)
414{
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000415 if (PyLong_CheckExact(ob) || PyBool_Check(ob))
416 return range_contains_long(r, ob);
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000417
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000418 return (int)_PySequence_IterSearch((PyObject*)r, ob,
419 PY_ITERSEARCH_CONTAINS);
420}
421
Mark Dickinson36645682011-10-23 19:53:01 +0100422/* Compare two range objects. Return 1 for equal, 0 for not equal
423 and -1 on error. The algorithm is roughly the C equivalent of
424
425 if r0 is r1:
426 return True
427 if len(r0) != len(r1):
428 return False
429 if not len(r0):
430 return True
431 if r0.start != r1.start:
432 return False
433 if len(r0) == 1:
434 return True
435 return r0.step == r1.step
436*/
437static int
438range_equals(rangeobject *r0, rangeobject *r1)
439{
440 int cmp_result;
Mark Dickinson36645682011-10-23 19:53:01 +0100441
442 if (r0 == r1)
443 return 1;
444 cmp_result = PyObject_RichCompareBool(r0->length, r1->length, Py_EQ);
445 /* Return False or error to the caller. */
446 if (cmp_result != 1)
447 return cmp_result;
448 cmp_result = PyObject_Not(r0->length);
449 /* Return True or error to the caller. */
450 if (cmp_result != 0)
451 return cmp_result;
452 cmp_result = PyObject_RichCompareBool(r0->start, r1->start, Py_EQ);
453 /* Return False or error to the caller. */
454 if (cmp_result != 1)
455 return cmp_result;
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300456 cmp_result = PyObject_RichCompareBool(r0->length, _PyLong_One, Py_EQ);
Mark Dickinson36645682011-10-23 19:53:01 +0100457 /* Return True or error to the caller. */
458 if (cmp_result != 0)
459 return cmp_result;
460 return PyObject_RichCompareBool(r0->step, r1->step, Py_EQ);
461}
462
463static PyObject *
464range_richcompare(PyObject *self, PyObject *other, int op)
465{
466 int result;
467
468 if (!PyRange_Check(other))
469 Py_RETURN_NOTIMPLEMENTED;
470 switch (op) {
471 case Py_NE:
472 case Py_EQ:
473 result = range_equals((rangeobject*)self, (rangeobject*)other);
474 if (result == -1)
475 return NULL;
476 if (op == Py_NE)
477 result = !result;
478 if (result)
479 Py_RETURN_TRUE;
480 else
481 Py_RETURN_FALSE;
482 case Py_LE:
483 case Py_GE:
484 case Py_LT:
485 case Py_GT:
486 Py_RETURN_NOTIMPLEMENTED;
487 default:
488 PyErr_BadArgument();
489 return NULL;
490 }
491}
492
493/* Hash function for range objects. Rough C equivalent of
494
495 if not len(r):
496 return hash((len(r), None, None))
497 if len(r) == 1:
498 return hash((len(r), r.start, None))
499 return hash((len(r), r.start, r.step))
500*/
501static Py_hash_t
502range_hash(rangeobject *r)
503{
504 PyObject *t;
505 Py_hash_t result = -1;
506 int cmp_result;
507
508 t = PyTuple_New(3);
509 if (!t)
510 return -1;
511 Py_INCREF(r->length);
512 PyTuple_SET_ITEM(t, 0, r->length);
513 cmp_result = PyObject_Not(r->length);
514 if (cmp_result == -1)
515 goto end;
516 if (cmp_result == 1) {
517 Py_INCREF(Py_None);
518 Py_INCREF(Py_None);
519 PyTuple_SET_ITEM(t, 1, Py_None);
520 PyTuple_SET_ITEM(t, 2, Py_None);
521 }
522 else {
Mark Dickinson36645682011-10-23 19:53:01 +0100523 Py_INCREF(r->start);
524 PyTuple_SET_ITEM(t, 1, r->start);
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300525 cmp_result = PyObject_RichCompareBool(r->length, _PyLong_One, Py_EQ);
Mark Dickinson36645682011-10-23 19:53:01 +0100526 if (cmp_result == -1)
527 goto end;
528 if (cmp_result == 1) {
529 Py_INCREF(Py_None);
530 PyTuple_SET_ITEM(t, 2, Py_None);
531 }
532 else {
533 Py_INCREF(r->step);
534 PyTuple_SET_ITEM(t, 2, r->step);
535 }
536 }
537 result = PyObject_Hash(t);
538 end:
539 Py_DECREF(t);
540 return result;
541}
542
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000543static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +0000544range_count(rangeobject *r, PyObject *ob)
545{
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000546 if (PyLong_CheckExact(ob) || PyBool_Check(ob)) {
Georg Brandl7e5343b2010-11-20 22:40:10 +0000547 int result = range_contains_long(r, ob);
548 if (result == -1)
549 return NULL;
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300550 return PyLong_FromLong(result);
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000551 } else {
552 Py_ssize_t count;
553 count = _PySequence_IterSearch((PyObject*)r, ob, PY_ITERSEARCH_COUNT);
554 if (count == -1)
555 return NULL;
556 return PyLong_FromSsize_t(count);
557 }
558}
559
560static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +0000561range_index(rangeobject *r, PyObject *ob)
562{
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000563 int contains;
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000564
565 if (!PyLong_CheckExact(ob) && !PyBool_Check(ob)) {
566 Py_ssize_t index;
567 index = _PySequence_IterSearch((PyObject*)r, ob, PY_ITERSEARCH_INDEX);
568 if (index == -1)
569 return NULL;
570 return PyLong_FromSsize_t(index);
571 }
572
573 contains = range_contains_long(r, ob);
574 if (contains == -1)
575 return NULL;
576
Benjamin Peterson155614b2010-11-20 22:44:32 +0000577 if (contains) {
578 PyObject *idx, *tmp = PyNumber_Subtract(ob, r->start);
579 if (tmp == NULL)
580 return NULL;
581 /* idx = (ob - r.start) // r.step */
582 idx = PyNumber_FloorDivide(tmp, r->step);
583 Py_DECREF(tmp);
584 return idx;
585 }
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000586
587 /* object is not in the range */
Benjamin Peterson155614b2010-11-20 22:44:32 +0000588 PyErr_Format(PyExc_ValueError, "%R is not in range", ob);
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000589 return NULL;
590}
591
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000592static PySequenceMethods range_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000593 (lenfunc)range_length, /* sq_length */
Nick Coghlan37ee8502010-12-03 14:26:13 +0000594 0, /* sq_concat */
595 0, /* sq_repeat */
596 (ssizeargfunc)range_item, /* sq_item */
597 0, /* sq_slice */
598 0, /* sq_ass_item */
599 0, /* sq_ass_slice */
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000600 (objobjproc)range_contains, /* sq_contains */
Guido van Rossum12d12c51993-10-26 17:58:25 +0000601};
602
Nick Coghlan37ee8502010-12-03 14:26:13 +0000603static PyObject *
604range_repr(rangeobject *r)
605{
606 Py_ssize_t istep;
607
608 /* Check for special case values for printing. We don't always
Alexey Izbyshev7ecae3c2018-08-24 07:39:45 +0300609 need the step value. We don't care about overflow. */
Nick Coghlan37ee8502010-12-03 14:26:13 +0000610 istep = PyNumber_AsSsize_t(r->step, NULL);
Alexey Izbyshev7ecae3c2018-08-24 07:39:45 +0300611 if (istep == -1 && PyErr_Occurred()) {
612 assert(!PyErr_ExceptionMatches(PyExc_OverflowError));
613 return NULL;
Nick Coghlan37ee8502010-12-03 14:26:13 +0000614 }
615
616 if (istep == 1)
617 return PyUnicode_FromFormat("range(%R, %R)", r->start, r->stop);
618 else
619 return PyUnicode_FromFormat("range(%R, %R, %R)",
620 r->start, r->stop, r->step);
621}
622
623/* Pickling support */
624static PyObject *
625range_reduce(rangeobject *r, PyObject *args)
626{
627 return Py_BuildValue("(O(OOO))", Py_TYPE(r),
628 r->start, r->stop, r->step);
629}
630
631static PyObject *
632range_subscript(rangeobject* self, PyObject* item)
633{
634 if (PyIndex_Check(item)) {
Nick Coghlane993b102011-01-12 03:15:52 +0000635 PyObject *i, *result;
636 i = PyNumber_Index(item);
637 if (!i)
Nick Coghlan37ee8502010-12-03 14:26:13 +0000638 return NULL;
Nick Coghlane993b102011-01-12 03:15:52 +0000639 result = compute_range_item(self, i);
640 Py_DECREF(i);
641 return result;
Nick Coghlan37ee8502010-12-03 14:26:13 +0000642 }
643 if (PySlice_Check(item)) {
Nick Coghlane993b102011-01-12 03:15:52 +0000644 return compute_slice(self, item);
Nick Coghlan37ee8502010-12-03 14:26:13 +0000645 }
646 PyErr_Format(PyExc_TypeError,
647 "range indices must be integers or slices, not %.200s",
Victor Stinner58ac7002020-02-07 03:04:21 +0100648 Py_TYPE(item)->tp_name);
Nick Coghlan37ee8502010-12-03 14:26:13 +0000649 return NULL;
650}
651
652
653static PyMappingMethods range_as_mapping = {
654 (lenfunc)range_length, /* mp_length */
655 (binaryfunc)range_subscript, /* mp_subscript */
656 (objobjargproc)0, /* mp_ass_subscript */
657};
658
4kir4e46fb862017-03-20 09:44:46 +0300659static int
660range_bool(rangeobject* self)
661{
662 return PyObject_IsTrue(self->length);
663}
664
665static PyNumberMethods range_as_number = {
666 .nb_bool = (inquiry)range_bool,
667};
668
Jeremy Hylton938ace62002-07-17 16:30:39 +0000669static PyObject * range_iter(PyObject *seq);
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530670static PyObject * range_reverse(PyObject *seq, PyObject *Py_UNUSED(ignored));
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000671
672PyDoc_STRVAR(reverse_doc,
Ezio Melotti5792ce12013-10-06 00:36:45 +0300673"Return a reverse iterator.");
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000674
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000675PyDoc_STRVAR(count_doc,
676"rangeobject.count(value) -> integer -- return number of occurrences of value");
677
678PyDoc_STRVAR(index_doc,
Srinivas Reddy Thatiparthy (శ్రీనివాస్ రెడ్డి తాటిపర్తి)22c52632019-05-03 17:52:12 +0530679"rangeobject.index(value) -> integer -- return index of value.\n"
Ezio Melotti5792ce12013-10-06 00:36:45 +0300680"Raise ValueError if the value is not present.");
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000681
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000682static PyMethodDef range_methods[] = {
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530683 {"__reversed__", range_reverse, METH_NOARGS, reverse_doc},
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000684 {"__reduce__", (PyCFunction)range_reduce, METH_VARARGS},
685 {"count", (PyCFunction)range_count, METH_O, count_doc},
686 {"index", (PyCFunction)range_index, METH_O, index_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000687 {NULL, NULL} /* sentinel */
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000688};
Raymond Hettinger48165d42002-06-05 20:08:48 +0000689
Benjamin Peterson878ce382011-11-05 15:17:52 -0400690static PyMemberDef range_members[] = {
691 {"start", T_OBJECT_EX, offsetof(rangeobject, start), READONLY},
692 {"stop", T_OBJECT_EX, offsetof(rangeobject, stop), READONLY},
693 {"step", T_OBJECT_EX, offsetof(rangeobject, step), READONLY},
694 {0}
695};
696
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000697PyTypeObject PyRange_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000698 PyVarObject_HEAD_INIT(&PyType_Type, 0)
699 "range", /* Name of this type */
700 sizeof(rangeobject), /* Basic object size */
701 0, /* Item size for varobject */
702 (destructor)range_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200703 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000704 0, /* tp_getattr */
705 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200706 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000707 (reprfunc)range_repr, /* tp_repr */
4kir4e46fb862017-03-20 09:44:46 +0300708 &range_as_number, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000709 &range_as_sequence, /* tp_as_sequence */
Nick Coghlan37ee8502010-12-03 14:26:13 +0000710 &range_as_mapping, /* tp_as_mapping */
Mark Dickinson36645682011-10-23 19:53:01 +0100711 (hashfunc)range_hash, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000712 0, /* tp_call */
713 0, /* tp_str */
714 PyObject_GenericGetAttr, /* tp_getattro */
715 0, /* tp_setattro */
716 0, /* tp_as_buffer */
717 Py_TPFLAGS_DEFAULT, /* tp_flags */
718 range_doc, /* tp_doc */
719 0, /* tp_traverse */
720 0, /* tp_clear */
Mark Dickinson36645682011-10-23 19:53:01 +0100721 range_richcompare, /* tp_richcompare */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000722 0, /* tp_weaklistoffset */
723 range_iter, /* tp_iter */
724 0, /* tp_iternext */
725 range_methods, /* tp_methods */
Benjamin Peterson878ce382011-11-05 15:17:52 -0400726 range_members, /* tp_members */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000727 0, /* tp_getset */
728 0, /* tp_base */
729 0, /* tp_dict */
730 0, /* tp_descr_get */
731 0, /* tp_descr_set */
732 0, /* tp_dictoffset */
733 0, /* tp_init */
734 0, /* tp_alloc */
735 range_new, /* tp_new */
Petr Viktorin6e35da92020-02-18 16:13:17 +0100736 .tp_vectorcall = (vectorcallfunc)range_vectorcall
Guido van Rossum12d12c51993-10-26 17:58:25 +0000737};
Raymond Hettinger48165d42002-06-05 20:08:48 +0000738
Walter Dörwald4ad94212007-05-21 18:01:17 +0000739/*********************** range Iterator **************************/
Raymond Hettinger48165d42002-06-05 20:08:48 +0000740
Guido van Rossum805365e2007-05-07 22:24:25 +0000741/* There are 2 types of iterators, one for C longs, the other for
Serhiy Storchaka95949422013-08-27 19:40:23 +0300742 Python ints (ie, PyObjects). This should make iteration fast
Guido van Rossum805365e2007-05-07 22:24:25 +0000743 in the normal case, but possible for any numeric value.
744*/
745
Raymond Hettinger48165d42002-06-05 20:08:48 +0000746typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000747 PyObject_HEAD
748 long index;
749 long start;
750 long step;
751 long len;
Raymond Hettinger48165d42002-06-05 20:08:48 +0000752} rangeiterobject;
753
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000754static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +0000755rangeiter_next(rangeiterobject *r)
756{
Guido van Rossum805365e2007-05-07 22:24:25 +0000757 if (r->index < r->len)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000758 /* cast to unsigned to avoid possible signed overflow
Mark Dickinsonb43dbc22009-11-15 12:56:08 +0000759 in intermediate calculations. */
760 return PyLong_FromLong((long)(r->start +
761 (unsigned long)(r->index++) * r->step));
Guido van Rossum805365e2007-05-07 22:24:25 +0000762 return NULL;
Raymond Hettinger48165d42002-06-05 20:08:48 +0000763}
764
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000765static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530766rangeiter_len(rangeiterobject *r, PyObject *Py_UNUSED(ignored))
Benjamin Petersona1864f32010-11-20 23:05:39 +0000767{
Christian Heimes217cfd12007-12-02 14:31:20 +0000768 return PyLong_FromLong(r->len - r->index);
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000769}
770
Guido van Rossum805365e2007-05-07 22:24:25 +0000771PyDoc_STRVAR(length_hint_doc,
772 "Private method returning an estimate of len(list(it)).");
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000773
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000774static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530775rangeiter_reduce(rangeiterobject *r, PyObject *Py_UNUSED(ignored))
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000776{
777 PyObject *start=NULL, *stop=NULL, *step=NULL;
778 PyObject *range;
Chris Jerdonek042fa652012-10-07 14:56:27 -0700779
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000780 /* create a range object for pickling */
781 start = PyLong_FromLong(r->start);
782 if (start == NULL)
783 goto err;
784 stop = PyLong_FromLong(r->start + r->len * r->step);
785 if (stop == NULL)
786 goto err;
787 step = PyLong_FromLong(r->step);
788 if (step == NULL)
789 goto err;
790 range = (PyObject*)make_range_object(&PyRange_Type,
791 start, stop, step);
792 if (range == NULL)
793 goto err;
794 /* return the result */
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200795 return Py_BuildValue("N(N)i", _PyEval_GetBuiltinId(&PyId_iter),
796 range, r->index);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000797err:
798 Py_XDECREF(start);
799 Py_XDECREF(stop);
800 Py_XDECREF(step);
801 return NULL;
802}
803
804static PyObject *
805rangeiter_setstate(rangeiterobject *r, PyObject *state)
806{
807 long index = PyLong_AsLong(state);
808 if (index == -1 && PyErr_Occurred())
809 return NULL;
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +0000810 /* silently clip the index value */
811 if (index < 0)
812 index = 0;
813 else if (index > r->len)
814 index = r->len; /* exhausted iterator */
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000815 r->index = index;
816 Py_RETURN_NONE;
817}
818
819PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
820PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
821
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000822static PyMethodDef rangeiter_methods[] = {
Guido van Rossum805365e2007-05-07 22:24:25 +0000823 {"__length_hint__", (PyCFunction)rangeiter_len, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000824 length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000825 {"__reduce__", (PyCFunction)rangeiter_reduce, METH_NOARGS,
826 reduce_doc},
827 {"__setstate__", (PyCFunction)rangeiter_setstate, METH_O,
828 setstate_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000829 {NULL, NULL} /* sentinel */
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000830};
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000831
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000832PyTypeObject PyRangeIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000833 PyVarObject_HEAD_INIT(&PyType_Type, 0)
834 "range_iterator", /* tp_name */
835 sizeof(rangeiterobject), /* tp_basicsize */
836 0, /* tp_itemsize */
837 /* methods */
838 (destructor)PyObject_Del, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200839 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000840 0, /* tp_getattr */
841 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200842 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000843 0, /* tp_repr */
844 0, /* tp_as_number */
845 0, /* tp_as_sequence */
846 0, /* tp_as_mapping */
847 0, /* tp_hash */
848 0, /* tp_call */
849 0, /* tp_str */
850 PyObject_GenericGetAttr, /* tp_getattro */
851 0, /* tp_setattro */
852 0, /* tp_as_buffer */
853 Py_TPFLAGS_DEFAULT, /* tp_flags */
854 0, /* tp_doc */
855 0, /* tp_traverse */
856 0, /* tp_clear */
857 0, /* tp_richcompare */
858 0, /* tp_weaklistoffset */
859 PyObject_SelfIter, /* tp_iter */
860 (iternextfunc)rangeiter_next, /* tp_iternext */
861 rangeiter_methods, /* tp_methods */
862 0, /* tp_members */
Guido van Rossum805365e2007-05-07 22:24:25 +0000863};
864
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000865/* Return number of items in range (lo, hi, step). step != 0
866 * required. The result always fits in an unsigned long.
Guido van Rossum805365e2007-05-07 22:24:25 +0000867 */
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000868static unsigned long
Benjamin Petersona1864f32010-11-20 23:05:39 +0000869get_len_of_range(long lo, long hi, long step)
870{
Guido van Rossum805365e2007-05-07 22:24:25 +0000871 /* -------------------------------------------------------------
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000872 If step > 0 and lo >= hi, or step < 0 and lo <= hi, the range is empty.
873 Else for step > 0, if n values are in the range, the last one is
Guido van Rossum805365e2007-05-07 22:24:25 +0000874 lo + (n-1)*step, which must be <= hi-1. Rearranging,
875 n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives
876 the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so
877 the RHS is non-negative and so truncation is the same as the
878 floor. Letting M be the largest positive long, the worst case
879 for the RHS numerator is hi=M, lo=-M-1, and then
880 hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000881 precision to compute the RHS exactly. The analysis for step < 0
882 is similar.
Guido van Rossum805365e2007-05-07 22:24:25 +0000883 ---------------------------------------------------------------*/
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000884 assert(step != 0);
885 if (step > 0 && lo < hi)
886 return 1UL + (hi - 1UL - lo) / step;
887 else if (step < 0 && lo > hi)
888 return 1UL + (lo - 1UL - hi) / (0UL - step);
889 else
890 return 0UL;
Guido van Rossum805365e2007-05-07 22:24:25 +0000891}
892
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000893/* Initialize a rangeiter object. If the length of the rangeiter object
894 is not representable as a C long, OverflowError is raised. */
895
Guido van Rossum805365e2007-05-07 22:24:25 +0000896static PyObject *
Nick Coghlan37ee8502010-12-03 14:26:13 +0000897fast_range_iter(long start, long stop, long step)
Benjamin Petersona1864f32010-11-20 23:05:39 +0000898{
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000899 rangeiterobject *it = PyObject_New(rangeiterobject, &PyRangeIter_Type);
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000900 unsigned long ulen;
Guido van Rossum805365e2007-05-07 22:24:25 +0000901 if (it == NULL)
902 return NULL;
903 it->start = start;
904 it->step = step;
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000905 ulen = get_len_of_range(start, stop, step);
906 if (ulen > (unsigned long)LONG_MAX) {
Benjamin Peterson36fbb732009-11-16 00:34:25 +0000907 Py_DECREF(it);
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000908 PyErr_SetString(PyExc_OverflowError,
909 "range too large to represent as a range_iterator");
910 return NULL;
911 }
912 it->len = (long)ulen;
Guido van Rossum805365e2007-05-07 22:24:25 +0000913 it->index = 0;
914 return (PyObject *)it;
915}
916
Nick Coghlan37ee8502010-12-03 14:26:13 +0000917typedef struct {
918 PyObject_HEAD
919 PyObject *index;
920 PyObject *start;
921 PyObject *step;
922 PyObject *len;
923} longrangeiterobject;
924
925static PyObject *
926longrangeiter_len(longrangeiterobject *r, PyObject *no_args)
927{
928 return PyNumber_Subtract(r->len, r->index);
Guido van Rossum805365e2007-05-07 22:24:25 +0000929}
930
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000931static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530932longrangeiter_reduce(longrangeiterobject *r, PyObject *Py_UNUSED(ignored))
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000933{
934 PyObject *product, *stop=NULL;
935 PyObject *range;
936
937 /* create a range object for pickling. Must calculate the "stop" value */
938 product = PyNumber_Multiply(r->len, r->step);
939 if (product == NULL)
940 return NULL;
941 stop = PyNumber_Add(r->start, product);
942 Py_DECREF(product);
943 if (stop == NULL)
944 return NULL;
945 Py_INCREF(r->start);
946 Py_INCREF(r->step);
947 range = (PyObject*)make_range_object(&PyRange_Type,
948 r->start, stop, r->step);
949 if (range == NULL) {
950 Py_DECREF(r->start);
951 Py_DECREF(stop);
952 Py_DECREF(r->step);
953 return NULL;
954 }
955
956 /* return the result */
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200957 return Py_BuildValue("N(N)O", _PyEval_GetBuiltinId(&PyId_iter),
958 range, r->index);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000959}
960
961static PyObject *
962longrangeiter_setstate(longrangeiterobject *r, PyObject *state)
963{
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +0000964 int cmp;
Serhiy Storchaka009b8112015-03-18 21:53:15 +0200965
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +0000966 /* clip the value */
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300967 cmp = PyObject_RichCompareBool(state, _PyLong_Zero, Py_LT);
968 if (cmp < 0)
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +0000969 return NULL;
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +0000970 if (cmp > 0) {
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300971 state = _PyLong_Zero;
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +0000972 }
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300973 else {
974 cmp = PyObject_RichCompareBool(r->len, state, Py_LT);
975 if (cmp < 0)
976 return NULL;
977 if (cmp > 0)
978 state = r->len;
979 }
Serhiy Storchaka4a1e70f2015-12-27 12:36:18 +0200980 Py_INCREF(state);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300981 Py_XSETREF(r->index, state);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000982 Py_RETURN_NONE;
983}
984
Guido van Rossum805365e2007-05-07 22:24:25 +0000985static PyMethodDef longrangeiter_methods[] = {
986 {"__length_hint__", (PyCFunction)longrangeiter_len, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000987 length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000988 {"__reduce__", (PyCFunction)longrangeiter_reduce, METH_NOARGS,
989 reduce_doc},
990 {"__setstate__", (PyCFunction)longrangeiter_setstate, METH_O,
991 setstate_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000992 {NULL, NULL} /* sentinel */
Guido van Rossum805365e2007-05-07 22:24:25 +0000993};
994
995static void
Benjamin Petersona1864f32010-11-20 23:05:39 +0000996longrangeiter_dealloc(longrangeiterobject *r)
997{
Guido van Rossum805365e2007-05-07 22:24:25 +0000998 Py_XDECREF(r->index);
Guido van Rossum317e7742007-05-08 15:18:31 +0000999 Py_XDECREF(r->start);
1000 Py_XDECREF(r->step);
1001 Py_XDECREF(r->len);
Amaury Forgeot d'Arcb7f17e42007-11-15 20:52:21 +00001002 PyObject_Del(r);
Guido van Rossum805365e2007-05-07 22:24:25 +00001003}
1004
1005static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +00001006longrangeiter_next(longrangeiterobject *r)
1007{
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001008 PyObject *product, *new_index, *result;
Guido van Rossum805365e2007-05-07 22:24:25 +00001009 if (PyObject_RichCompareBool(r->index, r->len, Py_LT) != 1)
1010 return NULL;
1011
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001012 new_index = PyNumber_Add(r->index, _PyLong_One);
Benjamin Peterson36fbb732009-11-16 00:34:25 +00001013 if (!new_index)
1014 return NULL;
1015
1016 product = PyNumber_Multiply(r->index, r->step);
1017 if (!product) {
1018 Py_DECREF(new_index);
Guido van Rossum805365e2007-05-07 22:24:25 +00001019 return NULL;
1020 }
1021
1022 result = PyNumber_Add(r->start, product);
1023 Py_DECREF(product);
1024 if (result) {
Serhiy Storchaka57a01d32016-04-10 18:05:40 +03001025 Py_SETREF(r->index, new_index);
Guido van Rossum805365e2007-05-07 22:24:25 +00001026 }
Benjamin Peterson36fbb732009-11-16 00:34:25 +00001027 else {
1028 Py_DECREF(new_index);
1029 }
Guido van Rossum805365e2007-05-07 22:24:25 +00001030
1031 return result;
1032}
1033
Christian Heimesa22e8bd2007-11-29 22:35:39 +00001034PyTypeObject PyLongRangeIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001035 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1036 "longrange_iterator", /* tp_name */
1037 sizeof(longrangeiterobject), /* tp_basicsize */
1038 0, /* tp_itemsize */
1039 /* methods */
1040 (destructor)longrangeiter_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001041 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001042 0, /* tp_getattr */
1043 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001044 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001045 0, /* tp_repr */
1046 0, /* tp_as_number */
1047 0, /* tp_as_sequence */
1048 0, /* tp_as_mapping */
1049 0, /* tp_hash */
1050 0, /* tp_call */
1051 0, /* tp_str */
1052 PyObject_GenericGetAttr, /* tp_getattro */
1053 0, /* tp_setattro */
1054 0, /* tp_as_buffer */
1055 Py_TPFLAGS_DEFAULT, /* tp_flags */
1056 0, /* tp_doc */
1057 0, /* tp_traverse */
1058 0, /* tp_clear */
1059 0, /* tp_richcompare */
1060 0, /* tp_weaklistoffset */
1061 PyObject_SelfIter, /* tp_iter */
1062 (iternextfunc)longrangeiter_next, /* tp_iternext */
1063 longrangeiter_methods, /* tp_methods */
1064 0,
Raymond Hettinger48165d42002-06-05 20:08:48 +00001065};
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001066
1067static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +00001068range_iter(PyObject *seq)
1069{
Guido van Rossum805365e2007-05-07 22:24:25 +00001070 rangeobject *r = (rangeobject *)seq;
1071 longrangeiterobject *it;
Martin v. Löwis84451042007-12-20 22:57:23 +00001072 long lstart, lstop, lstep;
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001073 PyObject *int_it;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001074
Guido van Rossum805365e2007-05-07 22:24:25 +00001075 assert(PyRange_Check(seq));
Martin v. Löwis84451042007-12-20 22:57:23 +00001076
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001077 /* If all three fields and the length convert to long, use the int
1078 * version */
Martin v. Löwis84451042007-12-20 22:57:23 +00001079 lstart = PyLong_AsLong(r->start);
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001080 if (lstart == -1 && PyErr_Occurred()) {
1081 PyErr_Clear();
1082 goto long_range;
Martin v. Löwis84451042007-12-20 22:57:23 +00001083 }
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001084 lstop = PyLong_AsLong(r->stop);
1085 if (lstop == -1 && PyErr_Occurred()) {
1086 PyErr_Clear();
1087 goto long_range;
1088 }
1089 lstep = PyLong_AsLong(r->step);
1090 if (lstep == -1 && PyErr_Occurred()) {
1091 PyErr_Clear();
1092 goto long_range;
1093 }
Nick Coghlan37ee8502010-12-03 14:26:13 +00001094 int_it = fast_range_iter(lstart, lstop, lstep);
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001095 if (int_it == NULL && PyErr_ExceptionMatches(PyExc_OverflowError)) {
1096 PyErr_Clear();
1097 goto long_range;
1098 }
1099 return (PyObject *)int_it;
1100
1101 long_range:
Christian Heimesa22e8bd2007-11-29 22:35:39 +00001102 it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
Guido van Rossum805365e2007-05-07 22:24:25 +00001103 if (it == NULL)
1104 return NULL;
Guido van Rossum317e7742007-05-08 15:18:31 +00001105
Guido van Rossum805365e2007-05-07 22:24:25 +00001106 it->start = r->start;
Guido van Rossum317e7742007-05-08 15:18:31 +00001107 it->step = r->step;
Nick Coghlan37ee8502010-12-03 14:26:13 +00001108 it->len = r->length;
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001109 it->index = _PyLong_Zero;
Guido van Rossum317e7742007-05-08 15:18:31 +00001110 Py_INCREF(it->start);
1111 Py_INCREF(it->step);
Nick Coghlan37ee8502010-12-03 14:26:13 +00001112 Py_INCREF(it->len);
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001113 Py_INCREF(it->index);
Guido van Rossum805365e2007-05-07 22:24:25 +00001114 return (PyObject *)it;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001115}
1116
1117static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301118range_reverse(PyObject *seq, PyObject *Py_UNUSED(ignored))
Benjamin Petersona1864f32010-11-20 23:05:39 +00001119{
Guido van Rossum805365e2007-05-07 22:24:25 +00001120 rangeobject *range = (rangeobject*) seq;
1121 longrangeiterobject *it;
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001122 PyObject *sum, *diff, *product;
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001123 long lstart, lstop, lstep, new_start, new_stop;
1124 unsigned long ulen;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001125
Guido van Rossum805365e2007-05-07 22:24:25 +00001126 assert(PyRange_Check(seq));
Martin v. Löwis84451042007-12-20 22:57:23 +00001127
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001128 /* reversed(range(start, stop, step)) can be expressed as
1129 range(start+(n-1)*step, start-step, -step), where n is the number of
1130 integers in the range.
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001131
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001132 If each of start, stop, step, -step, start-step, and the length
1133 of the iterator is representable as a C long, use the int
1134 version. This excludes some cases where the reversed range is
1135 representable as a range_iterator, but it's good enough for
1136 common cases and it makes the checks simple. */
1137
1138 lstart = PyLong_AsLong(range->start);
1139 if (lstart == -1 && PyErr_Occurred()) {
1140 PyErr_Clear();
1141 goto long_range;
1142 }
1143 lstop = PyLong_AsLong(range->stop);
1144 if (lstop == -1 && PyErr_Occurred()) {
1145 PyErr_Clear();
1146 goto long_range;
1147 }
1148 lstep = PyLong_AsLong(range->step);
1149 if (lstep == -1 && PyErr_Occurred()) {
1150 PyErr_Clear();
1151 goto long_range;
1152 }
1153 /* check for possible overflow of -lstep */
1154 if (lstep == LONG_MIN)
1155 goto long_range;
1156
1157 /* check for overflow of lstart - lstep:
1158
1159 for lstep > 0, need only check whether lstart - lstep < LONG_MIN.
1160 for lstep < 0, need only check whether lstart - lstep > LONG_MAX
1161
1162 Rearrange these inequalities as:
1163
1164 lstart - LONG_MIN < lstep (lstep > 0)
1165 LONG_MAX - lstart < -lstep (lstep < 0)
1166
1167 and compute both sides as unsigned longs, to avoid the
1168 possibility of undefined behaviour due to signed overflow. */
1169
1170 if (lstep > 0) {
1171 if ((unsigned long)lstart - LONG_MIN < (unsigned long)lstep)
1172 goto long_range;
1173 }
1174 else {
1175 if (LONG_MAX - (unsigned long)lstart < 0UL - lstep)
1176 goto long_range;
1177 }
1178
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001179 ulen = get_len_of_range(lstart, lstop, lstep);
1180 if (ulen > (unsigned long)LONG_MAX)
1181 goto long_range;
1182
1183 new_stop = lstart - lstep;
1184 new_start = (long)(new_stop + ulen * lstep);
Nick Coghlan37ee8502010-12-03 14:26:13 +00001185 return fast_range_iter(new_start, new_stop, -lstep);
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001186
1187long_range:
Christian Heimesa22e8bd2007-11-29 22:35:39 +00001188 it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
Guido van Rossum805365e2007-05-07 22:24:25 +00001189 if (it == NULL)
1190 return NULL;
Zackery Spytzc9a61682018-10-31 03:13:16 -06001191 it->index = it->start = it->step = NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001192
Guido van Rossum805365e2007-05-07 22:24:25 +00001193 /* start + (len - 1) * step */
Nick Coghlan37ee8502010-12-03 14:26:13 +00001194 it->len = range->length;
1195 Py_INCREF(it->len);
Benjamin Peterson36fbb732009-11-16 00:34:25 +00001196
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001197 diff = PyNumber_Subtract(it->len, _PyLong_One);
Guido van Rossum805365e2007-05-07 22:24:25 +00001198 if (!diff)
1199 goto create_failure;
1200
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001201 product = PyNumber_Multiply(diff, range->step);
1202 Py_DECREF(diff);
Guido van Rossum805365e2007-05-07 22:24:25 +00001203 if (!product)
1204 goto create_failure;
1205
1206 sum = PyNumber_Add(range->start, product);
1207 Py_DECREF(product);
1208 it->start = sum;
1209 if (!it->start)
1210 goto create_failure;
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001211
Guido van Rossum805365e2007-05-07 22:24:25 +00001212 it->step = PyNumber_Negative(range->step);
Benjamin Peterson36fbb732009-11-16 00:34:25 +00001213 if (!it->step)
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001214 goto create_failure;
Guido van Rossum805365e2007-05-07 22:24:25 +00001215
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001216 it->index = _PyLong_Zero;
1217 Py_INCREF(it->index);
Guido van Rossum805365e2007-05-07 22:24:25 +00001218 return (PyObject *)it;
1219
1220create_failure:
Benjamin Peterson36fbb732009-11-16 00:34:25 +00001221 Py_DECREF(it);
Guido van Rossum805365e2007-05-07 22:24:25 +00001222 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001223}