1 /* Range object implementation */
5 /* Support objects whose length is > PY_SSIZE_T_MAX.
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.
19 /* Helper function for validating step. Always returns a new reference or
23 validate_step(PyObject
*step
)
25 /* No step specified, use a step of 1. */
27 return PyLong_FromLong(1);
29 step
= PyNumber_Index(step
);
31 Py_ssize_t istep
= PyNumber_AsSsize_t(step
, NULL
);
32 if (istep
== -1 && PyErr_Occurred()) {
33 /* Ignore OverflowError, we know the value isn't 0. */
36 else if (istep
== 0) {
37 PyErr_SetString(PyExc_ValueError
,
38 "range() arg 3 must not be zero");
46 /* XXX(nnorwitz): should we error check if the user passes any empty ranges?
52 range_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kw
)
54 rangeobject
*obj
= NULL
;
55 PyObject
*start
= NULL
, *stop
= NULL
, *step
= NULL
;
57 if (!_PyArg_NoKeywords("range()", kw
))
60 if (PyTuple_Size(args
) <= 1) {
61 if (!PyArg_UnpackTuple(args
, "range", 1, 1, &stop
))
63 stop
= PyNumber_Index(stop
);
66 start
= PyLong_FromLong(0);
71 step
= PyLong_FromLong(1);
79 if (!PyArg_UnpackTuple(args
, "range", 2, 3,
80 &start
, &stop
, &step
))
83 /* Convert borrowed refs to owned refs */
84 start
= PyNumber_Index(start
);
87 stop
= PyNumber_Index(stop
);
92 step
= validate_step(step
); /* Caution, this can clear exceptions */
100 obj
= PyObject_New(rangeobject
, &PyRange_Type
);
106 return (PyObject
*) obj
;
115 PyDoc_STRVAR(range_doc
,
116 "range([start,] stop[, step]) -> range object\n\
118 Returns an iterator that generates the numbers in the range on demand.");
121 range_dealloc(rangeobject
*r
)
129 /* Return number of items in range (lo, hi, step) as a PyLong object,
130 * when arguments are PyLong objects. Arguments MUST return 1 with
131 * PyLong_Check(). Return NULL when there is an error.
134 range_length_obj(rangeobject
*r
)
136 /* -------------------------------------------------------------
137 Algorithm is equal to that of get_len_of_range(), but it operates
138 on PyObjects (which are assumed to be PyLong objects).
139 ---------------------------------------------------------------*/
142 PyObject
*step
= NULL
;
143 PyObject
*diff
= NULL
;
144 PyObject
*one
= NULL
;
145 PyObject
*tmp1
= NULL
, *tmp2
= NULL
, *result
;
146 /* holds sub-expression evaluations */
148 PyObject
*zero
= PyLong_FromLong(0);
151 cmp_result
= PyObject_RichCompareBool(r
->step
, zero
, Py_GT
);
153 if (cmp_result
== -1)
156 if (cmp_result
== 1) {
164 step
= PyNumber_Negative(r
->step
);
169 /* if (lo >= hi), return length of 0. */
170 if (PyObject_RichCompareBool(lo
, hi
, Py_GE
) == 1) {
172 return PyLong_FromLong(0);
175 if ((one
= PyLong_FromLong(1L)) == NULL
)
178 if ((tmp1
= PyNumber_Subtract(hi
, lo
)) == NULL
)
181 if ((diff
= PyNumber_Subtract(tmp1
, one
)) == NULL
)
184 if ((tmp2
= PyNumber_FloorDivide(diff
, step
)) == NULL
)
187 if ((result
= PyNumber_Add(tmp2
, one
)) == NULL
)
207 range_length(rangeobject
*r
)
209 PyObject
*len
= range_length_obj(r
);
210 Py_ssize_t result
= -1;
212 result
= PyLong_AsSsize_t(len
);
218 /* range(...)[x] is necessary for: seq[:] = range(...) */
221 range_item(rangeobject
*r
, Py_ssize_t i
)
223 Py_ssize_t len
= range_length(r
);
224 PyObject
*rem
, *incr
, *result
;
226 /* XXX(nnorwitz): should negative indices be supported? */
227 /* XXX(nnorwitz): should support range[x] where x > PY_SSIZE_T_MAX? */
228 if (i
< 0 || i
>= len
) {
229 if (!PyErr_Occurred())
230 PyErr_SetString(PyExc_IndexError
,
231 "range object index out of range");
235 /* XXX(nnorwitz): optimize for short ints. */
236 rem
= PyLong_FromSsize_t(i
);
239 incr
= PyNumber_Multiply(rem
, r
->step
);
243 result
= PyNumber_Add(r
->start
, incr
);
249 range_repr(rangeobject
*r
)
253 /* Check for special case values for printing. We don't always
254 need the step value. We don't care about errors
255 (it means overflow), so clear the errors. */
256 istep
= PyNumber_AsSsize_t(r
->step
, NULL
);
257 if (istep
!= 1 || (istep
== -1 && PyErr_Occurred())) {
262 return PyUnicode_FromFormat("range(%R, %R)", r
->start
, r
->stop
);
264 return PyUnicode_FromFormat("range(%R, %R, %R)",
265 r
->start
, r
->stop
, r
->step
);
268 /* Pickling support */
270 range_reduce(rangeobject
*r
, PyObject
*args
)
272 return Py_BuildValue("(O(OOO))", Py_TYPE(r
),
273 r
->start
, r
->stop
, r
->step
);
276 static PySequenceMethods range_as_sequence
= {
277 (lenfunc
)range_length
, /* sq_length */
280 (ssizeargfunc
)range_item
, /* sq_item */
284 static PyObject
* range_iter(PyObject
*seq
);
285 static PyObject
* range_reverse(PyObject
*seq
);
287 PyDoc_STRVAR(reverse_doc
,
288 "Returns a reverse iterator.");
290 static PyMethodDef range_methods
[] = {
291 {"__reversed__", (PyCFunction
)range_reverse
, METH_NOARGS
,
293 {"__reduce__", (PyCFunction
)range_reduce
, METH_VARARGS
},
294 {NULL
, NULL
} /* sentinel */
297 PyTypeObject PyRange_Type
= {
298 PyVarObject_HEAD_INIT(&PyType_Type
, 0)
299 "range", /* Name of this type */
300 sizeof(rangeobject
), /* Basic object size */
301 0, /* Item size for varobject */
302 (destructor
)range_dealloc
, /* tp_dealloc */
307 (reprfunc
)range_repr
, /* tp_repr */
308 0, /* tp_as_number */
309 &range_as_sequence
, /* tp_as_sequence */
310 0, /* tp_as_mapping */
314 PyObject_GenericGetAttr
, /* tp_getattro */
316 0, /* tp_as_buffer */
317 Py_TPFLAGS_DEFAULT
, /* tp_flags */
318 range_doc
, /* tp_doc */
321 0, /* tp_richcompare */
322 0, /* tp_weaklistoffset */
323 range_iter
, /* tp_iter */
325 range_methods
, /* tp_methods */
330 0, /* tp_descr_get */
331 0, /* tp_descr_set */
332 0, /* tp_dictoffset */
335 range_new
, /* tp_new */
338 /*********************** range Iterator **************************/
340 /* There are 2 types of iterators, one for C longs, the other for
341 Python longs (ie, PyObjects). This should make iteration fast
342 in the normal case, but possible for any numeric value.
354 rangeiter_next(rangeiterobject
*r
)
356 if (r
->index
< r
->len
)
357 /* cast to unsigned to avoid possible signed overflow
358 in intermediate calculations. */
359 return PyLong_FromLong((long)(r
->start
+
360 (unsigned long)(r
->index
++) * r
->step
));
365 rangeiter_len(rangeiterobject
*r
)
367 return PyLong_FromLong(r
->len
- r
->index
);
376 } longrangeiterobject
;
379 longrangeiter_len(longrangeiterobject
*r
, PyObject
*no_args
)
381 return PyNumber_Subtract(r
->len
, r
->index
);
384 static PyObject
*rangeiter_new(PyTypeObject
*, PyObject
*args
, PyObject
*kw
);
386 PyDoc_STRVAR(length_hint_doc
,
387 "Private method returning an estimate of len(list(it)).");
389 static PyMethodDef rangeiter_methods
[] = {
390 {"__length_hint__", (PyCFunction
)rangeiter_len
, METH_NOARGS
,
392 {NULL
, NULL
} /* sentinel */
395 PyTypeObject PyRangeIter_Type
= {
396 PyVarObject_HEAD_INIT(&PyType_Type
, 0)
397 "range_iterator", /* tp_name */
398 sizeof(rangeiterobject
), /* tp_basicsize */
401 (destructor
)PyObject_Del
, /* tp_dealloc */
407 0, /* tp_as_number */
408 0, /* tp_as_sequence */
409 0, /* tp_as_mapping */
413 PyObject_GenericGetAttr
, /* tp_getattro */
415 0, /* tp_as_buffer */
416 Py_TPFLAGS_DEFAULT
, /* tp_flags */
420 0, /* tp_richcompare */
421 0, /* tp_weaklistoffset */
422 PyObject_SelfIter
, /* tp_iter */
423 (iternextfunc
)rangeiter_next
, /* tp_iternext */
424 rangeiter_methods
, /* tp_methods */
429 0, /* tp_descr_get */
430 0, /* tp_descr_set */
431 0, /* tp_dictoffset */
434 rangeiter_new
, /* tp_new */
437 /* Return number of items in range (lo, hi, step). step != 0
438 * required. The result always fits in an unsigned long.
441 get_len_of_range(long lo
, long hi
, long step
)
443 /* -------------------------------------------------------------
444 If step > 0 and lo >= hi, or step < 0 and lo <= hi, the range is empty.
445 Else for step > 0, if n values are in the range, the last one is
446 lo + (n-1)*step, which must be <= hi-1. Rearranging,
447 n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives
448 the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so
449 the RHS is non-negative and so truncation is the same as the
450 floor. Letting M be the largest positive long, the worst case
451 for the RHS numerator is hi=M, lo=-M-1, and then
452 hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough
453 precision to compute the RHS exactly. The analysis for step < 0
455 ---------------------------------------------------------------*/
457 if (step
> 0 && lo
< hi
)
458 return 1UL + (hi
- 1UL - lo
) / step
;
459 else if (step
< 0 && lo
> hi
)
460 return 1UL + (lo
- 1UL - hi
) / (0UL - step
);
465 /* Initialize a rangeiter object. If the length of the rangeiter object
466 is not representable as a C long, OverflowError is raised. */
469 int_range_iter(long start
, long stop
, long step
)
471 rangeiterobject
*it
= PyObject_New(rangeiterobject
, &PyRangeIter_Type
);
477 ulen
= get_len_of_range(start
, stop
, step
);
478 if (ulen
> (unsigned long)LONG_MAX
) {
480 PyErr_SetString(PyExc_OverflowError
,
481 "range too large to represent as a range_iterator");
484 it
->len
= (long)ulen
;
486 return (PyObject
*)it
;
490 rangeiter_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kw
)
492 long start
, stop
, step
;
494 if (!_PyArg_NoKeywords("rangeiter()", kw
))
497 if (!PyArg_ParseTuple(args
, "lll;rangeiter() requires 3 int arguments",
498 &start
, &stop
, &step
))
501 return int_range_iter(start
, stop
, step
);
504 static PyMethodDef longrangeiter_methods
[] = {
505 {"__length_hint__", (PyCFunction
)longrangeiter_len
, METH_NOARGS
,
507 {NULL
, NULL
} /* sentinel */
511 longrangeiter_dealloc(longrangeiterobject
*r
)
513 Py_XDECREF(r
->index
);
514 Py_XDECREF(r
->start
);
521 longrangeiter_next(longrangeiterobject
*r
)
523 PyObject
*one
, *product
, *new_index
, *result
;
524 if (PyObject_RichCompareBool(r
->index
, r
->len
, Py_LT
) != 1)
527 one
= PyLong_FromLong(1);
531 new_index
= PyNumber_Add(r
->index
, one
);
536 product
= PyNumber_Multiply(r
->index
, r
->step
);
538 Py_DECREF(new_index
);
542 result
= PyNumber_Add(r
->start
, product
);
546 r
->index
= new_index
;
549 Py_DECREF(new_index
);
555 PyTypeObject PyLongRangeIter_Type
= {
556 PyVarObject_HEAD_INIT(&PyType_Type
, 0)
557 "longrange_iterator", /* tp_name */
558 sizeof(longrangeiterobject
), /* tp_basicsize */
561 (destructor
)longrangeiter_dealloc
, /* tp_dealloc */
567 0, /* tp_as_number */
568 0, /* tp_as_sequence */
569 0, /* tp_as_mapping */
573 PyObject_GenericGetAttr
, /* tp_getattro */
575 0, /* tp_as_buffer */
576 Py_TPFLAGS_DEFAULT
, /* tp_flags */
580 0, /* tp_richcompare */
581 0, /* tp_weaklistoffset */
582 PyObject_SelfIter
, /* tp_iter */
583 (iternextfunc
)longrangeiter_next
, /* tp_iternext */
584 longrangeiter_methods
, /* tp_methods */
589 range_iter(PyObject
*seq
)
591 rangeobject
*r
= (rangeobject
*)seq
;
592 longrangeiterobject
*it
;
593 long lstart
, lstop
, lstep
;
596 assert(PyRange_Check(seq
));
598 /* If all three fields and the length convert to long, use the int
600 lstart
= PyLong_AsLong(r
->start
);
601 if (lstart
== -1 && PyErr_Occurred()) {
605 lstop
= PyLong_AsLong(r
->stop
);
606 if (lstop
== -1 && PyErr_Occurred()) {
610 lstep
= PyLong_AsLong(r
->step
);
611 if (lstep
== -1 && PyErr_Occurred()) {
615 int_it
= int_range_iter(lstart
, lstop
, lstep
);
616 if (int_it
== NULL
&& PyErr_ExceptionMatches(PyExc_OverflowError
)) {
620 return (PyObject
*)int_it
;
623 it
= PyObject_New(longrangeiterobject
, &PyLongRangeIter_Type
);
627 /* Do all initialization here, so we can DECREF on failure. */
628 it
->start
= r
->start
;
630 Py_INCREF(it
->start
);
633 it
->len
= it
->index
= NULL
;
635 it
->len
= range_length_obj(r
);
638 it
->index
= PyLong_FromLong(0);
642 return (PyObject
*)it
;
650 range_reverse(PyObject
*seq
)
652 rangeobject
*range
= (rangeobject
*) seq
;
653 longrangeiterobject
*it
;
654 PyObject
*one
, *sum
, *diff
, *len
= NULL
, *product
;
655 long lstart
, lstop
, lstep
, new_start
, new_stop
;
658 assert(PyRange_Check(seq
));
660 /* reversed(range(start, stop, step)) can be expressed as
661 range(start+(n-1)*step, start-step, -step), where n is the number of
662 integers in the range.
664 If each of start, stop, step, -step, start-step, and the length
665 of the iterator is representable as a C long, use the int
666 version. This excludes some cases where the reversed range is
667 representable as a range_iterator, but it's good enough for
668 common cases and it makes the checks simple. */
670 lstart
= PyLong_AsLong(range
->start
);
671 if (lstart
== -1 && PyErr_Occurred()) {
675 lstop
= PyLong_AsLong(range
->stop
);
676 if (lstop
== -1 && PyErr_Occurred()) {
680 lstep
= PyLong_AsLong(range
->step
);
681 if (lstep
== -1 && PyErr_Occurred()) {
685 /* check for possible overflow of -lstep */
686 if (lstep
== LONG_MIN
)
689 /* check for overflow of lstart - lstep:
691 for lstep > 0, need only check whether lstart - lstep < LONG_MIN.
692 for lstep < 0, need only check whether lstart - lstep > LONG_MAX
694 Rearrange these inequalities as:
696 lstart - LONG_MIN < lstep (lstep > 0)
697 LONG_MAX - lstart < -lstep (lstep < 0)
699 and compute both sides as unsigned longs, to avoid the
700 possibility of undefined behaviour due to signed overflow. */
703 if ((unsigned long)lstart
- LONG_MIN
< (unsigned long)lstep
)
707 if (LONG_MAX
- (unsigned long)lstart
< 0UL - lstep
)
711 ulen
= get_len_of_range(lstart
, lstop
, lstep
);
712 if (ulen
> (unsigned long)LONG_MAX
)
715 new_stop
= lstart
- lstep
;
716 new_start
= (long)(new_stop
+ ulen
* lstep
);
717 return int_range_iter(new_start
, new_stop
, -lstep
);
720 it
= PyObject_New(longrangeiterobject
, &PyLongRangeIter_Type
);
724 /* start + (len - 1) * step */
725 len
= range_length_obj(range
);
729 /* Steal reference to len. */
732 one
= PyLong_FromLong(1);
736 diff
= PyNumber_Subtract(len
, one
);
741 product
= PyNumber_Multiply(diff
, range
->step
);
746 sum
= PyNumber_Add(range
->start
, product
);
752 it
->step
= PyNumber_Negative(range
->step
);
756 it
->index
= PyLong_FromLong(0);
760 return (PyObject
*)it
;