blob: 213f3dd382836666024aa5a4825a147e7040635f [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
Mark Dickinson732166d2009-06-28 22:08:40 +0000129/* 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.
Guido van Rossum805365e2007-05-07 22:24:25 +0000132 */
133static PyObject*
134range_length_obj(rangeobject *r)
135{
136 /* -------------------------------------------------------------
137 Algorithm is equal to that of get_len_of_range(), but it operates
Benjamin Petersona47af9c2009-06-24 21:14:38 +0000138 on PyObjects (which are assumed to be PyLong objects).
Guido van Rossum805365e2007-05-07 22:24:25 +0000139 ---------------------------------------------------------------*/
Mark Dickinson211c6252009-02-01 10:28:51 +0000140 int cmp_result;
Guido van Rossum805365e2007-05-07 22:24:25 +0000141 PyObject *lo, *hi;
142 PyObject *step = NULL;
143 PyObject *diff = NULL;
144 PyObject *one = NULL;
145 PyObject *tmp1 = NULL, *tmp2 = NULL, *result;
146 /* holds sub-expression evaluations */
147
148 PyObject *zero = PyLong_FromLong(0);
149 if (zero == NULL)
150 return NULL;
Mark Dickinson211c6252009-02-01 10:28:51 +0000151 cmp_result = PyObject_RichCompareBool(r->step, zero, Py_GT);
Guido van Rossum805365e2007-05-07 22:24:25 +0000152 Py_DECREF(zero);
Mark Dickinson211c6252009-02-01 10:28:51 +0000153 if (cmp_result == -1)
Guido van Rossum805365e2007-05-07 22:24:25 +0000154 return NULL;
155
Mark Dickinson211c6252009-02-01 10:28:51 +0000156 if (cmp_result == 1) {
Guido van Rossum805365e2007-05-07 22:24:25 +0000157 lo = r->start;
158 hi = r->stop;
159 step = r->step;
160 Py_INCREF(step);
161 } else {
162 lo = r->stop;
163 hi = r->start;
164 step = PyNumber_Negative(r->step);
165 if (!step)
166 return NULL;
167 }
168
169 /* if (lo >= hi), return length of 0. */
Mark Dickinson211c6252009-02-01 10:28:51 +0000170 if (PyObject_RichCompareBool(lo, hi, Py_GE) == 1) {
Guido van Rossum805365e2007-05-07 22:24:25 +0000171 Py_XDECREF(step);
172 return PyLong_FromLong(0);
173 }
174
175 if ((one = PyLong_FromLong(1L)) == NULL)
176 goto Fail;
177
178 if ((tmp1 = PyNumber_Subtract(hi, lo)) == NULL)
179 goto Fail;
180
181 if ((diff = PyNumber_Subtract(tmp1, one)) == NULL)
182 goto Fail;
183
184 if ((tmp2 = PyNumber_FloorDivide(diff, step)) == NULL)
185 goto Fail;
186
187 if ((result = PyNumber_Add(tmp2, one)) == NULL)
188 goto Fail;
189
190 Py_DECREF(tmp2);
191 Py_DECREF(diff);
192 Py_DECREF(step);
193 Py_DECREF(tmp1);
194 Py_DECREF(one);
195 return result;
196
197 Fail:
198 Py_XDECREF(tmp2);
199 Py_XDECREF(diff);
200 Py_XDECREF(step);
201 Py_XDECREF(tmp1);
202 Py_XDECREF(one);
203 return NULL;
Guido van Rossum12d12c51993-10-26 17:58:25 +0000204}
205
Martin v. Löwis18e16552006-02-15 17:27:45 +0000206static Py_ssize_t
Fred Drake45cfbcc2000-07-09 06:21:27 +0000207range_length(rangeobject *r)
Guido van Rossum12d12c51993-10-26 17:58:25 +0000208{
Guido van Rossum805365e2007-05-07 22:24:25 +0000209 PyObject *len = range_length_obj(r);
210 Py_ssize_t result = -1;
211 if (len) {
212 result = PyLong_AsSsize_t(len);
213 Py_DECREF(len);
214 }
215 return result;
216}
217
218/* range(...)[x] is necessary for: seq[:] = range(...) */
219
220static PyObject *
221range_item(rangeobject *r, Py_ssize_t i)
222{
223 Py_ssize_t len = range_length(r);
224 PyObject *rem, *incr, *result;
225
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,
Walter Dörwald4ad94212007-05-21 18:01:17 +0000231 "range object index out of range");
Benjamin Petersondf0a5cb2008-04-25 21:15:37 +0000232 return NULL;
233 }
Guido van Rossum805365e2007-05-07 22:24:25 +0000234
235 /* XXX(nnorwitz): optimize for short ints. */
Raymond Hettingerad3f3322008-02-09 04:13:49 +0000236 rem = PyLong_FromSsize_t(i);
Guido van Rossum805365e2007-05-07 22:24:25 +0000237 if (!rem)
238 return NULL;
239 incr = PyNumber_Multiply(rem, r->step);
240 Py_DECREF(rem);
241 if (!incr)
242 return NULL;
243 result = PyNumber_Add(r->start, incr);
244 Py_DECREF(incr);
245 return result;
Guido van Rossum7d6aa511993-12-21 22:50:31 +0000246}
247
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000248static PyObject *
Fred Drake45cfbcc2000-07-09 06:21:27 +0000249range_repr(rangeobject *r)
Guido van Rossum12d12c51993-10-26 17:58:25 +0000250{
Walter Dörwald03b43d82007-05-21 10:43:34 +0000251 Py_ssize_t istep;
Tim Petersd976ab72004-08-08 06:29:10 +0000252
Guido van Rossum805365e2007-05-07 22:24:25 +0000253 /* Check for special case values for printing. We don't always
Walter Dörwald03b43d82007-05-21 10:43:34 +0000254 need the step value. We don't care about errors
Guido van Rossum805365e2007-05-07 22:24:25 +0000255 (it means overflow), so clear the errors. */
Guido van Rossum805365e2007-05-07 22:24:25 +0000256 istep = PyNumber_AsSsize_t(r->step, NULL);
257 if (istep != 1 || (istep == -1 && PyErr_Occurred())) {
258 PyErr_Clear();
Guido van Rossum805365e2007-05-07 22:24:25 +0000259 }
260
Walter Dörwald03b43d82007-05-21 10:43:34 +0000261 if (istep == 1)
Walter Dörwald850e5162007-05-20 08:19:54 +0000262 return PyUnicode_FromFormat("range(%R, %R)", r->start, r->stop);
263 else
264 return PyUnicode_FromFormat("range(%R, %R, %R)",
265 r->start, r->stop, r->step);
Thomas Woutersefafcea2001-07-09 12:30:54 +0000266}
267
Alexandre Vassalotti75056072008-06-10 04:03:04 +0000268/* Pickling support */
269static PyObject *
270range_reduce(rangeobject *r, PyObject *args)
271{
272 return Py_BuildValue("(O(OOO))", Py_TYPE(r),
273 r->start, r->stop, r->step);
274}
275
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000276static int
277range_contains(rangeobject *r, PyObject *ob) {
278 if (PyLong_Check(ob)) {
279 int cmp1, cmp2, cmp3;
280 PyObject *tmp1 = NULL;
281 PyObject *tmp2 = NULL;
282 PyObject *zero = NULL;
283 int result = -1;
284
285 zero = PyLong_FromLong(0);
286 if (zero == NULL) /* MemoryError in int(0) */
287 goto end;
288
289 /* Check if the value can possibly be in the range. */
290
291 cmp1 = PyObject_RichCompareBool(r->step, zero, Py_GT);
292 if (cmp1 == -1)
293 goto end;
294 if (cmp1 == 1) { /* positive steps: start <= ob < stop */
295 cmp2 = PyObject_RichCompareBool(r->start, ob, Py_LE);
296 cmp3 = PyObject_RichCompareBool(ob, r->stop, Py_LT);
297 }
298 else { /* negative steps: stop < ob <= start */
299 cmp2 = PyObject_RichCompareBool(ob, r->start, Py_LE);
300 cmp3 = PyObject_RichCompareBool(r->stop, ob, Py_LT);
301 }
302
303 if (cmp2 == -1 || cmp3 == -1) /* TypeError */
304 goto end;
305 if (cmp2 == 0 || cmp3 == 0) { /* ob outside of range */
306 result = 0;
307 goto end;
308 }
309
310 /* Check that the stride does not invalidate ob's membership. */
311 tmp1 = PyNumber_Subtract(ob, r->start);
312 if (tmp1 == NULL)
313 goto end;
314 tmp2 = PyNumber_Remainder(tmp1, r->step);
315 if (tmp2 == NULL)
316 goto end;
317 /* result = (int(ob) - start % step) == 0 */
318 result = PyObject_RichCompareBool(tmp2, zero, Py_EQ);
319 end:
320 Py_XDECREF(tmp1);
321 Py_XDECREF(tmp2);
322 Py_XDECREF(zero);
323 return result;
324 }
325 /* Fall back to iterative search. */
326 return (int)_PySequence_IterSearch((PyObject*)r, ob,
327 PY_ITERSEARCH_CONTAINS);
328}
329
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000330static PySequenceMethods range_as_sequence = {
Guido van Rossum805365e2007-05-07 22:24:25 +0000331 (lenfunc)range_length, /* sq_length */
332 0, /* sq_concat */
333 0, /* sq_repeat */
334 (ssizeargfunc)range_item, /* sq_item */
335 0, /* sq_slice */
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000336 0, /* sq_ass_item */
337 0, /* sq_ass_slice */
338 (objobjproc)range_contains, /* sq_contains */
Guido van Rossum12d12c51993-10-26 17:58:25 +0000339};
340
Jeremy Hylton938ace62002-07-17 16:30:39 +0000341static PyObject * range_iter(PyObject *seq);
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000342static PyObject * range_reverse(PyObject *seq);
343
344PyDoc_STRVAR(reverse_doc,
345"Returns a reverse iterator.");
346
347static PyMethodDef range_methods[] = {
Guido van Rossum805365e2007-05-07 22:24:25 +0000348 {"__reversed__", (PyCFunction)range_reverse, METH_NOARGS,
349 reverse_doc},
Alexandre Vassalotti75056072008-06-10 04:03:04 +0000350 {"__reduce__", (PyCFunction)range_reduce, METH_VARARGS},
Guido van Rossum805365e2007-05-07 22:24:25 +0000351 {NULL, NULL} /* sentinel */
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000352};
Raymond Hettinger48165d42002-06-05 20:08:48 +0000353
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000354PyTypeObject PyRange_Type = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000355 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Guido van Rossum805365e2007-05-07 22:24:25 +0000356 "range", /* Name of this type */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000357 sizeof(rangeobject), /* Basic object size */
358 0, /* Item size for varobject */
Guido van Rossum805365e2007-05-07 22:24:25 +0000359 (destructor)range_dealloc, /* tp_dealloc */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000360 0, /* tp_print */
361 0, /* tp_getattr */
362 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +0000363 0, /* tp_reserved */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000364 (reprfunc)range_repr, /* tp_repr */
365 0, /* tp_as_number */
366 &range_as_sequence, /* tp_as_sequence */
367 0, /* tp_as_mapping */
368 0, /* tp_hash */
369 0, /* tp_call */
370 0, /* tp_str */
371 PyObject_GenericGetAttr, /* tp_getattro */
372 0, /* tp_setattro */
373 0, /* tp_as_buffer */
374 Py_TPFLAGS_DEFAULT, /* tp_flags */
375 range_doc, /* tp_doc */
376 0, /* tp_traverse */
377 0, /* tp_clear */
378 0, /* tp_richcompare */
379 0, /* tp_weaklistoffset */
380 range_iter, /* tp_iter */
381 0, /* tp_iternext */
382 range_methods, /* tp_methods */
383 0, /* tp_members */
384 0, /* tp_getset */
385 0, /* tp_base */
386 0, /* tp_dict */
387 0, /* tp_descr_get */
388 0, /* tp_descr_set */
389 0, /* tp_dictoffset */
390 0, /* tp_init */
391 0, /* tp_alloc */
392 range_new, /* tp_new */
Guido van Rossum12d12c51993-10-26 17:58:25 +0000393};
Raymond Hettinger48165d42002-06-05 20:08:48 +0000394
Walter Dörwald4ad94212007-05-21 18:01:17 +0000395/*********************** range Iterator **************************/
Raymond Hettinger48165d42002-06-05 20:08:48 +0000396
Guido van Rossum805365e2007-05-07 22:24:25 +0000397/* There are 2 types of iterators, one for C longs, the other for
398 Python longs (ie, PyObjects). This should make iteration fast
399 in the normal case, but possible for any numeric value.
400*/
401
Raymond Hettinger48165d42002-06-05 20:08:48 +0000402typedef struct {
403 PyObject_HEAD
404 long index;
405 long start;
406 long step;
407 long len;
408} rangeiterobject;
409
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000410static PyObject *
Raymond Hettinger48165d42002-06-05 20:08:48 +0000411rangeiter_next(rangeiterobject *r)
412{
Guido van Rossum805365e2007-05-07 22:24:25 +0000413 if (r->index < r->len)
Christian Heimes217cfd12007-12-02 14:31:20 +0000414 return PyLong_FromLong(r->start + (r->index++) * r->step);
Guido van Rossum805365e2007-05-07 22:24:25 +0000415 return NULL;
Raymond Hettinger48165d42002-06-05 20:08:48 +0000416}
417
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000418static PyObject *
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000419rangeiter_len(rangeiterobject *r)
420{
Christian Heimes217cfd12007-12-02 14:31:20 +0000421 return PyLong_FromLong(r->len - r->index);
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000422}
423
Guido van Rossum805365e2007-05-07 22:24:25 +0000424typedef struct {
425 PyObject_HEAD
426 PyObject *index;
427 PyObject *start;
428 PyObject *step;
429 PyObject *len;
430} longrangeiterobject;
431
432static PyObject *
433longrangeiter_len(longrangeiterobject *r, PyObject *no_args)
434{
435 return PyNumber_Subtract(r->len, r->index);
436}
Guido van Rossum317e7742007-05-08 15:18:31 +0000437
Guido van Rossum805365e2007-05-07 22:24:25 +0000438static PyObject *rangeiter_new(PyTypeObject *, PyObject *args, PyObject *kw);
439
440PyDoc_STRVAR(length_hint_doc,
441 "Private method returning an estimate of len(list(it)).");
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000442
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000443static PyMethodDef rangeiter_methods[] = {
Guido van Rossum805365e2007-05-07 22:24:25 +0000444 {"__length_hint__", (PyCFunction)rangeiter_len, METH_NOARGS,
445 length_hint_doc},
446 {NULL, NULL} /* sentinel */
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000447};
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000448
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000449PyTypeObject PyRangeIter_Type = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000450 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Christian Heimesf83be4e2007-11-28 09:44:38 +0000451 "range_iterator", /* tp_name */
Neal Norwitz56f46f82002-06-06 14:58:21 +0000452 sizeof(rangeiterobject), /* tp_basicsize */
Raymond Hettinger48165d42002-06-05 20:08:48 +0000453 0, /* tp_itemsize */
454 /* methods */
455 (destructor)PyObject_Del, /* tp_dealloc */
456 0, /* tp_print */
457 0, /* tp_getattr */
458 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +0000459 0, /* tp_reserved */
Raymond Hettinger48165d42002-06-05 20:08:48 +0000460 0, /* tp_repr */
461 0, /* tp_as_number */
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000462 0, /* tp_as_sequence */
Raymond Hettinger48165d42002-06-05 20:08:48 +0000463 0, /* tp_as_mapping */
464 0, /* tp_hash */
465 0, /* tp_call */
466 0, /* tp_str */
467 PyObject_GenericGetAttr, /* tp_getattro */
468 0, /* tp_setattro */
469 0, /* tp_as_buffer */
470 Py_TPFLAGS_DEFAULT, /* tp_flags */
471 0, /* tp_doc */
472 0, /* tp_traverse */
473 0, /* tp_clear */
474 0, /* tp_richcompare */
475 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +0000476 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger48165d42002-06-05 20:08:48 +0000477 (iternextfunc)rangeiter_next, /* tp_iternext */
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000478 rangeiter_methods, /* tp_methods */
Guido van Rossum805365e2007-05-07 22:24:25 +0000479 0, /* tp_members */
480 0, /* tp_getset */
481 0, /* tp_base */
482 0, /* tp_dict */
483 0, /* tp_descr_get */
484 0, /* tp_descr_set */
485 0, /* tp_dictoffset */
486 0, /* tp_init */
487 0, /* tp_alloc */
488 rangeiter_new, /* tp_new */
489};
490
Georg Brandlc9a5a0e2009-09-01 07:34:27 +0000491/* Return number of items in range (lo, hi, step). step > 0
Guido van Rossum805365e2007-05-07 22:24:25 +0000492 * required. Return a value < 0 if & only if the true value is too
493 * large to fit in a signed long.
494 */
495static long
496get_len_of_range(long lo, long hi, long step)
497{
498 /* -------------------------------------------------------------
499 If lo >= hi, the range is empty.
500 Else if n values are in the range, the last one is
501 lo + (n-1)*step, which must be <= hi-1. Rearranging,
502 n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives
503 the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so
504 the RHS is non-negative and so truncation is the same as the
505 floor. Letting M be the largest positive long, the worst case
506 for the RHS numerator is hi=M, lo=-M-1, and then
507 hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough
508 precision to compute the RHS exactly.
509 ---------------------------------------------------------------*/
510 long n = 0;
511 if (lo < hi) {
512 unsigned long uhi = (unsigned long)hi;
513 unsigned long ulo = (unsigned long)lo;
514 unsigned long diff = uhi - ulo - 1;
515 n = (long)(diff / (unsigned long)step + 1);
516 }
517 return n;
518}
519
520static PyObject *
521int_range_iter(long start, long stop, long step)
522{
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000523 rangeiterobject *it = PyObject_New(rangeiterobject, &PyRangeIter_Type);
Guido van Rossum805365e2007-05-07 22:24:25 +0000524 if (it == NULL)
525 return NULL;
526 it->start = start;
527 it->step = step;
528 if (step > 0)
529 it->len = get_len_of_range(start, stop, step);
530 else
531 it->len = get_len_of_range(stop, start, -step);
532 it->index = 0;
533 return (PyObject *)it;
534}
535
536static PyObject *
537rangeiter_new(PyTypeObject *type, PyObject *args, PyObject *kw)
538{
539 long start, stop, step;
540
541 if (!_PyArg_NoKeywords("rangeiter()", kw))
542 return NULL;
543
544 if (!PyArg_ParseTuple(args, "lll;rangeiter() requires 3 int arguments",
545 &start, &stop, &step))
546 return NULL;
547
548 return int_range_iter(start, stop, step);
549}
550
551static PyMethodDef longrangeiter_methods[] = {
552 {"__length_hint__", (PyCFunction)longrangeiter_len, METH_NOARGS,
553 length_hint_doc},
554 {NULL, NULL} /* sentinel */
555};
556
557static void
558longrangeiter_dealloc(longrangeiterobject *r)
559{
560 Py_XDECREF(r->index);
Guido van Rossum317e7742007-05-08 15:18:31 +0000561 Py_XDECREF(r->start);
562 Py_XDECREF(r->step);
563 Py_XDECREF(r->len);
Amaury Forgeot d'Arcb7f17e42007-11-15 20:52:21 +0000564 PyObject_Del(r);
Guido van Rossum805365e2007-05-07 22:24:25 +0000565}
566
567static PyObject *
568longrangeiter_next(longrangeiterobject *r)
569{
570 PyObject *one, *product, *new_index, *result;
571 if (PyObject_RichCompareBool(r->index, r->len, Py_LT) != 1)
572 return NULL;
573
574 one = PyLong_FromLong(1);
575 if (!one)
576 return NULL;
577
578 product = PyNumber_Multiply(r->index, r->step);
579 if (!product) {
580 Py_DECREF(one);
581 return NULL;
582 }
583
584 new_index = PyNumber_Add(r->index, one);
585 Py_DECREF(one);
586 if (!new_index) {
587 Py_DECREF(product);
588 return NULL;
589 }
590
591 result = PyNumber_Add(r->start, product);
592 Py_DECREF(product);
593 if (result) {
594 Py_DECREF(r->index);
595 r->index = new_index;
596 }
597
598 return result;
599}
600
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000601PyTypeObject PyLongRangeIter_Type = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000602 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000603 "longrange_iterator", /* tp_name */
Guido van Rossum805365e2007-05-07 22:24:25 +0000604 sizeof(longrangeiterobject), /* tp_basicsize */
605 0, /* tp_itemsize */
606 /* methods */
607 (destructor)longrangeiter_dealloc, /* tp_dealloc */
608 0, /* tp_print */
609 0, /* tp_getattr */
610 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +0000611 0, /* tp_reserved */
Guido van Rossum805365e2007-05-07 22:24:25 +0000612 0, /* tp_repr */
613 0, /* tp_as_number */
614 0, /* tp_as_sequence */
615 0, /* tp_as_mapping */
616 0, /* tp_hash */
617 0, /* tp_call */
618 0, /* tp_str */
619 PyObject_GenericGetAttr, /* tp_getattro */
620 0, /* tp_setattro */
621 0, /* tp_as_buffer */
622 Py_TPFLAGS_DEFAULT, /* tp_flags */
623 0, /* tp_doc */
624 0, /* tp_traverse */
625 0, /* tp_clear */
626 0, /* tp_richcompare */
627 0, /* tp_weaklistoffset */
628 PyObject_SelfIter, /* tp_iter */
629 (iternextfunc)longrangeiter_next, /* tp_iternext */
630 longrangeiter_methods, /* tp_methods */
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000631 0,
Raymond Hettinger48165d42002-06-05 20:08:48 +0000632};
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000633
634static PyObject *
635range_iter(PyObject *seq)
636{
Guido van Rossum805365e2007-05-07 22:24:25 +0000637 rangeobject *r = (rangeobject *)seq;
638 longrangeiterobject *it;
Martin v. Löwis84451042007-12-20 22:57:23 +0000639 long lstart, lstop, lstep;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000640
Guido van Rossum805365e2007-05-07 22:24:25 +0000641 assert(PyRange_Check(seq));
Martin v. Löwis84451042007-12-20 22:57:23 +0000642
643 /* If all three fields convert to long, use the int version */
644 lstart = PyLong_AsLong(r->start);
645 if (lstart != -1 || !PyErr_Occurred()) {
646 lstop = PyLong_AsLong(r->stop);
647 if (lstop != -1 || !PyErr_Occurred()) {
648 lstep = PyLong_AsLong(r->step);
649 if (lstep != -1 || !PyErr_Occurred())
650 return int_range_iter(lstart, lstop, lstep);
651 }
652 }
653 /* Some conversion failed, so there is an error set. Clear it,
654 and try again with a long range. */
655 PyErr_Clear();
Guido van Rossum805365e2007-05-07 22:24:25 +0000656
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000657 it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
Guido van Rossum805365e2007-05-07 22:24:25 +0000658 if (it == NULL)
659 return NULL;
Guido van Rossum317e7742007-05-08 15:18:31 +0000660
661 /* Do all initialization here, so we can DECREF on failure. */
Guido van Rossum805365e2007-05-07 22:24:25 +0000662 it->start = r->start;
Guido van Rossum317e7742007-05-08 15:18:31 +0000663 it->step = r->step;
664 Py_INCREF(it->start);
665 Py_INCREF(it->step);
666
667 it->len = it->index = NULL;
668
Mark Dickinsoneb36d312009-06-24 18:36:46 +0000669 it->len = range_length_obj(r);
670 if (!it->len)
Guido van Rossum805365e2007-05-07 22:24:25 +0000671 goto create_failure;
Guido van Rossum805365e2007-05-07 22:24:25 +0000672 it->index = PyLong_FromLong(0);
673 if (!it->index)
674 goto create_failure;
675
Guido van Rossum805365e2007-05-07 22:24:25 +0000676 return (PyObject *)it;
677
678create_failure:
Guido van Rossum317e7742007-05-08 15:18:31 +0000679 Py_DECREF(it);
Guido van Rossum805365e2007-05-07 22:24:25 +0000680 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000681}
682
683static PyObject *
684range_reverse(PyObject *seq)
685{
Guido van Rossum805365e2007-05-07 22:24:25 +0000686 rangeobject *range = (rangeobject*) seq;
687 longrangeiterobject *it;
688 PyObject *one, *sum, *diff, *len = NULL, *product;
Martin v. Löwis84451042007-12-20 22:57:23 +0000689 long lstart, lstop, lstep;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000690
Guido van Rossum805365e2007-05-07 22:24:25 +0000691 /* XXX(nnorwitz): do the calc for the new start/stop first,
692 then if they fit, call the proper iter()?
693 */
694 assert(PyRange_Check(seq));
Martin v. Löwis84451042007-12-20 22:57:23 +0000695
696 /* If all three fields convert to long, use the int version */
697 lstart = PyLong_AsLong(range->start);
698 if (lstart != -1 || !PyErr_Occurred()) {
699 lstop = PyLong_AsLong(range->stop);
700 if (lstop != -1 || !PyErr_Occurred()) {
701 lstep = PyLong_AsLong(range->step);
702 if (lstep != -1 || !PyErr_Occurred()) {
703 /* XXX(nnorwitz): need to check for overflow and simplify. */
704 long len = get_len_of_range(lstart, lstop, lstep);
705 long new_start = lstart + (len - 1) * lstep;
706 long new_stop = lstart;
707 if (lstep > 0)
708 new_stop -= 1;
709 else
710 new_stop += 1;
711 return int_range_iter(new_start, new_stop, -lstep);
712 }
713 }
Guido van Rossum805365e2007-05-07 22:24:25 +0000714 }
Martin v. Löwis84451042007-12-20 22:57:23 +0000715 PyErr_Clear();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000716
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000717 it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
Guido van Rossum805365e2007-05-07 22:24:25 +0000718 if (it == NULL)
719 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000720
Guido van Rossum805365e2007-05-07 22:24:25 +0000721 /* start + (len - 1) * step */
722 len = range_length_obj(range);
723 if (!len)
724 goto create_failure;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000725
Guido van Rossum805365e2007-05-07 22:24:25 +0000726 one = PyLong_FromLong(1);
727 if (!one)
728 goto create_failure;
729
730 diff = PyNumber_Subtract(len, one);
731 Py_DECREF(one);
732 if (!diff)
733 goto create_failure;
734
735 product = PyNumber_Multiply(len, range->step);
736 if (!product)
737 goto create_failure;
738
739 sum = PyNumber_Add(range->start, product);
740 Py_DECREF(product);
741 it->start = sum;
742 if (!it->start)
743 goto create_failure;
744 it->step = PyNumber_Negative(range->step);
745 if (!it->step) {
746 Py_DECREF(it->start);
747 PyObject_Del(it);
748 return NULL;
749 }
750
751 /* Steal reference to len. */
752 it->len = len;
753
754 it->index = PyLong_FromLong(0);
755 if (!it->index) {
756 Py_DECREF(it);
757 return NULL;
758 }
759
760 return (PyObject *)it;
761
762create_failure:
763 Py_XDECREF(len);
764 PyObject_Del(it);
765 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000766}