blob: 3e05707b1cee693efd47d37f362079cf8ca1ce9a [file] [log] [blame]
Guido van Rossum12d12c51993-10-26 17:58:25 +00001/* Range object implementation */
2
Guido van Rossumc0b618a1997-05-02 03:12:38 +00003#include "Python.h"
Victor Stinner384621c2020-06-22 17:27:35 +02004#include "pycore_abstract.h" // _PyIndex_Check()
Victor Stinnerc9bc2902020-10-27 02:24:34 +01005#include "pycore_long.h" // _PyLong_GetZero()
Victor Stinner384621c2020-06-22 17:27:35 +02006#include "pycore_tuple.h" // _PyTuple_ITEMS()
Victor Stinner4a21e572020-04-15 02:35:41 +02007#include "structmember.h" // PyMemberDef
Thomas Woutersefafcea2001-07-09 12:30:54 +00008
Guido van Rossum805365e2007-05-07 22:24:25 +00009/* Support objects whose length is > PY_SSIZE_T_MAX.
10
Serhiy Storchaka6a7b3a72016-04-17 08:32:47 +030011 This could be sped up for small PyLongs if they fit in a Py_ssize_t.
Benjamin Petersonaf580df2016-09-06 10:46:49 -070012 This only matters on Win64. Though we could use long long which
Guido van Rossum805365e2007-05-07 22:24:25 +000013 would presumably help perf.
14*/
15
Guido van Rossum12d12c51993-10-26 17:58:25 +000016typedef struct {
Guido van Rossum805365e2007-05-07 22:24:25 +000017 PyObject_HEAD
18 PyObject *start;
19 PyObject *stop;
20 PyObject *step;
Nick Coghlan37ee8502010-12-03 14:26:13 +000021 PyObject *length;
Guido van Rossum12d12c51993-10-26 17:58:25 +000022} rangeobject;
23
Hai Shi46874c22020-01-30 17:20:25 -060024_Py_IDENTIFIER(iter);
25
Guido van Rossum805365e2007-05-07 22:24:25 +000026/* Helper function for validating step. Always returns a new reference or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000027 NULL on error.
Guido van Rossum805365e2007-05-07 22:24:25 +000028*/
29static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +000030validate_step(PyObject *step)
31{
Guido van Rossum805365e2007-05-07 22:24:25 +000032 /* No step specified, use a step of 1. */
33 if (!step)
Christian Heimes217cfd12007-12-02 14:31:20 +000034 return PyLong_FromLong(1);
Guido van Rossum805365e2007-05-07 22:24:25 +000035
36 step = PyNumber_Index(step);
Serhiy Storchaka5d062d72016-06-18 09:51:55 +030037 if (step && _PyLong_Sign(step) == 0) {
38 PyErr_SetString(PyExc_ValueError,
39 "range() arg 3 must not be zero");
40 Py_CLEAR(step);
Guido van Rossum805365e2007-05-07 22:24:25 +000041 }
42
43 return step;
Raymond Hettingerc4c453f2002-06-05 23:12:45 +000044}
45
Nick Coghlan37ee8502010-12-03 14:26:13 +000046static PyObject *
47compute_range_length(PyObject *start, PyObject *stop, PyObject *step);
48
49static rangeobject *
50make_range_object(PyTypeObject *type, PyObject *start,
51 PyObject *stop, PyObject *step)
52{
53 rangeobject *obj = NULL;
54 PyObject *length;
55 length = compute_range_length(start, stop, step);
56 if (length == NULL) {
57 return NULL;
58 }
59 obj = PyObject_New(rangeobject, type);
60 if (obj == NULL) {
61 Py_DECREF(length);
62 return NULL;
63 }
64 obj->start = start;
65 obj->stop = stop;
66 obj->step = step;
67 obj->length = length;
68 return obj;
69}
70
Guido van Rossum805365e2007-05-07 22:24:25 +000071/* XXX(nnorwitz): should we error check if the user passes any empty ranges?
72 range(-10)
73 range(0, -5)
74 range(0, 5, -1)
75*/
Raymond Hettingerc4c453f2002-06-05 23:12:45 +000076static PyObject *
Petr Viktorin6e35da92020-02-18 16:13:17 +010077range_from_array(PyTypeObject *type, PyObject *const *args, Py_ssize_t num_args)
Benjamin Petersona1864f32010-11-20 23:05:39 +000078{
Nick Coghlan37ee8502010-12-03 14:26:13 +000079 rangeobject *obj;
Guido van Rossum805365e2007-05-07 22:24:25 +000080 PyObject *start = NULL, *stop = NULL, *step = NULL;
Raymond Hettingerc4c453f2002-06-05 23:12:45 +000081
Pablo Galindo4b66fa62020-01-05 17:30:53 +000082 switch (num_args) {
83 case 3:
Petr Viktorin6e35da92020-02-18 16:13:17 +010084 step = args[2];
Pablo Galindo4b66fa62020-01-05 17:30:53 +000085 /* fallthrough */
86 case 2:
Petr Viktorin6e35da92020-02-18 16:13:17 +010087 /* Convert borrowed refs to owned refs */
88 start = PyNumber_Index(args[0]);
Pablo Galindo4b66fa62020-01-05 17:30:53 +000089 if (!start) {
90 return NULL;
91 }
Petr Viktorin6e35da92020-02-18 16:13:17 +010092 stop = PyNumber_Index(args[1]);
Pablo Galindo4b66fa62020-01-05 17:30:53 +000093 if (!stop) {
94 Py_DECREF(start);
95 return NULL;
96 }
Petr Viktorin6e35da92020-02-18 16:13:17 +010097 step = validate_step(step); /* Caution, this can clear exceptions */
Pablo Galindo4b66fa62020-01-05 17:30:53 +000098 if (!step) {
99 Py_DECREF(start);
100 Py_DECREF(stop);
101 return NULL;
102 }
103 break;
104 case 1:
Petr Viktorin6e35da92020-02-18 16:13:17 +0100105 stop = PyNumber_Index(args[0]);
Pablo Galindo4b66fa62020-01-05 17:30:53 +0000106 if (!stop) {
107 return NULL;
108 }
Victor Stinnerc9bc2902020-10-27 02:24:34 +0100109 start = _PyLong_GetZero();
110 Py_INCREF(start);
111 step = _PyLong_GetOne();
112 Py_INCREF(step);
Pablo Galindo4b66fa62020-01-05 17:30:53 +0000113 break;
114 case 0:
115 PyErr_SetString(PyExc_TypeError,
116 "range expected at least 1 argument, got 0");
Raymond Hettinger94f55832009-06-12 18:40:16 +0000117 return NULL;
Pablo Galindo4b66fa62020-01-05 17:30:53 +0000118 default:
Victor Stinner58ac7002020-02-07 03:04:21 +0100119 PyErr_Format(PyExc_TypeError,
Pablo Galindo4b66fa62020-01-05 17:30:53 +0000120 "range expected at most 3 arguments, got %zd",
121 num_args);
Raymond Hettinger94f55832009-06-12 18:40:16 +0000122 return NULL;
Guido van Rossum805365e2007-05-07 22:24:25 +0000123 }
Nick Coghlan37ee8502010-12-03 14:26:13 +0000124 obj = make_range_object(type, start, stop, step);
Petr Viktorin6e35da92020-02-18 16:13:17 +0100125 if (obj != NULL) {
Nick Coghlan37ee8502010-12-03 14:26:13 +0000126 return (PyObject *) obj;
Petr Viktorin6e35da92020-02-18 16:13:17 +0100127 }
Guido van Rossum805365e2007-05-07 22:24:25 +0000128
Nick Coghlan37ee8502010-12-03 14:26:13 +0000129 /* Failed to create object, release attributes */
Serhiy Storchakacfdfbb42016-06-18 09:44:03 +0300130 Py_DECREF(start);
131 Py_DECREF(stop);
132 Py_DECREF(step);
Guido van Rossum805365e2007-05-07 22:24:25 +0000133 return NULL;
Raymond Hettingerc4c453f2002-06-05 23:12:45 +0000134}
135
Petr Viktorin6e35da92020-02-18 16:13:17 +0100136static PyObject *
137range_new(PyTypeObject *type, PyObject *args, PyObject *kw)
138{
139 if (!_PyArg_NoKeywords("range", kw))
140 return NULL;
141
142 return range_from_array(type, _PyTuple_ITEMS(args), PyTuple_GET_SIZE(args));
143}
144
145
146static PyObject *
147range_vectorcall(PyTypeObject *type, PyObject *const *args,
148 size_t nargsf, PyObject *kwnames)
149{
150 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
Dong-hee Na87ec86c2020-03-16 23:06:20 +0900151 if (!_PyArg_NoKwnames("range", kwnames)) {
Petr Viktorin6e35da92020-02-18 16:13:17 +0100152 return NULL;
153 }
154 return range_from_array(type, args, nargs);
155}
156
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000157PyDoc_STRVAR(range_doc,
Chris Jerdonek83fe2e12012-10-07 14:48:36 -0700158"range(stop) -> range object\n\
159range(start, stop[, step]) -> range object\n\
Raymond Hettingerc4c453f2002-06-05 23:12:45 +0000160\n\
Benjamin Petersonac22c6b2015-04-22 09:16:07 -0400161Return an object that produces a sequence of integers from start (inclusive)\n\
162to stop (exclusive) by step. range(i, j) produces i, i+1, i+2, ..., j-1.\n\
163start defaults to 0, and stop is omitted! range(4) produces 0, 1, 2, 3.\n\
164These are exactly the valid indices for a list of 4 elements.\n\
165When step is given, it specifies the increment (or decrement).");
Raymond Hettingerc4c453f2002-06-05 23:12:45 +0000166
Guido van Rossum805365e2007-05-07 22:24:25 +0000167static void
Benjamin Petersona1864f32010-11-20 23:05:39 +0000168range_dealloc(rangeobject *r)
169{
Guido van Rossum805365e2007-05-07 22:24:25 +0000170 Py_DECREF(r->start);
171 Py_DECREF(r->stop);
172 Py_DECREF(r->step);
Nick Coghlan37ee8502010-12-03 14:26:13 +0000173 Py_DECREF(r->length);
Victor Stinner32bd68c2020-12-01 10:37:39 +0100174 PyObject_Free(r);
Guido van Rossum805365e2007-05-07 22:24:25 +0000175}
176
Mark Dickinson732166d2009-06-28 22:08:40 +0000177/* Return number of items in range (lo, hi, step) as a PyLong object,
178 * when arguments are PyLong objects. Arguments MUST return 1 with
179 * PyLong_Check(). Return NULL when there is an error.
Guido van Rossum805365e2007-05-07 22:24:25 +0000180 */
181static PyObject*
Nick Coghlan37ee8502010-12-03 14:26:13 +0000182compute_range_length(PyObject *start, PyObject *stop, PyObject *step)
Benjamin Petersona1864f32010-11-20 23:05:39 +0000183{
Guido van Rossum805365e2007-05-07 22:24:25 +0000184 /* -------------------------------------------------------------
185 Algorithm is equal to that of get_len_of_range(), but it operates
Benjamin Petersona47af9c2009-06-24 21:14:38 +0000186 on PyObjects (which are assumed to be PyLong objects).
Guido van Rossum805365e2007-05-07 22:24:25 +0000187 ---------------------------------------------------------------*/
Mark Dickinson211c6252009-02-01 10:28:51 +0000188 int cmp_result;
Guido van Rossum805365e2007-05-07 22:24:25 +0000189 PyObject *lo, *hi;
Guido van Rossum805365e2007-05-07 22:24:25 +0000190 PyObject *diff = NULL;
Guido van Rossum805365e2007-05-07 22:24:25 +0000191 PyObject *tmp1 = NULL, *tmp2 = NULL, *result;
192 /* holds sub-expression evaluations */
193
Victor Stinnerc9bc2902020-10-27 02:24:34 +0100194 PyObject *zero = _PyLong_GetZero(); // borrowed reference
195 PyObject *one = _PyLong_GetOne(); // borrowed reference
196
197 cmp_result = PyObject_RichCompareBool(step, zero, Py_GT);
Mark Dickinson211c6252009-02-01 10:28:51 +0000198 if (cmp_result == -1)
Guido van Rossum805365e2007-05-07 22:24:25 +0000199 return NULL;
200
Mark Dickinson211c6252009-02-01 10:28:51 +0000201 if (cmp_result == 1) {
Nick Coghlan37ee8502010-12-03 14:26:13 +0000202 lo = start;
203 hi = stop;
Guido van Rossum805365e2007-05-07 22:24:25 +0000204 Py_INCREF(step);
205 } else {
Nick Coghlan37ee8502010-12-03 14:26:13 +0000206 lo = stop;
207 hi = start;
208 step = PyNumber_Negative(step);
Guido van Rossum805365e2007-05-07 22:24:25 +0000209 if (!step)
210 return NULL;
211 }
212
213 /* if (lo >= hi), return length of 0. */
Serhiy Storchakafa494fd2015-05-30 17:45:22 +0300214 cmp_result = PyObject_RichCompareBool(lo, hi, Py_GE);
215 if (cmp_result != 0) {
Serhiy Storchakacfdfbb42016-06-18 09:44:03 +0300216 Py_DECREF(step);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +0300217 if (cmp_result < 0)
218 return NULL;
Victor Stinnerc9bc2902020-10-27 02:24:34 +0100219 result = zero;
220 Py_INCREF(result);
221 return result;
Guido van Rossum805365e2007-05-07 22:24:25 +0000222 }
223
Guido van Rossum805365e2007-05-07 22:24:25 +0000224 if ((tmp1 = PyNumber_Subtract(hi, lo)) == NULL)
225 goto Fail;
226
Victor Stinnerc9bc2902020-10-27 02:24:34 +0100227 if ((diff = PyNumber_Subtract(tmp1, one)) == NULL)
Guido van Rossum805365e2007-05-07 22:24:25 +0000228 goto Fail;
229
230 if ((tmp2 = PyNumber_FloorDivide(diff, step)) == NULL)
231 goto Fail;
232
Victor Stinnerc9bc2902020-10-27 02:24:34 +0100233 if ((result = PyNumber_Add(tmp2, one)) == NULL)
Guido van Rossum805365e2007-05-07 22:24:25 +0000234 goto Fail;
235
236 Py_DECREF(tmp2);
237 Py_DECREF(diff);
238 Py_DECREF(step);
239 Py_DECREF(tmp1);
Guido van Rossum805365e2007-05-07 22:24:25 +0000240 return result;
241
242 Fail:
Serhiy Storchakacfdfbb42016-06-18 09:44:03 +0300243 Py_DECREF(step);
Guido van Rossum805365e2007-05-07 22:24:25 +0000244 Py_XDECREF(tmp2);
245 Py_XDECREF(diff);
Guido van Rossum805365e2007-05-07 22:24:25 +0000246 Py_XDECREF(tmp1);
Guido van Rossum805365e2007-05-07 22:24:25 +0000247 return NULL;
Guido van Rossum12d12c51993-10-26 17:58:25 +0000248}
249
Martin v. Löwis18e16552006-02-15 17:27:45 +0000250static Py_ssize_t
Benjamin Petersona1864f32010-11-20 23:05:39 +0000251range_length(rangeobject *r)
252{
Nick Coghlan37ee8502010-12-03 14:26:13 +0000253 return PyLong_AsSsize_t(r->length);
Guido van Rossum805365e2007-05-07 22:24:25 +0000254}
255
Guido van Rossum805365e2007-05-07 22:24:25 +0000256static PyObject *
Nick Coghlane993b102011-01-12 03:15:52 +0000257compute_item(rangeobject *r, PyObject *i)
Benjamin Petersona1864f32010-11-20 23:05:39 +0000258{
Nick Coghlane993b102011-01-12 03:15:52 +0000259 PyObject *incr, *result;
260 /* PyLong equivalent to:
261 * return r->start + (i * r->step)
262 */
Victor Stinnerc9bc2902020-10-27 02:24:34 +0100263 if (r->step == _PyLong_GetOne()) {
Dong-hee Na25492a52020-10-21 10:29:14 +0900264 result = PyNumber_Add(r->start, i);
265 }
266 else {
267 incr = PyNumber_Multiply(i, r->step);
268 if (!incr) {
269 return NULL;
270 }
271 result = PyNumber_Add(r->start, incr);
272 Py_DECREF(incr);
273 }
Guido van Rossum805365e2007-05-07 22:24:25 +0000274 return result;
Guido van Rossum7d6aa511993-12-21 22:50:31 +0000275}
276
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000277static PyObject *
Nick Coghlane993b102011-01-12 03:15:52 +0000278compute_range_item(rangeobject *r, PyObject *arg)
Benjamin Petersona1864f32010-11-20 23:05:39 +0000279{
Victor Stinnerc9bc2902020-10-27 02:24:34 +0100280 PyObject *zero = _PyLong_GetZero(); // borrowed reference
Nick Coghlane993b102011-01-12 03:15:52 +0000281 int cmp_result;
282 PyObject *i, *result;
Tim Petersd976ab72004-08-08 06:29:10 +0000283
Nick Coghlane993b102011-01-12 03:15:52 +0000284 /* PyLong equivalent to:
285 * if (arg < 0) {
286 * i = r->length + arg
287 * } else {
288 * i = arg
289 * }
290 */
Victor Stinnerc9bc2902020-10-27 02:24:34 +0100291 cmp_result = PyObject_RichCompareBool(arg, zero, Py_LT);
Nick Coghlane993b102011-01-12 03:15:52 +0000292 if (cmp_result == -1) {
Nick Coghlan37ee8502010-12-03 14:26:13 +0000293 return NULL;
Guido van Rossum805365e2007-05-07 22:24:25 +0000294 }
Nick Coghlane993b102011-01-12 03:15:52 +0000295 if (cmp_result == 1) {
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300296 i = PyNumber_Add(r->length, arg);
297 if (!i) {
298 return NULL;
299 }
Nick Coghlane993b102011-01-12 03:15:52 +0000300 } else {
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300301 i = arg;
302 Py_INCREF(i);
Nick Coghlane993b102011-01-12 03:15:52 +0000303 }
304
305 /* PyLong equivalent to:
306 * if (i < 0 || i >= r->length) {
307 * <report index out of bounds>
308 * }
309 */
Victor Stinnerc9bc2902020-10-27 02:24:34 +0100310 cmp_result = PyObject_RichCompareBool(i, zero, Py_LT);
Nick Coghlane993b102011-01-12 03:15:52 +0000311 if (cmp_result == 0) {
312 cmp_result = PyObject_RichCompareBool(i, r->length, Py_GE);
313 }
314 if (cmp_result == -1) {
315 Py_DECREF(i);
316 return NULL;
317 }
318 if (cmp_result == 1) {
319 Py_DECREF(i);
320 PyErr_SetString(PyExc_IndexError,
321 "range object index out of range");
322 return NULL;
323 }
324
325 result = compute_item(r, i);
326 Py_DECREF(i);
327 return result;
328}
329
330static PyObject *
331range_item(rangeobject *r, Py_ssize_t i)
332{
Antoine Pitroua103b962012-05-16 14:37:54 +0200333 PyObject *res, *arg = PyLong_FromSsize_t(i);
Nick Coghlane993b102011-01-12 03:15:52 +0000334 if (!arg) {
335 return NULL;
336 }
Benjamin Peterson547d4852011-01-13 04:22:54 +0000337 res = compute_range_item(r, arg);
338 Py_DECREF(arg);
339 return res;
Nick Coghlane993b102011-01-12 03:15:52 +0000340}
341
Nick Coghlane993b102011-01-12 03:15:52 +0000342static PyObject *
343compute_slice(rangeobject *r, PyObject *_slice)
344{
345 PySliceObject *slice = (PySliceObject *) _slice;
346 rangeobject *result;
347 PyObject *start = NULL, *stop = NULL, *step = NULL;
348 PyObject *substart = NULL, *substop = NULL, *substep = NULL;
Mark Dickinsonffdb2c22012-11-17 19:18:10 +0000349 int error;
Nick Coghlane993b102011-01-12 03:15:52 +0000350
Mark Dickinsonffdb2c22012-11-17 19:18:10 +0000351 error = _PySlice_GetLongIndices(slice, r->length, &start, &stop, &step);
352 if (error == -1)
353 return NULL;
Nick Coghlane993b102011-01-12 03:15:52 +0000354
355 substep = PyNumber_Multiply(r->step, step);
356 if (substep == NULL) goto fail;
357 Py_CLEAR(step);
358
359 substart = compute_item(r, start);
360 if (substart == NULL) goto fail;
361 Py_CLEAR(start);
362
Mark Dickinsonffdb2c22012-11-17 19:18:10 +0000363 substop = compute_item(r, stop);
364 if (substop == NULL) goto fail;
Nick Coghlane993b102011-01-12 03:15:52 +0000365 Py_CLEAR(stop);
366
367 result = make_range_object(Py_TYPE(r), substart, substop, substep);
368 if (result != NULL) {
369 return (PyObject *) result;
370 }
371fail:
372 Py_XDECREF(start);
373 Py_XDECREF(stop);
374 Py_XDECREF(step);
375 Py_XDECREF(substart);
376 Py_XDECREF(substop);
377 Py_XDECREF(substep);
378 return NULL;
Alexandre Vassalotti75056072008-06-10 04:03:04 +0000379}
380
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000381/* Assumes (PyLong_CheckExact(ob) || PyBool_Check(ob)) */
382static int
Benjamin Petersona1864f32010-11-20 23:05:39 +0000383range_contains_long(rangeobject *r, PyObject *ob)
384{
Victor Stinnerc9bc2902020-10-27 02:24:34 +0100385 PyObject *zero = _PyLong_GetZero(); // borrowed reference
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000386 int cmp1, cmp2, cmp3;
387 PyObject *tmp1 = NULL;
388 PyObject *tmp2 = NULL;
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000389 int result = -1;
390
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000391 /* Check if the value can possibly be in the range. */
392
Victor Stinnerc9bc2902020-10-27 02:24:34 +0100393 cmp1 = PyObject_RichCompareBool(r->step, zero, Py_GT);
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000394 if (cmp1 == -1)
395 goto end;
396 if (cmp1 == 1) { /* positive steps: start <= ob < stop */
397 cmp2 = PyObject_RichCompareBool(r->start, ob, Py_LE);
398 cmp3 = PyObject_RichCompareBool(ob, r->stop, Py_LT);
399 }
400 else { /* negative steps: stop < ob <= start */
401 cmp2 = PyObject_RichCompareBool(ob, r->start, Py_LE);
402 cmp3 = PyObject_RichCompareBool(r->stop, ob, Py_LT);
403 }
404
405 if (cmp2 == -1 || cmp3 == -1) /* TypeError */
406 goto end;
407 if (cmp2 == 0 || cmp3 == 0) { /* ob outside of range */
408 result = 0;
409 goto end;
410 }
411
412 /* Check that the stride does not invalidate ob's membership. */
413 tmp1 = PyNumber_Subtract(ob, r->start);
414 if (tmp1 == NULL)
415 goto end;
416 tmp2 = PyNumber_Remainder(tmp1, r->step);
417 if (tmp2 == NULL)
418 goto end;
Berker Peksaged6224e2016-09-12 07:47:04 +0300419 /* result = ((int(ob) - start) % step) == 0 */
Victor Stinnerc9bc2902020-10-27 02:24:34 +0100420 result = PyObject_RichCompareBool(tmp2, zero, Py_EQ);
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000421 end:
422 Py_XDECREF(tmp1);
423 Py_XDECREF(tmp2);
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000424 return result;
425}
426
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000427static int
Benjamin Petersona1864f32010-11-20 23:05:39 +0000428range_contains(rangeobject *r, PyObject *ob)
429{
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000430 if (PyLong_CheckExact(ob) || PyBool_Check(ob))
431 return range_contains_long(r, ob);
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000432
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000433 return (int)_PySequence_IterSearch((PyObject*)r, ob,
434 PY_ITERSEARCH_CONTAINS);
435}
436
Mark Dickinson36645682011-10-23 19:53:01 +0100437/* Compare two range objects. Return 1 for equal, 0 for not equal
438 and -1 on error. The algorithm is roughly the C equivalent of
439
440 if r0 is r1:
441 return True
442 if len(r0) != len(r1):
443 return False
444 if not len(r0):
445 return True
446 if r0.start != r1.start:
447 return False
448 if len(r0) == 1:
449 return True
450 return r0.step == r1.step
451*/
452static int
453range_equals(rangeobject *r0, rangeobject *r1)
454{
455 int cmp_result;
Mark Dickinson36645682011-10-23 19:53:01 +0100456
457 if (r0 == r1)
458 return 1;
459 cmp_result = PyObject_RichCompareBool(r0->length, r1->length, Py_EQ);
460 /* Return False or error to the caller. */
461 if (cmp_result != 1)
462 return cmp_result;
463 cmp_result = PyObject_Not(r0->length);
464 /* Return True or error to the caller. */
465 if (cmp_result != 0)
466 return cmp_result;
467 cmp_result = PyObject_RichCompareBool(r0->start, r1->start, Py_EQ);
468 /* Return False or error to the caller. */
469 if (cmp_result != 1)
470 return cmp_result;
Victor Stinnerc9bc2902020-10-27 02:24:34 +0100471 cmp_result = PyObject_RichCompareBool(r0->length, _PyLong_GetOne(), Py_EQ);
Mark Dickinson36645682011-10-23 19:53:01 +0100472 /* Return True or error to the caller. */
473 if (cmp_result != 0)
474 return cmp_result;
475 return PyObject_RichCompareBool(r0->step, r1->step, Py_EQ);
476}
477
478static PyObject *
479range_richcompare(PyObject *self, PyObject *other, int op)
480{
481 int result;
482
483 if (!PyRange_Check(other))
484 Py_RETURN_NOTIMPLEMENTED;
485 switch (op) {
486 case Py_NE:
487 case Py_EQ:
488 result = range_equals((rangeobject*)self, (rangeobject*)other);
489 if (result == -1)
490 return NULL;
491 if (op == Py_NE)
492 result = !result;
493 if (result)
494 Py_RETURN_TRUE;
495 else
496 Py_RETURN_FALSE;
497 case Py_LE:
498 case Py_GE:
499 case Py_LT:
500 case Py_GT:
501 Py_RETURN_NOTIMPLEMENTED;
502 default:
503 PyErr_BadArgument();
504 return NULL;
505 }
506}
507
508/* Hash function for range objects. Rough C equivalent of
509
510 if not len(r):
511 return hash((len(r), None, None))
512 if len(r) == 1:
513 return hash((len(r), r.start, None))
514 return hash((len(r), r.start, r.step))
515*/
516static Py_hash_t
517range_hash(rangeobject *r)
518{
519 PyObject *t;
520 Py_hash_t result = -1;
521 int cmp_result;
522
523 t = PyTuple_New(3);
524 if (!t)
525 return -1;
526 Py_INCREF(r->length);
527 PyTuple_SET_ITEM(t, 0, r->length);
528 cmp_result = PyObject_Not(r->length);
529 if (cmp_result == -1)
530 goto end;
531 if (cmp_result == 1) {
532 Py_INCREF(Py_None);
533 Py_INCREF(Py_None);
534 PyTuple_SET_ITEM(t, 1, Py_None);
535 PyTuple_SET_ITEM(t, 2, Py_None);
536 }
537 else {
Mark Dickinson36645682011-10-23 19:53:01 +0100538 Py_INCREF(r->start);
539 PyTuple_SET_ITEM(t, 1, r->start);
Victor Stinnerc9bc2902020-10-27 02:24:34 +0100540 cmp_result = PyObject_RichCompareBool(r->length, _PyLong_GetOne(), Py_EQ);
Mark Dickinson36645682011-10-23 19:53:01 +0100541 if (cmp_result == -1)
542 goto end;
543 if (cmp_result == 1) {
544 Py_INCREF(Py_None);
545 PyTuple_SET_ITEM(t, 2, Py_None);
546 }
547 else {
548 Py_INCREF(r->step);
549 PyTuple_SET_ITEM(t, 2, r->step);
550 }
551 }
552 result = PyObject_Hash(t);
553 end:
554 Py_DECREF(t);
555 return result;
556}
557
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000558static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +0000559range_count(rangeobject *r, PyObject *ob)
560{
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000561 if (PyLong_CheckExact(ob) || PyBool_Check(ob)) {
Georg Brandl7e5343b2010-11-20 22:40:10 +0000562 int result = range_contains_long(r, ob);
563 if (result == -1)
564 return NULL;
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300565 return PyLong_FromLong(result);
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000566 } else {
567 Py_ssize_t count;
568 count = _PySequence_IterSearch((PyObject*)r, ob, PY_ITERSEARCH_COUNT);
569 if (count == -1)
570 return NULL;
571 return PyLong_FromSsize_t(count);
572 }
573}
574
575static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +0000576range_index(rangeobject *r, PyObject *ob)
577{
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000578 int contains;
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000579
580 if (!PyLong_CheckExact(ob) && !PyBool_Check(ob)) {
581 Py_ssize_t index;
582 index = _PySequence_IterSearch((PyObject*)r, ob, PY_ITERSEARCH_INDEX);
583 if (index == -1)
584 return NULL;
585 return PyLong_FromSsize_t(index);
586 }
587
588 contains = range_contains_long(r, ob);
589 if (contains == -1)
590 return NULL;
591
Benjamin Peterson155614b2010-11-20 22:44:32 +0000592 if (contains) {
Dong-hee Nac0f22fb2020-10-21 11:29:56 +0900593 PyObject *idx = PyNumber_Subtract(ob, r->start);
594 if (idx == NULL) {
Benjamin Peterson155614b2010-11-20 22:44:32 +0000595 return NULL;
Dong-hee Nac0f22fb2020-10-21 11:29:56 +0900596 }
597
Victor Stinnerc9bc2902020-10-27 02:24:34 +0100598 if (r->step == _PyLong_GetOne()) {
Dong-hee Nac0f22fb2020-10-21 11:29:56 +0900599 return idx;
600 }
601
Benjamin Peterson155614b2010-11-20 22:44:32 +0000602 /* idx = (ob - r.start) // r.step */
Dong-hee Nac0f22fb2020-10-21 11:29:56 +0900603 PyObject *sidx = PyNumber_FloorDivide(idx, r->step);
604 Py_DECREF(idx);
605 return sidx;
Benjamin Peterson155614b2010-11-20 22:44:32 +0000606 }
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000607
608 /* object is not in the range */
Benjamin Peterson155614b2010-11-20 22:44:32 +0000609 PyErr_Format(PyExc_ValueError, "%R is not in range", ob);
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000610 return NULL;
611}
612
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000613static PySequenceMethods range_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000614 (lenfunc)range_length, /* sq_length */
Nick Coghlan37ee8502010-12-03 14:26:13 +0000615 0, /* sq_concat */
616 0, /* sq_repeat */
617 (ssizeargfunc)range_item, /* sq_item */
618 0, /* sq_slice */
619 0, /* sq_ass_item */
620 0, /* sq_ass_slice */
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000621 (objobjproc)range_contains, /* sq_contains */
Guido van Rossum12d12c51993-10-26 17:58:25 +0000622};
623
Nick Coghlan37ee8502010-12-03 14:26:13 +0000624static PyObject *
625range_repr(rangeobject *r)
626{
627 Py_ssize_t istep;
628
629 /* Check for special case values for printing. We don't always
Alexey Izbyshev7ecae3c2018-08-24 07:39:45 +0300630 need the step value. We don't care about overflow. */
Nick Coghlan37ee8502010-12-03 14:26:13 +0000631 istep = PyNumber_AsSsize_t(r->step, NULL);
Alexey Izbyshev7ecae3c2018-08-24 07:39:45 +0300632 if (istep == -1 && PyErr_Occurred()) {
633 assert(!PyErr_ExceptionMatches(PyExc_OverflowError));
634 return NULL;
Nick Coghlan37ee8502010-12-03 14:26:13 +0000635 }
636
637 if (istep == 1)
638 return PyUnicode_FromFormat("range(%R, %R)", r->start, r->stop);
639 else
640 return PyUnicode_FromFormat("range(%R, %R, %R)",
641 r->start, r->stop, r->step);
642}
643
644/* Pickling support */
645static PyObject *
646range_reduce(rangeobject *r, PyObject *args)
647{
648 return Py_BuildValue("(O(OOO))", Py_TYPE(r),
649 r->start, r->stop, r->step);
650}
651
652static PyObject *
653range_subscript(rangeobject* self, PyObject* item)
654{
Victor Stinnera15e2602020-04-08 02:01:56 +0200655 if (_PyIndex_Check(item)) {
Nick Coghlane993b102011-01-12 03:15:52 +0000656 PyObject *i, *result;
657 i = PyNumber_Index(item);
658 if (!i)
Nick Coghlan37ee8502010-12-03 14:26:13 +0000659 return NULL;
Nick Coghlane993b102011-01-12 03:15:52 +0000660 result = compute_range_item(self, i);
661 Py_DECREF(i);
662 return result;
Nick Coghlan37ee8502010-12-03 14:26:13 +0000663 }
664 if (PySlice_Check(item)) {
Nick Coghlane993b102011-01-12 03:15:52 +0000665 return compute_slice(self, item);
Nick Coghlan37ee8502010-12-03 14:26:13 +0000666 }
667 PyErr_Format(PyExc_TypeError,
668 "range indices must be integers or slices, not %.200s",
Victor Stinner58ac7002020-02-07 03:04:21 +0100669 Py_TYPE(item)->tp_name);
Nick Coghlan37ee8502010-12-03 14:26:13 +0000670 return NULL;
671}
672
673
674static PyMappingMethods range_as_mapping = {
675 (lenfunc)range_length, /* mp_length */
676 (binaryfunc)range_subscript, /* mp_subscript */
677 (objobjargproc)0, /* mp_ass_subscript */
678};
679
4kir4e46fb862017-03-20 09:44:46 +0300680static int
681range_bool(rangeobject* self)
682{
683 return PyObject_IsTrue(self->length);
684}
685
686static PyNumberMethods range_as_number = {
687 .nb_bool = (inquiry)range_bool,
688};
689
Jeremy Hylton938ace62002-07-17 16:30:39 +0000690static PyObject * range_iter(PyObject *seq);
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530691static PyObject * range_reverse(PyObject *seq, PyObject *Py_UNUSED(ignored));
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000692
693PyDoc_STRVAR(reverse_doc,
Ezio Melotti5792ce12013-10-06 00:36:45 +0300694"Return a reverse iterator.");
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000695
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000696PyDoc_STRVAR(count_doc,
697"rangeobject.count(value) -> integer -- return number of occurrences of value");
698
699PyDoc_STRVAR(index_doc,
Srinivas Reddy Thatiparthy (శ్రీనివాస్ రెడ్డి తాటిపర్తి)22c52632019-05-03 17:52:12 +0530700"rangeobject.index(value) -> integer -- return index of value.\n"
Ezio Melotti5792ce12013-10-06 00:36:45 +0300701"Raise ValueError if the value is not present.");
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000702
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000703static PyMethodDef range_methods[] = {
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530704 {"__reversed__", range_reverse, METH_NOARGS, reverse_doc},
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000705 {"__reduce__", (PyCFunction)range_reduce, METH_VARARGS},
706 {"count", (PyCFunction)range_count, METH_O, count_doc},
707 {"index", (PyCFunction)range_index, METH_O, index_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000708 {NULL, NULL} /* sentinel */
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000709};
Raymond Hettinger48165d42002-06-05 20:08:48 +0000710
Benjamin Peterson878ce382011-11-05 15:17:52 -0400711static PyMemberDef range_members[] = {
712 {"start", T_OBJECT_EX, offsetof(rangeobject, start), READONLY},
713 {"stop", T_OBJECT_EX, offsetof(rangeobject, stop), READONLY},
714 {"step", T_OBJECT_EX, offsetof(rangeobject, step), READONLY},
715 {0}
716};
717
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000718PyTypeObject PyRange_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000719 PyVarObject_HEAD_INIT(&PyType_Type, 0)
720 "range", /* Name of this type */
721 sizeof(rangeobject), /* Basic object size */
722 0, /* Item size for varobject */
723 (destructor)range_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200724 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000725 0, /* tp_getattr */
726 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200727 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000728 (reprfunc)range_repr, /* tp_repr */
4kir4e46fb862017-03-20 09:44:46 +0300729 &range_as_number, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000730 &range_as_sequence, /* tp_as_sequence */
Nick Coghlan37ee8502010-12-03 14:26:13 +0000731 &range_as_mapping, /* tp_as_mapping */
Mark Dickinson36645682011-10-23 19:53:01 +0100732 (hashfunc)range_hash, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000733 0, /* tp_call */
734 0, /* tp_str */
735 PyObject_GenericGetAttr, /* tp_getattro */
736 0, /* tp_setattro */
737 0, /* tp_as_buffer */
Mark Shannon069e81a2021-04-30 09:50:28 +0100738 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_SEQUENCE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000739 range_doc, /* tp_doc */
740 0, /* tp_traverse */
741 0, /* tp_clear */
Mark Dickinson36645682011-10-23 19:53:01 +0100742 range_richcompare, /* tp_richcompare */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000743 0, /* tp_weaklistoffset */
744 range_iter, /* tp_iter */
745 0, /* tp_iternext */
746 range_methods, /* tp_methods */
Benjamin Peterson878ce382011-11-05 15:17:52 -0400747 range_members, /* tp_members */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000748 0, /* tp_getset */
749 0, /* tp_base */
750 0, /* tp_dict */
751 0, /* tp_descr_get */
752 0, /* tp_descr_set */
753 0, /* tp_dictoffset */
754 0, /* tp_init */
755 0, /* tp_alloc */
756 range_new, /* tp_new */
Petr Viktorin6e35da92020-02-18 16:13:17 +0100757 .tp_vectorcall = (vectorcallfunc)range_vectorcall
Guido van Rossum12d12c51993-10-26 17:58:25 +0000758};
Raymond Hettinger48165d42002-06-05 20:08:48 +0000759
Walter Dörwald4ad94212007-05-21 18:01:17 +0000760/*********************** range Iterator **************************/
Raymond Hettinger48165d42002-06-05 20:08:48 +0000761
Guido van Rossum805365e2007-05-07 22:24:25 +0000762/* There are 2 types of iterators, one for C longs, the other for
Serhiy Storchaka95949422013-08-27 19:40:23 +0300763 Python ints (ie, PyObjects). This should make iteration fast
Guido van Rossum805365e2007-05-07 22:24:25 +0000764 in the normal case, but possible for any numeric value.
765*/
766
Raymond Hettinger48165d42002-06-05 20:08:48 +0000767typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000768 PyObject_HEAD
769 long index;
770 long start;
771 long step;
772 long len;
Raymond Hettinger48165d42002-06-05 20:08:48 +0000773} rangeiterobject;
774
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000775static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +0000776rangeiter_next(rangeiterobject *r)
777{
Guido van Rossum805365e2007-05-07 22:24:25 +0000778 if (r->index < r->len)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000779 /* cast to unsigned to avoid possible signed overflow
Mark Dickinsonb43dbc22009-11-15 12:56:08 +0000780 in intermediate calculations. */
781 return PyLong_FromLong((long)(r->start +
782 (unsigned long)(r->index++) * r->step));
Guido van Rossum805365e2007-05-07 22:24:25 +0000783 return NULL;
Raymond Hettinger48165d42002-06-05 20:08:48 +0000784}
785
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000786static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530787rangeiter_len(rangeiterobject *r, PyObject *Py_UNUSED(ignored))
Benjamin Petersona1864f32010-11-20 23:05:39 +0000788{
Christian Heimes217cfd12007-12-02 14:31:20 +0000789 return PyLong_FromLong(r->len - r->index);
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000790}
791
Guido van Rossum805365e2007-05-07 22:24:25 +0000792PyDoc_STRVAR(length_hint_doc,
793 "Private method returning an estimate of len(list(it)).");
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000794
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000795static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530796rangeiter_reduce(rangeiterobject *r, PyObject *Py_UNUSED(ignored))
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000797{
798 PyObject *start=NULL, *stop=NULL, *step=NULL;
799 PyObject *range;
Chris Jerdonek042fa652012-10-07 14:56:27 -0700800
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000801 /* create a range object for pickling */
802 start = PyLong_FromLong(r->start);
803 if (start == NULL)
804 goto err;
805 stop = PyLong_FromLong(r->start + r->len * r->step);
806 if (stop == NULL)
807 goto err;
808 step = PyLong_FromLong(r->step);
809 if (step == NULL)
810 goto err;
811 range = (PyObject*)make_range_object(&PyRange_Type,
812 start, stop, step);
813 if (range == NULL)
814 goto err;
815 /* return the result */
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200816 return Py_BuildValue("N(N)i", _PyEval_GetBuiltinId(&PyId_iter),
817 range, r->index);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000818err:
819 Py_XDECREF(start);
820 Py_XDECREF(stop);
821 Py_XDECREF(step);
822 return NULL;
823}
824
825static PyObject *
826rangeiter_setstate(rangeiterobject *r, PyObject *state)
827{
828 long index = PyLong_AsLong(state);
829 if (index == -1 && PyErr_Occurred())
830 return NULL;
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +0000831 /* silently clip the index value */
832 if (index < 0)
833 index = 0;
834 else if (index > r->len)
835 index = r->len; /* exhausted iterator */
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000836 r->index = index;
837 Py_RETURN_NONE;
838}
839
840PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
841PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
842
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000843static PyMethodDef rangeiter_methods[] = {
Guido van Rossum805365e2007-05-07 22:24:25 +0000844 {"__length_hint__", (PyCFunction)rangeiter_len, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000845 length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000846 {"__reduce__", (PyCFunction)rangeiter_reduce, METH_NOARGS,
847 reduce_doc},
848 {"__setstate__", (PyCFunction)rangeiter_setstate, METH_O,
849 setstate_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000850 {NULL, NULL} /* sentinel */
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000851};
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000852
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000853PyTypeObject PyRangeIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000854 PyVarObject_HEAD_INIT(&PyType_Type, 0)
855 "range_iterator", /* tp_name */
856 sizeof(rangeiterobject), /* tp_basicsize */
857 0, /* tp_itemsize */
858 /* methods */
859 (destructor)PyObject_Del, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200860 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000861 0, /* tp_getattr */
862 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200863 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000864 0, /* tp_repr */
865 0, /* tp_as_number */
866 0, /* tp_as_sequence */
867 0, /* tp_as_mapping */
868 0, /* tp_hash */
869 0, /* tp_call */
870 0, /* tp_str */
871 PyObject_GenericGetAttr, /* tp_getattro */
872 0, /* tp_setattro */
873 0, /* tp_as_buffer */
874 Py_TPFLAGS_DEFAULT, /* tp_flags */
875 0, /* tp_doc */
876 0, /* tp_traverse */
877 0, /* tp_clear */
878 0, /* tp_richcompare */
879 0, /* tp_weaklistoffset */
880 PyObject_SelfIter, /* tp_iter */
881 (iternextfunc)rangeiter_next, /* tp_iternext */
882 rangeiter_methods, /* tp_methods */
883 0, /* tp_members */
Guido van Rossum805365e2007-05-07 22:24:25 +0000884};
885
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000886/* Return number of items in range (lo, hi, step). step != 0
887 * required. The result always fits in an unsigned long.
Guido van Rossum805365e2007-05-07 22:24:25 +0000888 */
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000889static unsigned long
Benjamin Petersona1864f32010-11-20 23:05:39 +0000890get_len_of_range(long lo, long hi, long step)
891{
Guido van Rossum805365e2007-05-07 22:24:25 +0000892 /* -------------------------------------------------------------
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000893 If step > 0 and lo >= hi, or step < 0 and lo <= hi, the range is empty.
894 Else for step > 0, if n values are in the range, the last one is
Guido van Rossum805365e2007-05-07 22:24:25 +0000895 lo + (n-1)*step, which must be <= hi-1. Rearranging,
896 n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives
897 the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so
898 the RHS is non-negative and so truncation is the same as the
899 floor. Letting M be the largest positive long, the worst case
900 for the RHS numerator is hi=M, lo=-M-1, and then
901 hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000902 precision to compute the RHS exactly. The analysis for step < 0
903 is similar.
Guido van Rossum805365e2007-05-07 22:24:25 +0000904 ---------------------------------------------------------------*/
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000905 assert(step != 0);
906 if (step > 0 && lo < hi)
907 return 1UL + (hi - 1UL - lo) / step;
908 else if (step < 0 && lo > hi)
909 return 1UL + (lo - 1UL - hi) / (0UL - step);
910 else
911 return 0UL;
Guido van Rossum805365e2007-05-07 22:24:25 +0000912}
913
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000914/* Initialize a rangeiter object. If the length of the rangeiter object
915 is not representable as a C long, OverflowError is raised. */
916
Guido van Rossum805365e2007-05-07 22:24:25 +0000917static PyObject *
Nick Coghlan37ee8502010-12-03 14:26:13 +0000918fast_range_iter(long start, long stop, long step)
Benjamin Petersona1864f32010-11-20 23:05:39 +0000919{
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000920 rangeiterobject *it = PyObject_New(rangeiterobject, &PyRangeIter_Type);
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000921 unsigned long ulen;
Guido van Rossum805365e2007-05-07 22:24:25 +0000922 if (it == NULL)
923 return NULL;
924 it->start = start;
925 it->step = step;
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000926 ulen = get_len_of_range(start, stop, step);
927 if (ulen > (unsigned long)LONG_MAX) {
Benjamin Peterson36fbb732009-11-16 00:34:25 +0000928 Py_DECREF(it);
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000929 PyErr_SetString(PyExc_OverflowError,
930 "range too large to represent as a range_iterator");
931 return NULL;
932 }
933 it->len = (long)ulen;
Guido van Rossum805365e2007-05-07 22:24:25 +0000934 it->index = 0;
935 return (PyObject *)it;
936}
937
Nick Coghlan37ee8502010-12-03 14:26:13 +0000938typedef struct {
939 PyObject_HEAD
940 PyObject *index;
941 PyObject *start;
942 PyObject *step;
943 PyObject *len;
944} longrangeiterobject;
945
946static PyObject *
947longrangeiter_len(longrangeiterobject *r, PyObject *no_args)
948{
949 return PyNumber_Subtract(r->len, r->index);
Guido van Rossum805365e2007-05-07 22:24:25 +0000950}
951
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000952static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530953longrangeiter_reduce(longrangeiterobject *r, PyObject *Py_UNUSED(ignored))
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000954{
955 PyObject *product, *stop=NULL;
956 PyObject *range;
957
958 /* create a range object for pickling. Must calculate the "stop" value */
959 product = PyNumber_Multiply(r->len, r->step);
960 if (product == NULL)
961 return NULL;
962 stop = PyNumber_Add(r->start, product);
963 Py_DECREF(product);
964 if (stop == NULL)
965 return NULL;
966 Py_INCREF(r->start);
967 Py_INCREF(r->step);
968 range = (PyObject*)make_range_object(&PyRange_Type,
969 r->start, stop, r->step);
970 if (range == NULL) {
971 Py_DECREF(r->start);
972 Py_DECREF(stop);
973 Py_DECREF(r->step);
974 return NULL;
975 }
976
977 /* return the result */
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200978 return Py_BuildValue("N(N)O", _PyEval_GetBuiltinId(&PyId_iter),
979 range, r->index);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000980}
981
982static PyObject *
983longrangeiter_setstate(longrangeiterobject *r, PyObject *state)
984{
Victor Stinnerc9bc2902020-10-27 02:24:34 +0100985 PyObject *zero = _PyLong_GetZero(); // borrowed reference
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +0000986 int cmp;
Serhiy Storchaka009b8112015-03-18 21:53:15 +0200987
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +0000988 /* clip the value */
Victor Stinnerc9bc2902020-10-27 02:24:34 +0100989 cmp = PyObject_RichCompareBool(state, zero, Py_LT);
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300990 if (cmp < 0)
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +0000991 return NULL;
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +0000992 if (cmp > 0) {
Victor Stinnerc9bc2902020-10-27 02:24:34 +0100993 state = zero;
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +0000994 }
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300995 else {
996 cmp = PyObject_RichCompareBool(r->len, state, Py_LT);
997 if (cmp < 0)
998 return NULL;
999 if (cmp > 0)
1000 state = r->len;
1001 }
Serhiy Storchaka4a1e70f2015-12-27 12:36:18 +02001002 Py_INCREF(state);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001003 Py_XSETREF(r->index, state);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00001004 Py_RETURN_NONE;
1005}
1006
Guido van Rossum805365e2007-05-07 22:24:25 +00001007static PyMethodDef longrangeiter_methods[] = {
1008 {"__length_hint__", (PyCFunction)longrangeiter_len, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001009 length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00001010 {"__reduce__", (PyCFunction)longrangeiter_reduce, METH_NOARGS,
1011 reduce_doc},
1012 {"__setstate__", (PyCFunction)longrangeiter_setstate, METH_O,
1013 setstate_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001014 {NULL, NULL} /* sentinel */
Guido van Rossum805365e2007-05-07 22:24:25 +00001015};
1016
1017static void
Benjamin Petersona1864f32010-11-20 23:05:39 +00001018longrangeiter_dealloc(longrangeiterobject *r)
1019{
Guido van Rossum805365e2007-05-07 22:24:25 +00001020 Py_XDECREF(r->index);
Guido van Rossum317e7742007-05-08 15:18:31 +00001021 Py_XDECREF(r->start);
1022 Py_XDECREF(r->step);
1023 Py_XDECREF(r->len);
Victor Stinner32bd68c2020-12-01 10:37:39 +01001024 PyObject_Free(r);
Guido van Rossum805365e2007-05-07 22:24:25 +00001025}
1026
1027static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +00001028longrangeiter_next(longrangeiterobject *r)
1029{
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001030 PyObject *product, *new_index, *result;
Guido van Rossum805365e2007-05-07 22:24:25 +00001031 if (PyObject_RichCompareBool(r->index, r->len, Py_LT) != 1)
1032 return NULL;
1033
Victor Stinnerc9bc2902020-10-27 02:24:34 +01001034 new_index = PyNumber_Add(r->index, _PyLong_GetOne());
Benjamin Peterson36fbb732009-11-16 00:34:25 +00001035 if (!new_index)
1036 return NULL;
1037
1038 product = PyNumber_Multiply(r->index, r->step);
1039 if (!product) {
1040 Py_DECREF(new_index);
Guido van Rossum805365e2007-05-07 22:24:25 +00001041 return NULL;
1042 }
1043
1044 result = PyNumber_Add(r->start, product);
1045 Py_DECREF(product);
1046 if (result) {
Serhiy Storchaka57a01d32016-04-10 18:05:40 +03001047 Py_SETREF(r->index, new_index);
Guido van Rossum805365e2007-05-07 22:24:25 +00001048 }
Benjamin Peterson36fbb732009-11-16 00:34:25 +00001049 else {
1050 Py_DECREF(new_index);
1051 }
Guido van Rossum805365e2007-05-07 22:24:25 +00001052
1053 return result;
1054}
1055
Christian Heimesa22e8bd2007-11-29 22:35:39 +00001056PyTypeObject PyLongRangeIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001057 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1058 "longrange_iterator", /* tp_name */
1059 sizeof(longrangeiterobject), /* tp_basicsize */
1060 0, /* tp_itemsize */
1061 /* methods */
1062 (destructor)longrangeiter_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001063 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001064 0, /* tp_getattr */
1065 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001066 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001067 0, /* tp_repr */
1068 0, /* tp_as_number */
1069 0, /* tp_as_sequence */
1070 0, /* tp_as_mapping */
1071 0, /* tp_hash */
1072 0, /* tp_call */
1073 0, /* tp_str */
1074 PyObject_GenericGetAttr, /* tp_getattro */
1075 0, /* tp_setattro */
1076 0, /* tp_as_buffer */
1077 Py_TPFLAGS_DEFAULT, /* tp_flags */
1078 0, /* tp_doc */
1079 0, /* tp_traverse */
1080 0, /* tp_clear */
1081 0, /* tp_richcompare */
1082 0, /* tp_weaklistoffset */
1083 PyObject_SelfIter, /* tp_iter */
1084 (iternextfunc)longrangeiter_next, /* tp_iternext */
1085 longrangeiter_methods, /* tp_methods */
1086 0,
Raymond Hettinger48165d42002-06-05 20:08:48 +00001087};
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001088
1089static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +00001090range_iter(PyObject *seq)
1091{
Guido van Rossum805365e2007-05-07 22:24:25 +00001092 rangeobject *r = (rangeobject *)seq;
1093 longrangeiterobject *it;
Martin v. Löwis84451042007-12-20 22:57:23 +00001094 long lstart, lstop, lstep;
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001095 PyObject *int_it;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001096
Guido van Rossum805365e2007-05-07 22:24:25 +00001097 assert(PyRange_Check(seq));
Martin v. Löwis84451042007-12-20 22:57:23 +00001098
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001099 /* If all three fields and the length convert to long, use the int
1100 * version */
Martin v. Löwis84451042007-12-20 22:57:23 +00001101 lstart = PyLong_AsLong(r->start);
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001102 if (lstart == -1 && PyErr_Occurred()) {
1103 PyErr_Clear();
1104 goto long_range;
Martin v. Löwis84451042007-12-20 22:57:23 +00001105 }
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001106 lstop = PyLong_AsLong(r->stop);
1107 if (lstop == -1 && PyErr_Occurred()) {
1108 PyErr_Clear();
1109 goto long_range;
1110 }
1111 lstep = PyLong_AsLong(r->step);
1112 if (lstep == -1 && PyErr_Occurred()) {
1113 PyErr_Clear();
1114 goto long_range;
1115 }
Nick Coghlan37ee8502010-12-03 14:26:13 +00001116 int_it = fast_range_iter(lstart, lstop, lstep);
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001117 if (int_it == NULL && PyErr_ExceptionMatches(PyExc_OverflowError)) {
1118 PyErr_Clear();
1119 goto long_range;
1120 }
1121 return (PyObject *)int_it;
1122
1123 long_range:
Christian Heimesa22e8bd2007-11-29 22:35:39 +00001124 it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
Guido van Rossum805365e2007-05-07 22:24:25 +00001125 if (it == NULL)
1126 return NULL;
Guido van Rossum317e7742007-05-08 15:18:31 +00001127
Guido van Rossum805365e2007-05-07 22:24:25 +00001128 it->start = r->start;
Guido van Rossum317e7742007-05-08 15:18:31 +00001129 it->step = r->step;
Nick Coghlan37ee8502010-12-03 14:26:13 +00001130 it->len = r->length;
Victor Stinnerc9bc2902020-10-27 02:24:34 +01001131 it->index = _PyLong_GetZero();
Guido van Rossum317e7742007-05-08 15:18:31 +00001132 Py_INCREF(it->start);
1133 Py_INCREF(it->step);
Nick Coghlan37ee8502010-12-03 14:26:13 +00001134 Py_INCREF(it->len);
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001135 Py_INCREF(it->index);
Guido van Rossum805365e2007-05-07 22:24:25 +00001136 return (PyObject *)it;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001137}
1138
1139static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301140range_reverse(PyObject *seq, PyObject *Py_UNUSED(ignored))
Benjamin Petersona1864f32010-11-20 23:05:39 +00001141{
Guido van Rossum805365e2007-05-07 22:24:25 +00001142 rangeobject *range = (rangeobject*) seq;
1143 longrangeiterobject *it;
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001144 PyObject *sum, *diff, *product;
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001145 long lstart, lstop, lstep, new_start, new_stop;
1146 unsigned long ulen;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001147
Guido van Rossum805365e2007-05-07 22:24:25 +00001148 assert(PyRange_Check(seq));
Martin v. Löwis84451042007-12-20 22:57:23 +00001149
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001150 /* reversed(range(start, stop, step)) can be expressed as
1151 range(start+(n-1)*step, start-step, -step), where n is the number of
1152 integers in the range.
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001153
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001154 If each of start, stop, step, -step, start-step, and the length
1155 of the iterator is representable as a C long, use the int
1156 version. This excludes some cases where the reversed range is
1157 representable as a range_iterator, but it's good enough for
1158 common cases and it makes the checks simple. */
1159
1160 lstart = PyLong_AsLong(range->start);
1161 if (lstart == -1 && PyErr_Occurred()) {
1162 PyErr_Clear();
1163 goto long_range;
1164 }
1165 lstop = PyLong_AsLong(range->stop);
1166 if (lstop == -1 && PyErr_Occurred()) {
1167 PyErr_Clear();
1168 goto long_range;
1169 }
1170 lstep = PyLong_AsLong(range->step);
1171 if (lstep == -1 && PyErr_Occurred()) {
1172 PyErr_Clear();
1173 goto long_range;
1174 }
1175 /* check for possible overflow of -lstep */
1176 if (lstep == LONG_MIN)
1177 goto long_range;
1178
1179 /* check for overflow of lstart - lstep:
1180
1181 for lstep > 0, need only check whether lstart - lstep < LONG_MIN.
1182 for lstep < 0, need only check whether lstart - lstep > LONG_MAX
1183
1184 Rearrange these inequalities as:
1185
1186 lstart - LONG_MIN < lstep (lstep > 0)
1187 LONG_MAX - lstart < -lstep (lstep < 0)
1188
1189 and compute both sides as unsigned longs, to avoid the
1190 possibility of undefined behaviour due to signed overflow. */
1191
1192 if (lstep > 0) {
1193 if ((unsigned long)lstart - LONG_MIN < (unsigned long)lstep)
1194 goto long_range;
1195 }
1196 else {
1197 if (LONG_MAX - (unsigned long)lstart < 0UL - lstep)
1198 goto long_range;
1199 }
1200
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001201 ulen = get_len_of_range(lstart, lstop, lstep);
1202 if (ulen > (unsigned long)LONG_MAX)
1203 goto long_range;
1204
1205 new_stop = lstart - lstep;
1206 new_start = (long)(new_stop + ulen * lstep);
Nick Coghlan37ee8502010-12-03 14:26:13 +00001207 return fast_range_iter(new_start, new_stop, -lstep);
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001208
1209long_range:
Christian Heimesa22e8bd2007-11-29 22:35:39 +00001210 it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
Guido van Rossum805365e2007-05-07 22:24:25 +00001211 if (it == NULL)
1212 return NULL;
Zackery Spytzc9a61682018-10-31 03:13:16 -06001213 it->index = it->start = it->step = NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001214
Guido van Rossum805365e2007-05-07 22:24:25 +00001215 /* start + (len - 1) * step */
Nick Coghlan37ee8502010-12-03 14:26:13 +00001216 it->len = range->length;
1217 Py_INCREF(it->len);
Benjamin Peterson36fbb732009-11-16 00:34:25 +00001218
Victor Stinnerc9bc2902020-10-27 02:24:34 +01001219 diff = PyNumber_Subtract(it->len, _PyLong_GetOne());
Guido van Rossum805365e2007-05-07 22:24:25 +00001220 if (!diff)
1221 goto create_failure;
1222
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001223 product = PyNumber_Multiply(diff, range->step);
1224 Py_DECREF(diff);
Guido van Rossum805365e2007-05-07 22:24:25 +00001225 if (!product)
1226 goto create_failure;
1227
1228 sum = PyNumber_Add(range->start, product);
1229 Py_DECREF(product);
1230 it->start = sum;
1231 if (!it->start)
1232 goto create_failure;
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001233
Guido van Rossum805365e2007-05-07 22:24:25 +00001234 it->step = PyNumber_Negative(range->step);
Benjamin Peterson36fbb732009-11-16 00:34:25 +00001235 if (!it->step)
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001236 goto create_failure;
Guido van Rossum805365e2007-05-07 22:24:25 +00001237
Victor Stinnerc9bc2902020-10-27 02:24:34 +01001238 it->index = _PyLong_GetZero();
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001239 Py_INCREF(it->index);
Guido van Rossum805365e2007-05-07 22:24:25 +00001240 return (PyObject *)it;
1241
1242create_failure:
Benjamin Peterson36fbb732009-11-16 00:34:25 +00001243 Py_DECREF(it);
Guido van Rossum805365e2007-05-07 22:24:25 +00001244 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001245}