blob: f8174caa4268983dc13f35dc3f2fe010e46f7f4d [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))
Raymond Hettinger94f55832009-06-12 18:40:16 +000062 return NULL;
Guido van Rossum805365e2007-05-07 22:24:25 +000063 stop = PyNumber_Index(stop);
64 if (!stop)
Raymond Hettinger94f55832009-06-12 18:40:16 +000065 return NULL;
Christian Heimes217cfd12007-12-02 14:31:20 +000066 start = PyLong_FromLong(0);
Raymond Hettinger94f55832009-06-12 18:40:16 +000067 if (!start) {
68 Py_DECREF(stop);
69 return NULL;
70 }
Christian Heimes217cfd12007-12-02 14:31:20 +000071 step = PyLong_FromLong(1);
Raymond Hettinger94f55832009-06-12 18:40:16 +000072 if (!step) {
73 Py_DECREF(stop);
74 Py_DECREF(start);
75 return NULL;
76 }
Guido van Rossum805365e2007-05-07 22:24:25 +000077 }
78 else {
79 if (!PyArg_UnpackTuple(args, "range", 2, 3,
80 &start, &stop, &step))
Raymond Hettinger94f55832009-06-12 18:40:16 +000081 return NULL;
Tim Petersfeec4532004-08-08 07:17:39 +000082
Guido van Rossum805365e2007-05-07 22:24:25 +000083 /* Convert borrowed refs to owned refs */
84 start = PyNumber_Index(start);
Raymond Hettinger94f55832009-06-12 18:40:16 +000085 if (!start)
86 return NULL;
Guido van Rossum805365e2007-05-07 22:24:25 +000087 stop = PyNumber_Index(stop);
Raymond Hettinger94f55832009-06-12 18:40:16 +000088 if (!stop) {
89 Py_DECREF(start);
90 return NULL;
91 }
92 step = validate_step(step); /* Caution, this can clear exceptions */
93 if (!step) {
94 Py_DECREF(start);
95 Py_DECREF(stop);
96 return NULL;
97 }
Guido van Rossum805365e2007-05-07 22:24:25 +000098 }
99
100 obj = PyObject_New(rangeobject, &PyRange_Type);
101 if (obj == NULL)
102 goto Fail;
103 obj->start = start;
104 obj->stop = stop;
105 obj->step = step;
106 return (PyObject *) obj;
107
108Fail:
109 Py_XDECREF(start);
110 Py_XDECREF(stop);
111 Py_XDECREF(step);
112 return NULL;
Raymond Hettingerc4c453f2002-06-05 23:12:45 +0000113}
114
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000115PyDoc_STRVAR(range_doc,
Guido van Rossum805365e2007-05-07 22:24:25 +0000116"range([start,] stop[, step]) -> range object\n\
Raymond Hettingerc4c453f2002-06-05 23:12:45 +0000117\n\
Guido van Rossum805365e2007-05-07 22:24:25 +0000118Returns an iterator that generates the numbers in the range on demand.");
Raymond Hettingerc4c453f2002-06-05 23:12:45 +0000119
Guido van Rossum805365e2007-05-07 22:24:25 +0000120static void
121range_dealloc(rangeobject *r)
Guido van Rossum12d12c51993-10-26 17:58:25 +0000122{
Guido van Rossum805365e2007-05-07 22:24:25 +0000123 Py_DECREF(r->start);
124 Py_DECREF(r->stop);
125 Py_DECREF(r->step);
Amaury Forgeot d'Arcb7f17e42007-11-15 20:52:21 +0000126 PyObject_Del(r);
Guido van Rossum805365e2007-05-07 22:24:25 +0000127}
128
129/* Return number of items in range (lo, hi, step), when arguments are
130 * PyInt or PyLong objects. step > 0 required. Return a value < 0 if
131 * & only if the true value is too large to fit in a signed long.
Christian Heimes217cfd12007-12-02 14:31:20 +0000132 * Arguments MUST return 1 with either PyLong_Check() or
Guido van Rossum805365e2007-05-07 22:24:25 +0000133 * PyLong_Check(). Return -1 when there is an error.
134 */
135static PyObject*
136range_length_obj(rangeobject *r)
137{
138 /* -------------------------------------------------------------
139 Algorithm is equal to that of get_len_of_range(), but it operates
140 on PyObjects (which are assumed to be PyLong or PyInt objects).
141 ---------------------------------------------------------------*/
Mark Dickinson211c6252009-02-01 10:28:51 +0000142 int cmp_result;
Guido van Rossum805365e2007-05-07 22:24:25 +0000143 PyObject *lo, *hi;
144 PyObject *step = NULL;
145 PyObject *diff = NULL;
146 PyObject *one = NULL;
147 PyObject *tmp1 = NULL, *tmp2 = NULL, *result;
148 /* holds sub-expression evaluations */
149
150 PyObject *zero = PyLong_FromLong(0);
151 if (zero == NULL)
152 return NULL;
Mark Dickinson211c6252009-02-01 10:28:51 +0000153 cmp_result = PyObject_RichCompareBool(r->step, zero, Py_GT);
Guido van Rossum805365e2007-05-07 22:24:25 +0000154 Py_DECREF(zero);
Mark Dickinson211c6252009-02-01 10:28:51 +0000155 if (cmp_result == -1)
Guido van Rossum805365e2007-05-07 22:24:25 +0000156 return NULL;
157
Mark Dickinson211c6252009-02-01 10:28:51 +0000158 if (cmp_result == 1) {
Guido van Rossum805365e2007-05-07 22:24:25 +0000159 lo = r->start;
160 hi = r->stop;
161 step = r->step;
162 Py_INCREF(step);
163 } else {
164 lo = r->stop;
165 hi = r->start;
166 step = PyNumber_Negative(r->step);
167 if (!step)
168 return NULL;
169 }
170
171 /* if (lo >= hi), return length of 0. */
Mark Dickinson211c6252009-02-01 10:28:51 +0000172 if (PyObject_RichCompareBool(lo, hi, Py_GE) == 1) {
Guido van Rossum805365e2007-05-07 22:24:25 +0000173 Py_XDECREF(step);
174 return PyLong_FromLong(0);
175 }
176
177 if ((one = PyLong_FromLong(1L)) == NULL)
178 goto Fail;
179
180 if ((tmp1 = PyNumber_Subtract(hi, lo)) == NULL)
181 goto Fail;
182
183 if ((diff = PyNumber_Subtract(tmp1, one)) == NULL)
184 goto Fail;
185
186 if ((tmp2 = PyNumber_FloorDivide(diff, step)) == NULL)
187 goto Fail;
188
189 if ((result = PyNumber_Add(tmp2, one)) == NULL)
190 goto Fail;
191
192 Py_DECREF(tmp2);
193 Py_DECREF(diff);
194 Py_DECREF(step);
195 Py_DECREF(tmp1);
196 Py_DECREF(one);
197 return result;
198
199 Fail:
200 Py_XDECREF(tmp2);
201 Py_XDECREF(diff);
202 Py_XDECREF(step);
203 Py_XDECREF(tmp1);
204 Py_XDECREF(one);
205 return NULL;
Guido van Rossum12d12c51993-10-26 17:58:25 +0000206}
207
Martin v. Löwis18e16552006-02-15 17:27:45 +0000208static Py_ssize_t
Fred Drake45cfbcc2000-07-09 06:21:27 +0000209range_length(rangeobject *r)
Guido van Rossum12d12c51993-10-26 17:58:25 +0000210{
Guido van Rossum805365e2007-05-07 22:24:25 +0000211 PyObject *len = range_length_obj(r);
212 Py_ssize_t result = -1;
213 if (len) {
214 result = PyLong_AsSsize_t(len);
215 Py_DECREF(len);
216 }
217 return result;
218}
219
220/* range(...)[x] is necessary for: seq[:] = range(...) */
221
222static PyObject *
223range_item(rangeobject *r, Py_ssize_t i)
224{
225 Py_ssize_t len = range_length(r);
226 PyObject *rem, *incr, *result;
227
228 /* XXX(nnorwitz): should negative indices be supported? */
229 /* XXX(nnorwitz): should support range[x] where x > PY_SSIZE_T_MAX? */
230 if (i < 0 || i >= len) {
231 if (!PyErr_Occurred())
232 PyErr_SetString(PyExc_IndexError,
Walter Dörwald4ad94212007-05-21 18:01:17 +0000233 "range object index out of range");
Benjamin Petersondf0a5cb2008-04-25 21:15:37 +0000234 return NULL;
235 }
Guido van Rossum805365e2007-05-07 22:24:25 +0000236
237 /* XXX(nnorwitz): optimize for short ints. */
Raymond Hettingerad3f3322008-02-09 04:13:49 +0000238 rem = PyLong_FromSsize_t(i);
Guido van Rossum805365e2007-05-07 22:24:25 +0000239 if (!rem)
240 return NULL;
241 incr = PyNumber_Multiply(rem, r->step);
242 Py_DECREF(rem);
243 if (!incr)
244 return NULL;
245 result = PyNumber_Add(r->start, incr);
246 Py_DECREF(incr);
247 return result;
Guido van Rossum7d6aa511993-12-21 22:50:31 +0000248}
249
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000250static PyObject *
Fred Drake45cfbcc2000-07-09 06:21:27 +0000251range_repr(rangeobject *r)
Guido van Rossum12d12c51993-10-26 17:58:25 +0000252{
Walter Dörwald03b43d82007-05-21 10:43:34 +0000253 Py_ssize_t istep;
Tim Petersd976ab72004-08-08 06:29:10 +0000254
Guido van Rossum805365e2007-05-07 22:24:25 +0000255 /* Check for special case values for printing. We don't always
Walter Dörwald03b43d82007-05-21 10:43:34 +0000256 need the step value. We don't care about errors
Guido van Rossum805365e2007-05-07 22:24:25 +0000257 (it means overflow), so clear the errors. */
Guido van Rossum805365e2007-05-07 22:24:25 +0000258 istep = PyNumber_AsSsize_t(r->step, NULL);
259 if (istep != 1 || (istep == -1 && PyErr_Occurred())) {
260 PyErr_Clear();
Guido van Rossum805365e2007-05-07 22:24:25 +0000261 }
262
Walter Dörwald03b43d82007-05-21 10:43:34 +0000263 if (istep == 1)
Walter Dörwald850e5162007-05-20 08:19:54 +0000264 return PyUnicode_FromFormat("range(%R, %R)", r->start, r->stop);
265 else
266 return PyUnicode_FromFormat("range(%R, %R, %R)",
267 r->start, r->stop, r->step);
Thomas Woutersefafcea2001-07-09 12:30:54 +0000268}
269
Alexandre Vassalotti75056072008-06-10 04:03:04 +0000270/* Pickling support */
271static PyObject *
272range_reduce(rangeobject *r, PyObject *args)
273{
274 return Py_BuildValue("(O(OOO))", Py_TYPE(r),
275 r->start, r->stop, r->step);
276}
277
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000278static PySequenceMethods range_as_sequence = {
Guido van Rossum805365e2007-05-07 22:24:25 +0000279 (lenfunc)range_length, /* sq_length */
280 0, /* sq_concat */
281 0, /* sq_repeat */
282 (ssizeargfunc)range_item, /* sq_item */
283 0, /* sq_slice */
Guido van Rossum12d12c51993-10-26 17:58:25 +0000284};
285
Jeremy Hylton938ace62002-07-17 16:30:39 +0000286static PyObject * range_iter(PyObject *seq);
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000287static PyObject * range_reverse(PyObject *seq);
288
289PyDoc_STRVAR(reverse_doc,
290"Returns a reverse iterator.");
291
292static PyMethodDef range_methods[] = {
Guido van Rossum805365e2007-05-07 22:24:25 +0000293 {"__reversed__", (PyCFunction)range_reverse, METH_NOARGS,
294 reverse_doc},
Alexandre Vassalotti75056072008-06-10 04:03:04 +0000295 {"__reduce__", (PyCFunction)range_reduce, METH_VARARGS},
Guido van Rossum805365e2007-05-07 22:24:25 +0000296 {NULL, NULL} /* sentinel */
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000297};
Raymond Hettinger48165d42002-06-05 20:08:48 +0000298
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000299PyTypeObject PyRange_Type = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000300 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Guido van Rossum805365e2007-05-07 22:24:25 +0000301 "range", /* Name of this type */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000302 sizeof(rangeobject), /* Basic object size */
303 0, /* Item size for varobject */
Guido van Rossum805365e2007-05-07 22:24:25 +0000304 (destructor)range_dealloc, /* tp_dealloc */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000305 0, /* tp_print */
306 0, /* tp_getattr */
307 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +0000308 0, /* tp_reserved */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000309 (reprfunc)range_repr, /* tp_repr */
310 0, /* tp_as_number */
311 &range_as_sequence, /* tp_as_sequence */
312 0, /* tp_as_mapping */
313 0, /* tp_hash */
314 0, /* tp_call */
315 0, /* tp_str */
316 PyObject_GenericGetAttr, /* tp_getattro */
317 0, /* tp_setattro */
318 0, /* tp_as_buffer */
319 Py_TPFLAGS_DEFAULT, /* tp_flags */
320 range_doc, /* tp_doc */
321 0, /* tp_traverse */
322 0, /* tp_clear */
323 0, /* tp_richcompare */
324 0, /* tp_weaklistoffset */
325 range_iter, /* tp_iter */
326 0, /* tp_iternext */
327 range_methods, /* tp_methods */
328 0, /* tp_members */
329 0, /* tp_getset */
330 0, /* tp_base */
331 0, /* tp_dict */
332 0, /* tp_descr_get */
333 0, /* tp_descr_set */
334 0, /* tp_dictoffset */
335 0, /* tp_init */
336 0, /* tp_alloc */
337 range_new, /* tp_new */
Guido van Rossum12d12c51993-10-26 17:58:25 +0000338};
Raymond Hettinger48165d42002-06-05 20:08:48 +0000339
Walter Dörwald4ad94212007-05-21 18:01:17 +0000340/*********************** range Iterator **************************/
Raymond Hettinger48165d42002-06-05 20:08:48 +0000341
Guido van Rossum805365e2007-05-07 22:24:25 +0000342/* There are 2 types of iterators, one for C longs, the other for
343 Python longs (ie, PyObjects). This should make iteration fast
344 in the normal case, but possible for any numeric value.
345*/
346
Raymond Hettinger48165d42002-06-05 20:08:48 +0000347typedef struct {
348 PyObject_HEAD
349 long index;
350 long start;
351 long step;
352 long len;
353} rangeiterobject;
354
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000355static PyObject *
Raymond Hettinger48165d42002-06-05 20:08:48 +0000356rangeiter_next(rangeiterobject *r)
357{
Guido van Rossum805365e2007-05-07 22:24:25 +0000358 if (r->index < r->len)
Christian Heimes217cfd12007-12-02 14:31:20 +0000359 return PyLong_FromLong(r->start + (r->index++) * r->step);
Guido van Rossum805365e2007-05-07 22:24:25 +0000360 return NULL;
Raymond Hettinger48165d42002-06-05 20:08:48 +0000361}
362
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000363static PyObject *
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000364rangeiter_len(rangeiterobject *r)
365{
Christian Heimes217cfd12007-12-02 14:31:20 +0000366 return PyLong_FromLong(r->len - r->index);
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000367}
368
Guido van Rossum805365e2007-05-07 22:24:25 +0000369typedef struct {
370 PyObject_HEAD
371 PyObject *index;
372 PyObject *start;
373 PyObject *step;
374 PyObject *len;
375} longrangeiterobject;
376
377static PyObject *
378longrangeiter_len(longrangeiterobject *r, PyObject *no_args)
379{
380 return PyNumber_Subtract(r->len, r->index);
381}
Guido van Rossum317e7742007-05-08 15:18:31 +0000382
Guido van Rossum805365e2007-05-07 22:24:25 +0000383static PyObject *rangeiter_new(PyTypeObject *, PyObject *args, PyObject *kw);
384
385PyDoc_STRVAR(length_hint_doc,
386 "Private method returning an estimate of len(list(it)).");
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000387
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000388static PyMethodDef rangeiter_methods[] = {
Guido van Rossum805365e2007-05-07 22:24:25 +0000389 {"__length_hint__", (PyCFunction)rangeiter_len, METH_NOARGS,
390 length_hint_doc},
391 {NULL, NULL} /* sentinel */
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000392};
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000393
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000394PyTypeObject PyRangeIter_Type = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000395 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Christian Heimesf83be4e2007-11-28 09:44:38 +0000396 "range_iterator", /* tp_name */
Neal Norwitz56f46f82002-06-06 14:58:21 +0000397 sizeof(rangeiterobject), /* tp_basicsize */
Raymond Hettinger48165d42002-06-05 20:08:48 +0000398 0, /* tp_itemsize */
399 /* methods */
400 (destructor)PyObject_Del, /* tp_dealloc */
401 0, /* tp_print */
402 0, /* tp_getattr */
403 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +0000404 0, /* tp_reserved */
Raymond Hettinger48165d42002-06-05 20:08:48 +0000405 0, /* tp_repr */
406 0, /* tp_as_number */
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000407 0, /* tp_as_sequence */
Raymond Hettinger48165d42002-06-05 20:08:48 +0000408 0, /* tp_as_mapping */
409 0, /* tp_hash */
410 0, /* tp_call */
411 0, /* tp_str */
412 PyObject_GenericGetAttr, /* tp_getattro */
413 0, /* tp_setattro */
414 0, /* tp_as_buffer */
415 Py_TPFLAGS_DEFAULT, /* tp_flags */
416 0, /* tp_doc */
417 0, /* tp_traverse */
418 0, /* tp_clear */
419 0, /* tp_richcompare */
420 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +0000421 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger48165d42002-06-05 20:08:48 +0000422 (iternextfunc)rangeiter_next, /* tp_iternext */
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000423 rangeiter_methods, /* tp_methods */
Guido van Rossum805365e2007-05-07 22:24:25 +0000424 0, /* tp_members */
425 0, /* tp_getset */
426 0, /* tp_base */
427 0, /* tp_dict */
428 0, /* tp_descr_get */
429 0, /* tp_descr_set */
430 0, /* tp_dictoffset */
431 0, /* tp_init */
432 0, /* tp_alloc */
433 rangeiter_new, /* tp_new */
434};
435
436/* Return number of items in range/xrange (lo, hi, step). step > 0
437 * required. Return a value < 0 if & only if the true value is too
438 * large to fit in a signed long.
439 */
440static long
441get_len_of_range(long lo, long hi, long step)
442{
443 /* -------------------------------------------------------------
444 If lo >= hi, the range is empty.
445 Else 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.
454 ---------------------------------------------------------------*/
455 long n = 0;
456 if (lo < hi) {
457 unsigned long uhi = (unsigned long)hi;
458 unsigned long ulo = (unsigned long)lo;
459 unsigned long diff = uhi - ulo - 1;
460 n = (long)(diff / (unsigned long)step + 1);
461 }
462 return n;
463}
464
465static PyObject *
466int_range_iter(long start, long stop, long step)
467{
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000468 rangeiterobject *it = PyObject_New(rangeiterobject, &PyRangeIter_Type);
Guido van Rossum805365e2007-05-07 22:24:25 +0000469 if (it == NULL)
470 return NULL;
471 it->start = start;
472 it->step = step;
473 if (step > 0)
474 it->len = get_len_of_range(start, stop, step);
475 else
476 it->len = get_len_of_range(stop, start, -step);
477 it->index = 0;
478 return (PyObject *)it;
479}
480
481static PyObject *
482rangeiter_new(PyTypeObject *type, PyObject *args, PyObject *kw)
483{
484 long start, stop, step;
485
486 if (!_PyArg_NoKeywords("rangeiter()", kw))
487 return NULL;
488
489 if (!PyArg_ParseTuple(args, "lll;rangeiter() requires 3 int arguments",
490 &start, &stop, &step))
491 return NULL;
492
493 return int_range_iter(start, stop, step);
494}
495
496static PyMethodDef longrangeiter_methods[] = {
497 {"__length_hint__", (PyCFunction)longrangeiter_len, METH_NOARGS,
498 length_hint_doc},
499 {NULL, NULL} /* sentinel */
500};
501
502static void
503longrangeiter_dealloc(longrangeiterobject *r)
504{
505 Py_XDECREF(r->index);
Guido van Rossum317e7742007-05-08 15:18:31 +0000506 Py_XDECREF(r->start);
507 Py_XDECREF(r->step);
508 Py_XDECREF(r->len);
Amaury Forgeot d'Arcb7f17e42007-11-15 20:52:21 +0000509 PyObject_Del(r);
Guido van Rossum805365e2007-05-07 22:24:25 +0000510}
511
512static PyObject *
513longrangeiter_next(longrangeiterobject *r)
514{
515 PyObject *one, *product, *new_index, *result;
516 if (PyObject_RichCompareBool(r->index, r->len, Py_LT) != 1)
517 return NULL;
518
519 one = PyLong_FromLong(1);
520 if (!one)
521 return NULL;
522
523 product = PyNumber_Multiply(r->index, r->step);
524 if (!product) {
525 Py_DECREF(one);
526 return NULL;
527 }
528
529 new_index = PyNumber_Add(r->index, one);
530 Py_DECREF(one);
531 if (!new_index) {
532 Py_DECREF(product);
533 return NULL;
534 }
535
536 result = PyNumber_Add(r->start, product);
537 Py_DECREF(product);
538 if (result) {
539 Py_DECREF(r->index);
540 r->index = new_index;
541 }
542
543 return result;
544}
545
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000546PyTypeObject PyLongRangeIter_Type = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000547 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000548 "longrange_iterator", /* tp_name */
Guido van Rossum805365e2007-05-07 22:24:25 +0000549 sizeof(longrangeiterobject), /* tp_basicsize */
550 0, /* tp_itemsize */
551 /* methods */
552 (destructor)longrangeiter_dealloc, /* tp_dealloc */
553 0, /* tp_print */
554 0, /* tp_getattr */
555 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +0000556 0, /* tp_reserved */
Guido van Rossum805365e2007-05-07 22:24:25 +0000557 0, /* tp_repr */
558 0, /* tp_as_number */
559 0, /* tp_as_sequence */
560 0, /* tp_as_mapping */
561 0, /* tp_hash */
562 0, /* tp_call */
563 0, /* tp_str */
564 PyObject_GenericGetAttr, /* tp_getattro */
565 0, /* tp_setattro */
566 0, /* tp_as_buffer */
567 Py_TPFLAGS_DEFAULT, /* tp_flags */
568 0, /* tp_doc */
569 0, /* tp_traverse */
570 0, /* tp_clear */
571 0, /* tp_richcompare */
572 0, /* tp_weaklistoffset */
573 PyObject_SelfIter, /* tp_iter */
574 (iternextfunc)longrangeiter_next, /* tp_iternext */
575 longrangeiter_methods, /* tp_methods */
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000576 0,
Raymond Hettinger48165d42002-06-05 20:08:48 +0000577};
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000578
579static PyObject *
580range_iter(PyObject *seq)
581{
Guido van Rossum805365e2007-05-07 22:24:25 +0000582 rangeobject *r = (rangeobject *)seq;
583 longrangeiterobject *it;
584 PyObject *tmp, *len;
Martin v. Löwis84451042007-12-20 22:57:23 +0000585 long lstart, lstop, lstep;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000586
Guido van Rossum805365e2007-05-07 22:24:25 +0000587 assert(PyRange_Check(seq));
Martin v. Löwis84451042007-12-20 22:57:23 +0000588
589 /* If all three fields convert to long, use the int version */
590 lstart = PyLong_AsLong(r->start);
591 if (lstart != -1 || !PyErr_Occurred()) {
592 lstop = PyLong_AsLong(r->stop);
593 if (lstop != -1 || !PyErr_Occurred()) {
594 lstep = PyLong_AsLong(r->step);
595 if (lstep != -1 || !PyErr_Occurred())
596 return int_range_iter(lstart, lstop, lstep);
597 }
598 }
599 /* Some conversion failed, so there is an error set. Clear it,
600 and try again with a long range. */
601 PyErr_Clear();
Guido van Rossum805365e2007-05-07 22:24:25 +0000602
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000603 it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
Guido van Rossum805365e2007-05-07 22:24:25 +0000604 if (it == NULL)
605 return NULL;
Guido van Rossum317e7742007-05-08 15:18:31 +0000606
607 /* Do all initialization here, so we can DECREF on failure. */
Guido van Rossum805365e2007-05-07 22:24:25 +0000608 it->start = r->start;
Guido van Rossum317e7742007-05-08 15:18:31 +0000609 it->step = r->step;
610 Py_INCREF(it->start);
611 Py_INCREF(it->step);
612
613 it->len = it->index = NULL;
614
Guido van Rossum805365e2007-05-07 22:24:25 +0000615 /* Calculate length: (r->stop - r->start) / r->step */
616 tmp = PyNumber_Subtract(r->stop, r->start);
617 if (!tmp)
618 goto create_failure;
619 len = PyNumber_FloorDivide(tmp, r->step);
620 Py_DECREF(tmp);
621 if (!len)
622 goto create_failure;
623 it->len = len;
Guido van Rossum805365e2007-05-07 22:24:25 +0000624 it->index = PyLong_FromLong(0);
625 if (!it->index)
626 goto create_failure;
627
Guido van Rossum805365e2007-05-07 22:24:25 +0000628 return (PyObject *)it;
629
630create_failure:
Guido van Rossum317e7742007-05-08 15:18:31 +0000631 Py_DECREF(it);
Guido van Rossum805365e2007-05-07 22:24:25 +0000632 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000633}
634
635static PyObject *
636range_reverse(PyObject *seq)
637{
Guido van Rossum805365e2007-05-07 22:24:25 +0000638 rangeobject *range = (rangeobject*) seq;
639 longrangeiterobject *it;
640 PyObject *one, *sum, *diff, *len = NULL, *product;
Martin v. Löwis84451042007-12-20 22:57:23 +0000641 long lstart, lstop, lstep;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000642
Guido van Rossum805365e2007-05-07 22:24:25 +0000643 /* XXX(nnorwitz): do the calc for the new start/stop first,
644 then if they fit, call the proper iter()?
645 */
646 assert(PyRange_Check(seq));
Martin v. Löwis84451042007-12-20 22:57:23 +0000647
648 /* If all three fields convert to long, use the int version */
649 lstart = PyLong_AsLong(range->start);
650 if (lstart != -1 || !PyErr_Occurred()) {
651 lstop = PyLong_AsLong(range->stop);
652 if (lstop != -1 || !PyErr_Occurred()) {
653 lstep = PyLong_AsLong(range->step);
654 if (lstep != -1 || !PyErr_Occurred()) {
655 /* XXX(nnorwitz): need to check for overflow and simplify. */
656 long len = get_len_of_range(lstart, lstop, lstep);
657 long new_start = lstart + (len - 1) * lstep;
658 long new_stop = lstart;
659 if (lstep > 0)
660 new_stop -= 1;
661 else
662 new_stop += 1;
663 return int_range_iter(new_start, new_stop, -lstep);
664 }
665 }
Guido van Rossum805365e2007-05-07 22:24:25 +0000666 }
Martin v. Löwis84451042007-12-20 22:57:23 +0000667 PyErr_Clear();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000668
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000669 it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
Guido van Rossum805365e2007-05-07 22:24:25 +0000670 if (it == NULL)
671 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000672
Guido van Rossum805365e2007-05-07 22:24:25 +0000673 /* start + (len - 1) * step */
674 len = range_length_obj(range);
675 if (!len)
676 goto create_failure;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000677
Guido van Rossum805365e2007-05-07 22:24:25 +0000678 one = PyLong_FromLong(1);
679 if (!one)
680 goto create_failure;
681
682 diff = PyNumber_Subtract(len, one);
683 Py_DECREF(one);
684 if (!diff)
685 goto create_failure;
686
687 product = PyNumber_Multiply(len, range->step);
688 if (!product)
689 goto create_failure;
690
691 sum = PyNumber_Add(range->start, product);
692 Py_DECREF(product);
693 it->start = sum;
694 if (!it->start)
695 goto create_failure;
696 it->step = PyNumber_Negative(range->step);
697 if (!it->step) {
698 Py_DECREF(it->start);
699 PyObject_Del(it);
700 return NULL;
701 }
702
703 /* Steal reference to len. */
704 it->len = len;
705
706 it->index = PyLong_FromLong(0);
707 if (!it->index) {
708 Py_DECREF(it);
709 return NULL;
710 }
711
712 return (PyObject *)it;
713
714create_failure:
715 Py_XDECREF(len);
716 PyObject_Del(it);
717 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000718}