blob: 9311f8b1f174cceee16d5391c4aafc2ada49dd2b [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"
Thomas Woutersefafcea2001-07-09 12:30:54 +00005
Guido van Rossum805365e2007-05-07 22:24:25 +00006/* Support objects whose length is > PY_SSIZE_T_MAX.
7
Serhiy Storchaka6a7b3a72016-04-17 08:32:47 +03008 This could be sped up for small PyLongs if they fit in a Py_ssize_t.
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009 This only matters on Win64. Though we could use long long which
Guido van Rossum805365e2007-05-07 22:24:25 +000010 would presumably help perf.
11*/
12
Guido van Rossum12d12c51993-10-26 17:58:25 +000013typedef struct {
Guido van Rossum805365e2007-05-07 22:24:25 +000014 PyObject_HEAD
15 PyObject *start;
16 PyObject *stop;
17 PyObject *step;
Nick Coghlan37ee8502010-12-03 14:26:13 +000018 PyObject *length;
Guido van Rossum12d12c51993-10-26 17:58:25 +000019} rangeobject;
20
Guido van Rossum805365e2007-05-07 22:24:25 +000021/* Helper function for validating step. Always returns a new reference or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000022 NULL on error.
Guido van Rossum805365e2007-05-07 22:24:25 +000023*/
24static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +000025validate_step(PyObject *step)
26{
Guido van Rossum805365e2007-05-07 22:24:25 +000027 /* No step specified, use a step of 1. */
28 if (!step)
Christian Heimes217cfd12007-12-02 14:31:20 +000029 return PyLong_FromLong(1);
Guido van Rossum805365e2007-05-07 22:24:25 +000030
31 step = PyNumber_Index(step);
Serhiy Storchaka5d062d72016-06-18 09:51:55 +030032 if (step && _PyLong_Sign(step) == 0) {
33 PyErr_SetString(PyExc_ValueError,
34 "range() arg 3 must not be zero");
35 Py_CLEAR(step);
Guido van Rossum805365e2007-05-07 22:24:25 +000036 }
37
38 return step;
Raymond Hettingerc4c453f2002-06-05 23:12:45 +000039}
40
Nick Coghlan37ee8502010-12-03 14:26:13 +000041static PyObject *
42compute_range_length(PyObject *start, PyObject *stop, PyObject *step);
43
44static rangeobject *
45make_range_object(PyTypeObject *type, PyObject *start,
46 PyObject *stop, PyObject *step)
47{
48 rangeobject *obj = NULL;
49 PyObject *length;
50 length = compute_range_length(start, stop, step);
51 if (length == NULL) {
52 return NULL;
53 }
54 obj = PyObject_New(rangeobject, type);
55 if (obj == NULL) {
56 Py_DECREF(length);
57 return NULL;
58 }
59 obj->start = start;
60 obj->stop = stop;
61 obj->step = step;
62 obj->length = length;
63 return obj;
64}
65
Guido van Rossum805365e2007-05-07 22:24:25 +000066/* XXX(nnorwitz): should we error check if the user passes any empty ranges?
67 range(-10)
68 range(0, -5)
69 range(0, 5, -1)
70*/
Raymond Hettingerc4c453f2002-06-05 23:12:45 +000071static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +000072range_new(PyTypeObject *type, PyObject *args, PyObject *kw)
73{
Nick Coghlan37ee8502010-12-03 14:26:13 +000074 rangeobject *obj;
Guido van Rossum805365e2007-05-07 22:24:25 +000075 PyObject *start = NULL, *stop = NULL, *step = NULL;
Raymond Hettingerc4c453f2002-06-05 23:12:45 +000076
Serhiy Storchaka6cca5c82017-06-08 14:41:19 +030077 if (!_PyArg_NoKeywords("range", kw))
Guido van Rossum805365e2007-05-07 22:24:25 +000078 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +000079
Pablo Galindo4b66fa62020-01-05 17:30:53 +000080 Py_ssize_t num_args = PyTuple_GET_SIZE(args);
81 switch (num_args) {
82 case 3:
83 step = PyTuple_GET_ITEM(args, 2);
84 /* fallthrough */
85 case 2:
86 start = PyTuple_GET_ITEM(args, 0);
87 start = PyNumber_Index(start);
88 if (!start) {
89 return NULL;
90 }
Tim Petersfeec4532004-08-08 07:17:39 +000091
Pablo Galindo4b66fa62020-01-05 17:30:53 +000092 stop = PyTuple_GET_ITEM(args, 1);
93 stop = PyNumber_Index(stop);
94 if (!stop) {
95 Py_DECREF(start);
96 return NULL;
97 }
98
99 step = validate_step(step);
100 if (!step) {
101 Py_DECREF(start);
102 Py_DECREF(stop);
103 return NULL;
104 }
105 break;
106 case 1:
107 stop = PyTuple_GET_ITEM(args, 0);
108 stop = PyNumber_Index(stop);
109 if (!stop) {
110 return NULL;
111 }
112 Py_INCREF(_PyLong_Zero);
113 start = _PyLong_Zero;
114 Py_INCREF(_PyLong_One);
115 step = _PyLong_One;
116 break;
117 case 0:
118 PyErr_SetString(PyExc_TypeError,
119 "range expected at least 1 argument, got 0");
Raymond Hettinger94f55832009-06-12 18:40:16 +0000120 return NULL;
Pablo Galindo4b66fa62020-01-05 17:30:53 +0000121 default:
122 PyErr_Format(PyExc_TypeError,
123 "range expected at most 3 arguments, got %zd",
124 num_args);
Raymond Hettinger94f55832009-06-12 18:40:16 +0000125 return NULL;
Guido van Rossum805365e2007-05-07 22:24:25 +0000126 }
127
Nick Coghlan37ee8502010-12-03 14:26:13 +0000128 obj = make_range_object(type, start, stop, step);
129 if (obj != NULL)
130 return (PyObject *) obj;
Guido van Rossum805365e2007-05-07 22:24:25 +0000131
Nick Coghlan37ee8502010-12-03 14:26:13 +0000132 /* Failed to create object, release attributes */
Serhiy Storchakacfdfbb42016-06-18 09:44:03 +0300133 Py_DECREF(start);
134 Py_DECREF(stop);
135 Py_DECREF(step);
Guido van Rossum805365e2007-05-07 22:24:25 +0000136 return NULL;
Raymond Hettingerc4c453f2002-06-05 23:12:45 +0000137}
138
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000139PyDoc_STRVAR(range_doc,
Chris Jerdonek83fe2e12012-10-07 14:48:36 -0700140"range(stop) -> range object\n\
141range(start, stop[, step]) -> range object\n\
Raymond Hettingerc4c453f2002-06-05 23:12:45 +0000142\n\
Benjamin Petersonac22c6b2015-04-22 09:16:07 -0400143Return an object that produces a sequence of integers from start (inclusive)\n\
144to stop (exclusive) by step. range(i, j) produces i, i+1, i+2, ..., j-1.\n\
145start defaults to 0, and stop is omitted! range(4) produces 0, 1, 2, 3.\n\
146These are exactly the valid indices for a list of 4 elements.\n\
147When step is given, it specifies the increment (or decrement).");
Raymond Hettingerc4c453f2002-06-05 23:12:45 +0000148
Guido van Rossum805365e2007-05-07 22:24:25 +0000149static void
Benjamin Petersona1864f32010-11-20 23:05:39 +0000150range_dealloc(rangeobject *r)
151{
Guido van Rossum805365e2007-05-07 22:24:25 +0000152 Py_DECREF(r->start);
153 Py_DECREF(r->stop);
154 Py_DECREF(r->step);
Nick Coghlan37ee8502010-12-03 14:26:13 +0000155 Py_DECREF(r->length);
Amaury Forgeot d'Arcb7f17e42007-11-15 20:52:21 +0000156 PyObject_Del(r);
Guido van Rossum805365e2007-05-07 22:24:25 +0000157}
158
Mark Dickinson732166d2009-06-28 22:08:40 +0000159/* Return number of items in range (lo, hi, step) as a PyLong object,
160 * when arguments are PyLong objects. Arguments MUST return 1 with
161 * PyLong_Check(). Return NULL when there is an error.
Guido van Rossum805365e2007-05-07 22:24:25 +0000162 */
163static PyObject*
Nick Coghlan37ee8502010-12-03 14:26:13 +0000164compute_range_length(PyObject *start, PyObject *stop, PyObject *step)
Benjamin Petersona1864f32010-11-20 23:05:39 +0000165{
Guido van Rossum805365e2007-05-07 22:24:25 +0000166 /* -------------------------------------------------------------
167 Algorithm is equal to that of get_len_of_range(), but it operates
Benjamin Petersona47af9c2009-06-24 21:14:38 +0000168 on PyObjects (which are assumed to be PyLong objects).
Guido van Rossum805365e2007-05-07 22:24:25 +0000169 ---------------------------------------------------------------*/
Mark Dickinson211c6252009-02-01 10:28:51 +0000170 int cmp_result;
Guido van Rossum805365e2007-05-07 22:24:25 +0000171 PyObject *lo, *hi;
Guido van Rossum805365e2007-05-07 22:24:25 +0000172 PyObject *diff = NULL;
Guido van Rossum805365e2007-05-07 22:24:25 +0000173 PyObject *tmp1 = NULL, *tmp2 = NULL, *result;
174 /* holds sub-expression evaluations */
175
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300176 cmp_result = PyObject_RichCompareBool(step, _PyLong_Zero, Py_GT);
Mark Dickinson211c6252009-02-01 10:28:51 +0000177 if (cmp_result == -1)
Guido van Rossum805365e2007-05-07 22:24:25 +0000178 return NULL;
179
Mark Dickinson211c6252009-02-01 10:28:51 +0000180 if (cmp_result == 1) {
Nick Coghlan37ee8502010-12-03 14:26:13 +0000181 lo = start;
182 hi = stop;
Guido van Rossum805365e2007-05-07 22:24:25 +0000183 Py_INCREF(step);
184 } else {
Nick Coghlan37ee8502010-12-03 14:26:13 +0000185 lo = stop;
186 hi = start;
187 step = PyNumber_Negative(step);
Guido van Rossum805365e2007-05-07 22:24:25 +0000188 if (!step)
189 return NULL;
190 }
191
192 /* if (lo >= hi), return length of 0. */
Serhiy Storchakafa494fd2015-05-30 17:45:22 +0300193 cmp_result = PyObject_RichCompareBool(lo, hi, Py_GE);
194 if (cmp_result != 0) {
Serhiy Storchakacfdfbb42016-06-18 09:44:03 +0300195 Py_DECREF(step);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +0300196 if (cmp_result < 0)
197 return NULL;
Guido van Rossum805365e2007-05-07 22:24:25 +0000198 return PyLong_FromLong(0);
199 }
200
Guido van Rossum805365e2007-05-07 22:24:25 +0000201 if ((tmp1 = PyNumber_Subtract(hi, lo)) == NULL)
202 goto Fail;
203
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300204 if ((diff = PyNumber_Subtract(tmp1, _PyLong_One)) == NULL)
Guido van Rossum805365e2007-05-07 22:24:25 +0000205 goto Fail;
206
207 if ((tmp2 = PyNumber_FloorDivide(diff, step)) == NULL)
208 goto Fail;
209
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300210 if ((result = PyNumber_Add(tmp2, _PyLong_One)) == NULL)
Guido van Rossum805365e2007-05-07 22:24:25 +0000211 goto Fail;
212
213 Py_DECREF(tmp2);
214 Py_DECREF(diff);
215 Py_DECREF(step);
216 Py_DECREF(tmp1);
Guido van Rossum805365e2007-05-07 22:24:25 +0000217 return result;
218
219 Fail:
Serhiy Storchakacfdfbb42016-06-18 09:44:03 +0300220 Py_DECREF(step);
Guido van Rossum805365e2007-05-07 22:24:25 +0000221 Py_XDECREF(tmp2);
222 Py_XDECREF(diff);
Guido van Rossum805365e2007-05-07 22:24:25 +0000223 Py_XDECREF(tmp1);
Guido van Rossum805365e2007-05-07 22:24:25 +0000224 return NULL;
Guido van Rossum12d12c51993-10-26 17:58:25 +0000225}
226
Martin v. Löwis18e16552006-02-15 17:27:45 +0000227static Py_ssize_t
Benjamin Petersona1864f32010-11-20 23:05:39 +0000228range_length(rangeobject *r)
229{
Nick Coghlan37ee8502010-12-03 14:26:13 +0000230 return PyLong_AsSsize_t(r->length);
Guido van Rossum805365e2007-05-07 22:24:25 +0000231}
232
Guido van Rossum805365e2007-05-07 22:24:25 +0000233static PyObject *
Nick Coghlane993b102011-01-12 03:15:52 +0000234compute_item(rangeobject *r, PyObject *i)
Benjamin Petersona1864f32010-11-20 23:05:39 +0000235{
Nick Coghlane993b102011-01-12 03:15:52 +0000236 PyObject *incr, *result;
237 /* PyLong equivalent to:
238 * return r->start + (i * r->step)
239 */
240 incr = PyNumber_Multiply(i, r->step);
Guido van Rossum805365e2007-05-07 22:24:25 +0000241 if (!incr)
242 return NULL;
243 result = PyNumber_Add(r->start, incr);
244 Py_DECREF(incr);
245 return result;
Guido van Rossum7d6aa511993-12-21 22:50:31 +0000246}
247
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000248static PyObject *
Nick Coghlane993b102011-01-12 03:15:52 +0000249compute_range_item(rangeobject *r, PyObject *arg)
Benjamin Petersona1864f32010-11-20 23:05:39 +0000250{
Nick Coghlane993b102011-01-12 03:15:52 +0000251 int cmp_result;
252 PyObject *i, *result;
Tim Petersd976ab72004-08-08 06:29:10 +0000253
Nick Coghlane993b102011-01-12 03:15:52 +0000254 /* PyLong equivalent to:
255 * if (arg < 0) {
256 * i = r->length + arg
257 * } else {
258 * i = arg
259 * }
260 */
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300261 cmp_result = PyObject_RichCompareBool(arg, _PyLong_Zero, Py_LT);
Nick Coghlane993b102011-01-12 03:15:52 +0000262 if (cmp_result == -1) {
Nick Coghlan37ee8502010-12-03 14:26:13 +0000263 return NULL;
Guido van Rossum805365e2007-05-07 22:24:25 +0000264 }
Nick Coghlane993b102011-01-12 03:15:52 +0000265 if (cmp_result == 1) {
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300266 i = PyNumber_Add(r->length, arg);
267 if (!i) {
268 return NULL;
269 }
Nick Coghlane993b102011-01-12 03:15:52 +0000270 } else {
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300271 i = arg;
272 Py_INCREF(i);
Nick Coghlane993b102011-01-12 03:15:52 +0000273 }
274
275 /* PyLong equivalent to:
276 * if (i < 0 || i >= r->length) {
277 * <report index out of bounds>
278 * }
279 */
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300280 cmp_result = PyObject_RichCompareBool(i, _PyLong_Zero, Py_LT);
Nick Coghlane993b102011-01-12 03:15:52 +0000281 if (cmp_result == 0) {
282 cmp_result = PyObject_RichCompareBool(i, r->length, Py_GE);
283 }
284 if (cmp_result == -1) {
285 Py_DECREF(i);
286 return NULL;
287 }
288 if (cmp_result == 1) {
289 Py_DECREF(i);
290 PyErr_SetString(PyExc_IndexError,
291 "range object index out of range");
292 return NULL;
293 }
294
295 result = compute_item(r, i);
296 Py_DECREF(i);
297 return result;
298}
299
300static PyObject *
301range_item(rangeobject *r, Py_ssize_t i)
302{
Antoine Pitroua103b962012-05-16 14:37:54 +0200303 PyObject *res, *arg = PyLong_FromSsize_t(i);
Nick Coghlane993b102011-01-12 03:15:52 +0000304 if (!arg) {
305 return NULL;
306 }
Benjamin Peterson547d4852011-01-13 04:22:54 +0000307 res = compute_range_item(r, arg);
308 Py_DECREF(arg);
309 return res;
Nick Coghlane993b102011-01-12 03:15:52 +0000310}
311
Nick Coghlane993b102011-01-12 03:15:52 +0000312static PyObject *
313compute_slice(rangeobject *r, PyObject *_slice)
314{
315 PySliceObject *slice = (PySliceObject *) _slice;
316 rangeobject *result;
317 PyObject *start = NULL, *stop = NULL, *step = NULL;
318 PyObject *substart = NULL, *substop = NULL, *substep = NULL;
Mark Dickinsonffdb2c22012-11-17 19:18:10 +0000319 int error;
Nick Coghlane993b102011-01-12 03:15:52 +0000320
Mark Dickinsonffdb2c22012-11-17 19:18:10 +0000321 error = _PySlice_GetLongIndices(slice, r->length, &start, &stop, &step);
322 if (error == -1)
323 return NULL;
Nick Coghlane993b102011-01-12 03:15:52 +0000324
325 substep = PyNumber_Multiply(r->step, step);
326 if (substep == NULL) goto fail;
327 Py_CLEAR(step);
328
329 substart = compute_item(r, start);
330 if (substart == NULL) goto fail;
331 Py_CLEAR(start);
332
Mark Dickinsonffdb2c22012-11-17 19:18:10 +0000333 substop = compute_item(r, stop);
334 if (substop == NULL) goto fail;
Nick Coghlane993b102011-01-12 03:15:52 +0000335 Py_CLEAR(stop);
336
337 result = make_range_object(Py_TYPE(r), substart, substop, substep);
338 if (result != NULL) {
339 return (PyObject *) result;
340 }
341fail:
342 Py_XDECREF(start);
343 Py_XDECREF(stop);
344 Py_XDECREF(step);
345 Py_XDECREF(substart);
346 Py_XDECREF(substop);
347 Py_XDECREF(substep);
348 return NULL;
Alexandre Vassalotti75056072008-06-10 04:03:04 +0000349}
350
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000351/* Assumes (PyLong_CheckExact(ob) || PyBool_Check(ob)) */
352static int
Benjamin Petersona1864f32010-11-20 23:05:39 +0000353range_contains_long(rangeobject *r, PyObject *ob)
354{
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000355 int cmp1, cmp2, cmp3;
356 PyObject *tmp1 = NULL;
357 PyObject *tmp2 = NULL;
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000358 int result = -1;
359
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000360 /* Check if the value can possibly be in the range. */
361
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300362 cmp1 = PyObject_RichCompareBool(r->step, _PyLong_Zero, Py_GT);
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000363 if (cmp1 == -1)
364 goto end;
365 if (cmp1 == 1) { /* positive steps: start <= ob < stop */
366 cmp2 = PyObject_RichCompareBool(r->start, ob, Py_LE);
367 cmp3 = PyObject_RichCompareBool(ob, r->stop, Py_LT);
368 }
369 else { /* negative steps: stop < ob <= start */
370 cmp2 = PyObject_RichCompareBool(ob, r->start, Py_LE);
371 cmp3 = PyObject_RichCompareBool(r->stop, ob, Py_LT);
372 }
373
374 if (cmp2 == -1 || cmp3 == -1) /* TypeError */
375 goto end;
376 if (cmp2 == 0 || cmp3 == 0) { /* ob outside of range */
377 result = 0;
378 goto end;
379 }
380
381 /* Check that the stride does not invalidate ob's membership. */
382 tmp1 = PyNumber_Subtract(ob, r->start);
383 if (tmp1 == NULL)
384 goto end;
385 tmp2 = PyNumber_Remainder(tmp1, r->step);
386 if (tmp2 == NULL)
387 goto end;
Berker Peksaged6224e2016-09-12 07:47:04 +0300388 /* result = ((int(ob) - start) % step) == 0 */
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300389 result = PyObject_RichCompareBool(tmp2, _PyLong_Zero, Py_EQ);
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000390 end:
391 Py_XDECREF(tmp1);
392 Py_XDECREF(tmp2);
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000393 return result;
394}
395
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000396static int
Benjamin Petersona1864f32010-11-20 23:05:39 +0000397range_contains(rangeobject *r, PyObject *ob)
398{
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000399 if (PyLong_CheckExact(ob) || PyBool_Check(ob))
400 return range_contains_long(r, ob);
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000401
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000402 return (int)_PySequence_IterSearch((PyObject*)r, ob,
403 PY_ITERSEARCH_CONTAINS);
404}
405
Mark Dickinson36645682011-10-23 19:53:01 +0100406/* Compare two range objects. Return 1 for equal, 0 for not equal
407 and -1 on error. The algorithm is roughly the C equivalent of
408
409 if r0 is r1:
410 return True
411 if len(r0) != len(r1):
412 return False
413 if not len(r0):
414 return True
415 if r0.start != r1.start:
416 return False
417 if len(r0) == 1:
418 return True
419 return r0.step == r1.step
420*/
421static int
422range_equals(rangeobject *r0, rangeobject *r1)
423{
424 int cmp_result;
Mark Dickinson36645682011-10-23 19:53:01 +0100425
426 if (r0 == r1)
427 return 1;
428 cmp_result = PyObject_RichCompareBool(r0->length, r1->length, Py_EQ);
429 /* Return False or error to the caller. */
430 if (cmp_result != 1)
431 return cmp_result;
432 cmp_result = PyObject_Not(r0->length);
433 /* Return True or error to the caller. */
434 if (cmp_result != 0)
435 return cmp_result;
436 cmp_result = PyObject_RichCompareBool(r0->start, r1->start, Py_EQ);
437 /* Return False or error to the caller. */
438 if (cmp_result != 1)
439 return cmp_result;
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300440 cmp_result = PyObject_RichCompareBool(r0->length, _PyLong_One, Py_EQ);
Mark Dickinson36645682011-10-23 19:53:01 +0100441 /* Return True or error to the caller. */
442 if (cmp_result != 0)
443 return cmp_result;
444 return PyObject_RichCompareBool(r0->step, r1->step, Py_EQ);
445}
446
447static PyObject *
448range_richcompare(PyObject *self, PyObject *other, int op)
449{
450 int result;
451
452 if (!PyRange_Check(other))
453 Py_RETURN_NOTIMPLEMENTED;
454 switch (op) {
455 case Py_NE:
456 case Py_EQ:
457 result = range_equals((rangeobject*)self, (rangeobject*)other);
458 if (result == -1)
459 return NULL;
460 if (op == Py_NE)
461 result = !result;
462 if (result)
463 Py_RETURN_TRUE;
464 else
465 Py_RETURN_FALSE;
466 case Py_LE:
467 case Py_GE:
468 case Py_LT:
469 case Py_GT:
470 Py_RETURN_NOTIMPLEMENTED;
471 default:
472 PyErr_BadArgument();
473 return NULL;
474 }
475}
476
477/* Hash function for range objects. Rough C equivalent of
478
479 if not len(r):
480 return hash((len(r), None, None))
481 if len(r) == 1:
482 return hash((len(r), r.start, None))
483 return hash((len(r), r.start, r.step))
484*/
485static Py_hash_t
486range_hash(rangeobject *r)
487{
488 PyObject *t;
489 Py_hash_t result = -1;
490 int cmp_result;
491
492 t = PyTuple_New(3);
493 if (!t)
494 return -1;
495 Py_INCREF(r->length);
496 PyTuple_SET_ITEM(t, 0, r->length);
497 cmp_result = PyObject_Not(r->length);
498 if (cmp_result == -1)
499 goto end;
500 if (cmp_result == 1) {
501 Py_INCREF(Py_None);
502 Py_INCREF(Py_None);
503 PyTuple_SET_ITEM(t, 1, Py_None);
504 PyTuple_SET_ITEM(t, 2, Py_None);
505 }
506 else {
Mark Dickinson36645682011-10-23 19:53:01 +0100507 Py_INCREF(r->start);
508 PyTuple_SET_ITEM(t, 1, r->start);
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300509 cmp_result = PyObject_RichCompareBool(r->length, _PyLong_One, Py_EQ);
Mark Dickinson36645682011-10-23 19:53:01 +0100510 if (cmp_result == -1)
511 goto end;
512 if (cmp_result == 1) {
513 Py_INCREF(Py_None);
514 PyTuple_SET_ITEM(t, 2, Py_None);
515 }
516 else {
517 Py_INCREF(r->step);
518 PyTuple_SET_ITEM(t, 2, r->step);
519 }
520 }
521 result = PyObject_Hash(t);
522 end:
523 Py_DECREF(t);
524 return result;
525}
526
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000527static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +0000528range_count(rangeobject *r, PyObject *ob)
529{
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000530 if (PyLong_CheckExact(ob) || PyBool_Check(ob)) {
Georg Brandl7e5343b2010-11-20 22:40:10 +0000531 int result = range_contains_long(r, ob);
532 if (result == -1)
533 return NULL;
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300534 return PyLong_FromLong(result);
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000535 } else {
536 Py_ssize_t count;
537 count = _PySequence_IterSearch((PyObject*)r, ob, PY_ITERSEARCH_COUNT);
538 if (count == -1)
539 return NULL;
540 return PyLong_FromSsize_t(count);
541 }
542}
543
544static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +0000545range_index(rangeobject *r, PyObject *ob)
546{
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000547 int contains;
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000548
549 if (!PyLong_CheckExact(ob) && !PyBool_Check(ob)) {
550 Py_ssize_t index;
551 index = _PySequence_IterSearch((PyObject*)r, ob, PY_ITERSEARCH_INDEX);
552 if (index == -1)
553 return NULL;
554 return PyLong_FromSsize_t(index);
555 }
556
557 contains = range_contains_long(r, ob);
558 if (contains == -1)
559 return NULL;
560
Benjamin Peterson155614b2010-11-20 22:44:32 +0000561 if (contains) {
562 PyObject *idx, *tmp = PyNumber_Subtract(ob, r->start);
563 if (tmp == NULL)
564 return NULL;
565 /* idx = (ob - r.start) // r.step */
566 idx = PyNumber_FloorDivide(tmp, r->step);
567 Py_DECREF(tmp);
568 return idx;
569 }
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000570
571 /* object is not in the range */
Benjamin Peterson155614b2010-11-20 22:44:32 +0000572 PyErr_Format(PyExc_ValueError, "%R is not in range", ob);
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000573 return NULL;
574}
575
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000576static PySequenceMethods range_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000577 (lenfunc)range_length, /* sq_length */
Nick Coghlan37ee8502010-12-03 14:26:13 +0000578 0, /* sq_concat */
579 0, /* sq_repeat */
580 (ssizeargfunc)range_item, /* sq_item */
581 0, /* sq_slice */
582 0, /* sq_ass_item */
583 0, /* sq_ass_slice */
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000584 (objobjproc)range_contains, /* sq_contains */
Guido van Rossum12d12c51993-10-26 17:58:25 +0000585};
586
Nick Coghlan37ee8502010-12-03 14:26:13 +0000587static PyObject *
588range_repr(rangeobject *r)
589{
590 Py_ssize_t istep;
591
592 /* Check for special case values for printing. We don't always
Alexey Izbyshev7ecae3c2018-08-24 07:39:45 +0300593 need the step value. We don't care about overflow. */
Nick Coghlan37ee8502010-12-03 14:26:13 +0000594 istep = PyNumber_AsSsize_t(r->step, NULL);
Alexey Izbyshev7ecae3c2018-08-24 07:39:45 +0300595 if (istep == -1 && PyErr_Occurred()) {
596 assert(!PyErr_ExceptionMatches(PyExc_OverflowError));
597 return NULL;
Nick Coghlan37ee8502010-12-03 14:26:13 +0000598 }
599
600 if (istep == 1)
601 return PyUnicode_FromFormat("range(%R, %R)", r->start, r->stop);
602 else
603 return PyUnicode_FromFormat("range(%R, %R, %R)",
604 r->start, r->stop, r->step);
605}
606
607/* Pickling support */
608static PyObject *
609range_reduce(rangeobject *r, PyObject *args)
610{
611 return Py_BuildValue("(O(OOO))", Py_TYPE(r),
612 r->start, r->stop, r->step);
613}
614
615static PyObject *
616range_subscript(rangeobject* self, PyObject* item)
617{
618 if (PyIndex_Check(item)) {
Nick Coghlane993b102011-01-12 03:15:52 +0000619 PyObject *i, *result;
620 i = PyNumber_Index(item);
621 if (!i)
Nick Coghlan37ee8502010-12-03 14:26:13 +0000622 return NULL;
Nick Coghlane993b102011-01-12 03:15:52 +0000623 result = compute_range_item(self, i);
624 Py_DECREF(i);
625 return result;
Nick Coghlan37ee8502010-12-03 14:26:13 +0000626 }
627 if (PySlice_Check(item)) {
Nick Coghlane993b102011-01-12 03:15:52 +0000628 return compute_slice(self, item);
Nick Coghlan37ee8502010-12-03 14:26:13 +0000629 }
630 PyErr_Format(PyExc_TypeError,
631 "range indices must be integers or slices, not %.200s",
632 item->ob_type->tp_name);
633 return NULL;
634}
635
636
637static PyMappingMethods range_as_mapping = {
638 (lenfunc)range_length, /* mp_length */
639 (binaryfunc)range_subscript, /* mp_subscript */
640 (objobjargproc)0, /* mp_ass_subscript */
641};
642
4kir4e46fb862017-03-20 09:44:46 +0300643static int
644range_bool(rangeobject* self)
645{
646 return PyObject_IsTrue(self->length);
647}
648
649static PyNumberMethods range_as_number = {
650 .nb_bool = (inquiry)range_bool,
651};
652
Jeremy Hylton938ace62002-07-17 16:30:39 +0000653static PyObject * range_iter(PyObject *seq);
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530654static PyObject * range_reverse(PyObject *seq, PyObject *Py_UNUSED(ignored));
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000655
656PyDoc_STRVAR(reverse_doc,
Ezio Melotti5792ce12013-10-06 00:36:45 +0300657"Return a reverse iterator.");
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000658
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000659PyDoc_STRVAR(count_doc,
660"rangeobject.count(value) -> integer -- return number of occurrences of value");
661
662PyDoc_STRVAR(index_doc,
Srinivas Reddy Thatiparthy (శ్రీనివాస్ రెడ్డి తాటిపర్తి)22c52632019-05-03 17:52:12 +0530663"rangeobject.index(value) -> integer -- return index of value.\n"
Ezio Melotti5792ce12013-10-06 00:36:45 +0300664"Raise ValueError if the value is not present.");
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000665
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000666static PyMethodDef range_methods[] = {
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530667 {"__reversed__", range_reverse, METH_NOARGS, reverse_doc},
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000668 {"__reduce__", (PyCFunction)range_reduce, METH_VARARGS},
669 {"count", (PyCFunction)range_count, METH_O, count_doc},
670 {"index", (PyCFunction)range_index, METH_O, index_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000671 {NULL, NULL} /* sentinel */
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000672};
Raymond Hettinger48165d42002-06-05 20:08:48 +0000673
Benjamin Peterson878ce382011-11-05 15:17:52 -0400674static PyMemberDef range_members[] = {
675 {"start", T_OBJECT_EX, offsetof(rangeobject, start), READONLY},
676 {"stop", T_OBJECT_EX, offsetof(rangeobject, stop), READONLY},
677 {"step", T_OBJECT_EX, offsetof(rangeobject, step), READONLY},
678 {0}
679};
680
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000681PyTypeObject PyRange_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000682 PyVarObject_HEAD_INIT(&PyType_Type, 0)
683 "range", /* Name of this type */
684 sizeof(rangeobject), /* Basic object size */
685 0, /* Item size for varobject */
686 (destructor)range_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200687 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000688 0, /* tp_getattr */
689 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200690 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000691 (reprfunc)range_repr, /* tp_repr */
4kir4e46fb862017-03-20 09:44:46 +0300692 &range_as_number, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000693 &range_as_sequence, /* tp_as_sequence */
Nick Coghlan37ee8502010-12-03 14:26:13 +0000694 &range_as_mapping, /* tp_as_mapping */
Mark Dickinson36645682011-10-23 19:53:01 +0100695 (hashfunc)range_hash, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000696 0, /* tp_call */
697 0, /* tp_str */
698 PyObject_GenericGetAttr, /* tp_getattro */
699 0, /* tp_setattro */
700 0, /* tp_as_buffer */
701 Py_TPFLAGS_DEFAULT, /* tp_flags */
702 range_doc, /* tp_doc */
703 0, /* tp_traverse */
704 0, /* tp_clear */
Mark Dickinson36645682011-10-23 19:53:01 +0100705 range_richcompare, /* tp_richcompare */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000706 0, /* tp_weaklistoffset */
707 range_iter, /* tp_iter */
708 0, /* tp_iternext */
709 range_methods, /* tp_methods */
Benjamin Peterson878ce382011-11-05 15:17:52 -0400710 range_members, /* tp_members */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000711 0, /* tp_getset */
712 0, /* tp_base */
713 0, /* tp_dict */
714 0, /* tp_descr_get */
715 0, /* tp_descr_set */
716 0, /* tp_dictoffset */
717 0, /* tp_init */
718 0, /* tp_alloc */
719 range_new, /* tp_new */
Guido van Rossum12d12c51993-10-26 17:58:25 +0000720};
Raymond Hettinger48165d42002-06-05 20:08:48 +0000721
Walter Dörwald4ad94212007-05-21 18:01:17 +0000722/*********************** range Iterator **************************/
Raymond Hettinger48165d42002-06-05 20:08:48 +0000723
Guido van Rossum805365e2007-05-07 22:24:25 +0000724/* There are 2 types of iterators, one for C longs, the other for
Serhiy Storchaka95949422013-08-27 19:40:23 +0300725 Python ints (ie, PyObjects). This should make iteration fast
Guido van Rossum805365e2007-05-07 22:24:25 +0000726 in the normal case, but possible for any numeric value.
727*/
728
Raymond Hettinger48165d42002-06-05 20:08:48 +0000729typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000730 PyObject_HEAD
731 long index;
732 long start;
733 long step;
734 long len;
Raymond Hettinger48165d42002-06-05 20:08:48 +0000735} rangeiterobject;
736
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000737static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +0000738rangeiter_next(rangeiterobject *r)
739{
Guido van Rossum805365e2007-05-07 22:24:25 +0000740 if (r->index < r->len)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000741 /* cast to unsigned to avoid possible signed overflow
Mark Dickinsonb43dbc22009-11-15 12:56:08 +0000742 in intermediate calculations. */
743 return PyLong_FromLong((long)(r->start +
744 (unsigned long)(r->index++) * r->step));
Guido van Rossum805365e2007-05-07 22:24:25 +0000745 return NULL;
Raymond Hettinger48165d42002-06-05 20:08:48 +0000746}
747
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000748static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530749rangeiter_len(rangeiterobject *r, PyObject *Py_UNUSED(ignored))
Benjamin Petersona1864f32010-11-20 23:05:39 +0000750{
Christian Heimes217cfd12007-12-02 14:31:20 +0000751 return PyLong_FromLong(r->len - r->index);
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000752}
753
Guido van Rossum805365e2007-05-07 22:24:25 +0000754PyDoc_STRVAR(length_hint_doc,
755 "Private method returning an estimate of len(list(it)).");
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000756
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000757static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530758rangeiter_reduce(rangeiterobject *r, PyObject *Py_UNUSED(ignored))
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000759{
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200760 _Py_IDENTIFIER(iter);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000761 PyObject *start=NULL, *stop=NULL, *step=NULL;
762 PyObject *range;
Chris Jerdonek042fa652012-10-07 14:56:27 -0700763
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000764 /* create a range object for pickling */
765 start = PyLong_FromLong(r->start);
766 if (start == NULL)
767 goto err;
768 stop = PyLong_FromLong(r->start + r->len * r->step);
769 if (stop == NULL)
770 goto err;
771 step = PyLong_FromLong(r->step);
772 if (step == NULL)
773 goto err;
774 range = (PyObject*)make_range_object(&PyRange_Type,
775 start, stop, step);
776 if (range == NULL)
777 goto err;
778 /* return the result */
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200779 return Py_BuildValue("N(N)i", _PyEval_GetBuiltinId(&PyId_iter),
780 range, r->index);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000781err:
782 Py_XDECREF(start);
783 Py_XDECREF(stop);
784 Py_XDECREF(step);
785 return NULL;
786}
787
788static PyObject *
789rangeiter_setstate(rangeiterobject *r, PyObject *state)
790{
791 long index = PyLong_AsLong(state);
792 if (index == -1 && PyErr_Occurred())
793 return NULL;
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +0000794 /* silently clip the index value */
795 if (index < 0)
796 index = 0;
797 else if (index > r->len)
798 index = r->len; /* exhausted iterator */
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000799 r->index = index;
800 Py_RETURN_NONE;
801}
802
803PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
804PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
805
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000806static PyMethodDef rangeiter_methods[] = {
Guido van Rossum805365e2007-05-07 22:24:25 +0000807 {"__length_hint__", (PyCFunction)rangeiter_len, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000808 length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000809 {"__reduce__", (PyCFunction)rangeiter_reduce, METH_NOARGS,
810 reduce_doc},
811 {"__setstate__", (PyCFunction)rangeiter_setstate, METH_O,
812 setstate_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000813 {NULL, NULL} /* sentinel */
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000814};
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000815
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000816PyTypeObject PyRangeIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000817 PyVarObject_HEAD_INIT(&PyType_Type, 0)
818 "range_iterator", /* tp_name */
819 sizeof(rangeiterobject), /* tp_basicsize */
820 0, /* tp_itemsize */
821 /* methods */
822 (destructor)PyObject_Del, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200823 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000824 0, /* tp_getattr */
825 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200826 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000827 0, /* tp_repr */
828 0, /* tp_as_number */
829 0, /* tp_as_sequence */
830 0, /* tp_as_mapping */
831 0, /* tp_hash */
832 0, /* tp_call */
833 0, /* tp_str */
834 PyObject_GenericGetAttr, /* tp_getattro */
835 0, /* tp_setattro */
836 0, /* tp_as_buffer */
837 Py_TPFLAGS_DEFAULT, /* tp_flags */
838 0, /* tp_doc */
839 0, /* tp_traverse */
840 0, /* tp_clear */
841 0, /* tp_richcompare */
842 0, /* tp_weaklistoffset */
843 PyObject_SelfIter, /* tp_iter */
844 (iternextfunc)rangeiter_next, /* tp_iternext */
845 rangeiter_methods, /* tp_methods */
846 0, /* tp_members */
Guido van Rossum805365e2007-05-07 22:24:25 +0000847};
848
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000849/* Return number of items in range (lo, hi, step). step != 0
850 * required. The result always fits in an unsigned long.
Guido van Rossum805365e2007-05-07 22:24:25 +0000851 */
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000852static unsigned long
Benjamin Petersona1864f32010-11-20 23:05:39 +0000853get_len_of_range(long lo, long hi, long step)
854{
Guido van Rossum805365e2007-05-07 22:24:25 +0000855 /* -------------------------------------------------------------
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000856 If step > 0 and lo >= hi, or step < 0 and lo <= hi, the range is empty.
857 Else for step > 0, if n values are in the range, the last one is
Guido van Rossum805365e2007-05-07 22:24:25 +0000858 lo + (n-1)*step, which must be <= hi-1. Rearranging,
859 n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives
860 the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so
861 the RHS is non-negative and so truncation is the same as the
862 floor. Letting M be the largest positive long, the worst case
863 for the RHS numerator is hi=M, lo=-M-1, and then
864 hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000865 precision to compute the RHS exactly. The analysis for step < 0
866 is similar.
Guido van Rossum805365e2007-05-07 22:24:25 +0000867 ---------------------------------------------------------------*/
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000868 assert(step != 0);
869 if (step > 0 && lo < hi)
870 return 1UL + (hi - 1UL - lo) / step;
871 else if (step < 0 && lo > hi)
872 return 1UL + (lo - 1UL - hi) / (0UL - step);
873 else
874 return 0UL;
Guido van Rossum805365e2007-05-07 22:24:25 +0000875}
876
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000877/* Initialize a rangeiter object. If the length of the rangeiter object
878 is not representable as a C long, OverflowError is raised. */
879
Guido van Rossum805365e2007-05-07 22:24:25 +0000880static PyObject *
Nick Coghlan37ee8502010-12-03 14:26:13 +0000881fast_range_iter(long start, long stop, long step)
Benjamin Petersona1864f32010-11-20 23:05:39 +0000882{
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000883 rangeiterobject *it = PyObject_New(rangeiterobject, &PyRangeIter_Type);
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000884 unsigned long ulen;
Guido van Rossum805365e2007-05-07 22:24:25 +0000885 if (it == NULL)
886 return NULL;
887 it->start = start;
888 it->step = step;
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000889 ulen = get_len_of_range(start, stop, step);
890 if (ulen > (unsigned long)LONG_MAX) {
Benjamin Peterson36fbb732009-11-16 00:34:25 +0000891 Py_DECREF(it);
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000892 PyErr_SetString(PyExc_OverflowError,
893 "range too large to represent as a range_iterator");
894 return NULL;
895 }
896 it->len = (long)ulen;
Guido van Rossum805365e2007-05-07 22:24:25 +0000897 it->index = 0;
898 return (PyObject *)it;
899}
900
Nick Coghlan37ee8502010-12-03 14:26:13 +0000901typedef struct {
902 PyObject_HEAD
903 PyObject *index;
904 PyObject *start;
905 PyObject *step;
906 PyObject *len;
907} longrangeiterobject;
908
909static PyObject *
910longrangeiter_len(longrangeiterobject *r, PyObject *no_args)
911{
912 return PyNumber_Subtract(r->len, r->index);
Guido van Rossum805365e2007-05-07 22:24:25 +0000913}
914
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000915static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530916longrangeiter_reduce(longrangeiterobject *r, PyObject *Py_UNUSED(ignored))
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000917{
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200918 _Py_IDENTIFIER(iter);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000919 PyObject *product, *stop=NULL;
920 PyObject *range;
921
922 /* create a range object for pickling. Must calculate the "stop" value */
923 product = PyNumber_Multiply(r->len, r->step);
924 if (product == NULL)
925 return NULL;
926 stop = PyNumber_Add(r->start, product);
927 Py_DECREF(product);
928 if (stop == NULL)
929 return NULL;
930 Py_INCREF(r->start);
931 Py_INCREF(r->step);
932 range = (PyObject*)make_range_object(&PyRange_Type,
933 r->start, stop, r->step);
934 if (range == NULL) {
935 Py_DECREF(r->start);
936 Py_DECREF(stop);
937 Py_DECREF(r->step);
938 return NULL;
939 }
940
941 /* return the result */
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200942 return Py_BuildValue("N(N)O", _PyEval_GetBuiltinId(&PyId_iter),
943 range, r->index);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000944}
945
946static PyObject *
947longrangeiter_setstate(longrangeiterobject *r, PyObject *state)
948{
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +0000949 int cmp;
Serhiy Storchaka009b8112015-03-18 21:53:15 +0200950
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +0000951 /* clip the value */
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300952 cmp = PyObject_RichCompareBool(state, _PyLong_Zero, Py_LT);
953 if (cmp < 0)
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +0000954 return NULL;
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +0000955 if (cmp > 0) {
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300956 state = _PyLong_Zero;
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +0000957 }
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300958 else {
959 cmp = PyObject_RichCompareBool(r->len, state, Py_LT);
960 if (cmp < 0)
961 return NULL;
962 if (cmp > 0)
963 state = r->len;
964 }
Serhiy Storchaka4a1e70f2015-12-27 12:36:18 +0200965 Py_INCREF(state);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300966 Py_XSETREF(r->index, state);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000967 Py_RETURN_NONE;
968}
969
Guido van Rossum805365e2007-05-07 22:24:25 +0000970static PyMethodDef longrangeiter_methods[] = {
971 {"__length_hint__", (PyCFunction)longrangeiter_len, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000972 length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000973 {"__reduce__", (PyCFunction)longrangeiter_reduce, METH_NOARGS,
974 reduce_doc},
975 {"__setstate__", (PyCFunction)longrangeiter_setstate, METH_O,
976 setstate_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000977 {NULL, NULL} /* sentinel */
Guido van Rossum805365e2007-05-07 22:24:25 +0000978};
979
980static void
Benjamin Petersona1864f32010-11-20 23:05:39 +0000981longrangeiter_dealloc(longrangeiterobject *r)
982{
Guido van Rossum805365e2007-05-07 22:24:25 +0000983 Py_XDECREF(r->index);
Guido van Rossum317e7742007-05-08 15:18:31 +0000984 Py_XDECREF(r->start);
985 Py_XDECREF(r->step);
986 Py_XDECREF(r->len);
Amaury Forgeot d'Arcb7f17e42007-11-15 20:52:21 +0000987 PyObject_Del(r);
Guido van Rossum805365e2007-05-07 22:24:25 +0000988}
989
990static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +0000991longrangeiter_next(longrangeiterobject *r)
992{
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300993 PyObject *product, *new_index, *result;
Guido van Rossum805365e2007-05-07 22:24:25 +0000994 if (PyObject_RichCompareBool(r->index, r->len, Py_LT) != 1)
995 return NULL;
996
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300997 new_index = PyNumber_Add(r->index, _PyLong_One);
Benjamin Peterson36fbb732009-11-16 00:34:25 +0000998 if (!new_index)
999 return NULL;
1000
1001 product = PyNumber_Multiply(r->index, r->step);
1002 if (!product) {
1003 Py_DECREF(new_index);
Guido van Rossum805365e2007-05-07 22:24:25 +00001004 return NULL;
1005 }
1006
1007 result = PyNumber_Add(r->start, product);
1008 Py_DECREF(product);
1009 if (result) {
Serhiy Storchaka57a01d32016-04-10 18:05:40 +03001010 Py_SETREF(r->index, new_index);
Guido van Rossum805365e2007-05-07 22:24:25 +00001011 }
Benjamin Peterson36fbb732009-11-16 00:34:25 +00001012 else {
1013 Py_DECREF(new_index);
1014 }
Guido van Rossum805365e2007-05-07 22:24:25 +00001015
1016 return result;
1017}
1018
Christian Heimesa22e8bd2007-11-29 22:35:39 +00001019PyTypeObject PyLongRangeIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001020 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1021 "longrange_iterator", /* tp_name */
1022 sizeof(longrangeiterobject), /* tp_basicsize */
1023 0, /* tp_itemsize */
1024 /* methods */
1025 (destructor)longrangeiter_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001026 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001027 0, /* tp_getattr */
1028 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001029 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001030 0, /* tp_repr */
1031 0, /* tp_as_number */
1032 0, /* tp_as_sequence */
1033 0, /* tp_as_mapping */
1034 0, /* tp_hash */
1035 0, /* tp_call */
1036 0, /* tp_str */
1037 PyObject_GenericGetAttr, /* tp_getattro */
1038 0, /* tp_setattro */
1039 0, /* tp_as_buffer */
1040 Py_TPFLAGS_DEFAULT, /* tp_flags */
1041 0, /* tp_doc */
1042 0, /* tp_traverse */
1043 0, /* tp_clear */
1044 0, /* tp_richcompare */
1045 0, /* tp_weaklistoffset */
1046 PyObject_SelfIter, /* tp_iter */
1047 (iternextfunc)longrangeiter_next, /* tp_iternext */
1048 longrangeiter_methods, /* tp_methods */
1049 0,
Raymond Hettinger48165d42002-06-05 20:08:48 +00001050};
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001051
1052static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +00001053range_iter(PyObject *seq)
1054{
Guido van Rossum805365e2007-05-07 22:24:25 +00001055 rangeobject *r = (rangeobject *)seq;
1056 longrangeiterobject *it;
Martin v. Löwis84451042007-12-20 22:57:23 +00001057 long lstart, lstop, lstep;
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001058 PyObject *int_it;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001059
Guido van Rossum805365e2007-05-07 22:24:25 +00001060 assert(PyRange_Check(seq));
Martin v. Löwis84451042007-12-20 22:57:23 +00001061
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001062 /* If all three fields and the length convert to long, use the int
1063 * version */
Martin v. Löwis84451042007-12-20 22:57:23 +00001064 lstart = PyLong_AsLong(r->start);
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001065 if (lstart == -1 && PyErr_Occurred()) {
1066 PyErr_Clear();
1067 goto long_range;
Martin v. Löwis84451042007-12-20 22:57:23 +00001068 }
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001069 lstop = PyLong_AsLong(r->stop);
1070 if (lstop == -1 && PyErr_Occurred()) {
1071 PyErr_Clear();
1072 goto long_range;
1073 }
1074 lstep = PyLong_AsLong(r->step);
1075 if (lstep == -1 && PyErr_Occurred()) {
1076 PyErr_Clear();
1077 goto long_range;
1078 }
Nick Coghlan37ee8502010-12-03 14:26:13 +00001079 int_it = fast_range_iter(lstart, lstop, lstep);
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001080 if (int_it == NULL && PyErr_ExceptionMatches(PyExc_OverflowError)) {
1081 PyErr_Clear();
1082 goto long_range;
1083 }
1084 return (PyObject *)int_it;
1085
1086 long_range:
Christian Heimesa22e8bd2007-11-29 22:35:39 +00001087 it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
Guido van Rossum805365e2007-05-07 22:24:25 +00001088 if (it == NULL)
1089 return NULL;
Guido van Rossum317e7742007-05-08 15:18:31 +00001090
Guido van Rossum805365e2007-05-07 22:24:25 +00001091 it->start = r->start;
Guido van Rossum317e7742007-05-08 15:18:31 +00001092 it->step = r->step;
Nick Coghlan37ee8502010-12-03 14:26:13 +00001093 it->len = r->length;
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001094 it->index = _PyLong_Zero;
Guido van Rossum317e7742007-05-08 15:18:31 +00001095 Py_INCREF(it->start);
1096 Py_INCREF(it->step);
Nick Coghlan37ee8502010-12-03 14:26:13 +00001097 Py_INCREF(it->len);
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001098 Py_INCREF(it->index);
Guido van Rossum805365e2007-05-07 22:24:25 +00001099 return (PyObject *)it;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001100}
1101
1102static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301103range_reverse(PyObject *seq, PyObject *Py_UNUSED(ignored))
Benjamin Petersona1864f32010-11-20 23:05:39 +00001104{
Guido van Rossum805365e2007-05-07 22:24:25 +00001105 rangeobject *range = (rangeobject*) seq;
1106 longrangeiterobject *it;
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001107 PyObject *sum, *diff, *product;
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001108 long lstart, lstop, lstep, new_start, new_stop;
1109 unsigned long ulen;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001110
Guido van Rossum805365e2007-05-07 22:24:25 +00001111 assert(PyRange_Check(seq));
Martin v. Löwis84451042007-12-20 22:57:23 +00001112
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001113 /* reversed(range(start, stop, step)) can be expressed as
1114 range(start+(n-1)*step, start-step, -step), where n is the number of
1115 integers in the range.
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001116
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001117 If each of start, stop, step, -step, start-step, and the length
1118 of the iterator is representable as a C long, use the int
1119 version. This excludes some cases where the reversed range is
1120 representable as a range_iterator, but it's good enough for
1121 common cases and it makes the checks simple. */
1122
1123 lstart = PyLong_AsLong(range->start);
1124 if (lstart == -1 && PyErr_Occurred()) {
1125 PyErr_Clear();
1126 goto long_range;
1127 }
1128 lstop = PyLong_AsLong(range->stop);
1129 if (lstop == -1 && PyErr_Occurred()) {
1130 PyErr_Clear();
1131 goto long_range;
1132 }
1133 lstep = PyLong_AsLong(range->step);
1134 if (lstep == -1 && PyErr_Occurred()) {
1135 PyErr_Clear();
1136 goto long_range;
1137 }
1138 /* check for possible overflow of -lstep */
1139 if (lstep == LONG_MIN)
1140 goto long_range;
1141
1142 /* check for overflow of lstart - lstep:
1143
1144 for lstep > 0, need only check whether lstart - lstep < LONG_MIN.
1145 for lstep < 0, need only check whether lstart - lstep > LONG_MAX
1146
1147 Rearrange these inequalities as:
1148
1149 lstart - LONG_MIN < lstep (lstep > 0)
1150 LONG_MAX - lstart < -lstep (lstep < 0)
1151
1152 and compute both sides as unsigned longs, to avoid the
1153 possibility of undefined behaviour due to signed overflow. */
1154
1155 if (lstep > 0) {
1156 if ((unsigned long)lstart - LONG_MIN < (unsigned long)lstep)
1157 goto long_range;
1158 }
1159 else {
1160 if (LONG_MAX - (unsigned long)lstart < 0UL - lstep)
1161 goto long_range;
1162 }
1163
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001164 ulen = get_len_of_range(lstart, lstop, lstep);
1165 if (ulen > (unsigned long)LONG_MAX)
1166 goto long_range;
1167
1168 new_stop = lstart - lstep;
1169 new_start = (long)(new_stop + ulen * lstep);
Nick Coghlan37ee8502010-12-03 14:26:13 +00001170 return fast_range_iter(new_start, new_stop, -lstep);
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001171
1172long_range:
Christian Heimesa22e8bd2007-11-29 22:35:39 +00001173 it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
Guido van Rossum805365e2007-05-07 22:24:25 +00001174 if (it == NULL)
1175 return NULL;
Zackery Spytzc9a61682018-10-31 03:13:16 -06001176 it->index = it->start = it->step = NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001177
Guido van Rossum805365e2007-05-07 22:24:25 +00001178 /* start + (len - 1) * step */
Nick Coghlan37ee8502010-12-03 14:26:13 +00001179 it->len = range->length;
1180 Py_INCREF(it->len);
Benjamin Peterson36fbb732009-11-16 00:34:25 +00001181
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001182 diff = PyNumber_Subtract(it->len, _PyLong_One);
Guido van Rossum805365e2007-05-07 22:24:25 +00001183 if (!diff)
1184 goto create_failure;
1185
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001186 product = PyNumber_Multiply(diff, range->step);
1187 Py_DECREF(diff);
Guido van Rossum805365e2007-05-07 22:24:25 +00001188 if (!product)
1189 goto create_failure;
1190
1191 sum = PyNumber_Add(range->start, product);
1192 Py_DECREF(product);
1193 it->start = sum;
1194 if (!it->start)
1195 goto create_failure;
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001196
Guido van Rossum805365e2007-05-07 22:24:25 +00001197 it->step = PyNumber_Negative(range->step);
Benjamin Peterson36fbb732009-11-16 00:34:25 +00001198 if (!it->step)
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001199 goto create_failure;
Guido van Rossum805365e2007-05-07 22:24:25 +00001200
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001201 it->index = _PyLong_Zero;
1202 Py_INCREF(it->index);
Guido van Rossum805365e2007-05-07 22:24:25 +00001203 return (PyObject *)it;
1204
1205create_failure:
Benjamin Peterson36fbb732009-11-16 00:34:25 +00001206 Py_DECREF(it);
Guido van Rossum805365e2007-05-07 22:24:25 +00001207 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001208}