blob: 239ace6f4235ede252a51664f2d2eb89197ba3ad [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
Guido van Rossum805365e2007-05-07 22:24:25 +000080 if (PyTuple_Size(args) <= 1) {
81 if (!PyArg_UnpackTuple(args, "range", 1, 1, &stop))
Raymond Hettinger94f55832009-06-12 18:40:16 +000082 return NULL;
Guido van Rossum805365e2007-05-07 22:24:25 +000083 stop = PyNumber_Index(stop);
84 if (!stop)
Raymond Hettinger94f55832009-06-12 18:40:16 +000085 return NULL;
Serhiy Storchakaba85d692017-03-30 09:09:41 +030086 Py_INCREF(_PyLong_Zero);
87 start = _PyLong_Zero;
88 Py_INCREF(_PyLong_One);
89 step = _PyLong_One;
Guido van Rossum805365e2007-05-07 22:24:25 +000090 }
91 else {
92 if (!PyArg_UnpackTuple(args, "range", 2, 3,
93 &start, &stop, &step))
Raymond Hettinger94f55832009-06-12 18:40:16 +000094 return NULL;
Tim Petersfeec4532004-08-08 07:17:39 +000095
Guido van Rossum805365e2007-05-07 22:24:25 +000096 /* Convert borrowed refs to owned refs */
97 start = PyNumber_Index(start);
Raymond Hettinger94f55832009-06-12 18:40:16 +000098 if (!start)
99 return NULL;
Guido van Rossum805365e2007-05-07 22:24:25 +0000100 stop = PyNumber_Index(stop);
Raymond Hettinger94f55832009-06-12 18:40:16 +0000101 if (!stop) {
102 Py_DECREF(start);
103 return NULL;
104 }
105 step = validate_step(step); /* Caution, this can clear exceptions */
106 if (!step) {
107 Py_DECREF(start);
108 Py_DECREF(stop);
109 return NULL;
110 }
Guido van Rossum805365e2007-05-07 22:24:25 +0000111 }
112
Nick Coghlan37ee8502010-12-03 14:26:13 +0000113 obj = make_range_object(type, start, stop, step);
114 if (obj != NULL)
115 return (PyObject *) obj;
Guido van Rossum805365e2007-05-07 22:24:25 +0000116
Nick Coghlan37ee8502010-12-03 14:26:13 +0000117 /* Failed to create object, release attributes */
Serhiy Storchakacfdfbb42016-06-18 09:44:03 +0300118 Py_DECREF(start);
119 Py_DECREF(stop);
120 Py_DECREF(step);
Guido van Rossum805365e2007-05-07 22:24:25 +0000121 return NULL;
Raymond Hettingerc4c453f2002-06-05 23:12:45 +0000122}
123
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000124PyDoc_STRVAR(range_doc,
Chris Jerdonek83fe2e12012-10-07 14:48:36 -0700125"range(stop) -> range object\n\
126range(start, stop[, step]) -> range object\n\
Raymond Hettingerc4c453f2002-06-05 23:12:45 +0000127\n\
Benjamin Petersonac22c6b2015-04-22 09:16:07 -0400128Return an object that produces a sequence of integers from start (inclusive)\n\
129to stop (exclusive) by step. range(i, j) produces i, i+1, i+2, ..., j-1.\n\
130start defaults to 0, and stop is omitted! range(4) produces 0, 1, 2, 3.\n\
131These are exactly the valid indices for a list of 4 elements.\n\
132When step is given, it specifies the increment (or decrement).");
Raymond Hettingerc4c453f2002-06-05 23:12:45 +0000133
Guido van Rossum805365e2007-05-07 22:24:25 +0000134static void
Benjamin Petersona1864f32010-11-20 23:05:39 +0000135range_dealloc(rangeobject *r)
136{
Guido van Rossum805365e2007-05-07 22:24:25 +0000137 Py_DECREF(r->start);
138 Py_DECREF(r->stop);
139 Py_DECREF(r->step);
Nick Coghlan37ee8502010-12-03 14:26:13 +0000140 Py_DECREF(r->length);
Amaury Forgeot d'Arcb7f17e42007-11-15 20:52:21 +0000141 PyObject_Del(r);
Guido van Rossum805365e2007-05-07 22:24:25 +0000142}
143
Mark Dickinson732166d2009-06-28 22:08:40 +0000144/* Return number of items in range (lo, hi, step) as a PyLong object,
145 * when arguments are PyLong objects. Arguments MUST return 1 with
146 * PyLong_Check(). Return NULL when there is an error.
Guido van Rossum805365e2007-05-07 22:24:25 +0000147 */
148static PyObject*
Nick Coghlan37ee8502010-12-03 14:26:13 +0000149compute_range_length(PyObject *start, PyObject *stop, PyObject *step)
Benjamin Petersona1864f32010-11-20 23:05:39 +0000150{
Guido van Rossum805365e2007-05-07 22:24:25 +0000151 /* -------------------------------------------------------------
152 Algorithm is equal to that of get_len_of_range(), but it operates
Benjamin Petersona47af9c2009-06-24 21:14:38 +0000153 on PyObjects (which are assumed to be PyLong objects).
Guido van Rossum805365e2007-05-07 22:24:25 +0000154 ---------------------------------------------------------------*/
Mark Dickinson211c6252009-02-01 10:28:51 +0000155 int cmp_result;
Guido van Rossum805365e2007-05-07 22:24:25 +0000156 PyObject *lo, *hi;
Guido van Rossum805365e2007-05-07 22:24:25 +0000157 PyObject *diff = NULL;
Guido van Rossum805365e2007-05-07 22:24:25 +0000158 PyObject *tmp1 = NULL, *tmp2 = NULL, *result;
159 /* holds sub-expression evaluations */
160
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300161 cmp_result = PyObject_RichCompareBool(step, _PyLong_Zero, Py_GT);
Mark Dickinson211c6252009-02-01 10:28:51 +0000162 if (cmp_result == -1)
Guido van Rossum805365e2007-05-07 22:24:25 +0000163 return NULL;
164
Mark Dickinson211c6252009-02-01 10:28:51 +0000165 if (cmp_result == 1) {
Nick Coghlan37ee8502010-12-03 14:26:13 +0000166 lo = start;
167 hi = stop;
Guido van Rossum805365e2007-05-07 22:24:25 +0000168 Py_INCREF(step);
169 } else {
Nick Coghlan37ee8502010-12-03 14:26:13 +0000170 lo = stop;
171 hi = start;
172 step = PyNumber_Negative(step);
Guido van Rossum805365e2007-05-07 22:24:25 +0000173 if (!step)
174 return NULL;
175 }
176
177 /* if (lo >= hi), return length of 0. */
Serhiy Storchakafa494fd2015-05-30 17:45:22 +0300178 cmp_result = PyObject_RichCompareBool(lo, hi, Py_GE);
179 if (cmp_result != 0) {
Serhiy Storchakacfdfbb42016-06-18 09:44:03 +0300180 Py_DECREF(step);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +0300181 if (cmp_result < 0)
182 return NULL;
Guido van Rossum805365e2007-05-07 22:24:25 +0000183 return PyLong_FromLong(0);
184 }
185
Guido van Rossum805365e2007-05-07 22:24:25 +0000186 if ((tmp1 = PyNumber_Subtract(hi, lo)) == NULL)
187 goto Fail;
188
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300189 if ((diff = PyNumber_Subtract(tmp1, _PyLong_One)) == NULL)
Guido van Rossum805365e2007-05-07 22:24:25 +0000190 goto Fail;
191
192 if ((tmp2 = PyNumber_FloorDivide(diff, step)) == NULL)
193 goto Fail;
194
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300195 if ((result = PyNumber_Add(tmp2, _PyLong_One)) == NULL)
Guido van Rossum805365e2007-05-07 22:24:25 +0000196 goto Fail;
197
198 Py_DECREF(tmp2);
199 Py_DECREF(diff);
200 Py_DECREF(step);
201 Py_DECREF(tmp1);
Guido van Rossum805365e2007-05-07 22:24:25 +0000202 return result;
203
204 Fail:
Serhiy Storchakacfdfbb42016-06-18 09:44:03 +0300205 Py_DECREF(step);
Guido van Rossum805365e2007-05-07 22:24:25 +0000206 Py_XDECREF(tmp2);
207 Py_XDECREF(diff);
Guido van Rossum805365e2007-05-07 22:24:25 +0000208 Py_XDECREF(tmp1);
Guido van Rossum805365e2007-05-07 22:24:25 +0000209 return NULL;
Guido van Rossum12d12c51993-10-26 17:58:25 +0000210}
211
Martin v. Löwis18e16552006-02-15 17:27:45 +0000212static Py_ssize_t
Benjamin Petersona1864f32010-11-20 23:05:39 +0000213range_length(rangeobject *r)
214{
Nick Coghlan37ee8502010-12-03 14:26:13 +0000215 return PyLong_AsSsize_t(r->length);
Guido van Rossum805365e2007-05-07 22:24:25 +0000216}
217
Guido van Rossum805365e2007-05-07 22:24:25 +0000218static PyObject *
Nick Coghlane993b102011-01-12 03:15:52 +0000219compute_item(rangeobject *r, PyObject *i)
Benjamin Petersona1864f32010-11-20 23:05:39 +0000220{
Nick Coghlane993b102011-01-12 03:15:52 +0000221 PyObject *incr, *result;
222 /* PyLong equivalent to:
223 * return r->start + (i * r->step)
224 */
225 incr = PyNumber_Multiply(i, r->step);
Guido van Rossum805365e2007-05-07 22:24:25 +0000226 if (!incr)
227 return NULL;
228 result = PyNumber_Add(r->start, incr);
229 Py_DECREF(incr);
230 return result;
Guido van Rossum7d6aa511993-12-21 22:50:31 +0000231}
232
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000233static PyObject *
Nick Coghlane993b102011-01-12 03:15:52 +0000234compute_range_item(rangeobject *r, PyObject *arg)
Benjamin Petersona1864f32010-11-20 23:05:39 +0000235{
Nick Coghlane993b102011-01-12 03:15:52 +0000236 int cmp_result;
237 PyObject *i, *result;
Tim Petersd976ab72004-08-08 06:29:10 +0000238
Nick Coghlane993b102011-01-12 03:15:52 +0000239 /* PyLong equivalent to:
240 * if (arg < 0) {
241 * i = r->length + arg
242 * } else {
243 * i = arg
244 * }
245 */
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300246 cmp_result = PyObject_RichCompareBool(arg, _PyLong_Zero, Py_LT);
Nick Coghlane993b102011-01-12 03:15:52 +0000247 if (cmp_result == -1) {
Nick Coghlan37ee8502010-12-03 14:26:13 +0000248 return NULL;
Guido van Rossum805365e2007-05-07 22:24:25 +0000249 }
Nick Coghlane993b102011-01-12 03:15:52 +0000250 if (cmp_result == 1) {
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300251 i = PyNumber_Add(r->length, arg);
252 if (!i) {
253 return NULL;
254 }
Nick Coghlane993b102011-01-12 03:15:52 +0000255 } else {
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300256 i = arg;
257 Py_INCREF(i);
Nick Coghlane993b102011-01-12 03:15:52 +0000258 }
259
260 /* PyLong equivalent to:
261 * if (i < 0 || i >= r->length) {
262 * <report index out of bounds>
263 * }
264 */
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300265 cmp_result = PyObject_RichCompareBool(i, _PyLong_Zero, Py_LT);
Nick Coghlane993b102011-01-12 03:15:52 +0000266 if (cmp_result == 0) {
267 cmp_result = PyObject_RichCompareBool(i, r->length, Py_GE);
268 }
269 if (cmp_result == -1) {
270 Py_DECREF(i);
271 return NULL;
272 }
273 if (cmp_result == 1) {
274 Py_DECREF(i);
275 PyErr_SetString(PyExc_IndexError,
276 "range object index out of range");
277 return NULL;
278 }
279
280 result = compute_item(r, i);
281 Py_DECREF(i);
282 return result;
283}
284
285static PyObject *
286range_item(rangeobject *r, Py_ssize_t i)
287{
Antoine Pitroua103b962012-05-16 14:37:54 +0200288 PyObject *res, *arg = PyLong_FromSsize_t(i);
Nick Coghlane993b102011-01-12 03:15:52 +0000289 if (!arg) {
290 return NULL;
291 }
Benjamin Peterson547d4852011-01-13 04:22:54 +0000292 res = compute_range_item(r, arg);
293 Py_DECREF(arg);
294 return res;
Nick Coghlane993b102011-01-12 03:15:52 +0000295}
296
Nick Coghlane993b102011-01-12 03:15:52 +0000297static PyObject *
298compute_slice(rangeobject *r, PyObject *_slice)
299{
300 PySliceObject *slice = (PySliceObject *) _slice;
301 rangeobject *result;
302 PyObject *start = NULL, *stop = NULL, *step = NULL;
303 PyObject *substart = NULL, *substop = NULL, *substep = NULL;
Mark Dickinsonffdb2c22012-11-17 19:18:10 +0000304 int error;
Nick Coghlane993b102011-01-12 03:15:52 +0000305
Mark Dickinsonffdb2c22012-11-17 19:18:10 +0000306 error = _PySlice_GetLongIndices(slice, r->length, &start, &stop, &step);
307 if (error == -1)
308 return NULL;
Nick Coghlane993b102011-01-12 03:15:52 +0000309
310 substep = PyNumber_Multiply(r->step, step);
311 if (substep == NULL) goto fail;
312 Py_CLEAR(step);
313
314 substart = compute_item(r, start);
315 if (substart == NULL) goto fail;
316 Py_CLEAR(start);
317
Mark Dickinsonffdb2c22012-11-17 19:18:10 +0000318 substop = compute_item(r, stop);
319 if (substop == NULL) goto fail;
Nick Coghlane993b102011-01-12 03:15:52 +0000320 Py_CLEAR(stop);
321
322 result = make_range_object(Py_TYPE(r), substart, substop, substep);
323 if (result != NULL) {
324 return (PyObject *) result;
325 }
326fail:
327 Py_XDECREF(start);
328 Py_XDECREF(stop);
329 Py_XDECREF(step);
330 Py_XDECREF(substart);
331 Py_XDECREF(substop);
332 Py_XDECREF(substep);
333 return NULL;
Alexandre Vassalotti75056072008-06-10 04:03:04 +0000334}
335
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000336/* Assumes (PyLong_CheckExact(ob) || PyBool_Check(ob)) */
337static int
Benjamin Petersona1864f32010-11-20 23:05:39 +0000338range_contains_long(rangeobject *r, PyObject *ob)
339{
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000340 int cmp1, cmp2, cmp3;
341 PyObject *tmp1 = NULL;
342 PyObject *tmp2 = NULL;
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000343 int result = -1;
344
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000345 /* Check if the value can possibly be in the range. */
346
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300347 cmp1 = PyObject_RichCompareBool(r->step, _PyLong_Zero, Py_GT);
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000348 if (cmp1 == -1)
349 goto end;
350 if (cmp1 == 1) { /* positive steps: start <= ob < stop */
351 cmp2 = PyObject_RichCompareBool(r->start, ob, Py_LE);
352 cmp3 = PyObject_RichCompareBool(ob, r->stop, Py_LT);
353 }
354 else { /* negative steps: stop < ob <= start */
355 cmp2 = PyObject_RichCompareBool(ob, r->start, Py_LE);
356 cmp3 = PyObject_RichCompareBool(r->stop, ob, Py_LT);
357 }
358
359 if (cmp2 == -1 || cmp3 == -1) /* TypeError */
360 goto end;
361 if (cmp2 == 0 || cmp3 == 0) { /* ob outside of range */
362 result = 0;
363 goto end;
364 }
365
366 /* Check that the stride does not invalidate ob's membership. */
367 tmp1 = PyNumber_Subtract(ob, r->start);
368 if (tmp1 == NULL)
369 goto end;
370 tmp2 = PyNumber_Remainder(tmp1, r->step);
371 if (tmp2 == NULL)
372 goto end;
Berker Peksaged6224e2016-09-12 07:47:04 +0300373 /* result = ((int(ob) - start) % step) == 0 */
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300374 result = PyObject_RichCompareBool(tmp2, _PyLong_Zero, Py_EQ);
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000375 end:
376 Py_XDECREF(tmp1);
377 Py_XDECREF(tmp2);
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000378 return result;
379}
380
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000381static int
Benjamin Petersona1864f32010-11-20 23:05:39 +0000382range_contains(rangeobject *r, PyObject *ob)
383{
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000384 if (PyLong_CheckExact(ob) || PyBool_Check(ob))
385 return range_contains_long(r, ob);
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000386
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000387 return (int)_PySequence_IterSearch((PyObject*)r, ob,
388 PY_ITERSEARCH_CONTAINS);
389}
390
Mark Dickinson36645682011-10-23 19:53:01 +0100391/* Compare two range objects. Return 1 for equal, 0 for not equal
392 and -1 on error. The algorithm is roughly the C equivalent of
393
394 if r0 is r1:
395 return True
396 if len(r0) != len(r1):
397 return False
398 if not len(r0):
399 return True
400 if r0.start != r1.start:
401 return False
402 if len(r0) == 1:
403 return True
404 return r0.step == r1.step
405*/
406static int
407range_equals(rangeobject *r0, rangeobject *r1)
408{
409 int cmp_result;
Mark Dickinson36645682011-10-23 19:53:01 +0100410
411 if (r0 == r1)
412 return 1;
413 cmp_result = PyObject_RichCompareBool(r0->length, r1->length, Py_EQ);
414 /* Return False or error to the caller. */
415 if (cmp_result != 1)
416 return cmp_result;
417 cmp_result = PyObject_Not(r0->length);
418 /* Return True or error to the caller. */
419 if (cmp_result != 0)
420 return cmp_result;
421 cmp_result = PyObject_RichCompareBool(r0->start, r1->start, Py_EQ);
422 /* Return False or error to the caller. */
423 if (cmp_result != 1)
424 return cmp_result;
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300425 cmp_result = PyObject_RichCompareBool(r0->length, _PyLong_One, Py_EQ);
Mark Dickinson36645682011-10-23 19:53:01 +0100426 /* Return True or error to the caller. */
427 if (cmp_result != 0)
428 return cmp_result;
429 return PyObject_RichCompareBool(r0->step, r1->step, Py_EQ);
430}
431
432static PyObject *
433range_richcompare(PyObject *self, PyObject *other, int op)
434{
435 int result;
436
437 if (!PyRange_Check(other))
438 Py_RETURN_NOTIMPLEMENTED;
439 switch (op) {
440 case Py_NE:
441 case Py_EQ:
442 result = range_equals((rangeobject*)self, (rangeobject*)other);
443 if (result == -1)
444 return NULL;
445 if (op == Py_NE)
446 result = !result;
447 if (result)
448 Py_RETURN_TRUE;
449 else
450 Py_RETURN_FALSE;
451 case Py_LE:
452 case Py_GE:
453 case Py_LT:
454 case Py_GT:
455 Py_RETURN_NOTIMPLEMENTED;
456 default:
457 PyErr_BadArgument();
458 return NULL;
459 }
460}
461
462/* Hash function for range objects. Rough C equivalent of
463
464 if not len(r):
465 return hash((len(r), None, None))
466 if len(r) == 1:
467 return hash((len(r), r.start, None))
468 return hash((len(r), r.start, r.step))
469*/
470static Py_hash_t
471range_hash(rangeobject *r)
472{
473 PyObject *t;
474 Py_hash_t result = -1;
475 int cmp_result;
476
477 t = PyTuple_New(3);
478 if (!t)
479 return -1;
480 Py_INCREF(r->length);
481 PyTuple_SET_ITEM(t, 0, r->length);
482 cmp_result = PyObject_Not(r->length);
483 if (cmp_result == -1)
484 goto end;
485 if (cmp_result == 1) {
486 Py_INCREF(Py_None);
487 Py_INCREF(Py_None);
488 PyTuple_SET_ITEM(t, 1, Py_None);
489 PyTuple_SET_ITEM(t, 2, Py_None);
490 }
491 else {
Mark Dickinson36645682011-10-23 19:53:01 +0100492 Py_INCREF(r->start);
493 PyTuple_SET_ITEM(t, 1, r->start);
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300494 cmp_result = PyObject_RichCompareBool(r->length, _PyLong_One, Py_EQ);
Mark Dickinson36645682011-10-23 19:53:01 +0100495 if (cmp_result == -1)
496 goto end;
497 if (cmp_result == 1) {
498 Py_INCREF(Py_None);
499 PyTuple_SET_ITEM(t, 2, Py_None);
500 }
501 else {
502 Py_INCREF(r->step);
503 PyTuple_SET_ITEM(t, 2, r->step);
504 }
505 }
506 result = PyObject_Hash(t);
507 end:
508 Py_DECREF(t);
509 return result;
510}
511
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000512static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +0000513range_count(rangeobject *r, PyObject *ob)
514{
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000515 if (PyLong_CheckExact(ob) || PyBool_Check(ob)) {
Georg Brandl7e5343b2010-11-20 22:40:10 +0000516 int result = range_contains_long(r, ob);
517 if (result == -1)
518 return NULL;
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300519 return PyLong_FromLong(result);
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000520 } else {
521 Py_ssize_t count;
522 count = _PySequence_IterSearch((PyObject*)r, ob, PY_ITERSEARCH_COUNT);
523 if (count == -1)
524 return NULL;
525 return PyLong_FromSsize_t(count);
526 }
527}
528
529static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +0000530range_index(rangeobject *r, PyObject *ob)
531{
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000532 int contains;
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000533
534 if (!PyLong_CheckExact(ob) && !PyBool_Check(ob)) {
535 Py_ssize_t index;
536 index = _PySequence_IterSearch((PyObject*)r, ob, PY_ITERSEARCH_INDEX);
537 if (index == -1)
538 return NULL;
539 return PyLong_FromSsize_t(index);
540 }
541
542 contains = range_contains_long(r, ob);
543 if (contains == -1)
544 return NULL;
545
Benjamin Peterson155614b2010-11-20 22:44:32 +0000546 if (contains) {
547 PyObject *idx, *tmp = PyNumber_Subtract(ob, r->start);
548 if (tmp == NULL)
549 return NULL;
550 /* idx = (ob - r.start) // r.step */
551 idx = PyNumber_FloorDivide(tmp, r->step);
552 Py_DECREF(tmp);
553 return idx;
554 }
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000555
556 /* object is not in the range */
Benjamin Peterson155614b2010-11-20 22:44:32 +0000557 PyErr_Format(PyExc_ValueError, "%R is not in range", ob);
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000558 return NULL;
559}
560
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000561static PySequenceMethods range_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000562 (lenfunc)range_length, /* sq_length */
Nick Coghlan37ee8502010-12-03 14:26:13 +0000563 0, /* sq_concat */
564 0, /* sq_repeat */
565 (ssizeargfunc)range_item, /* sq_item */
566 0, /* sq_slice */
567 0, /* sq_ass_item */
568 0, /* sq_ass_slice */
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000569 (objobjproc)range_contains, /* sq_contains */
Guido van Rossum12d12c51993-10-26 17:58:25 +0000570};
571
Nick Coghlan37ee8502010-12-03 14:26:13 +0000572static PyObject *
573range_repr(rangeobject *r)
574{
575 Py_ssize_t istep;
576
577 /* Check for special case values for printing. We don't always
Alexey Izbyshev7ecae3c2018-08-24 07:39:45 +0300578 need the step value. We don't care about overflow. */
Nick Coghlan37ee8502010-12-03 14:26:13 +0000579 istep = PyNumber_AsSsize_t(r->step, NULL);
Alexey Izbyshev7ecae3c2018-08-24 07:39:45 +0300580 if (istep == -1 && PyErr_Occurred()) {
581 assert(!PyErr_ExceptionMatches(PyExc_OverflowError));
582 return NULL;
Nick Coghlan37ee8502010-12-03 14:26:13 +0000583 }
584
585 if (istep == 1)
586 return PyUnicode_FromFormat("range(%R, %R)", r->start, r->stop);
587 else
588 return PyUnicode_FromFormat("range(%R, %R, %R)",
589 r->start, r->stop, r->step);
590}
591
592/* Pickling support */
593static PyObject *
594range_reduce(rangeobject *r, PyObject *args)
595{
596 return Py_BuildValue("(O(OOO))", Py_TYPE(r),
597 r->start, r->stop, r->step);
598}
599
600static PyObject *
601range_subscript(rangeobject* self, PyObject* item)
602{
603 if (PyIndex_Check(item)) {
Nick Coghlane993b102011-01-12 03:15:52 +0000604 PyObject *i, *result;
605 i = PyNumber_Index(item);
606 if (!i)
Nick Coghlan37ee8502010-12-03 14:26:13 +0000607 return NULL;
Nick Coghlane993b102011-01-12 03:15:52 +0000608 result = compute_range_item(self, i);
609 Py_DECREF(i);
610 return result;
Nick Coghlan37ee8502010-12-03 14:26:13 +0000611 }
612 if (PySlice_Check(item)) {
Nick Coghlane993b102011-01-12 03:15:52 +0000613 return compute_slice(self, item);
Nick Coghlan37ee8502010-12-03 14:26:13 +0000614 }
615 PyErr_Format(PyExc_TypeError,
616 "range indices must be integers or slices, not %.200s",
617 item->ob_type->tp_name);
618 return NULL;
619}
620
621
622static PyMappingMethods range_as_mapping = {
623 (lenfunc)range_length, /* mp_length */
624 (binaryfunc)range_subscript, /* mp_subscript */
625 (objobjargproc)0, /* mp_ass_subscript */
626};
627
4kir4e46fb862017-03-20 09:44:46 +0300628static int
629range_bool(rangeobject* self)
630{
631 return PyObject_IsTrue(self->length);
632}
633
634static PyNumberMethods range_as_number = {
635 .nb_bool = (inquiry)range_bool,
636};
637
Jeremy Hylton938ace62002-07-17 16:30:39 +0000638static PyObject * range_iter(PyObject *seq);
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530639static PyObject * range_reverse(PyObject *seq, PyObject *Py_UNUSED(ignored));
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000640
641PyDoc_STRVAR(reverse_doc,
Ezio Melotti5792ce12013-10-06 00:36:45 +0300642"Return a reverse iterator.");
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000643
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000644PyDoc_STRVAR(count_doc,
645"rangeobject.count(value) -> integer -- return number of occurrences of value");
646
647PyDoc_STRVAR(index_doc,
Srinivas Reddy Thatiparthy (శ్రీనివాస్ రెడ్డి తాటిపర్తి)22c52632019-05-03 17:52:12 +0530648"rangeobject.index(value) -> integer -- return index of value.\n"
Ezio Melotti5792ce12013-10-06 00:36:45 +0300649"Raise ValueError if the value is not present.");
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000650
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000651static PyMethodDef range_methods[] = {
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530652 {"__reversed__", range_reverse, METH_NOARGS, reverse_doc},
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000653 {"__reduce__", (PyCFunction)range_reduce, METH_VARARGS},
654 {"count", (PyCFunction)range_count, METH_O, count_doc},
655 {"index", (PyCFunction)range_index, METH_O, index_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000656 {NULL, NULL} /* sentinel */
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000657};
Raymond Hettinger48165d42002-06-05 20:08:48 +0000658
Benjamin Peterson878ce382011-11-05 15:17:52 -0400659static PyMemberDef range_members[] = {
660 {"start", T_OBJECT_EX, offsetof(rangeobject, start), READONLY},
661 {"stop", T_OBJECT_EX, offsetof(rangeobject, stop), READONLY},
662 {"step", T_OBJECT_EX, offsetof(rangeobject, step), READONLY},
663 {0}
664};
665
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000666PyTypeObject PyRange_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000667 PyVarObject_HEAD_INIT(&PyType_Type, 0)
668 "range", /* Name of this type */
669 sizeof(rangeobject), /* Basic object size */
670 0, /* Item size for varobject */
671 (destructor)range_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200672 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000673 0, /* tp_getattr */
674 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200675 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000676 (reprfunc)range_repr, /* tp_repr */
4kir4e46fb862017-03-20 09:44:46 +0300677 &range_as_number, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000678 &range_as_sequence, /* tp_as_sequence */
Nick Coghlan37ee8502010-12-03 14:26:13 +0000679 &range_as_mapping, /* tp_as_mapping */
Mark Dickinson36645682011-10-23 19:53:01 +0100680 (hashfunc)range_hash, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000681 0, /* tp_call */
682 0, /* tp_str */
683 PyObject_GenericGetAttr, /* tp_getattro */
684 0, /* tp_setattro */
685 0, /* tp_as_buffer */
686 Py_TPFLAGS_DEFAULT, /* tp_flags */
687 range_doc, /* tp_doc */
688 0, /* tp_traverse */
689 0, /* tp_clear */
Mark Dickinson36645682011-10-23 19:53:01 +0100690 range_richcompare, /* tp_richcompare */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000691 0, /* tp_weaklistoffset */
692 range_iter, /* tp_iter */
693 0, /* tp_iternext */
694 range_methods, /* tp_methods */
Benjamin Peterson878ce382011-11-05 15:17:52 -0400695 range_members, /* tp_members */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000696 0, /* tp_getset */
697 0, /* tp_base */
698 0, /* tp_dict */
699 0, /* tp_descr_get */
700 0, /* tp_descr_set */
701 0, /* tp_dictoffset */
702 0, /* tp_init */
703 0, /* tp_alloc */
704 range_new, /* tp_new */
Guido van Rossum12d12c51993-10-26 17:58:25 +0000705};
Raymond Hettinger48165d42002-06-05 20:08:48 +0000706
Walter Dörwald4ad94212007-05-21 18:01:17 +0000707/*********************** range Iterator **************************/
Raymond Hettinger48165d42002-06-05 20:08:48 +0000708
Guido van Rossum805365e2007-05-07 22:24:25 +0000709/* There are 2 types of iterators, one for C longs, the other for
Serhiy Storchaka95949422013-08-27 19:40:23 +0300710 Python ints (ie, PyObjects). This should make iteration fast
Guido van Rossum805365e2007-05-07 22:24:25 +0000711 in the normal case, but possible for any numeric value.
712*/
713
Raymond Hettinger48165d42002-06-05 20:08:48 +0000714typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000715 PyObject_HEAD
716 long index;
717 long start;
718 long step;
719 long len;
Raymond Hettinger48165d42002-06-05 20:08:48 +0000720} rangeiterobject;
721
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000722static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +0000723rangeiter_next(rangeiterobject *r)
724{
Guido van Rossum805365e2007-05-07 22:24:25 +0000725 if (r->index < r->len)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000726 /* cast to unsigned to avoid possible signed overflow
Mark Dickinsonb43dbc22009-11-15 12:56:08 +0000727 in intermediate calculations. */
728 return PyLong_FromLong((long)(r->start +
729 (unsigned long)(r->index++) * r->step));
Guido van Rossum805365e2007-05-07 22:24:25 +0000730 return NULL;
Raymond Hettinger48165d42002-06-05 20:08:48 +0000731}
732
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000733static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530734rangeiter_len(rangeiterobject *r, PyObject *Py_UNUSED(ignored))
Benjamin Petersona1864f32010-11-20 23:05:39 +0000735{
Christian Heimes217cfd12007-12-02 14:31:20 +0000736 return PyLong_FromLong(r->len - r->index);
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000737}
738
Guido van Rossum805365e2007-05-07 22:24:25 +0000739PyDoc_STRVAR(length_hint_doc,
740 "Private method returning an estimate of len(list(it)).");
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000741
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000742static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530743rangeiter_reduce(rangeiterobject *r, PyObject *Py_UNUSED(ignored))
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000744{
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200745 _Py_IDENTIFIER(iter);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000746 PyObject *start=NULL, *stop=NULL, *step=NULL;
747 PyObject *range;
Chris Jerdonek042fa652012-10-07 14:56:27 -0700748
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000749 /* create a range object for pickling */
750 start = PyLong_FromLong(r->start);
751 if (start == NULL)
752 goto err;
753 stop = PyLong_FromLong(r->start + r->len * r->step);
754 if (stop == NULL)
755 goto err;
756 step = PyLong_FromLong(r->step);
757 if (step == NULL)
758 goto err;
759 range = (PyObject*)make_range_object(&PyRange_Type,
760 start, stop, step);
761 if (range == NULL)
762 goto err;
763 /* return the result */
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200764 return Py_BuildValue("N(N)i", _PyEval_GetBuiltinId(&PyId_iter),
765 range, r->index);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000766err:
767 Py_XDECREF(start);
768 Py_XDECREF(stop);
769 Py_XDECREF(step);
770 return NULL;
771}
772
773static PyObject *
774rangeiter_setstate(rangeiterobject *r, PyObject *state)
775{
776 long index = PyLong_AsLong(state);
777 if (index == -1 && PyErr_Occurred())
778 return NULL;
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +0000779 /* silently clip the index value */
780 if (index < 0)
781 index = 0;
782 else if (index > r->len)
783 index = r->len; /* exhausted iterator */
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000784 r->index = index;
785 Py_RETURN_NONE;
786}
787
788PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
789PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
790
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000791static PyMethodDef rangeiter_methods[] = {
Guido van Rossum805365e2007-05-07 22:24:25 +0000792 {"__length_hint__", (PyCFunction)rangeiter_len, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000793 length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000794 {"__reduce__", (PyCFunction)rangeiter_reduce, METH_NOARGS,
795 reduce_doc},
796 {"__setstate__", (PyCFunction)rangeiter_setstate, METH_O,
797 setstate_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000798 {NULL, NULL} /* sentinel */
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000799};
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000800
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000801PyTypeObject PyRangeIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000802 PyVarObject_HEAD_INIT(&PyType_Type, 0)
803 "range_iterator", /* tp_name */
804 sizeof(rangeiterobject), /* tp_basicsize */
805 0, /* tp_itemsize */
806 /* methods */
807 (destructor)PyObject_Del, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200808 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000809 0, /* tp_getattr */
810 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200811 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000812 0, /* tp_repr */
813 0, /* tp_as_number */
814 0, /* tp_as_sequence */
815 0, /* tp_as_mapping */
816 0, /* tp_hash */
817 0, /* tp_call */
818 0, /* tp_str */
819 PyObject_GenericGetAttr, /* tp_getattro */
820 0, /* tp_setattro */
821 0, /* tp_as_buffer */
822 Py_TPFLAGS_DEFAULT, /* tp_flags */
823 0, /* tp_doc */
824 0, /* tp_traverse */
825 0, /* tp_clear */
826 0, /* tp_richcompare */
827 0, /* tp_weaklistoffset */
828 PyObject_SelfIter, /* tp_iter */
829 (iternextfunc)rangeiter_next, /* tp_iternext */
830 rangeiter_methods, /* tp_methods */
831 0, /* tp_members */
Guido van Rossum805365e2007-05-07 22:24:25 +0000832};
833
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000834/* Return number of items in range (lo, hi, step). step != 0
835 * required. The result always fits in an unsigned long.
Guido van Rossum805365e2007-05-07 22:24:25 +0000836 */
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000837static unsigned long
Benjamin Petersona1864f32010-11-20 23:05:39 +0000838get_len_of_range(long lo, long hi, long step)
839{
Guido van Rossum805365e2007-05-07 22:24:25 +0000840 /* -------------------------------------------------------------
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000841 If step > 0 and lo >= hi, or step < 0 and lo <= hi, the range is empty.
842 Else for step > 0, if n values are in the range, the last one is
Guido van Rossum805365e2007-05-07 22:24:25 +0000843 lo + (n-1)*step, which must be <= hi-1. Rearranging,
844 n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives
845 the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so
846 the RHS is non-negative and so truncation is the same as the
847 floor. Letting M be the largest positive long, the worst case
848 for the RHS numerator is hi=M, lo=-M-1, and then
849 hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000850 precision to compute the RHS exactly. The analysis for step < 0
851 is similar.
Guido van Rossum805365e2007-05-07 22:24:25 +0000852 ---------------------------------------------------------------*/
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000853 assert(step != 0);
854 if (step > 0 && lo < hi)
855 return 1UL + (hi - 1UL - lo) / step;
856 else if (step < 0 && lo > hi)
857 return 1UL + (lo - 1UL - hi) / (0UL - step);
858 else
859 return 0UL;
Guido van Rossum805365e2007-05-07 22:24:25 +0000860}
861
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000862/* Initialize a rangeiter object. If the length of the rangeiter object
863 is not representable as a C long, OverflowError is raised. */
864
Guido van Rossum805365e2007-05-07 22:24:25 +0000865static PyObject *
Nick Coghlan37ee8502010-12-03 14:26:13 +0000866fast_range_iter(long start, long stop, long step)
Benjamin Petersona1864f32010-11-20 23:05:39 +0000867{
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000868 rangeiterobject *it = PyObject_New(rangeiterobject, &PyRangeIter_Type);
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000869 unsigned long ulen;
Guido van Rossum805365e2007-05-07 22:24:25 +0000870 if (it == NULL)
871 return NULL;
872 it->start = start;
873 it->step = step;
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000874 ulen = get_len_of_range(start, stop, step);
875 if (ulen > (unsigned long)LONG_MAX) {
Benjamin Peterson36fbb732009-11-16 00:34:25 +0000876 Py_DECREF(it);
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000877 PyErr_SetString(PyExc_OverflowError,
878 "range too large to represent as a range_iterator");
879 return NULL;
880 }
881 it->len = (long)ulen;
Guido van Rossum805365e2007-05-07 22:24:25 +0000882 it->index = 0;
883 return (PyObject *)it;
884}
885
Nick Coghlan37ee8502010-12-03 14:26:13 +0000886typedef struct {
887 PyObject_HEAD
888 PyObject *index;
889 PyObject *start;
890 PyObject *step;
891 PyObject *len;
892} longrangeiterobject;
893
894static PyObject *
895longrangeiter_len(longrangeiterobject *r, PyObject *no_args)
896{
897 return PyNumber_Subtract(r->len, r->index);
Guido van Rossum805365e2007-05-07 22:24:25 +0000898}
899
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000900static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530901longrangeiter_reduce(longrangeiterobject *r, PyObject *Py_UNUSED(ignored))
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000902{
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200903 _Py_IDENTIFIER(iter);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000904 PyObject *product, *stop=NULL;
905 PyObject *range;
906
907 /* create a range object for pickling. Must calculate the "stop" value */
908 product = PyNumber_Multiply(r->len, r->step);
909 if (product == NULL)
910 return NULL;
911 stop = PyNumber_Add(r->start, product);
912 Py_DECREF(product);
913 if (stop == NULL)
914 return NULL;
915 Py_INCREF(r->start);
916 Py_INCREF(r->step);
917 range = (PyObject*)make_range_object(&PyRange_Type,
918 r->start, stop, r->step);
919 if (range == NULL) {
920 Py_DECREF(r->start);
921 Py_DECREF(stop);
922 Py_DECREF(r->step);
923 return NULL;
924 }
925
926 /* return the result */
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200927 return Py_BuildValue("N(N)O", _PyEval_GetBuiltinId(&PyId_iter),
928 range, r->index);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000929}
930
931static PyObject *
932longrangeiter_setstate(longrangeiterobject *r, PyObject *state)
933{
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +0000934 int cmp;
Serhiy Storchaka009b8112015-03-18 21:53:15 +0200935
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +0000936 /* clip the value */
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300937 cmp = PyObject_RichCompareBool(state, _PyLong_Zero, Py_LT);
938 if (cmp < 0)
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +0000939 return NULL;
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +0000940 if (cmp > 0) {
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300941 state = _PyLong_Zero;
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +0000942 }
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300943 else {
944 cmp = PyObject_RichCompareBool(r->len, state, Py_LT);
945 if (cmp < 0)
946 return NULL;
947 if (cmp > 0)
948 state = r->len;
949 }
Serhiy Storchaka4a1e70f2015-12-27 12:36:18 +0200950 Py_INCREF(state);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300951 Py_XSETREF(r->index, state);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000952 Py_RETURN_NONE;
953}
954
Guido van Rossum805365e2007-05-07 22:24:25 +0000955static PyMethodDef longrangeiter_methods[] = {
956 {"__length_hint__", (PyCFunction)longrangeiter_len, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000957 length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000958 {"__reduce__", (PyCFunction)longrangeiter_reduce, METH_NOARGS,
959 reduce_doc},
960 {"__setstate__", (PyCFunction)longrangeiter_setstate, METH_O,
961 setstate_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000962 {NULL, NULL} /* sentinel */
Guido van Rossum805365e2007-05-07 22:24:25 +0000963};
964
965static void
Benjamin Petersona1864f32010-11-20 23:05:39 +0000966longrangeiter_dealloc(longrangeiterobject *r)
967{
Guido van Rossum805365e2007-05-07 22:24:25 +0000968 Py_XDECREF(r->index);
Guido van Rossum317e7742007-05-08 15:18:31 +0000969 Py_XDECREF(r->start);
970 Py_XDECREF(r->step);
971 Py_XDECREF(r->len);
Amaury Forgeot d'Arcb7f17e42007-11-15 20:52:21 +0000972 PyObject_Del(r);
Guido van Rossum805365e2007-05-07 22:24:25 +0000973}
974
975static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +0000976longrangeiter_next(longrangeiterobject *r)
977{
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300978 PyObject *product, *new_index, *result;
Guido van Rossum805365e2007-05-07 22:24:25 +0000979 if (PyObject_RichCompareBool(r->index, r->len, Py_LT) != 1)
980 return NULL;
981
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300982 new_index = PyNumber_Add(r->index, _PyLong_One);
Benjamin Peterson36fbb732009-11-16 00:34:25 +0000983 if (!new_index)
984 return NULL;
985
986 product = PyNumber_Multiply(r->index, r->step);
987 if (!product) {
988 Py_DECREF(new_index);
Guido van Rossum805365e2007-05-07 22:24:25 +0000989 return NULL;
990 }
991
992 result = PyNumber_Add(r->start, product);
993 Py_DECREF(product);
994 if (result) {
Serhiy Storchaka57a01d32016-04-10 18:05:40 +0300995 Py_SETREF(r->index, new_index);
Guido van Rossum805365e2007-05-07 22:24:25 +0000996 }
Benjamin Peterson36fbb732009-11-16 00:34:25 +0000997 else {
998 Py_DECREF(new_index);
999 }
Guido van Rossum805365e2007-05-07 22:24:25 +00001000
1001 return result;
1002}
1003
Christian Heimesa22e8bd2007-11-29 22:35:39 +00001004PyTypeObject PyLongRangeIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001005 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1006 "longrange_iterator", /* tp_name */
1007 sizeof(longrangeiterobject), /* tp_basicsize */
1008 0, /* tp_itemsize */
1009 /* methods */
1010 (destructor)longrangeiter_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001011 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001012 0, /* tp_getattr */
1013 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001014 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001015 0, /* tp_repr */
1016 0, /* tp_as_number */
1017 0, /* tp_as_sequence */
1018 0, /* tp_as_mapping */
1019 0, /* tp_hash */
1020 0, /* tp_call */
1021 0, /* tp_str */
1022 PyObject_GenericGetAttr, /* tp_getattro */
1023 0, /* tp_setattro */
1024 0, /* tp_as_buffer */
1025 Py_TPFLAGS_DEFAULT, /* tp_flags */
1026 0, /* tp_doc */
1027 0, /* tp_traverse */
1028 0, /* tp_clear */
1029 0, /* tp_richcompare */
1030 0, /* tp_weaklistoffset */
1031 PyObject_SelfIter, /* tp_iter */
1032 (iternextfunc)longrangeiter_next, /* tp_iternext */
1033 longrangeiter_methods, /* tp_methods */
1034 0,
Raymond Hettinger48165d42002-06-05 20:08:48 +00001035};
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001036
1037static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +00001038range_iter(PyObject *seq)
1039{
Guido van Rossum805365e2007-05-07 22:24:25 +00001040 rangeobject *r = (rangeobject *)seq;
1041 longrangeiterobject *it;
Martin v. Löwis84451042007-12-20 22:57:23 +00001042 long lstart, lstop, lstep;
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001043 PyObject *int_it;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001044
Guido van Rossum805365e2007-05-07 22:24:25 +00001045 assert(PyRange_Check(seq));
Martin v. Löwis84451042007-12-20 22:57:23 +00001046
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001047 /* If all three fields and the length convert to long, use the int
1048 * version */
Martin v. Löwis84451042007-12-20 22:57:23 +00001049 lstart = PyLong_AsLong(r->start);
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001050 if (lstart == -1 && PyErr_Occurred()) {
1051 PyErr_Clear();
1052 goto long_range;
Martin v. Löwis84451042007-12-20 22:57:23 +00001053 }
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001054 lstop = PyLong_AsLong(r->stop);
1055 if (lstop == -1 && PyErr_Occurred()) {
1056 PyErr_Clear();
1057 goto long_range;
1058 }
1059 lstep = PyLong_AsLong(r->step);
1060 if (lstep == -1 && PyErr_Occurred()) {
1061 PyErr_Clear();
1062 goto long_range;
1063 }
Nick Coghlan37ee8502010-12-03 14:26:13 +00001064 int_it = fast_range_iter(lstart, lstop, lstep);
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001065 if (int_it == NULL && PyErr_ExceptionMatches(PyExc_OverflowError)) {
1066 PyErr_Clear();
1067 goto long_range;
1068 }
1069 return (PyObject *)int_it;
1070
1071 long_range:
Christian Heimesa22e8bd2007-11-29 22:35:39 +00001072 it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
Guido van Rossum805365e2007-05-07 22:24:25 +00001073 if (it == NULL)
1074 return NULL;
Guido van Rossum317e7742007-05-08 15:18:31 +00001075
Guido van Rossum805365e2007-05-07 22:24:25 +00001076 it->start = r->start;
Guido van Rossum317e7742007-05-08 15:18:31 +00001077 it->step = r->step;
Nick Coghlan37ee8502010-12-03 14:26:13 +00001078 it->len = r->length;
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001079 it->index = _PyLong_Zero;
Guido van Rossum317e7742007-05-08 15:18:31 +00001080 Py_INCREF(it->start);
1081 Py_INCREF(it->step);
Nick Coghlan37ee8502010-12-03 14:26:13 +00001082 Py_INCREF(it->len);
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001083 Py_INCREF(it->index);
Guido van Rossum805365e2007-05-07 22:24:25 +00001084 return (PyObject *)it;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001085}
1086
1087static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301088range_reverse(PyObject *seq, PyObject *Py_UNUSED(ignored))
Benjamin Petersona1864f32010-11-20 23:05:39 +00001089{
Guido van Rossum805365e2007-05-07 22:24:25 +00001090 rangeobject *range = (rangeobject*) seq;
1091 longrangeiterobject *it;
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001092 PyObject *sum, *diff, *product;
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001093 long lstart, lstop, lstep, new_start, new_stop;
1094 unsigned long ulen;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001095
Guido van Rossum805365e2007-05-07 22:24:25 +00001096 assert(PyRange_Check(seq));
Martin v. Löwis84451042007-12-20 22:57:23 +00001097
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001098 /* reversed(range(start, stop, step)) can be expressed as
1099 range(start+(n-1)*step, start-step, -step), where n is the number of
1100 integers in the range.
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001101
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001102 If each of start, stop, step, -step, start-step, and the length
1103 of the iterator is representable as a C long, use the int
1104 version. This excludes some cases where the reversed range is
1105 representable as a range_iterator, but it's good enough for
1106 common cases and it makes the checks simple. */
1107
1108 lstart = PyLong_AsLong(range->start);
1109 if (lstart == -1 && PyErr_Occurred()) {
1110 PyErr_Clear();
1111 goto long_range;
1112 }
1113 lstop = PyLong_AsLong(range->stop);
1114 if (lstop == -1 && PyErr_Occurred()) {
1115 PyErr_Clear();
1116 goto long_range;
1117 }
1118 lstep = PyLong_AsLong(range->step);
1119 if (lstep == -1 && PyErr_Occurred()) {
1120 PyErr_Clear();
1121 goto long_range;
1122 }
1123 /* check for possible overflow of -lstep */
1124 if (lstep == LONG_MIN)
1125 goto long_range;
1126
1127 /* check for overflow of lstart - lstep:
1128
1129 for lstep > 0, need only check whether lstart - lstep < LONG_MIN.
1130 for lstep < 0, need only check whether lstart - lstep > LONG_MAX
1131
1132 Rearrange these inequalities as:
1133
1134 lstart - LONG_MIN < lstep (lstep > 0)
1135 LONG_MAX - lstart < -lstep (lstep < 0)
1136
1137 and compute both sides as unsigned longs, to avoid the
1138 possibility of undefined behaviour due to signed overflow. */
1139
1140 if (lstep > 0) {
1141 if ((unsigned long)lstart - LONG_MIN < (unsigned long)lstep)
1142 goto long_range;
1143 }
1144 else {
1145 if (LONG_MAX - (unsigned long)lstart < 0UL - lstep)
1146 goto long_range;
1147 }
1148
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001149 ulen = get_len_of_range(lstart, lstop, lstep);
1150 if (ulen > (unsigned long)LONG_MAX)
1151 goto long_range;
1152
1153 new_stop = lstart - lstep;
1154 new_start = (long)(new_stop + ulen * lstep);
Nick Coghlan37ee8502010-12-03 14:26:13 +00001155 return fast_range_iter(new_start, new_stop, -lstep);
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001156
1157long_range:
Christian Heimesa22e8bd2007-11-29 22:35:39 +00001158 it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
Guido van Rossum805365e2007-05-07 22:24:25 +00001159 if (it == NULL)
1160 return NULL;
Zackery Spytzc9a61682018-10-31 03:13:16 -06001161 it->index = it->start = it->step = NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001162
Guido van Rossum805365e2007-05-07 22:24:25 +00001163 /* start + (len - 1) * step */
Nick Coghlan37ee8502010-12-03 14:26:13 +00001164 it->len = range->length;
1165 Py_INCREF(it->len);
Benjamin Peterson36fbb732009-11-16 00:34:25 +00001166
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001167 diff = PyNumber_Subtract(it->len, _PyLong_One);
Guido van Rossum805365e2007-05-07 22:24:25 +00001168 if (!diff)
1169 goto create_failure;
1170
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001171 product = PyNumber_Multiply(diff, range->step);
1172 Py_DECREF(diff);
Guido van Rossum805365e2007-05-07 22:24:25 +00001173 if (!product)
1174 goto create_failure;
1175
1176 sum = PyNumber_Add(range->start, product);
1177 Py_DECREF(product);
1178 it->start = sum;
1179 if (!it->start)
1180 goto create_failure;
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001181
Guido van Rossum805365e2007-05-07 22:24:25 +00001182 it->step = PyNumber_Negative(range->step);
Benjamin Peterson36fbb732009-11-16 00:34:25 +00001183 if (!it->step)
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001184 goto create_failure;
Guido van Rossum805365e2007-05-07 22:24:25 +00001185
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001186 it->index = _PyLong_Zero;
1187 Py_INCREF(it->index);
Guido van Rossum805365e2007-05-07 22:24:25 +00001188 return (PyObject *)it;
1189
1190create_failure:
Benjamin Peterson36fbb732009-11-16 00:34:25 +00001191 Py_DECREF(it);
Guido van Rossum805365e2007-05-07 22:24:25 +00001192 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001193}