blob: f9a9cc99306223cdc94a3ce94ce63791145e7d05 [file] [log] [blame]
Guido van Rossum12d12c51993-10-26 17:58:25 +00001/* Range object implementation */
2
Guido van Rossumc0b618a1997-05-02 03:12:38 +00003#include "Python.h"
Thomas Woutersefafcea2001-07-09 12:30:54 +00004
Guido van Rossum805365e2007-05-07 22:24:25 +00005/* Support objects whose length is > PY_SSIZE_T_MAX.
6
7 This could be sped up for small PyLongs if they fit in an Py_ssize_t.
8 This only matters on Win64. Though we could use PY_LONG_LONG which
9 would presumably help perf.
10*/
11
Guido van Rossum12d12c51993-10-26 17:58:25 +000012typedef struct {
Guido van Rossum805365e2007-05-07 22:24:25 +000013 PyObject_HEAD
14 PyObject *start;
15 PyObject *stop;
16 PyObject *step;
Guido van Rossum12d12c51993-10-26 17:58:25 +000017} rangeobject;
18
Guido van Rossum805365e2007-05-07 22:24:25 +000019/* Helper function for validating step. Always returns a new reference or
20 NULL on error.
21*/
22static PyObject *
23validate_step(PyObject *step)
Raymond Hettingerc4c453f2002-06-05 23:12:45 +000024{
Guido van Rossum805365e2007-05-07 22:24:25 +000025 /* No step specified, use a step of 1. */
26 if (!step)
Christian Heimes217cfd12007-12-02 14:31:20 +000027 return PyLong_FromLong(1);
Guido van Rossum805365e2007-05-07 22:24:25 +000028
29 step = PyNumber_Index(step);
30 if (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. */
34 PyErr_Clear();
35 }
36 else if (istep == 0) {
37 PyErr_SetString(PyExc_ValueError,
38 "range() arg 3 must not be zero");
39 Py_CLEAR(step);
40 }
41 }
42
43 return step;
Raymond Hettingerc4c453f2002-06-05 23:12:45 +000044}
45
Guido van Rossum805365e2007-05-07 22:24:25 +000046/* XXX(nnorwitz): should we error check if the user passes any empty ranges?
47 range(-10)
48 range(0, -5)
49 range(0, 5, -1)
50*/
Raymond Hettingerc4c453f2002-06-05 23:12:45 +000051static PyObject *
52range_new(PyTypeObject *type, PyObject *args, PyObject *kw)
53{
Guido van Rossum805365e2007-05-07 22:24:25 +000054 rangeobject *obj = NULL;
55 PyObject *start = NULL, *stop = NULL, *step = NULL;
Raymond Hettingerc4c453f2002-06-05 23:12:45 +000056
Guido van Rossum805365e2007-05-07 22:24:25 +000057 if (!_PyArg_NoKeywords("range()", kw))
58 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +000059
Guido van Rossum805365e2007-05-07 22:24:25 +000060 if (PyTuple_Size(args) <= 1) {
61 if (!PyArg_UnpackTuple(args, "range", 1, 1, &stop))
62 goto Fail;
63 stop = PyNumber_Index(stop);
64 if (!stop)
65 goto Fail;
Christian Heimes217cfd12007-12-02 14:31:20 +000066 start = PyLong_FromLong(0);
67 step = PyLong_FromLong(1);
Guido van Rossum805365e2007-05-07 22:24:25 +000068 if (!start || !step)
69 goto Fail;
70 }
71 else {
72 if (!PyArg_UnpackTuple(args, "range", 2, 3,
73 &start, &stop, &step))
74 goto Fail;
Tim Petersfeec4532004-08-08 07:17:39 +000075
Guido van Rossum805365e2007-05-07 22:24:25 +000076 /* 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)
81 goto Fail;
82 }
83
84 obj = PyObject_New(rangeobject, &PyRange_Type);
85 if (obj == NULL)
86 goto Fail;
87 obj->start = start;
88 obj->stop = stop;
89 obj->step = step;
90 return (PyObject *) obj;
91
92Fail:
93 Py_XDECREF(start);
94 Py_XDECREF(stop);
95 Py_XDECREF(step);
96 return NULL;
Raymond Hettingerc4c453f2002-06-05 23:12:45 +000097}
98
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000099PyDoc_STRVAR(range_doc,
Guido van Rossum805365e2007-05-07 22:24:25 +0000100"range([start,] stop[, step]) -> range object\n\
Raymond Hettingerc4c453f2002-06-05 23:12:45 +0000101\n\
Guido van Rossum805365e2007-05-07 22:24:25 +0000102Returns an iterator that generates the numbers in the range on demand.");
Raymond Hettingerc4c453f2002-06-05 23:12:45 +0000103
Guido van Rossum805365e2007-05-07 22:24:25 +0000104static void
105range_dealloc(rangeobject *r)
Guido van Rossum12d12c51993-10-26 17:58:25 +0000106{
Guido van Rossum805365e2007-05-07 22:24:25 +0000107 Py_DECREF(r->start);
108 Py_DECREF(r->stop);
109 Py_DECREF(r->step);
Amaury Forgeot d'Arcb7f17e42007-11-15 20:52:21 +0000110 PyObject_Del(r);
Guido van Rossum805365e2007-05-07 22:24:25 +0000111}
112
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.
Christian Heimes217cfd12007-12-02 14:31:20 +0000116 * Arguments MUST return 1 with either PyLong_Check() or
Guido van Rossum805365e2007-05-07 22:24:25 +0000117 * PyLong_Check(). Return -1 when there is an error.
118 */
119static PyObject*
120range_length_obj(rangeobject *r)
121{
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 ---------------------------------------------------------------*/
126 int cmp_result, cmp_call;
127 PyObject *lo, *hi;
128 PyObject *step = NULL;
129 PyObject *diff = NULL;
130 PyObject *one = NULL;
131 PyObject *tmp1 = NULL, *tmp2 = NULL, *result;
132 /* holds sub-expression evaluations */
133
134 PyObject *zero = PyLong_FromLong(0);
135 if (zero == NULL)
136 return NULL;
137 cmp_call = PyObject_Cmp(r->step, zero, &cmp_result);
138 Py_DECREF(zero);
139 if (cmp_call == -1)
140 return NULL;
141
142 assert(cmp_result != 0);
143 if (cmp_result > 0) {
144 lo = r->start;
145 hi = r->stop;
146 step = r->step;
147 Py_INCREF(step);
148 } else {
149 lo = r->stop;
150 hi = r->start;
151 step = PyNumber_Negative(r->step);
152 if (!step)
153 return NULL;
154 }
155
156 /* if (lo >= hi), return length of 0. */
157 if (PyObject_Compare(lo, hi) >= 0) {
158 Py_XDECREF(step);
159 return PyLong_FromLong(0);
160 }
161
162 if ((one = PyLong_FromLong(1L)) == NULL)
163 goto Fail;
164
165 if ((tmp1 = PyNumber_Subtract(hi, lo)) == NULL)
166 goto Fail;
167
168 if ((diff = PyNumber_Subtract(tmp1, one)) == NULL)
169 goto Fail;
170
171 if ((tmp2 = PyNumber_FloorDivide(diff, step)) == NULL)
172 goto Fail;
173
174 if ((result = PyNumber_Add(tmp2, one)) == NULL)
175 goto Fail;
176
177 Py_DECREF(tmp2);
178 Py_DECREF(diff);
179 Py_DECREF(step);
180 Py_DECREF(tmp1);
181 Py_DECREF(one);
182 return result;
183
184 Fail:
185 Py_XDECREF(tmp2);
186 Py_XDECREF(diff);
187 Py_XDECREF(step);
188 Py_XDECREF(tmp1);
189 Py_XDECREF(one);
190 return NULL;
Guido van Rossum12d12c51993-10-26 17:58:25 +0000191}
192
Martin v. Löwis18e16552006-02-15 17:27:45 +0000193static Py_ssize_t
Fred Drake45cfbcc2000-07-09 06:21:27 +0000194range_length(rangeobject *r)
Guido van Rossum12d12c51993-10-26 17:58:25 +0000195{
Guido van Rossum805365e2007-05-07 22:24:25 +0000196 PyObject *len = range_length_obj(r);
197 Py_ssize_t result = -1;
198 if (len) {
199 result = PyLong_AsSsize_t(len);
200 Py_DECREF(len);
201 }
202 return result;
203}
204
205/* range(...)[x] is necessary for: seq[:] = range(...) */
206
207static PyObject *
208range_item(rangeobject *r, Py_ssize_t i)
209{
210 Py_ssize_t len = range_length(r);
211 PyObject *rem, *incr, *result;
212
213 /* XXX(nnorwitz): should negative indices be supported? */
214 /* XXX(nnorwitz): should support range[x] where x > PY_SSIZE_T_MAX? */
215 if (i < 0 || i >= len) {
216 if (!PyErr_Occurred())
217 PyErr_SetString(PyExc_IndexError,
Walter Dörwald4ad94212007-05-21 18:01:17 +0000218 "range object index out of range");
Benjamin Petersondf0a5cb2008-04-25 21:15:37 +0000219 return NULL;
220 }
Guido van Rossum805365e2007-05-07 22:24:25 +0000221
222 /* XXX(nnorwitz): optimize for short ints. */
Raymond Hettingerad3f3322008-02-09 04:13:49 +0000223 rem = PyLong_FromSsize_t(i);
Guido van Rossum805365e2007-05-07 22:24:25 +0000224 if (!rem)
225 return NULL;
226 incr = PyNumber_Multiply(rem, r->step);
227 Py_DECREF(rem);
228 if (!incr)
229 return NULL;
230 result = PyNumber_Add(r->start, incr);
231 Py_DECREF(incr);
232 return result;
Guido van Rossum7d6aa511993-12-21 22:50:31 +0000233}
234
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000235static PyObject *
Fred Drake45cfbcc2000-07-09 06:21:27 +0000236range_repr(rangeobject *r)
Guido van Rossum12d12c51993-10-26 17:58:25 +0000237{
Walter Dörwald03b43d82007-05-21 10:43:34 +0000238 Py_ssize_t istep;
Tim Petersd976ab72004-08-08 06:29:10 +0000239
Guido van Rossum805365e2007-05-07 22:24:25 +0000240 /* Check for special case values for printing. We don't always
Walter Dörwald03b43d82007-05-21 10:43:34 +0000241 need the step value. We don't care about errors
Guido van Rossum805365e2007-05-07 22:24:25 +0000242 (it means overflow), so clear the errors. */
Guido van Rossum805365e2007-05-07 22:24:25 +0000243 istep = PyNumber_AsSsize_t(r->step, NULL);
244 if (istep != 1 || (istep == -1 && PyErr_Occurred())) {
245 PyErr_Clear();
Guido van Rossum805365e2007-05-07 22:24:25 +0000246 }
247
Walter Dörwald03b43d82007-05-21 10:43:34 +0000248 if (istep == 1)
Walter Dörwald850e5162007-05-20 08:19:54 +0000249 return PyUnicode_FromFormat("range(%R, %R)", r->start, r->stop);
250 else
251 return PyUnicode_FromFormat("range(%R, %R, %R)",
252 r->start, r->stop, r->step);
Thomas Woutersefafcea2001-07-09 12:30:54 +0000253}
254
Alexandre Vassalotti75056072008-06-10 04:03:04 +0000255/* Pickling support */
256static PyObject *
257range_reduce(rangeobject *r, PyObject *args)
258{
259 return Py_BuildValue("(O(OOO))", Py_TYPE(r),
260 r->start, r->stop, r->step);
261}
262
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000263static PySequenceMethods range_as_sequence = {
Guido van Rossum805365e2007-05-07 22:24:25 +0000264 (lenfunc)range_length, /* sq_length */
265 0, /* sq_concat */
266 0, /* sq_repeat */
267 (ssizeargfunc)range_item, /* sq_item */
268 0, /* sq_slice */
Guido van Rossum12d12c51993-10-26 17:58:25 +0000269};
270
Jeremy Hylton938ace62002-07-17 16:30:39 +0000271static PyObject * range_iter(PyObject *seq);
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000272static PyObject * range_reverse(PyObject *seq);
273
274PyDoc_STRVAR(reverse_doc,
275"Returns a reverse iterator.");
276
277static PyMethodDef range_methods[] = {
Guido van Rossum805365e2007-05-07 22:24:25 +0000278 {"__reversed__", (PyCFunction)range_reverse, METH_NOARGS,
279 reverse_doc},
Alexandre Vassalotti75056072008-06-10 04:03:04 +0000280 {"__reduce__", (PyCFunction)range_reduce, METH_VARARGS},
Guido van Rossum805365e2007-05-07 22:24:25 +0000281 {NULL, NULL} /* sentinel */
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000282};
Raymond Hettinger48165d42002-06-05 20:08:48 +0000283
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000284PyTypeObject PyRange_Type = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000285 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Guido van Rossum805365e2007-05-07 22:24:25 +0000286 "range", /* Name of this type */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000287 sizeof(rangeobject), /* Basic object size */
288 0, /* Item size for varobject */
Guido van Rossum805365e2007-05-07 22:24:25 +0000289 (destructor)range_dealloc, /* tp_dealloc */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000290 0, /* tp_print */
291 0, /* tp_getattr */
292 0, /* tp_setattr */
293 0, /* tp_compare */
294 (reprfunc)range_repr, /* tp_repr */
295 0, /* tp_as_number */
296 &range_as_sequence, /* tp_as_sequence */
297 0, /* tp_as_mapping */
298 0, /* tp_hash */
299 0, /* tp_call */
300 0, /* tp_str */
301 PyObject_GenericGetAttr, /* tp_getattro */
302 0, /* tp_setattro */
303 0, /* tp_as_buffer */
304 Py_TPFLAGS_DEFAULT, /* tp_flags */
305 range_doc, /* tp_doc */
306 0, /* tp_traverse */
307 0, /* tp_clear */
308 0, /* tp_richcompare */
309 0, /* tp_weaklistoffset */
310 range_iter, /* tp_iter */
311 0, /* tp_iternext */
312 range_methods, /* tp_methods */
313 0, /* tp_members */
314 0, /* tp_getset */
315 0, /* tp_base */
316 0, /* tp_dict */
317 0, /* tp_descr_get */
318 0, /* tp_descr_set */
319 0, /* tp_dictoffset */
320 0, /* tp_init */
321 0, /* tp_alloc */
322 range_new, /* tp_new */
Guido van Rossum12d12c51993-10-26 17:58:25 +0000323};
Raymond Hettinger48165d42002-06-05 20:08:48 +0000324
Walter Dörwald4ad94212007-05-21 18:01:17 +0000325/*********************** range Iterator **************************/
Raymond Hettinger48165d42002-06-05 20:08:48 +0000326
Guido van Rossum805365e2007-05-07 22:24:25 +0000327/* There are 2 types of iterators, one for C longs, the other for
328 Python longs (ie, PyObjects). This should make iteration fast
329 in the normal case, but possible for any numeric value.
330*/
331
Raymond Hettinger48165d42002-06-05 20:08:48 +0000332typedef struct {
333 PyObject_HEAD
334 long index;
335 long start;
336 long step;
337 long len;
338} rangeiterobject;
339
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000340static PyObject *
Raymond Hettinger48165d42002-06-05 20:08:48 +0000341rangeiter_next(rangeiterobject *r)
342{
Guido van Rossum805365e2007-05-07 22:24:25 +0000343 if (r->index < r->len)
Christian Heimes217cfd12007-12-02 14:31:20 +0000344 return PyLong_FromLong(r->start + (r->index++) * r->step);
Guido van Rossum805365e2007-05-07 22:24:25 +0000345 return NULL;
Raymond Hettinger48165d42002-06-05 20:08:48 +0000346}
347
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000348static PyObject *
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000349rangeiter_len(rangeiterobject *r)
350{
Christian Heimes217cfd12007-12-02 14:31:20 +0000351 return PyLong_FromLong(r->len - r->index);
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000352}
353
Guido van Rossum805365e2007-05-07 22:24:25 +0000354typedef struct {
355 PyObject_HEAD
356 PyObject *index;
357 PyObject *start;
358 PyObject *step;
359 PyObject *len;
360} longrangeiterobject;
361
362static PyObject *
363longrangeiter_len(longrangeiterobject *r, PyObject *no_args)
364{
365 return PyNumber_Subtract(r->len, r->index);
366}
Guido van Rossum317e7742007-05-08 15:18:31 +0000367
Guido van Rossum805365e2007-05-07 22:24:25 +0000368static PyObject *rangeiter_new(PyTypeObject *, PyObject *args, PyObject *kw);
369
370PyDoc_STRVAR(length_hint_doc,
371 "Private method returning an estimate of len(list(it)).");
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000372
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000373static PyMethodDef rangeiter_methods[] = {
Guido van Rossum805365e2007-05-07 22:24:25 +0000374 {"__length_hint__", (PyCFunction)rangeiter_len, METH_NOARGS,
375 length_hint_doc},
376 {NULL, NULL} /* sentinel */
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000377};
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000378
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000379PyTypeObject PyRangeIter_Type = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000380 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Christian Heimesf83be4e2007-11-28 09:44:38 +0000381 "range_iterator", /* tp_name */
Neal Norwitz56f46f82002-06-06 14:58:21 +0000382 sizeof(rangeiterobject), /* tp_basicsize */
Raymond Hettinger48165d42002-06-05 20:08:48 +0000383 0, /* tp_itemsize */
384 /* methods */
385 (destructor)PyObject_Del, /* tp_dealloc */
386 0, /* tp_print */
387 0, /* tp_getattr */
388 0, /* tp_setattr */
389 0, /* tp_compare */
390 0, /* tp_repr */
391 0, /* tp_as_number */
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000392 0, /* tp_as_sequence */
Raymond Hettinger48165d42002-06-05 20:08:48 +0000393 0, /* tp_as_mapping */
394 0, /* tp_hash */
395 0, /* tp_call */
396 0, /* tp_str */
397 PyObject_GenericGetAttr, /* tp_getattro */
398 0, /* tp_setattro */
399 0, /* tp_as_buffer */
400 Py_TPFLAGS_DEFAULT, /* tp_flags */
401 0, /* tp_doc */
402 0, /* tp_traverse */
403 0, /* tp_clear */
404 0, /* tp_richcompare */
405 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +0000406 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger48165d42002-06-05 20:08:48 +0000407 (iternextfunc)rangeiter_next, /* tp_iternext */
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000408 rangeiter_methods, /* tp_methods */
Guido van Rossum805365e2007-05-07 22:24:25 +0000409 0, /* tp_members */
410 0, /* tp_getset */
411 0, /* tp_base */
412 0, /* tp_dict */
413 0, /* tp_descr_get */
414 0, /* tp_descr_set */
415 0, /* tp_dictoffset */
416 0, /* tp_init */
417 0, /* tp_alloc */
418 rangeiter_new, /* tp_new */
419};
420
421/* Return number of items in range/xrange (lo, hi, step). step > 0
422 * required. Return a value < 0 if & only if the true value is too
423 * large to fit in a signed long.
424 */
425static long
426get_len_of_range(long lo, long hi, long step)
427{
428 /* -------------------------------------------------------------
429 If lo >= hi, the range is empty.
430 Else if n values are in the range, the last one is
431 lo + (n-1)*step, which must be <= hi-1. Rearranging,
432 n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives
433 the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so
434 the RHS is non-negative and so truncation is the same as the
435 floor. Letting M be the largest positive long, the worst case
436 for the RHS numerator is hi=M, lo=-M-1, and then
437 hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough
438 precision to compute the RHS exactly.
439 ---------------------------------------------------------------*/
440 long n = 0;
441 if (lo < hi) {
442 unsigned long uhi = (unsigned long)hi;
443 unsigned long ulo = (unsigned long)lo;
444 unsigned long diff = uhi - ulo - 1;
445 n = (long)(diff / (unsigned long)step + 1);
446 }
447 return n;
448}
449
450static PyObject *
451int_range_iter(long start, long stop, long step)
452{
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000453 rangeiterobject *it = PyObject_New(rangeiterobject, &PyRangeIter_Type);
Guido van Rossum805365e2007-05-07 22:24:25 +0000454 if (it == NULL)
455 return NULL;
456 it->start = start;
457 it->step = step;
458 if (step > 0)
459 it->len = get_len_of_range(start, stop, step);
460 else
461 it->len = get_len_of_range(stop, start, -step);
462 it->index = 0;
463 return (PyObject *)it;
464}
465
466static PyObject *
467rangeiter_new(PyTypeObject *type, PyObject *args, PyObject *kw)
468{
469 long start, stop, step;
470
471 if (!_PyArg_NoKeywords("rangeiter()", kw))
472 return NULL;
473
474 if (!PyArg_ParseTuple(args, "lll;rangeiter() requires 3 int arguments",
475 &start, &stop, &step))
476 return NULL;
477
478 return int_range_iter(start, stop, step);
479}
480
481static PyMethodDef longrangeiter_methods[] = {
482 {"__length_hint__", (PyCFunction)longrangeiter_len, METH_NOARGS,
483 length_hint_doc},
484 {NULL, NULL} /* sentinel */
485};
486
487static void
488longrangeiter_dealloc(longrangeiterobject *r)
489{
490 Py_XDECREF(r->index);
Guido van Rossum317e7742007-05-08 15:18:31 +0000491 Py_XDECREF(r->start);
492 Py_XDECREF(r->step);
493 Py_XDECREF(r->len);
Amaury Forgeot d'Arcb7f17e42007-11-15 20:52:21 +0000494 PyObject_Del(r);
Guido van Rossum805365e2007-05-07 22:24:25 +0000495}
496
497static PyObject *
498longrangeiter_next(longrangeiterobject *r)
499{
500 PyObject *one, *product, *new_index, *result;
501 if (PyObject_RichCompareBool(r->index, r->len, Py_LT) != 1)
502 return NULL;
503
504 one = PyLong_FromLong(1);
505 if (!one)
506 return NULL;
507
508 product = PyNumber_Multiply(r->index, r->step);
509 if (!product) {
510 Py_DECREF(one);
511 return NULL;
512 }
513
514 new_index = PyNumber_Add(r->index, one);
515 Py_DECREF(one);
516 if (!new_index) {
517 Py_DECREF(product);
518 return NULL;
519 }
520
521 result = PyNumber_Add(r->start, product);
522 Py_DECREF(product);
523 if (result) {
524 Py_DECREF(r->index);
525 r->index = new_index;
526 }
527
528 return result;
529}
530
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000531PyTypeObject PyLongRangeIter_Type = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000532 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000533 "longrange_iterator", /* tp_name */
Guido van Rossum805365e2007-05-07 22:24:25 +0000534 sizeof(longrangeiterobject), /* tp_basicsize */
535 0, /* tp_itemsize */
536 /* methods */
537 (destructor)longrangeiter_dealloc, /* tp_dealloc */
538 0, /* tp_print */
539 0, /* tp_getattr */
540 0, /* tp_setattr */
541 0, /* tp_compare */
542 0, /* tp_repr */
543 0, /* tp_as_number */
544 0, /* tp_as_sequence */
545 0, /* tp_as_mapping */
546 0, /* tp_hash */
547 0, /* tp_call */
548 0, /* tp_str */
549 PyObject_GenericGetAttr, /* tp_getattro */
550 0, /* tp_setattro */
551 0, /* tp_as_buffer */
552 Py_TPFLAGS_DEFAULT, /* tp_flags */
553 0, /* tp_doc */
554 0, /* tp_traverse */
555 0, /* tp_clear */
556 0, /* tp_richcompare */
557 0, /* tp_weaklistoffset */
558 PyObject_SelfIter, /* tp_iter */
559 (iternextfunc)longrangeiter_next, /* tp_iternext */
560 longrangeiter_methods, /* tp_methods */
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000561 0,
Raymond Hettinger48165d42002-06-05 20:08:48 +0000562};
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000563
564static PyObject *
565range_iter(PyObject *seq)
566{
Guido van Rossum805365e2007-05-07 22:24:25 +0000567 rangeobject *r = (rangeobject *)seq;
568 longrangeiterobject *it;
569 PyObject *tmp, *len;
Martin v. Löwis84451042007-12-20 22:57:23 +0000570 long lstart, lstop, lstep;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000571
Guido van Rossum805365e2007-05-07 22:24:25 +0000572 assert(PyRange_Check(seq));
Martin v. Löwis84451042007-12-20 22:57:23 +0000573
574 /* If all three fields convert to long, use the int version */
575 lstart = PyLong_AsLong(r->start);
576 if (lstart != -1 || !PyErr_Occurred()) {
577 lstop = PyLong_AsLong(r->stop);
578 if (lstop != -1 || !PyErr_Occurred()) {
579 lstep = PyLong_AsLong(r->step);
580 if (lstep != -1 || !PyErr_Occurred())
581 return int_range_iter(lstart, lstop, lstep);
582 }
583 }
584 /* Some conversion failed, so there is an error set. Clear it,
585 and try again with a long range. */
586 PyErr_Clear();
Guido van Rossum805365e2007-05-07 22:24:25 +0000587
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000588 it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
Guido van Rossum805365e2007-05-07 22:24:25 +0000589 if (it == NULL)
590 return NULL;
Guido van Rossum317e7742007-05-08 15:18:31 +0000591
592 /* Do all initialization here, so we can DECREF on failure. */
Guido van Rossum805365e2007-05-07 22:24:25 +0000593 it->start = r->start;
Guido van Rossum317e7742007-05-08 15:18:31 +0000594 it->step = r->step;
595 Py_INCREF(it->start);
596 Py_INCREF(it->step);
597
598 it->len = it->index = NULL;
599
Guido van Rossum805365e2007-05-07 22:24:25 +0000600 /* Calculate length: (r->stop - r->start) / r->step */
601 tmp = PyNumber_Subtract(r->stop, r->start);
602 if (!tmp)
603 goto create_failure;
604 len = PyNumber_FloorDivide(tmp, r->step);
605 Py_DECREF(tmp);
606 if (!len)
607 goto create_failure;
608 it->len = len;
Guido van Rossum805365e2007-05-07 22:24:25 +0000609 it->index = PyLong_FromLong(0);
610 if (!it->index)
611 goto create_failure;
612
Guido van Rossum805365e2007-05-07 22:24:25 +0000613 return (PyObject *)it;
614
615create_failure:
Guido van Rossum317e7742007-05-08 15:18:31 +0000616 Py_DECREF(it);
Guido van Rossum805365e2007-05-07 22:24:25 +0000617 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000618}
619
620static PyObject *
621range_reverse(PyObject *seq)
622{
Guido van Rossum805365e2007-05-07 22:24:25 +0000623 rangeobject *range = (rangeobject*) seq;
624 longrangeiterobject *it;
625 PyObject *one, *sum, *diff, *len = NULL, *product;
Martin v. Löwis84451042007-12-20 22:57:23 +0000626 long lstart, lstop, lstep;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000627
Guido van Rossum805365e2007-05-07 22:24:25 +0000628 /* XXX(nnorwitz): do the calc for the new start/stop first,
629 then if they fit, call the proper iter()?
630 */
631 assert(PyRange_Check(seq));
Martin v. Löwis84451042007-12-20 22:57:23 +0000632
633 /* If all three fields convert to long, use the int version */
634 lstart = PyLong_AsLong(range->start);
635 if (lstart != -1 || !PyErr_Occurred()) {
636 lstop = PyLong_AsLong(range->stop);
637 if (lstop != -1 || !PyErr_Occurred()) {
638 lstep = PyLong_AsLong(range->step);
639 if (lstep != -1 || !PyErr_Occurred()) {
640 /* XXX(nnorwitz): need to check for overflow and simplify. */
641 long len = get_len_of_range(lstart, lstop, lstep);
642 long new_start = lstart + (len - 1) * lstep;
643 long new_stop = lstart;
644 if (lstep > 0)
645 new_stop -= 1;
646 else
647 new_stop += 1;
648 return int_range_iter(new_start, new_stop, -lstep);
649 }
650 }
Guido van Rossum805365e2007-05-07 22:24:25 +0000651 }
Martin v. Löwis84451042007-12-20 22:57:23 +0000652 PyErr_Clear();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000653
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000654 it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
Guido van Rossum805365e2007-05-07 22:24:25 +0000655 if (it == NULL)
656 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000657
Guido van Rossum805365e2007-05-07 22:24:25 +0000658 /* start + (len - 1) * step */
659 len = range_length_obj(range);
660 if (!len)
661 goto create_failure;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000662
Guido van Rossum805365e2007-05-07 22:24:25 +0000663 one = PyLong_FromLong(1);
664 if (!one)
665 goto create_failure;
666
667 diff = PyNumber_Subtract(len, one);
668 Py_DECREF(one);
669 if (!diff)
670 goto create_failure;
671
672 product = PyNumber_Multiply(len, range->step);
673 if (!product)
674 goto create_failure;
675
676 sum = PyNumber_Add(range->start, product);
677 Py_DECREF(product);
678 it->start = sum;
679 if (!it->start)
680 goto create_failure;
681 it->step = PyNumber_Negative(range->step);
682 if (!it->step) {
683 Py_DECREF(it->start);
684 PyObject_Del(it);
685 return NULL;
686 }
687
688 /* Steal reference to len. */
689 it->len = len;
690
691 it->index = PyLong_FromLong(0);
692 if (!it->index) {
693 Py_DECREF(it);
694 return NULL;
695 }
696
697 return (PyObject *)it;
698
699create_failure:
700 Py_XDECREF(len);
701 PyObject_Del(it);
702 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000703}