1
/* Range object implementation */
4
#include "structmember.h"
6
/* Support objects whose length is > PY_SSIZE_T_MAX.
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.
21
/* Helper function for validating step. Always returns a new reference or
25
validate_step(PyObject *step)
27
/* No step specified, use a step of 1. */
29
return PyLong_FromLong(1);
31
step = PyNumber_Index(step);
33
Py_ssize_t istep = PyNumber_AsSsize_t(step, NULL);
34
if (istep == -1 && PyErr_Occurred()) {
35
/* Ignore OverflowError, we know the value isn't 0. */
38
else if (istep == 0) {
39
PyErr_SetString(PyExc_ValueError,
40
"range() arg 3 must not be zero");
49
compute_range_length(PyObject *start, PyObject *stop, PyObject *step);
52
make_range_object(PyTypeObject *type, PyObject *start,
53
PyObject *stop, PyObject *step)
55
rangeobject *obj = NULL;
57
length = compute_range_length(start, stop, step);
61
obj = PyObject_New(rangeobject, type);
73
/* XXX(nnorwitz): should we error check if the user passes any empty ranges?
79
range_new(PyTypeObject *type, PyObject *args, PyObject *kw)
82
PyObject *start = NULL, *stop = NULL, *step = NULL;
84
if (!_PyArg_NoKeywords("range()", kw))
87
if (PyTuple_Size(args) <= 1) {
88
if (!PyArg_UnpackTuple(args, "range", 1, 1, &stop))
90
stop = PyNumber_Index(stop);
93
start = PyLong_FromLong(0);
98
step = PyLong_FromLong(1);
106
if (!PyArg_UnpackTuple(args, "range", 2, 3,
107
&start, &stop, &step))
110
/* Convert borrowed refs to owned refs */
111
start = PyNumber_Index(start);
114
stop = PyNumber_Index(stop);
119
step = validate_step(step); /* Caution, this can clear exceptions */
127
obj = make_range_object(type, start, stop, step);
129
return (PyObject *) obj;
131
/* Failed to create object, release attributes */
138
PyDoc_STRVAR(range_doc,
139
"range(stop) -> range object\n\
140
range(start, stop[, step]) -> range object\n\
142
Return a virtual sequence of numbers from start to stop by step.");
145
range_dealloc(rangeobject *r)
150
Py_DECREF(r->length);
154
/* Return number of items in range (lo, hi, step) as a PyLong object,
155
* when arguments are PyLong objects. Arguments MUST return 1 with
156
* PyLong_Check(). Return NULL when there is an error.
159
compute_range_length(PyObject *start, PyObject *stop, PyObject *step)
161
/* -------------------------------------------------------------
162
Algorithm is equal to that of get_len_of_range(), but it operates
163
on PyObjects (which are assumed to be PyLong objects).
164
---------------------------------------------------------------*/
167
PyObject *diff = NULL;
168
PyObject *one = NULL;
169
PyObject *tmp1 = NULL, *tmp2 = NULL, *result;
170
/* holds sub-expression evaluations */
172
PyObject *zero = PyLong_FromLong(0);
175
cmp_result = PyObject_RichCompareBool(step, zero, Py_GT);
177
if (cmp_result == -1)
180
if (cmp_result == 1) {
187
step = PyNumber_Negative(step);
192
/* if (lo >= hi), return length of 0. */
193
if (PyObject_RichCompareBool(lo, hi, Py_GE) == 1) {
195
return PyLong_FromLong(0);
198
if ((one = PyLong_FromLong(1L)) == NULL)
201
if ((tmp1 = PyNumber_Subtract(hi, lo)) == NULL)
204
if ((diff = PyNumber_Subtract(tmp1, one)) == NULL)
207
if ((tmp2 = PyNumber_FloorDivide(diff, step)) == NULL)
210
if ((result = PyNumber_Add(tmp2, one)) == NULL)
230
range_length(rangeobject *r)
232
return PyLong_AsSsize_t(r->length);
236
compute_item(rangeobject *r, PyObject *i)
238
PyObject *incr, *result;
239
/* PyLong equivalent to:
240
* return r->start + (i * r->step)
242
incr = PyNumber_Multiply(i, r->step);
245
result = PyNumber_Add(r->start, incr);
251
compute_range_item(rangeobject *r, PyObject *arg)
254
PyObject *i, *result;
256
PyObject *zero = PyLong_FromLong(0);
260
/* PyLong equivalent to:
262
* i = r->length + arg
267
cmp_result = PyObject_RichCompareBool(arg, zero, Py_LT);
268
if (cmp_result == -1) {
272
if (cmp_result == 1) {
273
i = PyNumber_Add(r->length, arg);
283
/* PyLong equivalent to:
284
* if (i < 0 || i >= r->length) {
285
* <report index out of bounds>
288
cmp_result = PyObject_RichCompareBool(i, zero, Py_LT);
290
if (cmp_result == 0) {
291
cmp_result = PyObject_RichCompareBool(i, r->length, Py_GE);
293
if (cmp_result == -1) {
297
if (cmp_result == 1) {
299
PyErr_SetString(PyExc_IndexError,
300
"range object index out of range");
304
result = compute_item(r, i);
310
range_item(rangeobject *r, Py_ssize_t i)
312
PyObject *res, *arg = PyLong_FromSsize_t(i);
316
res = compute_range_item(r, arg);
322
compute_slice(rangeobject *r, PyObject *_slice)
324
PySliceObject *slice = (PySliceObject *) _slice;
326
PyObject *start = NULL, *stop = NULL, *step = NULL;
327
PyObject *substart = NULL, *substop = NULL, *substep = NULL;
330
error = _PySlice_GetLongIndices(slice, r->length, &start, &stop, &step);
334
substep = PyNumber_Multiply(r->step, step);
335
if (substep == NULL) goto fail;
338
substart = compute_item(r, start);
339
if (substart == NULL) goto fail;
342
substop = compute_item(r, stop);
343
if (substop == NULL) goto fail;
346
result = make_range_object(Py_TYPE(r), substart, substop, substep);
347
if (result != NULL) {
348
return (PyObject *) result;
354
Py_XDECREF(substart);
360
/* Assumes (PyLong_CheckExact(ob) || PyBool_Check(ob)) */
362
range_contains_long(rangeobject *r, PyObject *ob)
364
int cmp1, cmp2, cmp3;
365
PyObject *tmp1 = NULL;
366
PyObject *tmp2 = NULL;
367
PyObject *zero = NULL;
370
zero = PyLong_FromLong(0);
371
if (zero == NULL) /* MemoryError in int(0) */
374
/* Check if the value can possibly be in the range. */
376
cmp1 = PyObject_RichCompareBool(r->step, zero, Py_GT);
379
if (cmp1 == 1) { /* positive steps: start <= ob < stop */
380
cmp2 = PyObject_RichCompareBool(r->start, ob, Py_LE);
381
cmp3 = PyObject_RichCompareBool(ob, r->stop, Py_LT);
383
else { /* negative steps: stop < ob <= start */
384
cmp2 = PyObject_RichCompareBool(ob, r->start, Py_LE);
385
cmp3 = PyObject_RichCompareBool(r->stop, ob, Py_LT);
388
if (cmp2 == -1 || cmp3 == -1) /* TypeError */
390
if (cmp2 == 0 || cmp3 == 0) { /* ob outside of range */
395
/* Check that the stride does not invalidate ob's membership. */
396
tmp1 = PyNumber_Subtract(ob, r->start);
399
tmp2 = PyNumber_Remainder(tmp1, r->step);
402
/* result = (int(ob) - start % step) == 0 */
403
result = PyObject_RichCompareBool(tmp2, zero, Py_EQ);
412
range_contains(rangeobject *r, PyObject *ob)
414
if (PyLong_CheckExact(ob) || PyBool_Check(ob))
415
return range_contains_long(r, ob);
417
return (int)_PySequence_IterSearch((PyObject*)r, ob,
418
PY_ITERSEARCH_CONTAINS);
421
/* Compare two range objects. Return 1 for equal, 0 for not equal
422
and -1 on error. The algorithm is roughly the C equivalent of
426
if len(r0) != len(r1):
430
if r0.start != r1.start:
434
return r0.step == r1.step
437
range_equals(rangeobject *r0, rangeobject *r1)
444
cmp_result = PyObject_RichCompareBool(r0->length, r1->length, Py_EQ);
445
/* Return False or error to the caller. */
448
cmp_result = PyObject_Not(r0->length);
449
/* Return True or error to the caller. */
452
cmp_result = PyObject_RichCompareBool(r0->start, r1->start, Py_EQ);
453
/* Return False or error to the caller. */
456
one = PyLong_FromLong(1);
459
cmp_result = PyObject_RichCompareBool(r0->length, one, Py_EQ);
461
/* Return True or error to the caller. */
464
return PyObject_RichCompareBool(r0->step, r1->step, Py_EQ);
468
range_richcompare(PyObject *self, PyObject *other, int op)
472
if (!PyRange_Check(other))
473
Py_RETURN_NOTIMPLEMENTED;
477
result = range_equals((rangeobject*)self, (rangeobject*)other);
490
Py_RETURN_NOTIMPLEMENTED;
497
/* Hash function for range objects. Rough C equivalent of
500
return hash((len(r), None, None))
502
return hash((len(r), r.start, None))
503
return hash((len(r), r.start, r.step))
506
range_hash(rangeobject *r)
509
Py_hash_t result = -1;
515
Py_INCREF(r->length);
516
PyTuple_SET_ITEM(t, 0, r->length);
517
cmp_result = PyObject_Not(r->length);
518
if (cmp_result == -1)
520
if (cmp_result == 1) {
523
PyTuple_SET_ITEM(t, 1, Py_None);
524
PyTuple_SET_ITEM(t, 2, Py_None);
529
PyTuple_SET_ITEM(t, 1, r->start);
530
one = PyLong_FromLong(1);
533
cmp_result = PyObject_RichCompareBool(r->length, one, Py_EQ);
535
if (cmp_result == -1)
537
if (cmp_result == 1) {
539
PyTuple_SET_ITEM(t, 2, Py_None);
543
PyTuple_SET_ITEM(t, 2, r->step);
546
result = PyObject_Hash(t);
553
range_count(rangeobject *r, PyObject *ob)
555
if (PyLong_CheckExact(ob) || PyBool_Check(ob)) {
556
int result = range_contains_long(r, ob);
560
return PyLong_FromLong(1);
562
return PyLong_FromLong(0);
565
count = _PySequence_IterSearch((PyObject*)r, ob, PY_ITERSEARCH_COUNT);
568
return PyLong_FromSsize_t(count);
573
range_index(rangeobject *r, PyObject *ob)
577
if (!PyLong_CheckExact(ob) && !PyBool_Check(ob)) {
579
index = _PySequence_IterSearch((PyObject*)r, ob, PY_ITERSEARCH_INDEX);
582
return PyLong_FromSsize_t(index);
585
contains = range_contains_long(r, ob);
590
PyObject *idx, *tmp = PyNumber_Subtract(ob, r->start);
593
/* idx = (ob - r.start) // r.step */
594
idx = PyNumber_FloorDivide(tmp, r->step);
599
/* object is not in the range */
600
PyErr_Format(PyExc_ValueError, "%R is not in range", ob);
604
static PySequenceMethods range_as_sequence = {
605
(lenfunc)range_length, /* sq_length */
608
(ssizeargfunc)range_item, /* sq_item */
611
0, /* sq_ass_slice */
612
(objobjproc)range_contains, /* sq_contains */
616
range_repr(rangeobject *r)
620
/* Check for special case values for printing. We don't always
621
need the step value. We don't care about errors
622
(it means overflow), so clear the errors. */
623
istep = PyNumber_AsSsize_t(r->step, NULL);
624
if (istep != 1 || (istep == -1 && PyErr_Occurred())) {
629
return PyUnicode_FromFormat("range(%R, %R)", r->start, r->stop);
631
return PyUnicode_FromFormat("range(%R, %R, %R)",
632
r->start, r->stop, r->step);
635
/* Pickling support */
637
range_reduce(rangeobject *r, PyObject *args)
639
return Py_BuildValue("(O(OOO))", Py_TYPE(r),
640
r->start, r->stop, r->step);
644
range_subscript(rangeobject* self, PyObject* item)
646
if (PyIndex_Check(item)) {
647
PyObject *i, *result;
648
i = PyNumber_Index(item);
651
result = compute_range_item(self, i);
655
if (PySlice_Check(item)) {
656
return compute_slice(self, item);
658
PyErr_Format(PyExc_TypeError,
659
"range indices must be integers or slices, not %.200s",
660
item->ob_type->tp_name);
665
static PyMappingMethods range_as_mapping = {
666
(lenfunc)range_length, /* mp_length */
667
(binaryfunc)range_subscript, /* mp_subscript */
668
(objobjargproc)0, /* mp_ass_subscript */
671
static PyObject * range_iter(PyObject *seq);
672
static PyObject * range_reverse(PyObject *seq);
674
PyDoc_STRVAR(reverse_doc,
675
"Return a reverse iterator.");
677
PyDoc_STRVAR(count_doc,
678
"rangeobject.count(value) -> integer -- return number of occurrences of value");
680
PyDoc_STRVAR(index_doc,
681
"rangeobject.index(value, [start, [stop]]) -> integer -- return index of value.\n"
682
"Raise ValueError if the value is not present.");
684
static PyMethodDef range_methods[] = {
685
{"__reversed__", (PyCFunction)range_reverse, METH_NOARGS, reverse_doc},
686
{"__reduce__", (PyCFunction)range_reduce, METH_VARARGS},
687
{"count", (PyCFunction)range_count, METH_O, count_doc},
688
{"index", (PyCFunction)range_index, METH_O, index_doc},
689
{NULL, NULL} /* sentinel */
692
static PyMemberDef range_members[] = {
693
{"start", T_OBJECT_EX, offsetof(rangeobject, start), READONLY},
694
{"stop", T_OBJECT_EX, offsetof(rangeobject, stop), READONLY},
695
{"step", T_OBJECT_EX, offsetof(rangeobject, step), READONLY},
699
PyTypeObject PyRange_Type = {
700
PyVarObject_HEAD_INIT(&PyType_Type, 0)
701
"range", /* Name of this type */
702
sizeof(rangeobject), /* Basic object size */
703
0, /* Item size for varobject */
704
(destructor)range_dealloc, /* tp_dealloc */
709
(reprfunc)range_repr, /* tp_repr */
710
0, /* tp_as_number */
711
&range_as_sequence, /* tp_as_sequence */
712
&range_as_mapping, /* tp_as_mapping */
713
(hashfunc)range_hash, /* tp_hash */
716
PyObject_GenericGetAttr, /* tp_getattro */
718
0, /* tp_as_buffer */
719
Py_TPFLAGS_DEFAULT, /* tp_flags */
720
range_doc, /* tp_doc */
723
range_richcompare, /* tp_richcompare */
724
0, /* tp_weaklistoffset */
725
range_iter, /* tp_iter */
727
range_methods, /* tp_methods */
728
range_members, /* tp_members */
732
0, /* tp_descr_get */
733
0, /* tp_descr_set */
734
0, /* tp_dictoffset */
737
range_new, /* tp_new */
740
/*********************** range Iterator **************************/
742
/* There are 2 types of iterators, one for C longs, the other for
743
Python ints (ie, PyObjects). This should make iteration fast
744
in the normal case, but possible for any numeric value.
756
rangeiter_next(rangeiterobject *r)
758
if (r->index < r->len)
759
/* cast to unsigned to avoid possible signed overflow
760
in intermediate calculations. */
761
return PyLong_FromLong((long)(r->start +
762
(unsigned long)(r->index++) * r->step));
767
rangeiter_len(rangeiterobject *r)
769
return PyLong_FromLong(r->len - r->index);
772
PyDoc_STRVAR(length_hint_doc,
773
"Private method returning an estimate of len(list(it)).");
776
rangeiter_reduce(rangeiterobject *r)
778
PyObject *start=NULL, *stop=NULL, *step=NULL;
781
/* create a range object for pickling */
782
start = PyLong_FromLong(r->start);
785
stop = PyLong_FromLong(r->start + r->len * r->step);
788
step = PyLong_FromLong(r->step);
791
range = (PyObject*)make_range_object(&PyRange_Type,
795
/* return the result */
796
return Py_BuildValue("N(N)i", _PyObject_GetBuiltin("iter"), range, r->index);
805
rangeiter_setstate(rangeiterobject *r, PyObject *state)
807
long index = PyLong_AsLong(state);
808
if (index == -1 && PyErr_Occurred())
810
if (index < 0 || index >= r->len) {
811
PyErr_SetString(PyExc_ValueError, "index out of range");
818
PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
819
PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
821
static PyMethodDef rangeiter_methods[] = {
822
{"__length_hint__", (PyCFunction)rangeiter_len, METH_NOARGS,
824
{"__reduce__", (PyCFunction)rangeiter_reduce, METH_NOARGS,
826
{"__setstate__", (PyCFunction)rangeiter_setstate, METH_O,
828
{NULL, NULL} /* sentinel */
831
static PyObject *rangeiter_new(PyTypeObject *, PyObject *args, PyObject *kw);
833
PyTypeObject PyRangeIter_Type = {
834
PyVarObject_HEAD_INIT(&PyType_Type, 0)
835
"range_iterator", /* tp_name */
836
sizeof(rangeiterobject), /* tp_basicsize */
839
(destructor)PyObject_Del, /* tp_dealloc */
845
0, /* tp_as_number */
846
0, /* tp_as_sequence */
847
0, /* tp_as_mapping */
851
PyObject_GenericGetAttr, /* tp_getattro */
853
0, /* tp_as_buffer */
854
Py_TPFLAGS_DEFAULT, /* tp_flags */
858
0, /* tp_richcompare */
859
0, /* tp_weaklistoffset */
860
PyObject_SelfIter, /* tp_iter */
861
(iternextfunc)rangeiter_next, /* tp_iternext */
862
rangeiter_methods, /* tp_methods */
867
0, /* tp_descr_get */
868
0, /* tp_descr_set */
869
0, /* tp_dictoffset */
872
rangeiter_new, /* tp_new */
875
/* Return number of items in range (lo, hi, step). step != 0
876
* required. The result always fits in an unsigned long.
879
get_len_of_range(long lo, long hi, long step)
881
/* -------------------------------------------------------------
882
If step > 0 and lo >= hi, or step < 0 and lo <= hi, the range is empty.
883
Else for step > 0, if n values are in the range, the last one is
884
lo + (n-1)*step, which must be <= hi-1. Rearranging,
885
n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives
886
the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so
887
the RHS is non-negative and so truncation is the same as the
888
floor. Letting M be the largest positive long, the worst case
889
for the RHS numerator is hi=M, lo=-M-1, and then
890
hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough
891
precision to compute the RHS exactly. The analysis for step < 0
893
---------------------------------------------------------------*/
895
if (step > 0 && lo < hi)
896
return 1UL + (hi - 1UL - lo) / step;
897
else if (step < 0 && lo > hi)
898
return 1UL + (lo - 1UL - hi) / (0UL - step);
903
/* Initialize a rangeiter object. If the length of the rangeiter object
904
is not representable as a C long, OverflowError is raised. */
907
fast_range_iter(long start, long stop, long step)
909
rangeiterobject *it = PyObject_New(rangeiterobject, &PyRangeIter_Type);
915
ulen = get_len_of_range(start, stop, step);
916
if (ulen > (unsigned long)LONG_MAX) {
918
PyErr_SetString(PyExc_OverflowError,
919
"range too large to represent as a range_iterator");
922
it->len = (long)ulen;
924
return (PyObject *)it;
928
rangeiter_new(PyTypeObject *type, PyObject *args, PyObject *kw)
930
long start, stop, step;
932
if (!_PyArg_NoKeywords("rangeiter()", kw))
935
if (!PyArg_ParseTuple(args, "lll;rangeiter() requires 3 int arguments",
936
&start, &stop, &step))
939
return fast_range_iter(start, stop, step);
948
} longrangeiterobject;
951
longrangeiter_len(longrangeiterobject *r, PyObject *no_args)
953
return PyNumber_Subtract(r->len, r->index);
957
longrangeiter_reduce(longrangeiterobject *r)
959
PyObject *product, *stop=NULL;
962
/* create a range object for pickling. Must calculate the "stop" value */
963
product = PyNumber_Multiply(r->len, r->step);
966
stop = PyNumber_Add(r->start, product);
972
range = (PyObject*)make_range_object(&PyRange_Type,
973
r->start, stop, r->step);
981
/* return the result */
982
return Py_BuildValue("N(N)O", _PyObject_GetBuiltin("iter"), range, r->index);
986
longrangeiter_setstate(longrangeiterobject *r, PyObject *state)
994
static PyMethodDef longrangeiter_methods[] = {
995
{"__length_hint__", (PyCFunction)longrangeiter_len, METH_NOARGS,
997
{"__reduce__", (PyCFunction)longrangeiter_reduce, METH_NOARGS,
999
{"__setstate__", (PyCFunction)longrangeiter_setstate, METH_O,
1001
{NULL, NULL} /* sentinel */
1005
longrangeiter_dealloc(longrangeiterobject *r)
1007
Py_XDECREF(r->index);
1008
Py_XDECREF(r->start);
1009
Py_XDECREF(r->step);
1015
longrangeiter_next(longrangeiterobject *r)
1017
PyObject *one, *product, *new_index, *result;
1018
if (PyObject_RichCompareBool(r->index, r->len, Py_LT) != 1)
1021
one = PyLong_FromLong(1);
1025
new_index = PyNumber_Add(r->index, one);
1030
product = PyNumber_Multiply(r->index, r->step);
1032
Py_DECREF(new_index);
1036
result = PyNumber_Add(r->start, product);
1039
Py_DECREF(r->index);
1040
r->index = new_index;
1043
Py_DECREF(new_index);
1049
PyTypeObject PyLongRangeIter_Type = {
1050
PyVarObject_HEAD_INIT(&PyType_Type, 0)
1051
"longrange_iterator", /* tp_name */
1052
sizeof(longrangeiterobject), /* tp_basicsize */
1053
0, /* tp_itemsize */
1055
(destructor)longrangeiter_dealloc, /* tp_dealloc */
1059
0, /* tp_reserved */
1061
0, /* tp_as_number */
1062
0, /* tp_as_sequence */
1063
0, /* tp_as_mapping */
1067
PyObject_GenericGetAttr, /* tp_getattro */
1068
0, /* tp_setattro */
1069
0, /* tp_as_buffer */
1070
Py_TPFLAGS_DEFAULT, /* tp_flags */
1072
0, /* tp_traverse */
1074
0, /* tp_richcompare */
1075
0, /* tp_weaklistoffset */
1076
PyObject_SelfIter, /* tp_iter */
1077
(iternextfunc)longrangeiter_next, /* tp_iternext */
1078
longrangeiter_methods, /* tp_methods */
1083
range_iter(PyObject *seq)
1085
rangeobject *r = (rangeobject *)seq;
1086
longrangeiterobject *it;
1087
long lstart, lstop, lstep;
1090
assert(PyRange_Check(seq));
1092
/* If all three fields and the length convert to long, use the int
1094
lstart = PyLong_AsLong(r->start);
1095
if (lstart == -1 && PyErr_Occurred()) {
1099
lstop = PyLong_AsLong(r->stop);
1100
if (lstop == -1 && PyErr_Occurred()) {
1104
lstep = PyLong_AsLong(r->step);
1105
if (lstep == -1 && PyErr_Occurred()) {
1109
int_it = fast_range_iter(lstart, lstop, lstep);
1110
if (int_it == NULL && PyErr_ExceptionMatches(PyExc_OverflowError)) {
1114
return (PyObject *)int_it;
1117
it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
1121
/* Do all initialization here, so we can DECREF on failure. */
1122
it->start = r->start;
1124
it->len = r->length;
1125
Py_INCREF(it->start);
1126
Py_INCREF(it->step);
1129
it->index = PyLong_FromLong(0);
1131
goto create_failure;
1133
return (PyObject *)it;
1141
range_reverse(PyObject *seq)
1143
rangeobject *range = (rangeobject*) seq;
1144
longrangeiterobject *it;
1145
PyObject *one, *sum, *diff, *product;
1146
long lstart, lstop, lstep, new_start, new_stop;
1149
assert(PyRange_Check(seq));
1151
/* reversed(range(start, stop, step)) can be expressed as
1152
range(start+(n-1)*step, start-step, -step), where n is the number of
1153
integers in the range.
1155
If each of start, stop, step, -step, start-step, and the length
1156
of the iterator is representable as a C long, use the int
1157
version. This excludes some cases where the reversed range is
1158
representable as a range_iterator, but it's good enough for
1159
common cases and it makes the checks simple. */
1161
lstart = PyLong_AsLong(range->start);
1162
if (lstart == -1 && PyErr_Occurred()) {
1166
lstop = PyLong_AsLong(range->stop);
1167
if (lstop == -1 && PyErr_Occurred()) {
1171
lstep = PyLong_AsLong(range->step);
1172
if (lstep == -1 && PyErr_Occurred()) {
1176
/* check for possible overflow of -lstep */
1177
if (lstep == LONG_MIN)
1180
/* check for overflow of lstart - lstep:
1182
for lstep > 0, need only check whether lstart - lstep < LONG_MIN.
1183
for lstep < 0, need only check whether lstart - lstep > LONG_MAX
1185
Rearrange these inequalities as:
1187
lstart - LONG_MIN < lstep (lstep > 0)
1188
LONG_MAX - lstart < -lstep (lstep < 0)
1190
and compute both sides as unsigned longs, to avoid the
1191
possibility of undefined behaviour due to signed overflow. */
1194
if ((unsigned long)lstart - LONG_MIN < (unsigned long)lstep)
1198
if (LONG_MAX - (unsigned long)lstart < 0UL - lstep)
1202
ulen = get_len_of_range(lstart, lstop, lstep);
1203
if (ulen > (unsigned long)LONG_MAX)
1206
new_stop = lstart - lstep;
1207
new_start = (long)(new_stop + ulen * lstep);
1208
return fast_range_iter(new_start, new_stop, -lstep);
1211
it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
1215
/* start + (len - 1) * step */
1216
it->len = range->length;
1219
one = PyLong_FromLong(1);
1221
goto create_failure;
1223
diff = PyNumber_Subtract(it->len, one);
1226
goto create_failure;
1228
product = PyNumber_Multiply(diff, range->step);
1231
goto create_failure;
1233
sum = PyNumber_Add(range->start, product);
1237
goto create_failure;
1239
it->step = PyNumber_Negative(range->step);
1241
goto create_failure;
1243
it->index = PyLong_FromLong(0);
1245
goto create_failure;
1247
return (PyObject *)it;