blob: c1e9e5430303b6bdb136af4802a7f9f2e7162364 [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"
Thomas Woutersefafcea2001-07-09 12:30:54 +00004
Guido van Rossum805365e2007-05-07 22:24:25 +00005/* Support objects whose length is > PY_SSIZE_T_MAX.
6
7 This could be sped up for small PyLongs if they fit in an Py_ssize_t.
8 This only matters on Win64. Though we could use PY_LONG_LONG which
9 would presumably help perf.
10*/
11
Guido van Rossum12d12c51993-10-26 17:58:25 +000012typedef struct {
Guido van Rossum805365e2007-05-07 22:24:25 +000013 PyObject_HEAD
14 PyObject *start;
15 PyObject *stop;
16 PyObject *step;
Nick Coghlan37ee8502010-12-03 14:26:13 +000017 PyObject *length;
Guido van Rossum12d12c51993-10-26 17:58:25 +000018} rangeobject;
19
Guido van Rossum805365e2007-05-07 22:24:25 +000020/* Helper function for validating step. Always returns a new reference or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000021 NULL on error.
Guido van Rossum805365e2007-05-07 22:24:25 +000022*/
23static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +000024validate_step(PyObject *step)
25{
Guido van Rossum805365e2007-05-07 22:24:25 +000026 /* No step specified, use a step of 1. */
27 if (!step)
Christian Heimes217cfd12007-12-02 14:31:20 +000028 return PyLong_FromLong(1);
Guido van Rossum805365e2007-05-07 22:24:25 +000029
30 step = PyNumber_Index(step);
31 if (step) {
32 Py_ssize_t istep = PyNumber_AsSsize_t(step, NULL);
33 if (istep == -1 && PyErr_Occurred()) {
34 /* Ignore OverflowError, we know the value isn't 0. */
35 PyErr_Clear();
36 }
37 else if (istep == 0) {
38 PyErr_SetString(PyExc_ValueError,
39 "range() arg 3 must not be zero");
40 Py_CLEAR(step);
41 }
42 }
43
44 return step;
Raymond Hettingerc4c453f2002-06-05 23:12:45 +000045}
46
Nick Coghlan37ee8502010-12-03 14:26:13 +000047static PyObject *
48compute_range_length(PyObject *start, PyObject *stop, PyObject *step);
49
50static rangeobject *
51make_range_object(PyTypeObject *type, PyObject *start,
52 PyObject *stop, PyObject *step)
53{
54 rangeobject *obj = NULL;
55 PyObject *length;
56 length = compute_range_length(start, stop, step);
57 if (length == NULL) {
58 return NULL;
59 }
60 obj = PyObject_New(rangeobject, type);
61 if (obj == NULL) {
62 Py_DECREF(length);
63 return NULL;
64 }
65 obj->start = start;
66 obj->stop = stop;
67 obj->step = step;
68 obj->length = length;
69 return obj;
70}
71
Guido van Rossum805365e2007-05-07 22:24:25 +000072/* XXX(nnorwitz): should we error check if the user passes any empty ranges?
73 range(-10)
74 range(0, -5)
75 range(0, 5, -1)
76*/
Raymond Hettingerc4c453f2002-06-05 23:12:45 +000077static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +000078range_new(PyTypeObject *type, PyObject *args, PyObject *kw)
79{
Nick Coghlan37ee8502010-12-03 14:26:13 +000080 rangeobject *obj;
Guido van Rossum805365e2007-05-07 22:24:25 +000081 PyObject *start = NULL, *stop = NULL, *step = NULL;
Raymond Hettingerc4c453f2002-06-05 23:12:45 +000082
Guido van Rossum805365e2007-05-07 22:24:25 +000083 if (!_PyArg_NoKeywords("range()", kw))
84 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +000085
Guido van Rossum805365e2007-05-07 22:24:25 +000086 if (PyTuple_Size(args) <= 1) {
87 if (!PyArg_UnpackTuple(args, "range", 1, 1, &stop))
Raymond Hettinger94f55832009-06-12 18:40:16 +000088 return NULL;
Guido van Rossum805365e2007-05-07 22:24:25 +000089 stop = PyNumber_Index(stop);
90 if (!stop)
Raymond Hettinger94f55832009-06-12 18:40:16 +000091 return NULL;
Christian Heimes217cfd12007-12-02 14:31:20 +000092 start = PyLong_FromLong(0);
Raymond Hettinger94f55832009-06-12 18:40:16 +000093 if (!start) {
94 Py_DECREF(stop);
95 return NULL;
96 }
Christian Heimes217cfd12007-12-02 14:31:20 +000097 step = PyLong_FromLong(1);
Raymond Hettinger94f55832009-06-12 18:40:16 +000098 if (!step) {
99 Py_DECREF(stop);
100 Py_DECREF(start);
101 return NULL;
102 }
Guido van Rossum805365e2007-05-07 22:24:25 +0000103 }
104 else {
105 if (!PyArg_UnpackTuple(args, "range", 2, 3,
106 &start, &stop, &step))
Raymond Hettinger94f55832009-06-12 18:40:16 +0000107 return NULL;
Tim Petersfeec4532004-08-08 07:17:39 +0000108
Guido van Rossum805365e2007-05-07 22:24:25 +0000109 /* Convert borrowed refs to owned refs */
110 start = PyNumber_Index(start);
Raymond Hettinger94f55832009-06-12 18:40:16 +0000111 if (!start)
112 return NULL;
Guido van Rossum805365e2007-05-07 22:24:25 +0000113 stop = PyNumber_Index(stop);
Raymond Hettinger94f55832009-06-12 18:40:16 +0000114 if (!stop) {
115 Py_DECREF(start);
116 return NULL;
117 }
118 step = validate_step(step); /* Caution, this can clear exceptions */
119 if (!step) {
120 Py_DECREF(start);
121 Py_DECREF(stop);
122 return NULL;
123 }
Guido van Rossum805365e2007-05-07 22:24:25 +0000124 }
125
Nick Coghlan37ee8502010-12-03 14:26:13 +0000126 obj = make_range_object(type, start, stop, step);
127 if (obj != NULL)
128 return (PyObject *) obj;
Guido van Rossum805365e2007-05-07 22:24:25 +0000129
Nick Coghlan37ee8502010-12-03 14:26:13 +0000130 /* Failed to create object, release attributes */
Guido van Rossum805365e2007-05-07 22:24:25 +0000131 Py_XDECREF(start);
132 Py_XDECREF(stop);
133 Py_XDECREF(step);
134 return NULL;
Raymond Hettingerc4c453f2002-06-05 23:12:45 +0000135}
136
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000137PyDoc_STRVAR(range_doc,
Guido van Rossum805365e2007-05-07 22:24:25 +0000138"range([start,] stop[, step]) -> range object\n\
Raymond Hettingerc4c453f2002-06-05 23:12:45 +0000139\n\
Nick Coghlan37ee8502010-12-03 14:26:13 +0000140Returns a virtual sequence of numbers from start to stop by step.");
Raymond Hettingerc4c453f2002-06-05 23:12:45 +0000141
Guido van Rossum805365e2007-05-07 22:24:25 +0000142static void
Benjamin Petersona1864f32010-11-20 23:05:39 +0000143range_dealloc(rangeobject *r)
144{
Guido van Rossum805365e2007-05-07 22:24:25 +0000145 Py_DECREF(r->start);
146 Py_DECREF(r->stop);
147 Py_DECREF(r->step);
Nick Coghlan37ee8502010-12-03 14:26:13 +0000148 Py_DECREF(r->length);
Amaury Forgeot d'Arcb7f17e42007-11-15 20:52:21 +0000149 PyObject_Del(r);
Guido van Rossum805365e2007-05-07 22:24:25 +0000150}
151
Mark Dickinson732166d2009-06-28 22:08:40 +0000152/* Return number of items in range (lo, hi, step) as a PyLong object,
153 * when arguments are PyLong objects. Arguments MUST return 1 with
154 * PyLong_Check(). Return NULL when there is an error.
Guido van Rossum805365e2007-05-07 22:24:25 +0000155 */
156static PyObject*
Nick Coghlan37ee8502010-12-03 14:26:13 +0000157compute_range_length(PyObject *start, PyObject *stop, PyObject *step)
Benjamin Petersona1864f32010-11-20 23:05:39 +0000158{
Guido van Rossum805365e2007-05-07 22:24:25 +0000159 /* -------------------------------------------------------------
160 Algorithm is equal to that of get_len_of_range(), but it operates
Benjamin Petersona47af9c2009-06-24 21:14:38 +0000161 on PyObjects (which are assumed to be PyLong objects).
Guido van Rossum805365e2007-05-07 22:24:25 +0000162 ---------------------------------------------------------------*/
Mark Dickinson211c6252009-02-01 10:28:51 +0000163 int cmp_result;
Guido van Rossum805365e2007-05-07 22:24:25 +0000164 PyObject *lo, *hi;
Guido van Rossum805365e2007-05-07 22:24:25 +0000165 PyObject *diff = NULL;
166 PyObject *one = NULL;
167 PyObject *tmp1 = NULL, *tmp2 = NULL, *result;
168 /* holds sub-expression evaluations */
169
170 PyObject *zero = PyLong_FromLong(0);
171 if (zero == NULL)
172 return NULL;
Nick Coghlan37ee8502010-12-03 14:26:13 +0000173 cmp_result = PyObject_RichCompareBool(step, zero, Py_GT);
Guido van Rossum805365e2007-05-07 22:24:25 +0000174 Py_DECREF(zero);
Mark Dickinson211c6252009-02-01 10:28:51 +0000175 if (cmp_result == -1)
Guido van Rossum805365e2007-05-07 22:24:25 +0000176 return NULL;
177
Mark Dickinson211c6252009-02-01 10:28:51 +0000178 if (cmp_result == 1) {
Nick Coghlan37ee8502010-12-03 14:26:13 +0000179 lo = start;
180 hi = stop;
Guido van Rossum805365e2007-05-07 22:24:25 +0000181 Py_INCREF(step);
182 } else {
Nick Coghlan37ee8502010-12-03 14:26:13 +0000183 lo = stop;
184 hi = start;
185 step = PyNumber_Negative(step);
Guido van Rossum805365e2007-05-07 22:24:25 +0000186 if (!step)
187 return NULL;
188 }
189
190 /* if (lo >= hi), return length of 0. */
Mark Dickinson211c6252009-02-01 10:28:51 +0000191 if (PyObject_RichCompareBool(lo, hi, Py_GE) == 1) {
Guido van Rossum805365e2007-05-07 22:24:25 +0000192 Py_XDECREF(step);
193 return PyLong_FromLong(0);
194 }
195
196 if ((one = PyLong_FromLong(1L)) == NULL)
197 goto Fail;
198
199 if ((tmp1 = PyNumber_Subtract(hi, lo)) == NULL)
200 goto Fail;
201
202 if ((diff = PyNumber_Subtract(tmp1, one)) == NULL)
203 goto Fail;
204
205 if ((tmp2 = PyNumber_FloorDivide(diff, step)) == NULL)
206 goto Fail;
207
208 if ((result = PyNumber_Add(tmp2, one)) == NULL)
209 goto Fail;
210
211 Py_DECREF(tmp2);
212 Py_DECREF(diff);
213 Py_DECREF(step);
214 Py_DECREF(tmp1);
215 Py_DECREF(one);
216 return result;
217
218 Fail:
219 Py_XDECREF(tmp2);
220 Py_XDECREF(diff);
221 Py_XDECREF(step);
222 Py_XDECREF(tmp1);
223 Py_XDECREF(one);
224 return NULL;
Guido van Rossum12d12c51993-10-26 17:58:25 +0000225}
226
Martin v. Löwis18e16552006-02-15 17:27:45 +0000227static Py_ssize_t
Benjamin Petersona1864f32010-11-20 23:05:39 +0000228range_length(rangeobject *r)
229{
Nick Coghlan37ee8502010-12-03 14:26:13 +0000230 return PyLong_AsSsize_t(r->length);
Guido van Rossum805365e2007-05-07 22:24:25 +0000231}
232
Guido van Rossum805365e2007-05-07 22:24:25 +0000233static PyObject *
Nick Coghlane993b102011-01-12 03:15:52 +0000234compute_item(rangeobject *r, PyObject *i)
Benjamin Petersona1864f32010-11-20 23:05:39 +0000235{
Nick Coghlane993b102011-01-12 03:15:52 +0000236 PyObject *incr, *result;
237 /* PyLong equivalent to:
238 * return r->start + (i * r->step)
239 */
240 incr = PyNumber_Multiply(i, r->step);
Guido van Rossum805365e2007-05-07 22:24:25 +0000241 if (!incr)
242 return NULL;
243 result = PyNumber_Add(r->start, incr);
244 Py_DECREF(incr);
245 return result;
Guido van Rossum7d6aa511993-12-21 22:50:31 +0000246}
247
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000248static PyObject *
Nick Coghlane993b102011-01-12 03:15:52 +0000249compute_range_item(rangeobject *r, PyObject *arg)
Benjamin Petersona1864f32010-11-20 23:05:39 +0000250{
Nick Coghlane993b102011-01-12 03:15:52 +0000251 int cmp_result;
252 PyObject *i, *result;
Tim Petersd976ab72004-08-08 06:29:10 +0000253
Nick Coghlane993b102011-01-12 03:15:52 +0000254 PyObject *zero = PyLong_FromLong(0);
255 if (zero == NULL)
256 return NULL;
Nick Coghlan37ee8502010-12-03 14:26:13 +0000257
Nick Coghlane993b102011-01-12 03:15:52 +0000258 /* PyLong equivalent to:
259 * if (arg < 0) {
260 * i = r->length + arg
261 * } else {
262 * i = arg
263 * }
264 */
265 cmp_result = PyObject_RichCompareBool(arg, zero, Py_LT);
266 if (cmp_result == -1) {
267 Py_DECREF(zero);
Nick Coghlan37ee8502010-12-03 14:26:13 +0000268 return NULL;
Guido van Rossum805365e2007-05-07 22:24:25 +0000269 }
Nick Coghlane993b102011-01-12 03:15:52 +0000270 if (cmp_result == 1) {
271 i = PyNumber_Add(r->length, arg);
272 if (!i) {
273 Py_DECREF(zero);
274 return NULL;
275 }
276 } else {
277 i = arg;
278 Py_INCREF(i);
279 }
280
281 /* PyLong equivalent to:
282 * if (i < 0 || i >= r->length) {
283 * <report index out of bounds>
284 * }
285 */
286 cmp_result = PyObject_RichCompareBool(i, zero, Py_LT);
287 Py_DECREF(zero);
288 if (cmp_result == 0) {
289 cmp_result = PyObject_RichCompareBool(i, r->length, Py_GE);
290 }
291 if (cmp_result == -1) {
292 Py_DECREF(i);
293 return NULL;
294 }
295 if (cmp_result == 1) {
296 Py_DECREF(i);
297 PyErr_SetString(PyExc_IndexError,
298 "range object index out of range");
299 return NULL;
300 }
301
302 result = compute_item(r, i);
303 Py_DECREF(i);
304 return result;
305}
306
307static PyObject *
308range_item(rangeobject *r, Py_ssize_t i)
309{
Benjamin Peterson547d4852011-01-13 04:22:54 +0000310 PyObject *res, *arg = PyLong_FromLong(i);
Nick Coghlane993b102011-01-12 03:15:52 +0000311 if (!arg) {
312 return NULL;
313 }
Benjamin Peterson547d4852011-01-13 04:22:54 +0000314 res = compute_range_item(r, arg);
315 Py_DECREF(arg);
316 return res;
Nick Coghlane993b102011-01-12 03:15:52 +0000317}
318
319/* Additional helpers, since the standard slice helpers
320 * all clip to PY_SSIZE_T_MAX
321 */
322
323/* Replace _PyEval_SliceIndex */
324static PyObject *
325compute_slice_element(PyObject *obj)
326{
327 PyObject *result = NULL;
328 if (obj != NULL) {
329 if (PyIndex_Check(obj)) {
330 result = PyNumber_Index(obj);
331 }
332 }
333 if (result == NULL) {
334 PyErr_SetString(PyExc_TypeError,
335 "slice indices must be integers or "
336 "None or have an __index__ method");
337 }
338 return result;
339}
340
341/* Replace PySlice_GetIndicesEx
342 * Result indicates whether or not the slice is empty
343 * (-1 = error, 0 = empty slice, 1 = slice contains elements)
344 */
Matthias Klose616667f2011-01-16 20:57:01 +0000345static int
Nick Coghlane993b102011-01-12 03:15:52 +0000346compute_slice_indices(rangeobject *r, PySliceObject *slice,
347 PyObject **start, PyObject **stop, PyObject **step)
348{
349 int cmp_result, has_elements;
350 Py_ssize_t clamped_step = 0;
351 PyObject *zero = NULL, *one = NULL, *neg_one = NULL, *candidate = NULL;
352 PyObject *tmp_start = NULL, *tmp_stop = NULL, *tmp_step = NULL;
353 zero = PyLong_FromLong(0);
354 if (zero == NULL) goto Fail;
355 one = PyLong_FromLong(1);
356 if (one == NULL) goto Fail;
357 neg_one = PyLong_FromLong(-1);
358 if (neg_one == NULL) goto Fail;
359
360 /* Calculate step value */
361 if (slice->step == Py_None) {
362 clamped_step = 1;
363 tmp_step = one;
364 Py_INCREF(tmp_step);
365 } else {
366 if (!_PyEval_SliceIndex(slice->step, &clamped_step)) goto Fail;
367 if (clamped_step == 0) {
368 PyErr_SetString(PyExc_ValueError,
369 "slice step cannot be zero");
370 goto Fail;
371 }
372 tmp_step = compute_slice_element(slice->step);
373 if (tmp_step == NULL) goto Fail;
374 }
375
376 /* Calculate start value */
377 if (slice->start == Py_None) {
378 if (clamped_step < 0) {
379 tmp_start = PyNumber_Subtract(r->length, one);
380 if (tmp_start == NULL) goto Fail;
381 } else {
382 tmp_start = zero;
383 Py_INCREF(tmp_start);
384 }
385 } else {
386 candidate = compute_slice_element(slice->start);
387 if (candidate == NULL) goto Fail;
388 cmp_result = PyObject_RichCompareBool(candidate, zero, Py_LT);
389 if (cmp_result == -1) goto Fail;
390 if (cmp_result) {
391 /* candidate < 0 */
392 tmp_start = PyNumber_Add(r->length, candidate);
393 if (tmp_start == NULL) goto Fail;
394 Py_CLEAR(candidate);
395 } else {
396 /* candidate >= 0 */
397 tmp_start = candidate;
398 candidate = NULL;
399 }
400 cmp_result = PyObject_RichCompareBool(tmp_start, zero, Py_LT);
401 if (cmp_result == -1) goto Fail;
402 if (cmp_result) {
403 /* tmp_start < 0 */
404 Py_CLEAR(tmp_start);
405 if (clamped_step < 0) {
406 tmp_start = neg_one;
407 } else {
408 tmp_start = zero;
409 }
410 Py_INCREF(tmp_start);
411 } else {
412 /* tmp_start >= 0 */
413 cmp_result = PyObject_RichCompareBool(tmp_start, r->length, Py_GE);
414 if (cmp_result == -1) goto Fail;
415 if (cmp_result) {
416 /* tmp_start >= r->length */
417 Py_CLEAR(tmp_start);
418 if (clamped_step < 0) {
419 tmp_start = PyNumber_Subtract(r->length, one);
420 if (tmp_start == NULL) goto Fail;
421 } else {
422 tmp_start = r->length;
423 Py_INCREF(tmp_start);
424 }
425 }
426 }
427 }
428
429 /* Calculate stop value */
430 if (slice->stop == Py_None) {
431 if (clamped_step < 0) {
432 tmp_stop = neg_one;
433 } else {
434 tmp_stop = r->length;
435 }
436 Py_INCREF(tmp_stop);
437 } else {
438 candidate = compute_slice_element(slice->stop);
439 if (candidate == NULL) goto Fail;
440 cmp_result = PyObject_RichCompareBool(candidate, zero, Py_LT);
441 if (cmp_result == -1) goto Fail;
442 if (cmp_result) {
443 /* candidate < 0 */
444 tmp_stop = PyNumber_Add(r->length, candidate);
445 if (tmp_stop == NULL) goto Fail;
446 Py_CLEAR(candidate);
447 } else {
448 /* candidate >= 0 */
449 tmp_stop = candidate;
450 candidate = NULL;
451 }
452 cmp_result = PyObject_RichCompareBool(tmp_stop, zero, Py_LT);
453 if (cmp_result == -1) goto Fail;
454 if (cmp_result) {
455 /* tmp_stop < 0 */
456 Py_CLEAR(tmp_stop);
457 if (clamped_step < 0) {
458 tmp_stop = neg_one;
459 } else {
460 tmp_stop = zero;
461 }
462 Py_INCREF(tmp_stop);
463 } else {
464 /* tmp_stop >= 0 */
465 cmp_result = PyObject_RichCompareBool(tmp_stop, r->length, Py_GE);
466 if (cmp_result == -1) goto Fail;
467 if (cmp_result) {
468 /* tmp_stop >= r->length */
469 Py_CLEAR(tmp_stop);
470 if (clamped_step < 0) {
471 tmp_stop = PyNumber_Subtract(r->length, one);
472 if (tmp_stop == NULL) goto Fail;
473 } else {
474 tmp_stop = r->length;
Ezio Melotti982ef4e2011-04-15 08:15:40 +0300475 Py_INCREF(tmp_stop);
Nick Coghlane993b102011-01-12 03:15:52 +0000476 }
477 }
478 }
479 }
480
481 /* Check if the slice is empty or not */
482 if (clamped_step < 0) {
483 has_elements = PyObject_RichCompareBool(tmp_start, tmp_stop, Py_GT);
484 } else {
485 has_elements = PyObject_RichCompareBool(tmp_start, tmp_stop, Py_LT);
486 }
487 if (has_elements == -1) goto Fail;
488
489 *start = tmp_start;
490 *stop = tmp_stop;
491 *step = tmp_step;
492 Py_DECREF(neg_one);
493 Py_DECREF(one);
494 Py_DECREF(zero);
495 return has_elements;
496
497 Fail:
498 Py_XDECREF(tmp_start);
499 Py_XDECREF(tmp_stop);
500 Py_XDECREF(tmp_step);
501 Py_XDECREF(candidate);
502 Py_XDECREF(neg_one);
503 Py_XDECREF(one);
504 Py_XDECREF(zero);
505 return -1;
506}
507
508static PyObject *
509compute_slice(rangeobject *r, PyObject *_slice)
510{
511 PySliceObject *slice = (PySliceObject *) _slice;
512 rangeobject *result;
513 PyObject *start = NULL, *stop = NULL, *step = NULL;
514 PyObject *substart = NULL, *substop = NULL, *substep = NULL;
515 int has_elements;
516
517 has_elements = compute_slice_indices(r, slice, &start, &stop, &step);
518 if (has_elements == -1) return NULL;
519
520 substep = PyNumber_Multiply(r->step, step);
521 if (substep == NULL) goto fail;
522 Py_CLEAR(step);
523
524 substart = compute_item(r, start);
525 if (substart == NULL) goto fail;
526 Py_CLEAR(start);
527
528 if (has_elements) {
529 substop = compute_item(r, stop);
530 if (substop == NULL) goto fail;
531 } else {
532 substop = substart;
533 Py_INCREF(substop);
534 }
535 Py_CLEAR(stop);
536
537 result = make_range_object(Py_TYPE(r), substart, substop, substep);
538 if (result != NULL) {
539 return (PyObject *) result;
540 }
541fail:
542 Py_XDECREF(start);
543 Py_XDECREF(stop);
544 Py_XDECREF(step);
545 Py_XDECREF(substart);
546 Py_XDECREF(substop);
547 Py_XDECREF(substep);
548 return NULL;
Alexandre Vassalotti75056072008-06-10 04:03:04 +0000549}
550
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000551/* Assumes (PyLong_CheckExact(ob) || PyBool_Check(ob)) */
552static int
Benjamin Petersona1864f32010-11-20 23:05:39 +0000553range_contains_long(rangeobject *r, PyObject *ob)
554{
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000555 int cmp1, cmp2, cmp3;
556 PyObject *tmp1 = NULL;
557 PyObject *tmp2 = NULL;
558 PyObject *zero = NULL;
559 int result = -1;
560
561 zero = PyLong_FromLong(0);
562 if (zero == NULL) /* MemoryError in int(0) */
563 goto end;
564
565 /* Check if the value can possibly be in the range. */
566
567 cmp1 = PyObject_RichCompareBool(r->step, zero, Py_GT);
568 if (cmp1 == -1)
569 goto end;
570 if (cmp1 == 1) { /* positive steps: start <= ob < stop */
571 cmp2 = PyObject_RichCompareBool(r->start, ob, Py_LE);
572 cmp3 = PyObject_RichCompareBool(ob, r->stop, Py_LT);
573 }
574 else { /* negative steps: stop < ob <= start */
575 cmp2 = PyObject_RichCompareBool(ob, r->start, Py_LE);
576 cmp3 = PyObject_RichCompareBool(r->stop, ob, Py_LT);
577 }
578
579 if (cmp2 == -1 || cmp3 == -1) /* TypeError */
580 goto end;
581 if (cmp2 == 0 || cmp3 == 0) { /* ob outside of range */
582 result = 0;
583 goto end;
584 }
585
586 /* Check that the stride does not invalidate ob's membership. */
587 tmp1 = PyNumber_Subtract(ob, r->start);
588 if (tmp1 == NULL)
589 goto end;
590 tmp2 = PyNumber_Remainder(tmp1, r->step);
591 if (tmp2 == NULL)
592 goto end;
593 /* result = (int(ob) - start % step) == 0 */
594 result = PyObject_RichCompareBool(tmp2, zero, Py_EQ);
595 end:
596 Py_XDECREF(tmp1);
597 Py_XDECREF(tmp2);
598 Py_XDECREF(zero);
599 return result;
600}
601
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000602static int
Benjamin Petersona1864f32010-11-20 23:05:39 +0000603range_contains(rangeobject *r, PyObject *ob)
604{
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000605 if (PyLong_CheckExact(ob) || PyBool_Check(ob))
606 return range_contains_long(r, ob);
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000607
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000608 return (int)_PySequence_IterSearch((PyObject*)r, ob,
609 PY_ITERSEARCH_CONTAINS);
610}
611
Mark Dickinson36645682011-10-23 19:53:01 +0100612/* Compare two range objects. Return 1 for equal, 0 for not equal
613 and -1 on error. The algorithm is roughly the C equivalent of
614
615 if r0 is r1:
616 return True
617 if len(r0) != len(r1):
618 return False
619 if not len(r0):
620 return True
621 if r0.start != r1.start:
622 return False
623 if len(r0) == 1:
624 return True
625 return r0.step == r1.step
626*/
627static int
628range_equals(rangeobject *r0, rangeobject *r1)
629{
630 int cmp_result;
631 PyObject *one;
632
633 if (r0 == r1)
634 return 1;
635 cmp_result = PyObject_RichCompareBool(r0->length, r1->length, Py_EQ);
636 /* Return False or error to the caller. */
637 if (cmp_result != 1)
638 return cmp_result;
639 cmp_result = PyObject_Not(r0->length);
640 /* Return True or error to the caller. */
641 if (cmp_result != 0)
642 return cmp_result;
643 cmp_result = PyObject_RichCompareBool(r0->start, r1->start, Py_EQ);
644 /* Return False or error to the caller. */
645 if (cmp_result != 1)
646 return cmp_result;
647 one = PyLong_FromLong(1);
648 if (!one)
649 return -1;
650 cmp_result = PyObject_RichCompareBool(r0->length, one, Py_EQ);
651 Py_DECREF(one);
652 /* Return True or error to the caller. */
653 if (cmp_result != 0)
654 return cmp_result;
655 return PyObject_RichCompareBool(r0->step, r1->step, Py_EQ);
656}
657
658static PyObject *
659range_richcompare(PyObject *self, PyObject *other, int op)
660{
661 int result;
662
663 if (!PyRange_Check(other))
664 Py_RETURN_NOTIMPLEMENTED;
665 switch (op) {
666 case Py_NE:
667 case Py_EQ:
668 result = range_equals((rangeobject*)self, (rangeobject*)other);
669 if (result == -1)
670 return NULL;
671 if (op == Py_NE)
672 result = !result;
673 if (result)
674 Py_RETURN_TRUE;
675 else
676 Py_RETURN_FALSE;
677 case Py_LE:
678 case Py_GE:
679 case Py_LT:
680 case Py_GT:
681 Py_RETURN_NOTIMPLEMENTED;
682 default:
683 PyErr_BadArgument();
684 return NULL;
685 }
686}
687
688/* Hash function for range objects. Rough C equivalent of
689
690 if not len(r):
691 return hash((len(r), None, None))
692 if len(r) == 1:
693 return hash((len(r), r.start, None))
694 return hash((len(r), r.start, r.step))
695*/
696static Py_hash_t
697range_hash(rangeobject *r)
698{
699 PyObject *t;
700 Py_hash_t result = -1;
701 int cmp_result;
702
703 t = PyTuple_New(3);
704 if (!t)
705 return -1;
706 Py_INCREF(r->length);
707 PyTuple_SET_ITEM(t, 0, r->length);
708 cmp_result = PyObject_Not(r->length);
709 if (cmp_result == -1)
710 goto end;
711 if (cmp_result == 1) {
712 Py_INCREF(Py_None);
713 Py_INCREF(Py_None);
714 PyTuple_SET_ITEM(t, 1, Py_None);
715 PyTuple_SET_ITEM(t, 2, Py_None);
716 }
717 else {
718 PyObject *one;
719 Py_INCREF(r->start);
720 PyTuple_SET_ITEM(t, 1, r->start);
721 one = PyLong_FromLong(1);
722 if (!one)
723 goto end;
724 cmp_result = PyObject_RichCompareBool(r->length, one, Py_EQ);
725 Py_DECREF(one);
726 if (cmp_result == -1)
727 goto end;
728 if (cmp_result == 1) {
729 Py_INCREF(Py_None);
730 PyTuple_SET_ITEM(t, 2, Py_None);
731 }
732 else {
733 Py_INCREF(r->step);
734 PyTuple_SET_ITEM(t, 2, r->step);
735 }
736 }
737 result = PyObject_Hash(t);
738 end:
739 Py_DECREF(t);
740 return result;
741}
742
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000743static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +0000744range_count(rangeobject *r, PyObject *ob)
745{
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000746 if (PyLong_CheckExact(ob) || PyBool_Check(ob)) {
Georg Brandl7e5343b2010-11-20 22:40:10 +0000747 int result = range_contains_long(r, ob);
748 if (result == -1)
749 return NULL;
750 else if (result)
Benjamin Peterson0b458d52010-11-20 22:35:41 +0000751 return PyLong_FromLong(1);
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000752 else
Benjamin Peterson0b458d52010-11-20 22:35:41 +0000753 return PyLong_FromLong(0);
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000754 } else {
755 Py_ssize_t count;
756 count = _PySequence_IterSearch((PyObject*)r, ob, PY_ITERSEARCH_COUNT);
757 if (count == -1)
758 return NULL;
759 return PyLong_FromSsize_t(count);
760 }
761}
762
763static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +0000764range_index(rangeobject *r, PyObject *ob)
765{
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000766 int contains;
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000767
768 if (!PyLong_CheckExact(ob) && !PyBool_Check(ob)) {
769 Py_ssize_t index;
770 index = _PySequence_IterSearch((PyObject*)r, ob, PY_ITERSEARCH_INDEX);
771 if (index == -1)
772 return NULL;
773 return PyLong_FromSsize_t(index);
774 }
775
776 contains = range_contains_long(r, ob);
777 if (contains == -1)
778 return NULL;
779
Benjamin Peterson155614b2010-11-20 22:44:32 +0000780 if (contains) {
781 PyObject *idx, *tmp = PyNumber_Subtract(ob, r->start);
782 if (tmp == NULL)
783 return NULL;
784 /* idx = (ob - r.start) // r.step */
785 idx = PyNumber_FloorDivide(tmp, r->step);
786 Py_DECREF(tmp);
787 return idx;
788 }
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000789
790 /* object is not in the range */
Benjamin Peterson155614b2010-11-20 22:44:32 +0000791 PyErr_Format(PyExc_ValueError, "%R is not in range", ob);
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000792 return NULL;
793}
794
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000795static PySequenceMethods range_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000796 (lenfunc)range_length, /* sq_length */
Nick Coghlan37ee8502010-12-03 14:26:13 +0000797 0, /* sq_concat */
798 0, /* sq_repeat */
799 (ssizeargfunc)range_item, /* sq_item */
800 0, /* sq_slice */
801 0, /* sq_ass_item */
802 0, /* sq_ass_slice */
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000803 (objobjproc)range_contains, /* sq_contains */
Guido van Rossum12d12c51993-10-26 17:58:25 +0000804};
805
Nick Coghlan37ee8502010-12-03 14:26:13 +0000806static PyObject *
807range_repr(rangeobject *r)
808{
809 Py_ssize_t istep;
810
811 /* Check for special case values for printing. We don't always
812 need the step value. We don't care about errors
813 (it means overflow), so clear the errors. */
814 istep = PyNumber_AsSsize_t(r->step, NULL);
815 if (istep != 1 || (istep == -1 && PyErr_Occurred())) {
816 PyErr_Clear();
817 }
818
819 if (istep == 1)
820 return PyUnicode_FromFormat("range(%R, %R)", r->start, r->stop);
821 else
822 return PyUnicode_FromFormat("range(%R, %R, %R)",
823 r->start, r->stop, r->step);
824}
825
826/* Pickling support */
827static PyObject *
828range_reduce(rangeobject *r, PyObject *args)
829{
830 return Py_BuildValue("(O(OOO))", Py_TYPE(r),
831 r->start, r->stop, r->step);
832}
833
834static PyObject *
835range_subscript(rangeobject* self, PyObject* item)
836{
837 if (PyIndex_Check(item)) {
Nick Coghlane993b102011-01-12 03:15:52 +0000838 PyObject *i, *result;
839 i = PyNumber_Index(item);
840 if (!i)
Nick Coghlan37ee8502010-12-03 14:26:13 +0000841 return NULL;
Nick Coghlane993b102011-01-12 03:15:52 +0000842 result = compute_range_item(self, i);
843 Py_DECREF(i);
844 return result;
Nick Coghlan37ee8502010-12-03 14:26:13 +0000845 }
846 if (PySlice_Check(item)) {
Nick Coghlane993b102011-01-12 03:15:52 +0000847 return compute_slice(self, item);
Nick Coghlan37ee8502010-12-03 14:26:13 +0000848 }
849 PyErr_Format(PyExc_TypeError,
850 "range indices must be integers or slices, not %.200s",
851 item->ob_type->tp_name);
852 return NULL;
853}
854
855
856static PyMappingMethods range_as_mapping = {
857 (lenfunc)range_length, /* mp_length */
858 (binaryfunc)range_subscript, /* mp_subscript */
859 (objobjargproc)0, /* mp_ass_subscript */
860};
861
Jeremy Hylton938ace62002-07-17 16:30:39 +0000862static PyObject * range_iter(PyObject *seq);
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000863static PyObject * range_reverse(PyObject *seq);
864
865PyDoc_STRVAR(reverse_doc,
866"Returns a reverse iterator.");
867
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000868PyDoc_STRVAR(count_doc,
869"rangeobject.count(value) -> integer -- return number of occurrences of value");
870
871PyDoc_STRVAR(index_doc,
872"rangeobject.index(value, [start, [stop]]) -> integer -- return index of value.\n"
873"Raises ValueError if the value is not present.");
874
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000875static PyMethodDef range_methods[] = {
Daniel Stutzbach9f0cbf12010-09-13 21:16:29 +0000876 {"__reversed__", (PyCFunction)range_reverse, METH_NOARGS, reverse_doc},
877 {"__reduce__", (PyCFunction)range_reduce, METH_VARARGS},
878 {"count", (PyCFunction)range_count, METH_O, count_doc},
879 {"index", (PyCFunction)range_index, METH_O, index_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000880 {NULL, NULL} /* sentinel */
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000881};
Raymond Hettinger48165d42002-06-05 20:08:48 +0000882
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000883PyTypeObject PyRange_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000884 PyVarObject_HEAD_INIT(&PyType_Type, 0)
885 "range", /* Name of this type */
886 sizeof(rangeobject), /* Basic object size */
887 0, /* Item size for varobject */
888 (destructor)range_dealloc, /* tp_dealloc */
889 0, /* tp_print */
890 0, /* tp_getattr */
891 0, /* tp_setattr */
892 0, /* tp_reserved */
893 (reprfunc)range_repr, /* tp_repr */
894 0, /* tp_as_number */
895 &range_as_sequence, /* tp_as_sequence */
Nick Coghlan37ee8502010-12-03 14:26:13 +0000896 &range_as_mapping, /* tp_as_mapping */
Mark Dickinson36645682011-10-23 19:53:01 +0100897 (hashfunc)range_hash, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000898 0, /* tp_call */
899 0, /* tp_str */
900 PyObject_GenericGetAttr, /* tp_getattro */
901 0, /* tp_setattro */
902 0, /* tp_as_buffer */
903 Py_TPFLAGS_DEFAULT, /* tp_flags */
904 range_doc, /* tp_doc */
905 0, /* tp_traverse */
906 0, /* tp_clear */
Mark Dickinson36645682011-10-23 19:53:01 +0100907 range_richcompare, /* tp_richcompare */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000908 0, /* tp_weaklistoffset */
909 range_iter, /* tp_iter */
910 0, /* tp_iternext */
911 range_methods, /* tp_methods */
912 0, /* tp_members */
913 0, /* tp_getset */
914 0, /* tp_base */
915 0, /* tp_dict */
916 0, /* tp_descr_get */
917 0, /* tp_descr_set */
918 0, /* tp_dictoffset */
919 0, /* tp_init */
920 0, /* tp_alloc */
921 range_new, /* tp_new */
Guido van Rossum12d12c51993-10-26 17:58:25 +0000922};
Raymond Hettinger48165d42002-06-05 20:08:48 +0000923
Walter Dörwald4ad94212007-05-21 18:01:17 +0000924/*********************** range Iterator **************************/
Raymond Hettinger48165d42002-06-05 20:08:48 +0000925
Guido van Rossum805365e2007-05-07 22:24:25 +0000926/* There are 2 types of iterators, one for C longs, the other for
927 Python longs (ie, PyObjects). This should make iteration fast
928 in the normal case, but possible for any numeric value.
929*/
930
Raymond Hettinger48165d42002-06-05 20:08:48 +0000931typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000932 PyObject_HEAD
933 long index;
934 long start;
935 long step;
936 long len;
Raymond Hettinger48165d42002-06-05 20:08:48 +0000937} rangeiterobject;
938
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000939static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +0000940rangeiter_next(rangeiterobject *r)
941{
Guido van Rossum805365e2007-05-07 22:24:25 +0000942 if (r->index < r->len)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000943 /* cast to unsigned to avoid possible signed overflow
Mark Dickinsonb43dbc22009-11-15 12:56:08 +0000944 in intermediate calculations. */
945 return PyLong_FromLong((long)(r->start +
946 (unsigned long)(r->index++) * r->step));
Guido van Rossum805365e2007-05-07 22:24:25 +0000947 return NULL;
Raymond Hettinger48165d42002-06-05 20:08:48 +0000948}
949
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000950static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +0000951rangeiter_len(rangeiterobject *r)
952{
Christian Heimes217cfd12007-12-02 14:31:20 +0000953 return PyLong_FromLong(r->len - r->index);
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000954}
955
Guido van Rossum805365e2007-05-07 22:24:25 +0000956PyDoc_STRVAR(length_hint_doc,
957 "Private method returning an estimate of len(list(it)).");
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000958
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000959static PyMethodDef rangeiter_methods[] = {
Guido van Rossum805365e2007-05-07 22:24:25 +0000960 {"__length_hint__", (PyCFunction)rangeiter_len, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000961 length_hint_doc},
962 {NULL, NULL} /* sentinel */
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000963};
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000964
Nick Coghlan37ee8502010-12-03 14:26:13 +0000965static PyObject *rangeiter_new(PyTypeObject *, PyObject *args, PyObject *kw);
966
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000967PyTypeObject PyRangeIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000968 PyVarObject_HEAD_INIT(&PyType_Type, 0)
969 "range_iterator", /* tp_name */
970 sizeof(rangeiterobject), /* tp_basicsize */
971 0, /* tp_itemsize */
972 /* methods */
973 (destructor)PyObject_Del, /* tp_dealloc */
974 0, /* tp_print */
975 0, /* tp_getattr */
976 0, /* tp_setattr */
977 0, /* tp_reserved */
978 0, /* tp_repr */
979 0, /* tp_as_number */
980 0, /* tp_as_sequence */
981 0, /* tp_as_mapping */
982 0, /* tp_hash */
983 0, /* tp_call */
984 0, /* tp_str */
985 PyObject_GenericGetAttr, /* tp_getattro */
986 0, /* tp_setattro */
987 0, /* tp_as_buffer */
988 Py_TPFLAGS_DEFAULT, /* tp_flags */
989 0, /* tp_doc */
990 0, /* tp_traverse */
991 0, /* tp_clear */
992 0, /* tp_richcompare */
993 0, /* tp_weaklistoffset */
994 PyObject_SelfIter, /* tp_iter */
995 (iternextfunc)rangeiter_next, /* tp_iternext */
996 rangeiter_methods, /* tp_methods */
997 0, /* tp_members */
998 0, /* tp_getset */
999 0, /* tp_base */
1000 0, /* tp_dict */
1001 0, /* tp_descr_get */
1002 0, /* tp_descr_set */
1003 0, /* tp_dictoffset */
1004 0, /* tp_init */
1005 0, /* tp_alloc */
1006 rangeiter_new, /* tp_new */
Guido van Rossum805365e2007-05-07 22:24:25 +00001007};
1008
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001009/* Return number of items in range (lo, hi, step). step != 0
1010 * required. The result always fits in an unsigned long.
Guido van Rossum805365e2007-05-07 22:24:25 +00001011 */
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001012static unsigned long
Benjamin Petersona1864f32010-11-20 23:05:39 +00001013get_len_of_range(long lo, long hi, long step)
1014{
Guido van Rossum805365e2007-05-07 22:24:25 +00001015 /* -------------------------------------------------------------
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001016 If step > 0 and lo >= hi, or step < 0 and lo <= hi, the range is empty.
1017 Else for step > 0, if n values are in the range, the last one is
Guido van Rossum805365e2007-05-07 22:24:25 +00001018 lo + (n-1)*step, which must be <= hi-1. Rearranging,
1019 n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives
1020 the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so
1021 the RHS is non-negative and so truncation is the same as the
1022 floor. Letting M be the largest positive long, the worst case
1023 for the RHS numerator is hi=M, lo=-M-1, and then
1024 hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001025 precision to compute the RHS exactly. The analysis for step < 0
1026 is similar.
Guido van Rossum805365e2007-05-07 22:24:25 +00001027 ---------------------------------------------------------------*/
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001028 assert(step != 0);
1029 if (step > 0 && lo < hi)
1030 return 1UL + (hi - 1UL - lo) / step;
1031 else if (step < 0 && lo > hi)
1032 return 1UL + (lo - 1UL - hi) / (0UL - step);
1033 else
1034 return 0UL;
Guido van Rossum805365e2007-05-07 22:24:25 +00001035}
1036
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001037/* Initialize a rangeiter object. If the length of the rangeiter object
1038 is not representable as a C long, OverflowError is raised. */
1039
Guido van Rossum805365e2007-05-07 22:24:25 +00001040static PyObject *
Nick Coghlan37ee8502010-12-03 14:26:13 +00001041fast_range_iter(long start, long stop, long step)
Benjamin Petersona1864f32010-11-20 23:05:39 +00001042{
Christian Heimesa22e8bd2007-11-29 22:35:39 +00001043 rangeiterobject *it = PyObject_New(rangeiterobject, &PyRangeIter_Type);
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001044 unsigned long ulen;
Guido van Rossum805365e2007-05-07 22:24:25 +00001045 if (it == NULL)
1046 return NULL;
1047 it->start = start;
1048 it->step = step;
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001049 ulen = get_len_of_range(start, stop, step);
1050 if (ulen > (unsigned long)LONG_MAX) {
Benjamin Peterson36fbb732009-11-16 00:34:25 +00001051 Py_DECREF(it);
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001052 PyErr_SetString(PyExc_OverflowError,
1053 "range too large to represent as a range_iterator");
1054 return NULL;
1055 }
1056 it->len = (long)ulen;
Guido van Rossum805365e2007-05-07 22:24:25 +00001057 it->index = 0;
1058 return (PyObject *)it;
1059}
1060
1061static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +00001062rangeiter_new(PyTypeObject *type, PyObject *args, PyObject *kw)
1063{
Guido van Rossum805365e2007-05-07 22:24:25 +00001064 long start, stop, step;
1065
1066 if (!_PyArg_NoKeywords("rangeiter()", kw))
1067 return NULL;
1068
1069 if (!PyArg_ParseTuple(args, "lll;rangeiter() requires 3 int arguments",
1070 &start, &stop, &step))
1071 return NULL;
1072
Nick Coghlan37ee8502010-12-03 14:26:13 +00001073 return fast_range_iter(start, stop, step);
1074}
1075
1076typedef struct {
1077 PyObject_HEAD
1078 PyObject *index;
1079 PyObject *start;
1080 PyObject *step;
1081 PyObject *len;
1082} longrangeiterobject;
1083
1084static PyObject *
1085longrangeiter_len(longrangeiterobject *r, PyObject *no_args)
1086{
1087 return PyNumber_Subtract(r->len, r->index);
Guido van Rossum805365e2007-05-07 22:24:25 +00001088}
1089
1090static PyMethodDef longrangeiter_methods[] = {
1091 {"__length_hint__", (PyCFunction)longrangeiter_len, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001092 length_hint_doc},
1093 {NULL, NULL} /* sentinel */
Guido van Rossum805365e2007-05-07 22:24:25 +00001094};
1095
1096static void
Benjamin Petersona1864f32010-11-20 23:05:39 +00001097longrangeiter_dealloc(longrangeiterobject *r)
1098{
Guido van Rossum805365e2007-05-07 22:24:25 +00001099 Py_XDECREF(r->index);
Guido van Rossum317e7742007-05-08 15:18:31 +00001100 Py_XDECREF(r->start);
1101 Py_XDECREF(r->step);
1102 Py_XDECREF(r->len);
Amaury Forgeot d'Arcb7f17e42007-11-15 20:52:21 +00001103 PyObject_Del(r);
Guido van Rossum805365e2007-05-07 22:24:25 +00001104}
1105
1106static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +00001107longrangeiter_next(longrangeiterobject *r)
1108{
Guido van Rossum805365e2007-05-07 22:24:25 +00001109 PyObject *one, *product, *new_index, *result;
1110 if (PyObject_RichCompareBool(r->index, r->len, Py_LT) != 1)
1111 return NULL;
1112
1113 one = PyLong_FromLong(1);
1114 if (!one)
1115 return NULL;
1116
Guido van Rossum805365e2007-05-07 22:24:25 +00001117 new_index = PyNumber_Add(r->index, one);
1118 Py_DECREF(one);
Benjamin Peterson36fbb732009-11-16 00:34:25 +00001119 if (!new_index)
1120 return NULL;
1121
1122 product = PyNumber_Multiply(r->index, r->step);
1123 if (!product) {
1124 Py_DECREF(new_index);
Guido van Rossum805365e2007-05-07 22:24:25 +00001125 return NULL;
1126 }
1127
1128 result = PyNumber_Add(r->start, product);
1129 Py_DECREF(product);
1130 if (result) {
1131 Py_DECREF(r->index);
1132 r->index = new_index;
1133 }
Benjamin Peterson36fbb732009-11-16 00:34:25 +00001134 else {
1135 Py_DECREF(new_index);
1136 }
Guido van Rossum805365e2007-05-07 22:24:25 +00001137
1138 return result;
1139}
1140
Christian Heimesa22e8bd2007-11-29 22:35:39 +00001141PyTypeObject PyLongRangeIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001142 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1143 "longrange_iterator", /* tp_name */
1144 sizeof(longrangeiterobject), /* tp_basicsize */
1145 0, /* tp_itemsize */
1146 /* methods */
1147 (destructor)longrangeiter_dealloc, /* tp_dealloc */
1148 0, /* tp_print */
1149 0, /* tp_getattr */
1150 0, /* tp_setattr */
1151 0, /* tp_reserved */
1152 0, /* tp_repr */
1153 0, /* tp_as_number */
1154 0, /* tp_as_sequence */
1155 0, /* tp_as_mapping */
1156 0, /* tp_hash */
1157 0, /* tp_call */
1158 0, /* tp_str */
1159 PyObject_GenericGetAttr, /* tp_getattro */
1160 0, /* tp_setattro */
1161 0, /* tp_as_buffer */
1162 Py_TPFLAGS_DEFAULT, /* tp_flags */
1163 0, /* tp_doc */
1164 0, /* tp_traverse */
1165 0, /* tp_clear */
1166 0, /* tp_richcompare */
1167 0, /* tp_weaklistoffset */
1168 PyObject_SelfIter, /* tp_iter */
1169 (iternextfunc)longrangeiter_next, /* tp_iternext */
1170 longrangeiter_methods, /* tp_methods */
1171 0,
Raymond Hettinger48165d42002-06-05 20:08:48 +00001172};
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001173
1174static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +00001175range_iter(PyObject *seq)
1176{
Guido van Rossum805365e2007-05-07 22:24:25 +00001177 rangeobject *r = (rangeobject *)seq;
1178 longrangeiterobject *it;
Martin v. Löwis84451042007-12-20 22:57:23 +00001179 long lstart, lstop, lstep;
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001180 PyObject *int_it;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001181
Guido van Rossum805365e2007-05-07 22:24:25 +00001182 assert(PyRange_Check(seq));
Martin v. Löwis84451042007-12-20 22:57:23 +00001183
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001184 /* If all three fields and the length convert to long, use the int
1185 * version */
Martin v. Löwis84451042007-12-20 22:57:23 +00001186 lstart = PyLong_AsLong(r->start);
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001187 if (lstart == -1 && PyErr_Occurred()) {
1188 PyErr_Clear();
1189 goto long_range;
Martin v. Löwis84451042007-12-20 22:57:23 +00001190 }
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001191 lstop = PyLong_AsLong(r->stop);
1192 if (lstop == -1 && PyErr_Occurred()) {
1193 PyErr_Clear();
1194 goto long_range;
1195 }
1196 lstep = PyLong_AsLong(r->step);
1197 if (lstep == -1 && PyErr_Occurred()) {
1198 PyErr_Clear();
1199 goto long_range;
1200 }
Nick Coghlan37ee8502010-12-03 14:26:13 +00001201 int_it = fast_range_iter(lstart, lstop, lstep);
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001202 if (int_it == NULL && PyErr_ExceptionMatches(PyExc_OverflowError)) {
1203 PyErr_Clear();
1204 goto long_range;
1205 }
1206 return (PyObject *)int_it;
1207
1208 long_range:
Christian Heimesa22e8bd2007-11-29 22:35:39 +00001209 it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
Guido van Rossum805365e2007-05-07 22:24:25 +00001210 if (it == NULL)
1211 return NULL;
Guido van Rossum317e7742007-05-08 15:18:31 +00001212
1213 /* Do all initialization here, so we can DECREF on failure. */
Guido van Rossum805365e2007-05-07 22:24:25 +00001214 it->start = r->start;
Guido van Rossum317e7742007-05-08 15:18:31 +00001215 it->step = r->step;
Nick Coghlan37ee8502010-12-03 14:26:13 +00001216 it->len = r->length;
Guido van Rossum317e7742007-05-08 15:18:31 +00001217 Py_INCREF(it->start);
1218 Py_INCREF(it->step);
Nick Coghlan37ee8502010-12-03 14:26:13 +00001219 Py_INCREF(it->len);
Guido van Rossum317e7742007-05-08 15:18:31 +00001220
Guido van Rossum805365e2007-05-07 22:24:25 +00001221 it->index = PyLong_FromLong(0);
1222 if (!it->index)
1223 goto create_failure;
1224
Guido van Rossum805365e2007-05-07 22:24:25 +00001225 return (PyObject *)it;
1226
1227create_failure:
Guido van Rossum317e7742007-05-08 15:18:31 +00001228 Py_DECREF(it);
Guido van Rossum805365e2007-05-07 22:24:25 +00001229 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001230}
1231
1232static PyObject *
Benjamin Petersona1864f32010-11-20 23:05:39 +00001233range_reverse(PyObject *seq)
1234{
Guido van Rossum805365e2007-05-07 22:24:25 +00001235 rangeobject *range = (rangeobject*) seq;
1236 longrangeiterobject *it;
Nick Coghlan37ee8502010-12-03 14:26:13 +00001237 PyObject *one, *sum, *diff, *product;
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001238 long lstart, lstop, lstep, new_start, new_stop;
1239 unsigned long ulen;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001240
Guido van Rossum805365e2007-05-07 22:24:25 +00001241 assert(PyRange_Check(seq));
Martin v. Löwis84451042007-12-20 22:57:23 +00001242
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001243 /* reversed(range(start, stop, step)) can be expressed as
1244 range(start+(n-1)*step, start-step, -step), where n is the number of
1245 integers in the range.
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001246
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001247 If each of start, stop, step, -step, start-step, and the length
1248 of the iterator is representable as a C long, use the int
1249 version. This excludes some cases where the reversed range is
1250 representable as a range_iterator, but it's good enough for
1251 common cases and it makes the checks simple. */
1252
1253 lstart = PyLong_AsLong(range->start);
1254 if (lstart == -1 && PyErr_Occurred()) {
1255 PyErr_Clear();
1256 goto long_range;
1257 }
1258 lstop = PyLong_AsLong(range->stop);
1259 if (lstop == -1 && PyErr_Occurred()) {
1260 PyErr_Clear();
1261 goto long_range;
1262 }
1263 lstep = PyLong_AsLong(range->step);
1264 if (lstep == -1 && PyErr_Occurred()) {
1265 PyErr_Clear();
1266 goto long_range;
1267 }
1268 /* check for possible overflow of -lstep */
1269 if (lstep == LONG_MIN)
1270 goto long_range;
1271
1272 /* check for overflow of lstart - lstep:
1273
1274 for lstep > 0, need only check whether lstart - lstep < LONG_MIN.
1275 for lstep < 0, need only check whether lstart - lstep > LONG_MAX
1276
1277 Rearrange these inequalities as:
1278
1279 lstart - LONG_MIN < lstep (lstep > 0)
1280 LONG_MAX - lstart < -lstep (lstep < 0)
1281
1282 and compute both sides as unsigned longs, to avoid the
1283 possibility of undefined behaviour due to signed overflow. */
1284
1285 if (lstep > 0) {
1286 if ((unsigned long)lstart - LONG_MIN < (unsigned long)lstep)
1287 goto long_range;
1288 }
1289 else {
1290 if (LONG_MAX - (unsigned long)lstart < 0UL - lstep)
1291 goto long_range;
1292 }
1293
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001294 ulen = get_len_of_range(lstart, lstop, lstep);
1295 if (ulen > (unsigned long)LONG_MAX)
1296 goto long_range;
1297
1298 new_stop = lstart - lstep;
1299 new_start = (long)(new_stop + ulen * lstep);
Nick Coghlan37ee8502010-12-03 14:26:13 +00001300 return fast_range_iter(new_start, new_stop, -lstep);
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001301
1302long_range:
Christian Heimesa22e8bd2007-11-29 22:35:39 +00001303 it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
Guido van Rossum805365e2007-05-07 22:24:25 +00001304 if (it == NULL)
1305 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001306
Guido van Rossum805365e2007-05-07 22:24:25 +00001307 /* start + (len - 1) * step */
Nick Coghlan37ee8502010-12-03 14:26:13 +00001308 it->len = range->length;
1309 Py_INCREF(it->len);
Benjamin Peterson36fbb732009-11-16 00:34:25 +00001310
Guido van Rossum805365e2007-05-07 22:24:25 +00001311 one = PyLong_FromLong(1);
1312 if (!one)
1313 goto create_failure;
1314
Nick Coghlan37ee8502010-12-03 14:26:13 +00001315 diff = PyNumber_Subtract(it->len, one);
Guido van Rossum805365e2007-05-07 22:24:25 +00001316 Py_DECREF(one);
1317 if (!diff)
1318 goto create_failure;
1319
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001320 product = PyNumber_Multiply(diff, range->step);
1321 Py_DECREF(diff);
Guido van Rossum805365e2007-05-07 22:24:25 +00001322 if (!product)
1323 goto create_failure;
1324
1325 sum = PyNumber_Add(range->start, product);
1326 Py_DECREF(product);
1327 it->start = sum;
1328 if (!it->start)
1329 goto create_failure;
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001330
Guido van Rossum805365e2007-05-07 22:24:25 +00001331 it->step = PyNumber_Negative(range->step);
Benjamin Peterson36fbb732009-11-16 00:34:25 +00001332 if (!it->step)
Mark Dickinsond550c9a2009-11-15 09:57:26 +00001333 goto create_failure;
Guido van Rossum805365e2007-05-07 22:24:25 +00001334
1335 it->index = PyLong_FromLong(0);
Benjamin Peterson36fbb732009-11-16 00:34:25 +00001336 if (!it->index)
1337 goto create_failure;
Guido van Rossum805365e2007-05-07 22:24:25 +00001338
1339 return (PyObject *)it;
1340
1341create_failure:
Benjamin Peterson36fbb732009-11-16 00:34:25 +00001342 Py_DECREF(it);
Guido van Rossum805365e2007-05-07 22:24:25 +00001343 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001344}