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);
67 step
= PyLong_FromLong(1);
72 if (!PyArg_UnpackTuple(args
, "range", 2, 3,
73 &start
, &stop
, &step
))
76 /* Convert borrowed refs to owned refs */
77 start
= PyNumber_Index(start
);
78 stop
= PyNumber_Index(stop
);
79 step
= validate_step(step
);
80 if (!start
|| !stop
|| !step
)
84 obj
= PyObject_New(rangeobject
, &PyRange_Type
);
90 return (PyObject
*) obj
;
99 PyDoc_STRVAR(range_doc
,
100 "range([start,] stop[, step]) -> range object\n\
102 Returns an iterator that generates the numbers in the range on demand.");
105 range_dealloc(rangeobject
*r
)
113 /* Return number of items in range (lo, hi, step), when arguments are
114 * PyInt or PyLong objects. step > 0 required. Return a value < 0 if
115 * & only if the true value is too large to fit in a signed long.
116 * Arguments MUST return 1 with either PyLong_Check() or
117 * PyLong_Check(). Return -1 when there is an error.
120 range_length_obj(rangeobject
*r
)
122 /* -------------------------------------------------------------
123 Algorithm is equal to that of get_len_of_range(), but it operates
124 on PyObjects (which are assumed to be PyLong or PyInt objects).
125 ---------------------------------------------------------------*/
128 PyObject
*step
= NULL
;
129 PyObject
*diff
= NULL
;
130 PyObject
*one
= NULL
;
131 PyObject
*tmp1
= NULL
, *tmp2
= NULL
, *result
;
132 /* holds sub-expression evaluations */
134 PyObject
*zero
= PyLong_FromLong(0);
137 cmp_result
= PyObject_RichCompareBool(r
->step
, zero
, Py_GT
);
139 if (cmp_result
== -1)
142 if (cmp_result
== 1) {
150 step
= PyNumber_Negative(r
->step
);
155 /* if (lo >= hi), return length of 0. */
156 if (PyObject_RichCompareBool(lo
, hi
, Py_GE
) == 1) {
158 return PyLong_FromLong(0);
161 if ((one
= PyLong_FromLong(1L)) == NULL
)
164 if ((tmp1
= PyNumber_Subtract(hi
, lo
)) == NULL
)
167 if ((diff
= PyNumber_Subtract(tmp1
, one
)) == NULL
)
170 if ((tmp2
= PyNumber_FloorDivide(diff
, step
)) == NULL
)
173 if ((result
= PyNumber_Add(tmp2
, one
)) == NULL
)
193 range_length(rangeobject
*r
)
195 PyObject
*len
= range_length_obj(r
);
196 Py_ssize_t result
= -1;
198 result
= PyLong_AsSsize_t(len
);
204 /* range(...)[x] is necessary for: seq[:] = range(...) */
207 range_item(rangeobject
*r
, Py_ssize_t i
)
209 Py_ssize_t len
= range_length(r
);
210 PyObject
*rem
, *incr
, *result
;
212 /* XXX(nnorwitz): should negative indices be supported? */
213 /* XXX(nnorwitz): should support range[x] where x > PY_SSIZE_T_MAX? */
214 if (i
< 0 || i
>= len
) {
215 if (!PyErr_Occurred())
216 PyErr_SetString(PyExc_IndexError
,
217 "range object index out of range");
221 /* XXX(nnorwitz): optimize for short ints. */
222 rem
= PyLong_FromSsize_t(i
);
225 incr
= PyNumber_Multiply(rem
, r
->step
);
229 result
= PyNumber_Add(r
->start
, incr
);
235 range_repr(rangeobject
*r
)
239 /* Check for special case values for printing. We don't always
240 need the step value. We don't care about errors
241 (it means overflow), so clear the errors. */
242 istep
= PyNumber_AsSsize_t(r
->step
, NULL
);
243 if (istep
!= 1 || (istep
== -1 && PyErr_Occurred())) {
248 return PyUnicode_FromFormat("range(%R, %R)", r
->start
, r
->stop
);
250 return PyUnicode_FromFormat("range(%R, %R, %R)",
251 r
->start
, r
->stop
, r
->step
);
254 /* Pickling support */
256 range_reduce(rangeobject
*r
, PyObject
*args
)
258 return Py_BuildValue("(O(OOO))", Py_TYPE(r
),
259 r
->start
, r
->stop
, r
->step
);
262 static PySequenceMethods range_as_sequence
= {
263 (lenfunc
)range_length
, /* sq_length */
266 (ssizeargfunc
)range_item
, /* sq_item */
270 static PyObject
* range_iter(PyObject
*seq
);
271 static PyObject
* range_reverse(PyObject
*seq
);
273 PyDoc_STRVAR(reverse_doc
,
274 "Returns a reverse iterator.");
276 static PyMethodDef range_methods
[] = {
277 {"__reversed__", (PyCFunction
)range_reverse
, METH_NOARGS
,
279 {"__reduce__", (PyCFunction
)range_reduce
, METH_VARARGS
},
280 {NULL
, NULL
} /* sentinel */
283 PyTypeObject PyRange_Type
= {
284 PyVarObject_HEAD_INIT(&PyType_Type
, 0)
285 "range", /* Name of this type */
286 sizeof(rangeobject
), /* Basic object size */
287 0, /* Item size for varobject */
288 (destructor
)range_dealloc
, /* tp_dealloc */
293 (reprfunc
)range_repr
, /* tp_repr */
294 0, /* tp_as_number */
295 &range_as_sequence
, /* tp_as_sequence */
296 0, /* tp_as_mapping */
300 PyObject_GenericGetAttr
, /* tp_getattro */
302 0, /* tp_as_buffer */
303 Py_TPFLAGS_DEFAULT
, /* tp_flags */
304 range_doc
, /* tp_doc */
307 0, /* tp_richcompare */
308 0, /* tp_weaklistoffset */
309 range_iter
, /* tp_iter */
311 range_methods
, /* tp_methods */
316 0, /* tp_descr_get */
317 0, /* tp_descr_set */
318 0, /* tp_dictoffset */
321 range_new
, /* tp_new */
324 /*********************** range Iterator **************************/
326 /* There are 2 types of iterators, one for C longs, the other for
327 Python longs (ie, PyObjects). This should make iteration fast
328 in the normal case, but possible for any numeric value.
340 rangeiter_next(rangeiterobject
*r
)
342 if (r
->index
< r
->len
)
343 return PyLong_FromLong(r
->start
+ (r
->index
++) * r
->step
);
348 rangeiter_len(rangeiterobject
*r
)
350 return PyLong_FromLong(r
->len
- r
->index
);
359 } longrangeiterobject
;
362 longrangeiter_len(longrangeiterobject
*r
, PyObject
*no_args
)
364 return PyNumber_Subtract(r
->len
, r
->index
);
367 static PyObject
*rangeiter_new(PyTypeObject
*, PyObject
*args
, PyObject
*kw
);
369 PyDoc_STRVAR(length_hint_doc
,
370 "Private method returning an estimate of len(list(it)).");
372 static PyMethodDef rangeiter_methods
[] = {
373 {"__length_hint__", (PyCFunction
)rangeiter_len
, METH_NOARGS
,
375 {NULL
, NULL
} /* sentinel */
378 PyTypeObject PyRangeIter_Type
= {
379 PyVarObject_HEAD_INIT(&PyType_Type
, 0)
380 "range_iterator", /* tp_name */
381 sizeof(rangeiterobject
), /* tp_basicsize */
384 (destructor
)PyObject_Del
, /* tp_dealloc */
390 0, /* tp_as_number */
391 0, /* tp_as_sequence */
392 0, /* tp_as_mapping */
396 PyObject_GenericGetAttr
, /* tp_getattro */
398 0, /* tp_as_buffer */
399 Py_TPFLAGS_DEFAULT
, /* tp_flags */
403 0, /* tp_richcompare */
404 0, /* tp_weaklistoffset */
405 PyObject_SelfIter
, /* tp_iter */
406 (iternextfunc
)rangeiter_next
, /* tp_iternext */
407 rangeiter_methods
, /* tp_methods */
412 0, /* tp_descr_get */
413 0, /* tp_descr_set */
414 0, /* tp_dictoffset */
417 rangeiter_new
, /* tp_new */
420 /* Return number of items in range/xrange (lo, hi, step). step > 0
421 * required. Return a value < 0 if & only if the true value is too
422 * large to fit in a signed long.
425 get_len_of_range(long lo
, long hi
, long step
)
427 /* -------------------------------------------------------------
428 If lo >= hi, the range is empty.
429 Else if n values are in the range, the last one is
430 lo + (n-1)*step, which must be <= hi-1. Rearranging,
431 n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives
432 the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so
433 the RHS is non-negative and so truncation is the same as the
434 floor. Letting M be the largest positive long, the worst case
435 for the RHS numerator is hi=M, lo=-M-1, and then
436 hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough
437 precision to compute the RHS exactly.
438 ---------------------------------------------------------------*/
441 unsigned long uhi
= (unsigned long)hi
;
442 unsigned long ulo
= (unsigned long)lo
;
443 unsigned long diff
= uhi
- ulo
- 1;
444 n
= (long)(diff
/ (unsigned long)step
+ 1);
450 int_range_iter(long start
, long stop
, long step
)
452 rangeiterobject
*it
= PyObject_New(rangeiterobject
, &PyRangeIter_Type
);
458 it
->len
= get_len_of_range(start
, stop
, step
);
460 it
->len
= get_len_of_range(stop
, start
, -step
);
462 return (PyObject
*)it
;
466 rangeiter_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kw
)
468 long start
, stop
, step
;
470 if (!_PyArg_NoKeywords("rangeiter()", kw
))
473 if (!PyArg_ParseTuple(args
, "lll;rangeiter() requires 3 int arguments",
474 &start
, &stop
, &step
))
477 return int_range_iter(start
, stop
, step
);
480 static PyMethodDef longrangeiter_methods
[] = {
481 {"__length_hint__", (PyCFunction
)longrangeiter_len
, METH_NOARGS
,
483 {NULL
, NULL
} /* sentinel */
487 longrangeiter_dealloc(longrangeiterobject
*r
)
489 Py_XDECREF(r
->index
);
490 Py_XDECREF(r
->start
);
497 longrangeiter_next(longrangeiterobject
*r
)
499 PyObject
*one
, *product
, *new_index
, *result
;
500 if (PyObject_RichCompareBool(r
->index
, r
->len
, Py_LT
) != 1)
503 one
= PyLong_FromLong(1);
507 product
= PyNumber_Multiply(r
->index
, r
->step
);
513 new_index
= PyNumber_Add(r
->index
, one
);
520 result
= PyNumber_Add(r
->start
, product
);
524 r
->index
= new_index
;
530 PyTypeObject PyLongRangeIter_Type
= {
531 PyVarObject_HEAD_INIT(&PyType_Type
, 0)
532 "longrange_iterator", /* tp_name */
533 sizeof(longrangeiterobject
), /* tp_basicsize */
536 (destructor
)longrangeiter_dealloc
, /* tp_dealloc */
542 0, /* tp_as_number */
543 0, /* tp_as_sequence */
544 0, /* tp_as_mapping */
548 PyObject_GenericGetAttr
, /* tp_getattro */
550 0, /* tp_as_buffer */
551 Py_TPFLAGS_DEFAULT
, /* tp_flags */
555 0, /* tp_richcompare */
556 0, /* tp_weaklistoffset */
557 PyObject_SelfIter
, /* tp_iter */
558 (iternextfunc
)longrangeiter_next
, /* tp_iternext */
559 longrangeiter_methods
, /* tp_methods */
564 range_iter(PyObject
*seq
)
566 rangeobject
*r
= (rangeobject
*)seq
;
567 longrangeiterobject
*it
;
569 long lstart
, lstop
, lstep
;
571 assert(PyRange_Check(seq
));
573 /* If all three fields convert to long, use the int version */
574 lstart
= PyLong_AsLong(r
->start
);
575 if (lstart
!= -1 || !PyErr_Occurred()) {
576 lstop
= PyLong_AsLong(r
->stop
);
577 if (lstop
!= -1 || !PyErr_Occurred()) {
578 lstep
= PyLong_AsLong(r
->step
);
579 if (lstep
!= -1 || !PyErr_Occurred())
580 return int_range_iter(lstart
, lstop
, lstep
);
583 /* Some conversion failed, so there is an error set. Clear it,
584 and try again with a long range. */
587 it
= PyObject_New(longrangeiterobject
, &PyLongRangeIter_Type
);
591 /* Do all initialization here, so we can DECREF on failure. */
592 it
->start
= r
->start
;
594 Py_INCREF(it
->start
);
597 it
->len
= it
->index
= NULL
;
599 /* Calculate length: (r->stop - r->start) / r->step */
600 tmp
= PyNumber_Subtract(r
->stop
, r
->start
);
603 len
= PyNumber_FloorDivide(tmp
, r
->step
);
608 it
->index
= PyLong_FromLong(0);
612 return (PyObject
*)it
;
620 range_reverse(PyObject
*seq
)
622 rangeobject
*range
= (rangeobject
*) seq
;
623 longrangeiterobject
*it
;
624 PyObject
*one
, *sum
, *diff
, *len
= NULL
, *product
;
625 long lstart
, lstop
, lstep
;
627 /* XXX(nnorwitz): do the calc for the new start/stop first,
628 then if they fit, call the proper iter()?
630 assert(PyRange_Check(seq
));
632 /* If all three fields convert to long, use the int version */
633 lstart
= PyLong_AsLong(range
->start
);
634 if (lstart
!= -1 || !PyErr_Occurred()) {
635 lstop
= PyLong_AsLong(range
->stop
);
636 if (lstop
!= -1 || !PyErr_Occurred()) {
637 lstep
= PyLong_AsLong(range
->step
);
638 if (lstep
!= -1 || !PyErr_Occurred()) {
639 /* XXX(nnorwitz): need to check for overflow and simplify. */
640 long len
= get_len_of_range(lstart
, lstop
, lstep
);
641 long new_start
= lstart
+ (len
- 1) * lstep
;
642 long new_stop
= lstart
;
647 return int_range_iter(new_start
, new_stop
, -lstep
);
653 it
= PyObject_New(longrangeiterobject
, &PyLongRangeIter_Type
);
657 /* start + (len - 1) * step */
658 len
= range_length_obj(range
);
662 one
= PyLong_FromLong(1);
666 diff
= PyNumber_Subtract(len
, one
);
671 product
= PyNumber_Multiply(len
, range
->step
);
675 sum
= PyNumber_Add(range
->start
, product
);
680 it
->step
= PyNumber_Negative(range
->step
);
682 Py_DECREF(it
->start
);
687 /* Steal reference to len. */
690 it
->index
= PyLong_FromLong(0);
696 return (PyObject
*)it
;