Line data Source code
1 : /* Range object implementation */
2 :
3 : #include "Python.h"
4 : #include "structmember.h"
5 :
6 : /* Support objects whose length is > PY_SSIZE_T_MAX.
7 :
8 : This could be sped up for small PyLongs if they fit in an Py_ssize_t.
9 : This only matters on Win64. Though we could use PY_LONG_LONG which
10 : would presumably help perf.
11 : */
12 :
13 : typedef struct {
14 : PyObject_HEAD
15 : PyObject *start;
16 : PyObject *stop;
17 : PyObject *step;
18 : PyObject *length;
19 : } rangeobject;
20 :
21 : /* Helper function for validating step. Always returns a new reference or
22 : NULL on error.
23 : */
24 : static PyObject *
25 57 : validate_step(PyObject *step)
26 : {
27 : /* No step specified, use a step of 1. */
28 57 : if (!step)
29 56 : return PyLong_FromLong(1);
30 :
31 1 : step = PyNumber_Index(step);
32 1 : if (step) {
33 1 : Py_ssize_t istep = PyNumber_AsSsize_t(step, NULL);
34 1 : if (istep == -1 && PyErr_Occurred()) {
35 : /* Ignore OverflowError, we know the value isn't 0. */
36 0 : PyErr_Clear();
37 : }
38 1 : else if (istep == 0) {
39 0 : PyErr_SetString(PyExc_ValueError,
40 : "range() arg 3 must not be zero");
41 0 : Py_CLEAR(step);
42 : }
43 : }
44 :
45 1 : return step;
46 : }
47 :
48 : static PyObject *
49 : compute_range_length(PyObject *start, PyObject *stop, PyObject *step);
50 :
51 : static rangeobject *
52 109 : make_range_object(PyTypeObject *type, PyObject *start,
53 : PyObject *stop, PyObject *step)
54 : {
55 109 : rangeobject *obj = NULL;
56 : PyObject *length;
57 109 : length = compute_range_length(start, stop, step);
58 109 : if (length == NULL) {
59 0 : return NULL;
60 : }
61 109 : obj = PyObject_New(rangeobject, type);
62 109 : if (obj == NULL) {
63 0 : Py_DECREF(length);
64 0 : return NULL;
65 : }
66 109 : obj->start = start;
67 109 : obj->stop = stop;
68 109 : obj->step = step;
69 109 : obj->length = length;
70 109 : return obj;
71 : }
72 :
73 : /* XXX(nnorwitz): should we error check if the user passes any empty ranges?
74 : range(-10)
75 : range(0, -5)
76 : range(0, 5, -1)
77 : */
78 : static PyObject *
79 109 : range_new(PyTypeObject *type, PyObject *args, PyObject *kw)
80 : {
81 : rangeobject *obj;
82 109 : PyObject *start = NULL, *stop = NULL, *step = NULL;
83 :
84 109 : if (!_PyArg_NoKeywords("range()", kw))
85 0 : return NULL;
86 :
87 109 : if (PyTuple_Size(args) <= 1) {
88 52 : if (!PyArg_UnpackTuple(args, "range", 1, 1, &stop))
89 0 : return NULL;
90 52 : stop = PyNumber_Index(stop);
91 52 : if (!stop)
92 0 : return NULL;
93 52 : start = PyLong_FromLong(0);
94 52 : if (!start) {
95 0 : Py_DECREF(stop);
96 0 : return NULL;
97 : }
98 52 : step = PyLong_FromLong(1);
99 52 : if (!step) {
100 0 : Py_DECREF(stop);
101 0 : Py_DECREF(start);
102 0 : return NULL;
103 : }
104 : }
105 : else {
106 57 : if (!PyArg_UnpackTuple(args, "range", 2, 3,
107 : &start, &stop, &step))
108 0 : return NULL;
109 :
110 : /* Convert borrowed refs to owned refs */
111 57 : start = PyNumber_Index(start);
112 57 : if (!start)
113 0 : return NULL;
114 57 : stop = PyNumber_Index(stop);
115 57 : if (!stop) {
116 0 : Py_DECREF(start);
117 0 : return NULL;
118 : }
119 57 : step = validate_step(step); /* Caution, this can clear exceptions */
120 57 : if (!step) {
121 0 : Py_DECREF(start);
122 0 : Py_DECREF(stop);
123 0 : return NULL;
124 : }
125 : }
126 :
127 109 : obj = make_range_object(type, start, stop, step);
128 109 : if (obj != NULL)
129 109 : return (PyObject *) obj;
130 :
131 : /* Failed to create object, release attributes */
132 0 : Py_XDECREF(start);
133 0 : Py_XDECREF(stop);
134 0 : Py_XDECREF(step);
135 0 : return NULL;
136 : }
137 :
138 : PyDoc_STRVAR(range_doc,
139 : "range([start,] stop[, step]) -> range object\n\
140 : \n\
141 : Returns a virtual sequence of numbers from start to stop by step.");
142 :
143 : static void
144 109 : range_dealloc(rangeobject *r)
145 : {
146 109 : Py_DECREF(r->start);
147 109 : Py_DECREF(r->stop);
148 109 : Py_DECREF(r->step);
149 109 : Py_DECREF(r->length);
150 109 : PyObject_Del(r);
151 109 : }
152 :
153 : /* Return number of items in range (lo, hi, step) as a PyLong object,
154 : * when arguments are PyLong objects. Arguments MUST return 1 with
155 : * PyLong_Check(). Return NULL when there is an error.
156 : */
157 : static PyObject*
158 109 : compute_range_length(PyObject *start, PyObject *stop, PyObject *step)
159 : {
160 : /* -------------------------------------------------------------
161 : Algorithm is equal to that of get_len_of_range(), but it operates
162 : on PyObjects (which are assumed to be PyLong objects).
163 : ---------------------------------------------------------------*/
164 : int cmp_result;
165 : PyObject *lo, *hi;
166 109 : PyObject *diff = NULL;
167 109 : PyObject *one = NULL;
168 109 : PyObject *tmp1 = NULL, *tmp2 = NULL, *result;
169 : /* holds sub-expression evaluations */
170 :
171 109 : PyObject *zero = PyLong_FromLong(0);
172 109 : if (zero == NULL)
173 0 : return NULL;
174 109 : cmp_result = PyObject_RichCompareBool(step, zero, Py_GT);
175 109 : Py_DECREF(zero);
176 109 : if (cmp_result == -1)
177 0 : return NULL;
178 :
179 109 : if (cmp_result == 1) {
180 109 : lo = start;
181 109 : hi = stop;
182 109 : Py_INCREF(step);
183 : } else {
184 0 : lo = stop;
185 0 : hi = start;
186 0 : step = PyNumber_Negative(step);
187 0 : if (!step)
188 0 : return NULL;
189 : }
190 :
191 : /* if (lo >= hi), return length of 0. */
192 109 : if (PyObject_RichCompareBool(lo, hi, Py_GE) == 1) {
193 1 : Py_XDECREF(step);
194 1 : return PyLong_FromLong(0);
195 : }
196 :
197 108 : if ((one = PyLong_FromLong(1L)) == NULL)
198 0 : goto Fail;
199 :
200 108 : if ((tmp1 = PyNumber_Subtract(hi, lo)) == NULL)
201 0 : goto Fail;
202 :
203 108 : if ((diff = PyNumber_Subtract(tmp1, one)) == NULL)
204 0 : goto Fail;
205 :
206 108 : if ((tmp2 = PyNumber_FloorDivide(diff, step)) == NULL)
207 0 : goto Fail;
208 :
209 108 : if ((result = PyNumber_Add(tmp2, one)) == NULL)
210 0 : goto Fail;
211 :
212 108 : Py_DECREF(tmp2);
213 108 : Py_DECREF(diff);
214 108 : Py_DECREF(step);
215 108 : Py_DECREF(tmp1);
216 108 : Py_DECREF(one);
217 108 : return result;
218 :
219 : Fail:
220 0 : Py_XDECREF(tmp2);
221 0 : Py_XDECREF(diff);
222 0 : Py_XDECREF(step);
223 0 : Py_XDECREF(tmp1);
224 0 : Py_XDECREF(one);
225 0 : return NULL;
226 : }
227 :
228 : static Py_ssize_t
229 0 : range_length(rangeobject *r)
230 : {
231 0 : return PyLong_AsSsize_t(r->length);
232 : }
233 :
234 : static PyObject *
235 0 : compute_item(rangeobject *r, PyObject *i)
236 : {
237 : PyObject *incr, *result;
238 : /* PyLong equivalent to:
239 : * return r->start + (i * r->step)
240 : */
241 0 : incr = PyNumber_Multiply(i, r->step);
242 0 : if (!incr)
243 0 : return NULL;
244 0 : result = PyNumber_Add(r->start, incr);
245 0 : Py_DECREF(incr);
246 0 : return result;
247 : }
248 :
249 : static PyObject *
250 0 : compute_range_item(rangeobject *r, PyObject *arg)
251 : {
252 : int cmp_result;
253 : PyObject *i, *result;
254 :
255 0 : PyObject *zero = PyLong_FromLong(0);
256 0 : if (zero == NULL)
257 0 : return NULL;
258 :
259 : /* PyLong equivalent to:
260 : * if (arg < 0) {
261 : * i = r->length + arg
262 : * } else {
263 : * i = arg
264 : * }
265 : */
266 0 : cmp_result = PyObject_RichCompareBool(arg, zero, Py_LT);
267 0 : if (cmp_result == -1) {
268 0 : Py_DECREF(zero);
269 0 : return NULL;
270 : }
271 0 : if (cmp_result == 1) {
272 0 : i = PyNumber_Add(r->length, arg);
273 0 : if (!i) {
274 0 : Py_DECREF(zero);
275 0 : return NULL;
276 : }
277 : } else {
278 0 : i = arg;
279 0 : Py_INCREF(i);
280 : }
281 :
282 : /* PyLong equivalent to:
283 : * if (i < 0 || i >= r->length) {
284 : * <report index out of bounds>
285 : * }
286 : */
287 0 : cmp_result = PyObject_RichCompareBool(i, zero, Py_LT);
288 0 : Py_DECREF(zero);
289 0 : if (cmp_result == 0) {
290 0 : cmp_result = PyObject_RichCompareBool(i, r->length, Py_GE);
291 : }
292 0 : if (cmp_result == -1) {
293 0 : Py_DECREF(i);
294 0 : return NULL;
295 : }
296 0 : if (cmp_result == 1) {
297 0 : Py_DECREF(i);
298 0 : PyErr_SetString(PyExc_IndexError,
299 : "range object index out of range");
300 0 : return NULL;
301 : }
302 :
303 0 : result = compute_item(r, i);
304 0 : Py_DECREF(i);
305 0 : return result;
306 : }
307 :
308 : static PyObject *
309 0 : range_item(rangeobject *r, Py_ssize_t i)
310 : {
311 0 : PyObject *res, *arg = PyLong_FromSsize_t(i);
312 0 : if (!arg) {
313 0 : return NULL;
314 : }
315 0 : res = compute_range_item(r, arg);
316 0 : Py_DECREF(arg);
317 0 : return res;
318 : }
319 :
320 : /* Additional helpers, since the standard slice helpers
321 : * all clip to PY_SSIZE_T_MAX
322 : */
323 :
324 : /* Replace _PyEval_SliceIndex */
325 : static PyObject *
326 0 : compute_slice_element(PyObject *obj)
327 : {
328 0 : PyObject *result = NULL;
329 0 : if (obj != NULL) {
330 0 : if (PyIndex_Check(obj)) {
331 0 : result = PyNumber_Index(obj);
332 : }
333 : }
334 0 : if (result == NULL) {
335 0 : PyErr_SetString(PyExc_TypeError,
336 : "slice indices must be integers or "
337 : "None or have an __index__ method");
338 : }
339 0 : return result;
340 : }
341 :
342 : /* Replace PySlice_GetIndicesEx
343 : * Result indicates whether or not the slice is empty
344 : * (-1 = error, 0 = empty slice, 1 = slice contains elements)
345 : */
346 : static int
347 0 : compute_slice_indices(rangeobject *r, PySliceObject *slice,
348 : PyObject **start, PyObject **stop, PyObject **step)
349 : {
350 : int cmp_result, has_elements;
351 0 : Py_ssize_t clamped_step = 0;
352 0 : PyObject *zero = NULL, *one = NULL, *neg_one = NULL, *candidate = NULL;
353 0 : PyObject *tmp_start = NULL, *tmp_stop = NULL, *tmp_step = NULL;
354 0 : zero = PyLong_FromLong(0);
355 0 : if (zero == NULL) goto Fail;
356 0 : one = PyLong_FromLong(1);
357 0 : if (one == NULL) goto Fail;
358 0 : neg_one = PyLong_FromLong(-1);
359 0 : if (neg_one == NULL) goto Fail;
360 :
361 : /* Calculate step value */
362 0 : if (slice->step == Py_None) {
363 0 : clamped_step = 1;
364 0 : tmp_step = one;
365 0 : Py_INCREF(tmp_step);
366 : } else {
367 0 : if (!_PyEval_SliceIndex(slice->step, &clamped_step)) goto Fail;
368 0 : if (clamped_step == 0) {
369 0 : PyErr_SetString(PyExc_ValueError,
370 : "slice step cannot be zero");
371 0 : goto Fail;
372 : }
373 0 : tmp_step = compute_slice_element(slice->step);
374 0 : if (tmp_step == NULL) goto Fail;
375 : }
376 :
377 : /* Calculate start value */
378 0 : if (slice->start == Py_None) {
379 0 : if (clamped_step < 0) {
380 0 : tmp_start = PyNumber_Subtract(r->length, one);
381 0 : if (tmp_start == NULL) goto Fail;
382 : } else {
383 0 : tmp_start = zero;
384 0 : Py_INCREF(tmp_start);
385 : }
386 : } else {
387 0 : candidate = compute_slice_element(slice->start);
388 0 : if (candidate == NULL) goto Fail;
389 0 : cmp_result = PyObject_RichCompareBool(candidate, zero, Py_LT);
390 0 : if (cmp_result == -1) goto Fail;
391 0 : if (cmp_result) {
392 : /* candidate < 0 */
393 0 : tmp_start = PyNumber_Add(r->length, candidate);
394 0 : if (tmp_start == NULL) goto Fail;
395 0 : Py_CLEAR(candidate);
396 : } else {
397 : /* candidate >= 0 */
398 0 : tmp_start = candidate;
399 0 : candidate = NULL;
400 : }
401 0 : cmp_result = PyObject_RichCompareBool(tmp_start, zero, Py_LT);
402 0 : if (cmp_result == -1) goto Fail;
403 0 : if (cmp_result) {
404 : /* tmp_start < 0 */
405 0 : Py_CLEAR(tmp_start);
406 0 : if (clamped_step < 0) {
407 0 : tmp_start = neg_one;
408 : } else {
409 0 : tmp_start = zero;
410 : }
411 0 : Py_INCREF(tmp_start);
412 : } else {
413 : /* tmp_start >= 0 */
414 0 : cmp_result = PyObject_RichCompareBool(tmp_start, r->length, Py_GE);
415 0 : if (cmp_result == -1) goto Fail;
416 0 : if (cmp_result) {
417 : /* tmp_start >= r->length */
418 0 : Py_CLEAR(tmp_start);
419 0 : if (clamped_step < 0) {
420 0 : tmp_start = PyNumber_Subtract(r->length, one);
421 0 : if (tmp_start == NULL) goto Fail;
422 : } else {
423 0 : tmp_start = r->length;
424 0 : Py_INCREF(tmp_start);
425 : }
426 : }
427 : }
428 : }
429 :
430 : /* Calculate stop value */
431 0 : if (slice->stop == Py_None) {
432 0 : if (clamped_step < 0) {
433 0 : tmp_stop = neg_one;
434 : } else {
435 0 : tmp_stop = r->length;
436 : }
437 0 : Py_INCREF(tmp_stop);
438 : } else {
439 0 : candidate = compute_slice_element(slice->stop);
440 0 : if (candidate == NULL) goto Fail;
441 0 : cmp_result = PyObject_RichCompareBool(candidate, zero, Py_LT);
442 0 : if (cmp_result == -1) goto Fail;
443 0 : if (cmp_result) {
444 : /* candidate < 0 */
445 0 : tmp_stop = PyNumber_Add(r->length, candidate);
446 0 : if (tmp_stop == NULL) goto Fail;
447 0 : Py_CLEAR(candidate);
448 : } else {
449 : /* candidate >= 0 */
450 0 : tmp_stop = candidate;
451 0 : candidate = NULL;
452 : }
453 0 : cmp_result = PyObject_RichCompareBool(tmp_stop, zero, Py_LT);
454 0 : if (cmp_result == -1) goto Fail;
455 0 : if (cmp_result) {
456 : /* tmp_stop < 0 */
457 0 : Py_CLEAR(tmp_stop);
458 0 : if (clamped_step < 0) {
459 0 : tmp_stop = neg_one;
460 : } else {
461 0 : tmp_stop = zero;
462 : }
463 0 : Py_INCREF(tmp_stop);
464 : } else {
465 : /* tmp_stop >= 0 */
466 0 : cmp_result = PyObject_RichCompareBool(tmp_stop, r->length, Py_GE);
467 0 : if (cmp_result == -1) goto Fail;
468 0 : if (cmp_result) {
469 : /* tmp_stop >= r->length */
470 0 : Py_CLEAR(tmp_stop);
471 0 : if (clamped_step < 0) {
472 0 : tmp_stop = PyNumber_Subtract(r->length, one);
473 0 : if (tmp_stop == NULL) goto Fail;
474 : } else {
475 0 : tmp_stop = r->length;
476 0 : Py_INCREF(tmp_stop);
477 : }
478 : }
479 : }
480 : }
481 :
482 : /* Check if the slice is empty or not */
483 0 : if (clamped_step < 0) {
484 0 : has_elements = PyObject_RichCompareBool(tmp_start, tmp_stop, Py_GT);
485 : } else {
486 0 : has_elements = PyObject_RichCompareBool(tmp_start, tmp_stop, Py_LT);
487 : }
488 0 : if (has_elements == -1) goto Fail;
489 :
490 0 : *start = tmp_start;
491 0 : *stop = tmp_stop;
492 0 : *step = tmp_step;
493 0 : Py_DECREF(neg_one);
494 0 : Py_DECREF(one);
495 0 : Py_DECREF(zero);
496 0 : return has_elements;
497 :
498 : Fail:
499 0 : Py_XDECREF(tmp_start);
500 0 : Py_XDECREF(tmp_stop);
501 0 : Py_XDECREF(tmp_step);
502 0 : Py_XDECREF(candidate);
503 0 : Py_XDECREF(neg_one);
504 0 : Py_XDECREF(one);
505 0 : Py_XDECREF(zero);
506 0 : return -1;
507 : }
508 :
509 : static PyObject *
510 0 : compute_slice(rangeobject *r, PyObject *_slice)
511 : {
512 0 : PySliceObject *slice = (PySliceObject *) _slice;
513 : rangeobject *result;
514 0 : PyObject *start = NULL, *stop = NULL, *step = NULL;
515 0 : PyObject *substart = NULL, *substop = NULL, *substep = NULL;
516 : int has_elements;
517 :
518 0 : has_elements = compute_slice_indices(r, slice, &start, &stop, &step);
519 0 : if (has_elements == -1) return NULL;
520 :
521 0 : substep = PyNumber_Multiply(r->step, step);
522 0 : if (substep == NULL) goto fail;
523 0 : Py_CLEAR(step);
524 :
525 0 : substart = compute_item(r, start);
526 0 : if (substart == NULL) goto fail;
527 0 : Py_CLEAR(start);
528 :
529 0 : if (has_elements) {
530 0 : substop = compute_item(r, stop);
531 0 : if (substop == NULL) goto fail;
532 : } else {
533 0 : substop = substart;
534 0 : Py_INCREF(substop);
535 : }
536 0 : Py_CLEAR(stop);
537 :
538 0 : result = make_range_object(Py_TYPE(r), substart, substop, substep);
539 0 : if (result != NULL) {
540 0 : return (PyObject *) result;
541 : }
542 : fail:
543 0 : Py_XDECREF(start);
544 0 : Py_XDECREF(stop);
545 0 : Py_XDECREF(step);
546 0 : Py_XDECREF(substart);
547 0 : Py_XDECREF(substop);
548 0 : Py_XDECREF(substep);
549 0 : return NULL;
550 : }
551 :
552 : /* Assumes (PyLong_CheckExact(ob) || PyBool_Check(ob)) */
553 : static int
554 0 : range_contains_long(rangeobject *r, PyObject *ob)
555 : {
556 : int cmp1, cmp2, cmp3;
557 0 : PyObject *tmp1 = NULL;
558 0 : PyObject *tmp2 = NULL;
559 0 : PyObject *zero = NULL;
560 0 : int result = -1;
561 :
562 0 : zero = PyLong_FromLong(0);
563 0 : if (zero == NULL) /* MemoryError in int(0) */
564 0 : goto end;
565 :
566 : /* Check if the value can possibly be in the range. */
567 :
568 0 : cmp1 = PyObject_RichCompareBool(r->step, zero, Py_GT);
569 0 : if (cmp1 == -1)
570 0 : goto end;
571 0 : if (cmp1 == 1) { /* positive steps: start <= ob < stop */
572 0 : cmp2 = PyObject_RichCompareBool(r->start, ob, Py_LE);
573 0 : cmp3 = PyObject_RichCompareBool(ob, r->stop, Py_LT);
574 : }
575 : else { /* negative steps: stop < ob <= start */
576 0 : cmp2 = PyObject_RichCompareBool(ob, r->start, Py_LE);
577 0 : cmp3 = PyObject_RichCompareBool(r->stop, ob, Py_LT);
578 : }
579 :
580 0 : if (cmp2 == -1 || cmp3 == -1) /* TypeError */
581 : goto end;
582 0 : if (cmp2 == 0 || cmp3 == 0) { /* ob outside of range */
583 0 : result = 0;
584 0 : goto end;
585 : }
586 :
587 : /* Check that the stride does not invalidate ob's membership. */
588 0 : tmp1 = PyNumber_Subtract(ob, r->start);
589 0 : if (tmp1 == NULL)
590 0 : goto end;
591 0 : tmp2 = PyNumber_Remainder(tmp1, r->step);
592 0 : if (tmp2 == NULL)
593 0 : goto end;
594 : /* result = (int(ob) - start % step) == 0 */
595 0 : result = PyObject_RichCompareBool(tmp2, zero, Py_EQ);
596 : end:
597 0 : Py_XDECREF(tmp1);
598 0 : Py_XDECREF(tmp2);
599 0 : Py_XDECREF(zero);
600 0 : return result;
601 : }
602 :
603 : static int
604 0 : range_contains(rangeobject *r, PyObject *ob)
605 : {
606 0 : if (PyLong_CheckExact(ob) || PyBool_Check(ob))
607 0 : return range_contains_long(r, ob);
608 :
609 0 : return (int)_PySequence_IterSearch((PyObject*)r, ob,
610 : PY_ITERSEARCH_CONTAINS);
611 : }
612 :
613 : /* Compare two range objects. Return 1 for equal, 0 for not equal
614 : and -1 on error. The algorithm is roughly the C equivalent of
615 :
616 : if r0 is r1:
617 : return True
618 : if len(r0) != len(r1):
619 : return False
620 : if not len(r0):
621 : return True
622 : if r0.start != r1.start:
623 : return False
624 : if len(r0) == 1:
625 : return True
626 : return r0.step == r1.step
627 : */
628 : static int
629 0 : range_equals(rangeobject *r0, rangeobject *r1)
630 : {
631 : int cmp_result;
632 : PyObject *one;
633 :
634 0 : if (r0 == r1)
635 0 : return 1;
636 0 : cmp_result = PyObject_RichCompareBool(r0->length, r1->length, Py_EQ);
637 : /* Return False or error to the caller. */
638 0 : if (cmp_result != 1)
639 0 : return cmp_result;
640 0 : cmp_result = PyObject_Not(r0->length);
641 : /* Return True or error to the caller. */
642 0 : if (cmp_result != 0)
643 0 : return cmp_result;
644 0 : cmp_result = PyObject_RichCompareBool(r0->start, r1->start, Py_EQ);
645 : /* Return False or error to the caller. */
646 0 : if (cmp_result != 1)
647 0 : return cmp_result;
648 0 : one = PyLong_FromLong(1);
649 0 : if (!one)
650 0 : return -1;
651 0 : cmp_result = PyObject_RichCompareBool(r0->length, one, Py_EQ);
652 0 : Py_DECREF(one);
653 : /* Return True or error to the caller. */
654 0 : if (cmp_result != 0)
655 0 : return cmp_result;
656 0 : return PyObject_RichCompareBool(r0->step, r1->step, Py_EQ);
657 : }
658 :
659 : static PyObject *
660 0 : range_richcompare(PyObject *self, PyObject *other, int op)
661 : {
662 : int result;
663 :
664 0 : if (!PyRange_Check(other))
665 0 : Py_RETURN_NOTIMPLEMENTED;
666 0 : switch (op) {
667 : case Py_NE:
668 : case Py_EQ:
669 0 : result = range_equals((rangeobject*)self, (rangeobject*)other);
670 0 : if (result == -1)
671 0 : return NULL;
672 0 : if (op == Py_NE)
673 0 : result = !result;
674 0 : if (result)
675 0 : Py_RETURN_TRUE;
676 : else
677 0 : Py_RETURN_FALSE;
678 : case Py_LE:
679 : case Py_GE:
680 : case Py_LT:
681 : case Py_GT:
682 0 : Py_RETURN_NOTIMPLEMENTED;
683 : default:
684 0 : PyErr_BadArgument();
685 0 : return NULL;
686 : }
687 : }
688 :
689 : /* Hash function for range objects. Rough C equivalent of
690 :
691 : if not len(r):
692 : return hash((len(r), None, None))
693 : if len(r) == 1:
694 : return hash((len(r), r.start, None))
695 : return hash((len(r), r.start, r.step))
696 : */
697 : static Py_hash_t
698 0 : range_hash(rangeobject *r)
699 : {
700 : PyObject *t;
701 0 : Py_hash_t result = -1;
702 : int cmp_result;
703 :
704 0 : t = PyTuple_New(3);
705 0 : if (!t)
706 0 : return -1;
707 0 : Py_INCREF(r->length);
708 0 : PyTuple_SET_ITEM(t, 0, r->length);
709 0 : cmp_result = PyObject_Not(r->length);
710 0 : if (cmp_result == -1)
711 0 : goto end;
712 0 : if (cmp_result == 1) {
713 0 : Py_INCREF(Py_None);
714 0 : Py_INCREF(Py_None);
715 0 : PyTuple_SET_ITEM(t, 1, Py_None);
716 0 : PyTuple_SET_ITEM(t, 2, Py_None);
717 : }
718 : else {
719 : PyObject *one;
720 0 : Py_INCREF(r->start);
721 0 : PyTuple_SET_ITEM(t, 1, r->start);
722 0 : one = PyLong_FromLong(1);
723 0 : if (!one)
724 0 : goto end;
725 0 : cmp_result = PyObject_RichCompareBool(r->length, one, Py_EQ);
726 0 : Py_DECREF(one);
727 0 : if (cmp_result == -1)
728 0 : goto end;
729 0 : if (cmp_result == 1) {
730 0 : Py_INCREF(Py_None);
731 0 : PyTuple_SET_ITEM(t, 2, Py_None);
732 : }
733 : else {
734 0 : Py_INCREF(r->step);
735 0 : PyTuple_SET_ITEM(t, 2, r->step);
736 : }
737 : }
738 0 : result = PyObject_Hash(t);
739 : end:
740 0 : Py_DECREF(t);
741 0 : return result;
742 : }
743 :
744 : static PyObject *
745 0 : range_count(rangeobject *r, PyObject *ob)
746 : {
747 0 : if (PyLong_CheckExact(ob) || PyBool_Check(ob)) {
748 0 : int result = range_contains_long(r, ob);
749 0 : if (result == -1)
750 0 : return NULL;
751 0 : else if (result)
752 0 : return PyLong_FromLong(1);
753 : else
754 0 : return PyLong_FromLong(0);
755 : } else {
756 : Py_ssize_t count;
757 0 : count = _PySequence_IterSearch((PyObject*)r, ob, PY_ITERSEARCH_COUNT);
758 0 : if (count == -1)
759 0 : return NULL;
760 0 : return PyLong_FromSsize_t(count);
761 : }
762 : }
763 :
764 : static PyObject *
765 0 : range_index(rangeobject *r, PyObject *ob)
766 : {
767 : int contains;
768 :
769 0 : if (!PyLong_CheckExact(ob) && !PyBool_Check(ob)) {
770 : Py_ssize_t index;
771 0 : index = _PySequence_IterSearch((PyObject*)r, ob, PY_ITERSEARCH_INDEX);
772 0 : if (index == -1)
773 0 : return NULL;
774 0 : return PyLong_FromSsize_t(index);
775 : }
776 :
777 0 : contains = range_contains_long(r, ob);
778 0 : if (contains == -1)
779 0 : return NULL;
780 :
781 0 : if (contains) {
782 0 : PyObject *idx, *tmp = PyNumber_Subtract(ob, r->start);
783 0 : if (tmp == NULL)
784 0 : return NULL;
785 : /* idx = (ob - r.start) // r.step */
786 0 : idx = PyNumber_FloorDivide(tmp, r->step);
787 0 : Py_DECREF(tmp);
788 0 : return idx;
789 : }
790 :
791 : /* object is not in the range */
792 0 : PyErr_Format(PyExc_ValueError, "%R is not in range", ob);
793 0 : return NULL;
794 : }
795 :
796 : static PySequenceMethods range_as_sequence = {
797 : (lenfunc)range_length, /* sq_length */
798 : 0, /* sq_concat */
799 : 0, /* sq_repeat */
800 : (ssizeargfunc)range_item, /* sq_item */
801 : 0, /* sq_slice */
802 : 0, /* sq_ass_item */
803 : 0, /* sq_ass_slice */
804 : (objobjproc)range_contains, /* sq_contains */
805 : };
806 :
807 : static PyObject *
808 0 : range_repr(rangeobject *r)
809 : {
810 : Py_ssize_t istep;
811 :
812 : /* Check for special case values for printing. We don't always
813 : need the step value. We don't care about errors
814 : (it means overflow), so clear the errors. */
815 0 : istep = PyNumber_AsSsize_t(r->step, NULL);
816 0 : if (istep != 1 || (istep == -1 && PyErr_Occurred())) {
817 0 : PyErr_Clear();
818 : }
819 :
820 0 : if (istep == 1)
821 0 : return PyUnicode_FromFormat("range(%R, %R)", r->start, r->stop);
822 : else
823 0 : return PyUnicode_FromFormat("range(%R, %R, %R)",
824 : r->start, r->stop, r->step);
825 : }
826 :
827 : /* Pickling support */
828 : static PyObject *
829 0 : range_reduce(rangeobject *r, PyObject *args)
830 : {
831 0 : return Py_BuildValue("(O(OOO))", Py_TYPE(r),
832 : r->start, r->stop, r->step);
833 : }
834 :
835 : static PyObject *
836 0 : range_subscript(rangeobject* self, PyObject* item)
837 : {
838 0 : if (PyIndex_Check(item)) {
839 : PyObject *i, *result;
840 0 : i = PyNumber_Index(item);
841 0 : if (!i)
842 0 : return NULL;
843 0 : result = compute_range_item(self, i);
844 0 : Py_DECREF(i);
845 0 : return result;
846 : }
847 0 : if (PySlice_Check(item)) {
848 0 : return compute_slice(self, item);
849 : }
850 0 : PyErr_Format(PyExc_TypeError,
851 : "range indices must be integers or slices, not %.200s",
852 0 : item->ob_type->tp_name);
853 0 : return NULL;
854 : }
855 :
856 :
857 : static PyMappingMethods range_as_mapping = {
858 : (lenfunc)range_length, /* mp_length */
859 : (binaryfunc)range_subscript, /* mp_subscript */
860 : (objobjargproc)0, /* mp_ass_subscript */
861 : };
862 :
863 : static PyObject * range_iter(PyObject *seq);
864 : static PyObject * range_reverse(PyObject *seq);
865 :
866 : PyDoc_STRVAR(reverse_doc,
867 : "Returns a reverse iterator.");
868 :
869 : PyDoc_STRVAR(count_doc,
870 : "rangeobject.count(value) -> integer -- return number of occurrences of value");
871 :
872 : PyDoc_STRVAR(index_doc,
873 : "rangeobject.index(value, [start, [stop]]) -> integer -- return index of value.\n"
874 : "Raises ValueError if the value is not present.");
875 :
876 : static PyMethodDef range_methods[] = {
877 : {"__reversed__", (PyCFunction)range_reverse, METH_NOARGS, reverse_doc},
878 : {"__reduce__", (PyCFunction)range_reduce, METH_VARARGS},
879 : {"count", (PyCFunction)range_count, METH_O, count_doc},
880 : {"index", (PyCFunction)range_index, METH_O, index_doc},
881 : {NULL, NULL} /* sentinel */
882 : };
883 :
884 : static PyMemberDef range_members[] = {
885 : {"start", T_OBJECT_EX, offsetof(rangeobject, start), READONLY},
886 : {"stop", T_OBJECT_EX, offsetof(rangeobject, stop), READONLY},
887 : {"step", T_OBJECT_EX, offsetof(rangeobject, step), READONLY},
888 : {0}
889 : };
890 :
891 : PyTypeObject PyRange_Type = {
892 : PyVarObject_HEAD_INIT(&PyType_Type, 0)
893 : "range", /* Name of this type */
894 : sizeof(rangeobject), /* Basic object size */
895 : 0, /* Item size for varobject */
896 : (destructor)range_dealloc, /* tp_dealloc */
897 : 0, /* tp_print */
898 : 0, /* tp_getattr */
899 : 0, /* tp_setattr */
900 : 0, /* tp_reserved */
901 : (reprfunc)range_repr, /* tp_repr */
902 : 0, /* tp_as_number */
903 : &range_as_sequence, /* tp_as_sequence */
904 : &range_as_mapping, /* tp_as_mapping */
905 : (hashfunc)range_hash, /* tp_hash */
906 : 0, /* tp_call */
907 : 0, /* tp_str */
908 : PyObject_GenericGetAttr, /* tp_getattro */
909 : 0, /* tp_setattro */
910 : 0, /* tp_as_buffer */
911 : Py_TPFLAGS_DEFAULT, /* tp_flags */
912 : range_doc, /* tp_doc */
913 : 0, /* tp_traverse */
914 : 0, /* tp_clear */
915 : range_richcompare, /* tp_richcompare */
916 : 0, /* tp_weaklistoffset */
917 : range_iter, /* tp_iter */
918 : 0, /* tp_iternext */
919 : range_methods, /* tp_methods */
920 : range_members, /* tp_members */
921 : 0, /* tp_getset */
922 : 0, /* tp_base */
923 : 0, /* tp_dict */
924 : 0, /* tp_descr_get */
925 : 0, /* tp_descr_set */
926 : 0, /* tp_dictoffset */
927 : 0, /* tp_init */
928 : 0, /* tp_alloc */
929 : range_new, /* tp_new */
930 : };
931 :
932 : /*********************** range Iterator **************************/
933 :
934 : /* There are 2 types of iterators, one for C longs, the other for
935 : Python longs (ie, PyObjects). This should make iteration fast
936 : in the normal case, but possible for any numeric value.
937 : */
938 :
939 : typedef struct {
940 : PyObject_HEAD
941 : long index;
942 : long start;
943 : long step;
944 : long len;
945 : } rangeiterobject;
946 :
947 : static PyObject *
948 12038 : rangeiter_next(rangeiterobject *r)
949 : {
950 12038 : if (r->index < r->len)
951 : /* cast to unsigned to avoid possible signed overflow
952 : in intermediate calculations. */
953 35790 : return PyLong_FromLong((long)(r->start +
954 23860 : (unsigned long)(r->index++) * r->step));
955 108 : return NULL;
956 : }
957 :
958 : static PyObject *
959 0 : rangeiter_len(rangeiterobject *r)
960 : {
961 0 : return PyLong_FromLong(r->len - r->index);
962 : }
963 :
964 : PyDoc_STRVAR(length_hint_doc,
965 : "Private method returning an estimate of len(list(it)).");
966 :
967 : static PyObject *
968 0 : rangeiter_reduce(rangeiterobject *r)
969 : {
970 0 : PyObject *start=NULL, *stop=NULL, *step=NULL;
971 : PyObject *range;
972 :
973 : /* create a range object for pickling */
974 0 : start = PyLong_FromLong(r->start);
975 0 : if (start == NULL)
976 0 : goto err;
977 0 : stop = PyLong_FromLong(r->start + r->len * r->step);
978 0 : if (stop == NULL)
979 0 : goto err;
980 0 : step = PyLong_FromLong(r->step);
981 0 : if (step == NULL)
982 0 : goto err;
983 0 : range = (PyObject*)make_range_object(&PyRange_Type,
984 : start, stop, step);
985 0 : if (range == NULL)
986 0 : goto err;
987 : /* return the result */
988 0 : return Py_BuildValue("N(N)i", _PyObject_GetBuiltin("iter"), range, r->index);
989 : err:
990 0 : Py_XDECREF(start);
991 0 : Py_XDECREF(stop);
992 0 : Py_XDECREF(step);
993 0 : return NULL;
994 : }
995 :
996 : static PyObject *
997 0 : rangeiter_setstate(rangeiterobject *r, PyObject *state)
998 : {
999 0 : long index = PyLong_AsLong(state);
1000 0 : if (index == -1 && PyErr_Occurred())
1001 0 : return NULL;
1002 0 : if (index < 0 || index >= r->len) {
1003 0 : PyErr_SetString(PyExc_ValueError, "index out of range");
1004 0 : return NULL;
1005 : }
1006 0 : r->index = index;
1007 0 : Py_RETURN_NONE;
1008 : }
1009 :
1010 : PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
1011 : PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
1012 :
1013 : static PyMethodDef rangeiter_methods[] = {
1014 : {"__length_hint__", (PyCFunction)rangeiter_len, METH_NOARGS,
1015 : length_hint_doc},
1016 : {"__reduce__", (PyCFunction)rangeiter_reduce, METH_NOARGS,
1017 : reduce_doc},
1018 : {"__setstate__", (PyCFunction)rangeiter_setstate, METH_O,
1019 : setstate_doc},
1020 : {NULL, NULL} /* sentinel */
1021 : };
1022 :
1023 : static PyObject *rangeiter_new(PyTypeObject *, PyObject *args, PyObject *kw);
1024 :
1025 : PyTypeObject PyRangeIter_Type = {
1026 : PyVarObject_HEAD_INIT(&PyType_Type, 0)
1027 : "range_iterator", /* tp_name */
1028 : sizeof(rangeiterobject), /* tp_basicsize */
1029 : 0, /* tp_itemsize */
1030 : /* methods */
1031 : (destructor)PyObject_Del, /* tp_dealloc */
1032 : 0, /* tp_print */
1033 : 0, /* tp_getattr */
1034 : 0, /* tp_setattr */
1035 : 0, /* tp_reserved */
1036 : 0, /* tp_repr */
1037 : 0, /* tp_as_number */
1038 : 0, /* tp_as_sequence */
1039 : 0, /* tp_as_mapping */
1040 : 0, /* tp_hash */
1041 : 0, /* tp_call */
1042 : 0, /* tp_str */
1043 : PyObject_GenericGetAttr, /* tp_getattro */
1044 : 0, /* tp_setattro */
1045 : 0, /* tp_as_buffer */
1046 : Py_TPFLAGS_DEFAULT, /* tp_flags */
1047 : 0, /* tp_doc */
1048 : 0, /* tp_traverse */
1049 : 0, /* tp_clear */
1050 : 0, /* tp_richcompare */
1051 : 0, /* tp_weaklistoffset */
1052 : PyObject_SelfIter, /* tp_iter */
1053 : (iternextfunc)rangeiter_next, /* tp_iternext */
1054 : rangeiter_methods, /* tp_methods */
1055 : 0, /* tp_members */
1056 : 0, /* tp_getset */
1057 : 0, /* tp_base */
1058 : 0, /* tp_dict */
1059 : 0, /* tp_descr_get */
1060 : 0, /* tp_descr_set */
1061 : 0, /* tp_dictoffset */
1062 : 0, /* tp_init */
1063 : 0, /* tp_alloc */
1064 : rangeiter_new, /* tp_new */
1065 : };
1066 :
1067 : /* Return number of items in range (lo, hi, step). step != 0
1068 : * required. The result always fits in an unsigned long.
1069 : */
1070 : static unsigned long
1071 109 : get_len_of_range(long lo, long hi, long step)
1072 : {
1073 : /* -------------------------------------------------------------
1074 : If step > 0 and lo >= hi, or step < 0 and lo <= hi, the range is empty.
1075 : Else for step > 0, if n values are in the range, the last one is
1076 : lo + (n-1)*step, which must be <= hi-1. Rearranging,
1077 : n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives
1078 : the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so
1079 : the RHS is non-negative and so truncation is the same as the
1080 : floor. Letting M be the largest positive long, the worst case
1081 : for the RHS numerator is hi=M, lo=-M-1, and then
1082 : hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough
1083 : precision to compute the RHS exactly. The analysis for step < 0
1084 : is similar.
1085 : ---------------------------------------------------------------*/
1086 : assert(step != 0);
1087 109 : if (step > 0 && lo < hi)
1088 108 : return 1UL + (hi - 1UL - lo) / step;
1089 1 : else if (step < 0 && lo > hi)
1090 0 : return 1UL + (lo - 1UL - hi) / (0UL - step);
1091 : else
1092 1 : return 0UL;
1093 : }
1094 :
1095 : /* Initialize a rangeiter object. If the length of the rangeiter object
1096 : is not representable as a C long, OverflowError is raised. */
1097 :
1098 : static PyObject *
1099 109 : fast_range_iter(long start, long stop, long step)
1100 : {
1101 109 : rangeiterobject *it = PyObject_New(rangeiterobject, &PyRangeIter_Type);
1102 : unsigned long ulen;
1103 109 : if (it == NULL)
1104 0 : return NULL;
1105 109 : it->start = start;
1106 109 : it->step = step;
1107 109 : ulen = get_len_of_range(start, stop, step);
1108 109 : if (ulen > (unsigned long)LONG_MAX) {
1109 0 : Py_DECREF(it);
1110 0 : PyErr_SetString(PyExc_OverflowError,
1111 : "range too large to represent as a range_iterator");
1112 0 : return NULL;
1113 : }
1114 109 : it->len = (long)ulen;
1115 109 : it->index = 0;
1116 109 : return (PyObject *)it;
1117 : }
1118 :
1119 : static PyObject *
1120 0 : rangeiter_new(PyTypeObject *type, PyObject *args, PyObject *kw)
1121 : {
1122 : long start, stop, step;
1123 :
1124 0 : if (!_PyArg_NoKeywords("rangeiter()", kw))
1125 0 : return NULL;
1126 :
1127 0 : if (!PyArg_ParseTuple(args, "lll;rangeiter() requires 3 int arguments",
1128 : &start, &stop, &step))
1129 0 : return NULL;
1130 :
1131 0 : return fast_range_iter(start, stop, step);
1132 : }
1133 :
1134 : typedef struct {
1135 : PyObject_HEAD
1136 : PyObject *index;
1137 : PyObject *start;
1138 : PyObject *step;
1139 : PyObject *len;
1140 : } longrangeiterobject;
1141 :
1142 : static PyObject *
1143 0 : longrangeiter_len(longrangeiterobject *r, PyObject *no_args)
1144 : {
1145 0 : return PyNumber_Subtract(r->len, r->index);
1146 : }
1147 :
1148 : static PyObject *
1149 0 : longrangeiter_reduce(longrangeiterobject *r)
1150 : {
1151 0 : PyObject *product, *stop=NULL;
1152 : PyObject *range;
1153 :
1154 : /* create a range object for pickling. Must calculate the "stop" value */
1155 0 : product = PyNumber_Multiply(r->len, r->step);
1156 0 : if (product == NULL)
1157 0 : return NULL;
1158 0 : stop = PyNumber_Add(r->start, product);
1159 0 : Py_DECREF(product);
1160 0 : if (stop == NULL)
1161 0 : return NULL;
1162 0 : Py_INCREF(r->start);
1163 0 : Py_INCREF(r->step);
1164 0 : range = (PyObject*)make_range_object(&PyRange_Type,
1165 : r->start, stop, r->step);
1166 0 : if (range == NULL) {
1167 0 : Py_DECREF(r->start);
1168 0 : Py_DECREF(stop);
1169 0 : Py_DECREF(r->step);
1170 0 : return NULL;
1171 : }
1172 :
1173 : /* return the result */
1174 0 : return Py_BuildValue("N(N)O", _PyObject_GetBuiltin("iter"), range, r->index);
1175 : }
1176 :
1177 : static PyObject *
1178 0 : longrangeiter_setstate(longrangeiterobject *r, PyObject *state)
1179 : {
1180 0 : Py_CLEAR(r->index);
1181 0 : r->index = state;
1182 0 : Py_INCREF(r->index);
1183 0 : Py_RETURN_NONE;
1184 : }
1185 :
1186 : static PyMethodDef longrangeiter_methods[] = {
1187 : {"__length_hint__", (PyCFunction)longrangeiter_len, METH_NOARGS,
1188 : length_hint_doc},
1189 : {"__reduce__", (PyCFunction)longrangeiter_reduce, METH_NOARGS,
1190 : reduce_doc},
1191 : {"__setstate__", (PyCFunction)longrangeiter_setstate, METH_O,
1192 : setstate_doc},
1193 : {NULL, NULL} /* sentinel */
1194 : };
1195 :
1196 : static void
1197 0 : longrangeiter_dealloc(longrangeiterobject *r)
1198 : {
1199 0 : Py_XDECREF(r->index);
1200 0 : Py_XDECREF(r->start);
1201 0 : Py_XDECREF(r->step);
1202 0 : Py_XDECREF(r->len);
1203 0 : PyObject_Del(r);
1204 0 : }
1205 :
1206 : static PyObject *
1207 0 : longrangeiter_next(longrangeiterobject *r)
1208 : {
1209 : PyObject *one, *product, *new_index, *result;
1210 0 : if (PyObject_RichCompareBool(r->index, r->len, Py_LT) != 1)
1211 0 : return NULL;
1212 :
1213 0 : one = PyLong_FromLong(1);
1214 0 : if (!one)
1215 0 : return NULL;
1216 :
1217 0 : new_index = PyNumber_Add(r->index, one);
1218 0 : Py_DECREF(one);
1219 0 : if (!new_index)
1220 0 : return NULL;
1221 :
1222 0 : product = PyNumber_Multiply(r->index, r->step);
1223 0 : if (!product) {
1224 0 : Py_DECREF(new_index);
1225 0 : return NULL;
1226 : }
1227 :
1228 0 : result = PyNumber_Add(r->start, product);
1229 0 : Py_DECREF(product);
1230 0 : if (result) {
1231 0 : Py_DECREF(r->index);
1232 0 : r->index = new_index;
1233 : }
1234 : else {
1235 0 : Py_DECREF(new_index);
1236 : }
1237 :
1238 0 : return result;
1239 : }
1240 :
1241 : PyTypeObject PyLongRangeIter_Type = {
1242 : PyVarObject_HEAD_INIT(&PyType_Type, 0)
1243 : "longrange_iterator", /* tp_name */
1244 : sizeof(longrangeiterobject), /* tp_basicsize */
1245 : 0, /* tp_itemsize */
1246 : /* methods */
1247 : (destructor)longrangeiter_dealloc, /* tp_dealloc */
1248 : 0, /* tp_print */
1249 : 0, /* tp_getattr */
1250 : 0, /* tp_setattr */
1251 : 0, /* tp_reserved */
1252 : 0, /* tp_repr */
1253 : 0, /* tp_as_number */
1254 : 0, /* tp_as_sequence */
1255 : 0, /* tp_as_mapping */
1256 : 0, /* tp_hash */
1257 : 0, /* tp_call */
1258 : 0, /* tp_str */
1259 : PyObject_GenericGetAttr, /* tp_getattro */
1260 : 0, /* tp_setattro */
1261 : 0, /* tp_as_buffer */
1262 : Py_TPFLAGS_DEFAULT, /* tp_flags */
1263 : 0, /* tp_doc */
1264 : 0, /* tp_traverse */
1265 : 0, /* tp_clear */
1266 : 0, /* tp_richcompare */
1267 : 0, /* tp_weaklistoffset */
1268 : PyObject_SelfIter, /* tp_iter */
1269 : (iternextfunc)longrangeiter_next, /* tp_iternext */
1270 : longrangeiter_methods, /* tp_methods */
1271 : 0,
1272 : };
1273 :
1274 : static PyObject *
1275 109 : range_iter(PyObject *seq)
1276 : {
1277 109 : rangeobject *r = (rangeobject *)seq;
1278 : longrangeiterobject *it;
1279 : long lstart, lstop, lstep;
1280 : PyObject *int_it;
1281 :
1282 : assert(PyRange_Check(seq));
1283 :
1284 : /* If all three fields and the length convert to long, use the int
1285 : * version */
1286 109 : lstart = PyLong_AsLong(r->start);
1287 109 : if (lstart == -1 && PyErr_Occurred()) {
1288 0 : PyErr_Clear();
1289 0 : goto long_range;
1290 : }
1291 109 : lstop = PyLong_AsLong(r->stop);
1292 109 : if (lstop == -1 && PyErr_Occurred()) {
1293 0 : PyErr_Clear();
1294 0 : goto long_range;
1295 : }
1296 109 : lstep = PyLong_AsLong(r->step);
1297 109 : if (lstep == -1 && PyErr_Occurred()) {
1298 0 : PyErr_Clear();
1299 0 : goto long_range;
1300 : }
1301 109 : int_it = fast_range_iter(lstart, lstop, lstep);
1302 109 : if (int_it == NULL && PyErr_ExceptionMatches(PyExc_OverflowError)) {
1303 0 : PyErr_Clear();
1304 0 : goto long_range;
1305 : }
1306 109 : return (PyObject *)int_it;
1307 :
1308 : long_range:
1309 0 : it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
1310 0 : if (it == NULL)
1311 0 : return NULL;
1312 :
1313 : /* Do all initialization here, so we can DECREF on failure. */
1314 0 : it->start = r->start;
1315 0 : it->step = r->step;
1316 0 : it->len = r->length;
1317 0 : Py_INCREF(it->start);
1318 0 : Py_INCREF(it->step);
1319 0 : Py_INCREF(it->len);
1320 :
1321 0 : it->index = PyLong_FromLong(0);
1322 0 : if (!it->index)
1323 0 : goto create_failure;
1324 :
1325 0 : return (PyObject *)it;
1326 :
1327 : create_failure:
1328 0 : Py_DECREF(it);
1329 0 : return NULL;
1330 : }
1331 :
1332 : static PyObject *
1333 0 : range_reverse(PyObject *seq)
1334 : {
1335 0 : rangeobject *range = (rangeobject*) seq;
1336 : longrangeiterobject *it;
1337 : PyObject *one, *sum, *diff, *product;
1338 : long lstart, lstop, lstep, new_start, new_stop;
1339 : unsigned long ulen;
1340 :
1341 : assert(PyRange_Check(seq));
1342 :
1343 : /* reversed(range(start, stop, step)) can be expressed as
1344 : range(start+(n-1)*step, start-step, -step), where n is the number of
1345 : integers in the range.
1346 :
1347 : If each of start, stop, step, -step, start-step, and the length
1348 : of the iterator is representable as a C long, use the int
1349 : version. This excludes some cases where the reversed range is
1350 : representable as a range_iterator, but it's good enough for
1351 : common cases and it makes the checks simple. */
1352 :
1353 0 : lstart = PyLong_AsLong(range->start);
1354 0 : if (lstart == -1 && PyErr_Occurred()) {
1355 0 : PyErr_Clear();
1356 0 : goto long_range;
1357 : }
1358 0 : lstop = PyLong_AsLong(range->stop);
1359 0 : if (lstop == -1 && PyErr_Occurred()) {
1360 0 : PyErr_Clear();
1361 0 : goto long_range;
1362 : }
1363 0 : lstep = PyLong_AsLong(range->step);
1364 0 : if (lstep == -1 && PyErr_Occurred()) {
1365 0 : PyErr_Clear();
1366 0 : goto long_range;
1367 : }
1368 : /* check for possible overflow of -lstep */
1369 0 : if (lstep == LONG_MIN)
1370 0 : goto long_range;
1371 :
1372 : /* check for overflow of lstart - lstep:
1373 :
1374 : for lstep > 0, need only check whether lstart - lstep < LONG_MIN.
1375 : for lstep < 0, need only check whether lstart - lstep > LONG_MAX
1376 :
1377 : Rearrange these inequalities as:
1378 :
1379 : lstart - LONG_MIN < lstep (lstep > 0)
1380 : LONG_MAX - lstart < -lstep (lstep < 0)
1381 :
1382 : and compute both sides as unsigned longs, to avoid the
1383 : possibility of undefined behaviour due to signed overflow. */
1384 :
1385 0 : if (lstep > 0) {
1386 0 : if ((unsigned long)lstart - LONG_MIN < (unsigned long)lstep)
1387 0 : goto long_range;
1388 : }
1389 : else {
1390 0 : if (LONG_MAX - (unsigned long)lstart < 0UL - lstep)
1391 0 : goto long_range;
1392 : }
1393 :
1394 0 : ulen = get_len_of_range(lstart, lstop, lstep);
1395 0 : if (ulen > (unsigned long)LONG_MAX)
1396 0 : goto long_range;
1397 :
1398 0 : new_stop = lstart - lstep;
1399 0 : new_start = (long)(new_stop + ulen * lstep);
1400 0 : return fast_range_iter(new_start, new_stop, -lstep);
1401 :
1402 : long_range:
1403 0 : it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
1404 0 : if (it == NULL)
1405 0 : return NULL;
1406 :
1407 : /* start + (len - 1) * step */
1408 0 : it->len = range->length;
1409 0 : Py_INCREF(it->len);
1410 :
1411 0 : one = PyLong_FromLong(1);
1412 0 : if (!one)
1413 0 : goto create_failure;
1414 :
1415 0 : diff = PyNumber_Subtract(it->len, one);
1416 0 : Py_DECREF(one);
1417 0 : if (!diff)
1418 0 : goto create_failure;
1419 :
1420 0 : product = PyNumber_Multiply(diff, range->step);
1421 0 : Py_DECREF(diff);
1422 0 : if (!product)
1423 0 : goto create_failure;
1424 :
1425 0 : sum = PyNumber_Add(range->start, product);
1426 0 : Py_DECREF(product);
1427 0 : it->start = sum;
1428 0 : if (!it->start)
1429 0 : goto create_failure;
1430 :
1431 0 : it->step = PyNumber_Negative(range->step);
1432 0 : if (!it->step)
1433 0 : goto create_failure;
1434 :
1435 0 : it->index = PyLong_FromLong(0);
1436 0 : if (!it->index)
1437 0 : goto create_failure;
1438 :
1439 0 : return (PyObject *)it;
1440 :
1441 : create_failure:
1442 0 : Py_DECREF(it);
1443 0 : return NULL;
1444 : }
|