blob: 8d71a908680ff9ced8652c758ec66506e2165064 [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)
27 return PyInt_FromLong(1);
28
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;
66 start = PyInt_FromLong(0);
67 step = PyInt_FromLong(1);
68 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);
110}
111
112/* Return number of items in range (lo, hi, step), when arguments are
113 * PyInt or PyLong objects. step > 0 required. Return a value < 0 if
114 * & only if the true value is too large to fit in a signed long.
115 * Arguments MUST return 1 with either PyInt_Check() or
116 * PyLong_Check(). Return -1 when there is an error.
117 */
118static PyObject*
119range_length_obj(rangeobject *r)
120{
121 /* -------------------------------------------------------------
122 Algorithm is equal to that of get_len_of_range(), but it operates
123 on PyObjects (which are assumed to be PyLong or PyInt objects).
124 ---------------------------------------------------------------*/
125 int cmp_result, cmp_call;
126 PyObject *lo, *hi;
127 PyObject *step = NULL;
128 PyObject *diff = NULL;
129 PyObject *one = NULL;
130 PyObject *tmp1 = NULL, *tmp2 = NULL, *result;
131 /* holds sub-expression evaluations */
132
133 PyObject *zero = PyLong_FromLong(0);
134 if (zero == NULL)
135 return NULL;
136 cmp_call = PyObject_Cmp(r->step, zero, &cmp_result);
137 Py_DECREF(zero);
138 if (cmp_call == -1)
139 return NULL;
140
141 assert(cmp_result != 0);
142 if (cmp_result > 0) {
143 lo = r->start;
144 hi = r->stop;
145 step = r->step;
146 Py_INCREF(step);
147 } else {
148 lo = r->stop;
149 hi = r->start;
150 step = PyNumber_Negative(r->step);
151 if (!step)
152 return NULL;
153 }
154
155 /* if (lo >= hi), return length of 0. */
156 if (PyObject_Compare(lo, hi) >= 0) {
157 Py_XDECREF(step);
158 return PyLong_FromLong(0);
159 }
160
161 if ((one = PyLong_FromLong(1L)) == NULL)
162 goto Fail;
163
164 if ((tmp1 = PyNumber_Subtract(hi, lo)) == NULL)
165 goto Fail;
166
167 if ((diff = PyNumber_Subtract(tmp1, one)) == NULL)
168 goto Fail;
169
170 if ((tmp2 = PyNumber_FloorDivide(diff, step)) == NULL)
171 goto Fail;
172
173 if ((result = PyNumber_Add(tmp2, one)) == NULL)
174 goto Fail;
175
176 Py_DECREF(tmp2);
177 Py_DECREF(diff);
178 Py_DECREF(step);
179 Py_DECREF(tmp1);
180 Py_DECREF(one);
181 return result;
182
183 Fail:
184 Py_XDECREF(tmp2);
185 Py_XDECREF(diff);
186 Py_XDECREF(step);
187 Py_XDECREF(tmp1);
188 Py_XDECREF(one);
189 return NULL;
Guido van Rossum12d12c51993-10-26 17:58:25 +0000190}
191
Martin v. Löwis18e16552006-02-15 17:27:45 +0000192static Py_ssize_t
Fred Drake45cfbcc2000-07-09 06:21:27 +0000193range_length(rangeobject *r)
Guido van Rossum12d12c51993-10-26 17:58:25 +0000194{
Guido van Rossum805365e2007-05-07 22:24:25 +0000195 PyObject *len = range_length_obj(r);
196 Py_ssize_t result = -1;
197 if (len) {
198 result = PyLong_AsSsize_t(len);
199 Py_DECREF(len);
200 }
201 return result;
202}
203
204/* range(...)[x] is necessary for: seq[:] = range(...) */
205
206static PyObject *
207range_item(rangeobject *r, Py_ssize_t i)
208{
209 Py_ssize_t len = range_length(r);
210 PyObject *rem, *incr, *result;
211
212 /* XXX(nnorwitz): should negative indices be supported? */
213 /* XXX(nnorwitz): should support range[x] where x > PY_SSIZE_T_MAX? */
214 if (i < 0 || i >= len) {
215 if (!PyErr_Occurred())
216 PyErr_SetString(PyExc_IndexError,
217 "xrange object index out of range");
218 return NULL;
219 }
220
221 /* XXX(nnorwitz): optimize for short ints. */
222 rem = PyLong_FromSsize_t(i % len);
223 if (!rem)
224 return NULL;
225 incr = PyNumber_Multiply(rem, r->step);
226 Py_DECREF(rem);
227 if (!incr)
228 return NULL;
229 result = PyNumber_Add(r->start, incr);
230 Py_DECREF(incr);
231 return result;
Guido van Rossum7d6aa511993-12-21 22:50:31 +0000232}
233
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000234static PyObject *
Fred Drake45cfbcc2000-07-09 06:21:27 +0000235range_repr(rangeobject *r)
Guido van Rossum12d12c51993-10-26 17:58:25 +0000236{
Guido van Rossum805365e2007-05-07 22:24:25 +0000237 PyObject *start_str = NULL, *stop_str = NULL, *step_str = NULL;
238 PyObject *result = NULL;
239 Py_ssize_t istart, istep;
Tim Petersd976ab72004-08-08 06:29:10 +0000240
Guido van Rossum805365e2007-05-07 22:24:25 +0000241 /* We always need the stop value. */
242 stop_str = PyObject_Str(r->stop);
243 if (!stop_str)
244 return NULL;
Tim Peters72d421b2000-08-04 03:05:40 +0000245
Guido van Rossum805365e2007-05-07 22:24:25 +0000246 /* XXX(nnorwitz): should we use PyObject_Repr instead of str? */
Tim Peters72d421b2000-08-04 03:05:40 +0000247
Guido van Rossum805365e2007-05-07 22:24:25 +0000248 /* Check for special case values for printing. We don't always
249 need the start or step values. We don't care about errors
250 (it means overflow), so clear the errors. */
251 istart = PyNumber_AsSsize_t(r->start, NULL);
252 if (istart != 0 || (istart == -1 && PyErr_Occurred())) {
253 PyErr_Clear();
254 start_str = PyObject_Str(r->start);
255 }
256
257 istep = PyNumber_AsSsize_t(r->step, NULL);
258 if (istep != 1 || (istep == -1 && PyErr_Occurred())) {
259 PyErr_Clear();
260 step_str = PyObject_Str(r->step);
261 }
262
263 if (istart == 0 && istep == 1)
264 result = PyString_FromFormat("range(%s)",
265 PyString_AS_STRING(stop_str));
266 else if (istep == 1) {
267 if (start_str)
268 result = PyString_FromFormat("range(%s, %s)",
269 PyString_AS_STRING(start_str),
270 PyString_AS_STRING(stop_str));
271 }
272 else if (start_str && step_str)
273 result = PyString_FromFormat("range(%s, %s, %s)",
274 PyString_AS_STRING(start_str),
275 PyString_AS_STRING(stop_str),
276 PyString_AS_STRING(step_str));
277 /* else result is NULL and an error should already be set. */
278
279 Py_XDECREF(start_str);
280 Py_XDECREF(stop_str);
281 Py_XDECREF(step_str);
282 return result;
Thomas Woutersefafcea2001-07-09 12:30:54 +0000283}
284
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000285static PySequenceMethods range_as_sequence = {
Guido van Rossum805365e2007-05-07 22:24:25 +0000286 (lenfunc)range_length, /* sq_length */
287 0, /* sq_concat */
288 0, /* sq_repeat */
289 (ssizeargfunc)range_item, /* sq_item */
290 0, /* sq_slice */
Guido van Rossum12d12c51993-10-26 17:58:25 +0000291};
292
Jeremy Hylton938ace62002-07-17 16:30:39 +0000293static PyObject * range_iter(PyObject *seq);
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000294static PyObject * range_reverse(PyObject *seq);
295
296PyDoc_STRVAR(reverse_doc,
297"Returns a reverse iterator.");
298
299static PyMethodDef range_methods[] = {
Guido van Rossum805365e2007-05-07 22:24:25 +0000300 {"__reversed__", (PyCFunction)range_reverse, METH_NOARGS,
301 reverse_doc},
302 {NULL, NULL} /* sentinel */
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000303};
Raymond Hettinger48165d42002-06-05 20:08:48 +0000304
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000305PyTypeObject PyRange_Type = {
306 PyObject_HEAD_INIT(&PyType_Type)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000307 0, /* Number of items for varobject */
Guido van Rossum805365e2007-05-07 22:24:25 +0000308 "range", /* Name of this type */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000309 sizeof(rangeobject), /* Basic object size */
310 0, /* Item size for varobject */
Guido van Rossum805365e2007-05-07 22:24:25 +0000311 (destructor)range_dealloc, /* tp_dealloc */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000312 0, /* tp_print */
313 0, /* tp_getattr */
314 0, /* tp_setattr */
315 0, /* tp_compare */
316 (reprfunc)range_repr, /* tp_repr */
317 0, /* tp_as_number */
318 &range_as_sequence, /* tp_as_sequence */
319 0, /* tp_as_mapping */
320 0, /* tp_hash */
321 0, /* tp_call */
322 0, /* tp_str */
323 PyObject_GenericGetAttr, /* tp_getattro */
324 0, /* tp_setattro */
325 0, /* tp_as_buffer */
326 Py_TPFLAGS_DEFAULT, /* tp_flags */
327 range_doc, /* tp_doc */
328 0, /* tp_traverse */
329 0, /* tp_clear */
330 0, /* tp_richcompare */
331 0, /* tp_weaklistoffset */
332 range_iter, /* tp_iter */
333 0, /* tp_iternext */
334 range_methods, /* tp_methods */
335 0, /* tp_members */
336 0, /* tp_getset */
337 0, /* tp_base */
338 0, /* tp_dict */
339 0, /* tp_descr_get */
340 0, /* tp_descr_set */
341 0, /* tp_dictoffset */
342 0, /* tp_init */
343 0, /* tp_alloc */
344 range_new, /* tp_new */
Guido van Rossum12d12c51993-10-26 17:58:25 +0000345};
Raymond Hettinger48165d42002-06-05 20:08:48 +0000346
347/*********************** Xrange Iterator **************************/
348
Guido van Rossum805365e2007-05-07 22:24:25 +0000349/* There are 2 types of iterators, one for C longs, the other for
350 Python longs (ie, PyObjects). This should make iteration fast
351 in the normal case, but possible for any numeric value.
352*/
353
Raymond Hettinger48165d42002-06-05 20:08:48 +0000354typedef struct {
355 PyObject_HEAD
356 long index;
357 long start;
358 long step;
359 long len;
360} rangeiterobject;
361
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000362static PyObject *
Raymond Hettinger48165d42002-06-05 20:08:48 +0000363rangeiter_next(rangeiterobject *r)
364{
Guido van Rossum805365e2007-05-07 22:24:25 +0000365 if (r->index < r->len)
366 return PyInt_FromLong(r->start + (r->index++) * r->step);
367 return NULL;
Raymond Hettinger48165d42002-06-05 20:08:48 +0000368}
369
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000370static PyObject *
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000371rangeiter_len(rangeiterobject *r)
372{
Guido van Rossum805365e2007-05-07 22:24:25 +0000373 return PyInt_FromLong(r->len - r->index);
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000374}
375
Guido van Rossum805365e2007-05-07 22:24:25 +0000376typedef struct {
377 PyObject_HEAD
378 PyObject *index;
379 PyObject *start;
380 PyObject *step;
381 PyObject *len;
382} longrangeiterobject;
383
384static PyObject *
385longrangeiter_len(longrangeiterobject *r, PyObject *no_args)
386{
387 return PyNumber_Subtract(r->len, r->index);
388}
Guido van Rossum317e7742007-05-08 15:18:31 +0000389
Guido van Rossum805365e2007-05-07 22:24:25 +0000390static PyObject *rangeiter_new(PyTypeObject *, PyObject *args, PyObject *kw);
391
392PyDoc_STRVAR(length_hint_doc,
393 "Private method returning an estimate of len(list(it)).");
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000394
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000395static PyMethodDef rangeiter_methods[] = {
Guido van Rossum805365e2007-05-07 22:24:25 +0000396 {"__length_hint__", (PyCFunction)rangeiter_len, METH_NOARGS,
397 length_hint_doc},
398 {NULL, NULL} /* sentinel */
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000399};
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000400
Guido van Rossum805365e2007-05-07 22:24:25 +0000401PyTypeObject Pyrangeiter_Type = {
Raymond Hettinger48165d42002-06-05 20:08:48 +0000402 PyObject_HEAD_INIT(&PyType_Type)
403 0, /* ob_size */
Neal Norwitz56f46f82002-06-06 14:58:21 +0000404 "rangeiterator", /* tp_name */
405 sizeof(rangeiterobject), /* tp_basicsize */
Raymond Hettinger48165d42002-06-05 20:08:48 +0000406 0, /* tp_itemsize */
407 /* methods */
408 (destructor)PyObject_Del, /* tp_dealloc */
409 0, /* tp_print */
410 0, /* tp_getattr */
411 0, /* tp_setattr */
412 0, /* tp_compare */
413 0, /* tp_repr */
414 0, /* tp_as_number */
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000415 0, /* tp_as_sequence */
Raymond Hettinger48165d42002-06-05 20:08:48 +0000416 0, /* tp_as_mapping */
417 0, /* tp_hash */
418 0, /* tp_call */
419 0, /* tp_str */
420 PyObject_GenericGetAttr, /* tp_getattro */
421 0, /* tp_setattro */
422 0, /* tp_as_buffer */
423 Py_TPFLAGS_DEFAULT, /* tp_flags */
424 0, /* tp_doc */
425 0, /* tp_traverse */
426 0, /* tp_clear */
427 0, /* tp_richcompare */
428 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +0000429 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger48165d42002-06-05 20:08:48 +0000430 (iternextfunc)rangeiter_next, /* tp_iternext */
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000431 rangeiter_methods, /* tp_methods */
Guido van Rossum805365e2007-05-07 22:24:25 +0000432 0, /* tp_members */
433 0, /* tp_getset */
434 0, /* tp_base */
435 0, /* tp_dict */
436 0, /* tp_descr_get */
437 0, /* tp_descr_set */
438 0, /* tp_dictoffset */
439 0, /* tp_init */
440 0, /* tp_alloc */
441 rangeiter_new, /* tp_new */
442};
443
444/* Return number of items in range/xrange (lo, hi, step). step > 0
445 * required. Return a value < 0 if & only if the true value is too
446 * large to fit in a signed long.
447 */
448static long
449get_len_of_range(long lo, long hi, long step)
450{
451 /* -------------------------------------------------------------
452 If lo >= hi, the range is empty.
453 Else if n values are in the range, the last one is
454 lo + (n-1)*step, which must be <= hi-1. Rearranging,
455 n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives
456 the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so
457 the RHS is non-negative and so truncation is the same as the
458 floor. Letting M be the largest positive long, the worst case
459 for the RHS numerator is hi=M, lo=-M-1, and then
460 hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough
461 precision to compute the RHS exactly.
462 ---------------------------------------------------------------*/
463 long n = 0;
464 if (lo < hi) {
465 unsigned long uhi = (unsigned long)hi;
466 unsigned long ulo = (unsigned long)lo;
467 unsigned long diff = uhi - ulo - 1;
468 n = (long)(diff / (unsigned long)step + 1);
469 }
470 return n;
471}
472
473static PyObject *
474int_range_iter(long start, long stop, long step)
475{
476 rangeiterobject *it = PyObject_New(rangeiterobject, &Pyrangeiter_Type);
477 if (it == NULL)
478 return NULL;
479 it->start = start;
480 it->step = step;
481 if (step > 0)
482 it->len = get_len_of_range(start, stop, step);
483 else
484 it->len = get_len_of_range(stop, start, -step);
485 it->index = 0;
486 return (PyObject *)it;
487}
488
489static PyObject *
490rangeiter_new(PyTypeObject *type, PyObject *args, PyObject *kw)
491{
492 long start, stop, step;
493
494 if (!_PyArg_NoKeywords("rangeiter()", kw))
495 return NULL;
496
497 if (!PyArg_ParseTuple(args, "lll;rangeiter() requires 3 int arguments",
498 &start, &stop, &step))
499 return NULL;
500
501 return int_range_iter(start, stop, step);
502}
503
504static PyMethodDef longrangeiter_methods[] = {
505 {"__length_hint__", (PyCFunction)longrangeiter_len, METH_NOARGS,
506 length_hint_doc},
507 {NULL, NULL} /* sentinel */
508};
509
510static void
511longrangeiter_dealloc(longrangeiterobject *r)
512{
513 Py_XDECREF(r->index);
Guido van Rossum317e7742007-05-08 15:18:31 +0000514 Py_XDECREF(r->start);
515 Py_XDECREF(r->step);
516 Py_XDECREF(r->len);
Guido van Rossum805365e2007-05-07 22:24:25 +0000517}
518
519static PyObject *
520longrangeiter_next(longrangeiterobject *r)
521{
522 PyObject *one, *product, *new_index, *result;
523 if (PyObject_RichCompareBool(r->index, r->len, Py_LT) != 1)
524 return NULL;
525
526 one = PyLong_FromLong(1);
527 if (!one)
528 return NULL;
529
530 product = PyNumber_Multiply(r->index, r->step);
531 if (!product) {
532 Py_DECREF(one);
533 return NULL;
534 }
535
536 new_index = PyNumber_Add(r->index, one);
537 Py_DECREF(one);
538 if (!new_index) {
539 Py_DECREF(product);
540 return NULL;
541 }
542
543 result = PyNumber_Add(r->start, product);
544 Py_DECREF(product);
545 if (result) {
546 Py_DECREF(r->index);
547 r->index = new_index;
548 }
549
550 return result;
551}
552
553static PyTypeObject Pylongrangeiter_Type = {
554 PyObject_HEAD_INIT(&PyType_Type)
555 0, /* ob_size */
556 "rangeiterator", /* tp_name */
557 sizeof(longrangeiterobject), /* tp_basicsize */
558 0, /* tp_itemsize */
559 /* methods */
560 (destructor)longrangeiter_dealloc, /* tp_dealloc */
561 0, /* tp_print */
562 0, /* tp_getattr */
563 0, /* tp_setattr */
564 0, /* tp_compare */
565 0, /* tp_repr */
566 0, /* tp_as_number */
567 0, /* tp_as_sequence */
568 0, /* tp_as_mapping */
569 0, /* tp_hash */
570 0, /* tp_call */
571 0, /* tp_str */
572 PyObject_GenericGetAttr, /* tp_getattro */
573 0, /* tp_setattro */
574 0, /* tp_as_buffer */
575 Py_TPFLAGS_DEFAULT, /* tp_flags */
576 0, /* tp_doc */
577 0, /* tp_traverse */
578 0, /* tp_clear */
579 0, /* tp_richcompare */
580 0, /* tp_weaklistoffset */
581 PyObject_SelfIter, /* tp_iter */
582 (iternextfunc)longrangeiter_next, /* tp_iternext */
583 longrangeiter_methods, /* tp_methods */
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000584 0,
Raymond Hettinger48165d42002-06-05 20:08:48 +0000585};
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000586
587static PyObject *
588range_iter(PyObject *seq)
589{
Guido van Rossum805365e2007-05-07 22:24:25 +0000590 rangeobject *r = (rangeobject *)seq;
591 longrangeiterobject *it;
592 PyObject *tmp, *len;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000593
Guido van Rossum805365e2007-05-07 22:24:25 +0000594 assert(PyRange_Check(seq));
595 if (_PyLong_FitsInLong(r->start) &&
596 _PyLong_FitsInLong(r->stop) &&
597 _PyLong_FitsInLong(r->step))
598 return int_range_iter(PyLong_AsLong(r->start),
599 PyLong_AsLong(r->stop),
600 PyLong_AsLong(r->step));
601
602 it = PyObject_New(longrangeiterobject, &Pylongrangeiter_Type);
603 if (it == NULL)
604 return NULL;
Guido van Rossum317e7742007-05-08 15:18:31 +0000605
606 /* Do all initialization here, so we can DECREF on failure. */
Guido van Rossum805365e2007-05-07 22:24:25 +0000607 it->start = r->start;
Guido van Rossum317e7742007-05-08 15:18:31 +0000608 it->step = r->step;
609 Py_INCREF(it->start);
610 Py_INCREF(it->step);
611
612 it->len = it->index = NULL;
613
Guido van Rossum805365e2007-05-07 22:24:25 +0000614 /* Calculate length: (r->stop - r->start) / r->step */
615 tmp = PyNumber_Subtract(r->stop, r->start);
616 if (!tmp)
617 goto create_failure;
618 len = PyNumber_FloorDivide(tmp, r->step);
619 Py_DECREF(tmp);
620 if (!len)
621 goto create_failure;
622 it->len = len;
Guido van Rossum805365e2007-05-07 22:24:25 +0000623 it->index = PyLong_FromLong(0);
624 if (!it->index)
625 goto create_failure;
626
Guido van Rossum805365e2007-05-07 22:24:25 +0000627 return (PyObject *)it;
628
629create_failure:
Guido van Rossum317e7742007-05-08 15:18:31 +0000630 Py_DECREF(it);
Guido van Rossum805365e2007-05-07 22:24:25 +0000631 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000632}
633
634static PyObject *
635range_reverse(PyObject *seq)
636{
Guido van Rossum805365e2007-05-07 22:24:25 +0000637 rangeobject *range = (rangeobject*) seq;
638 longrangeiterobject *it;
639 PyObject *one, *sum, *diff, *len = NULL, *product;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000640
Guido van Rossum805365e2007-05-07 22:24:25 +0000641 /* XXX(nnorwitz): do the calc for the new start/stop first,
642 then if they fit, call the proper iter()?
643 */
644 assert(PyRange_Check(seq));
645 if (_PyLong_FitsInLong(range->start) &&
646 _PyLong_FitsInLong(range->stop) &&
647 _PyLong_FitsInLong(range->step)) {
648 long start = PyLong_AsLong(range->start);
649 long step = PyLong_AsLong(range->step);
650 long stop = PyLong_AsLong(range->stop);
651 /* XXX(nnorwitz): need to check for overflow and simplify. */
652 long len = get_len_of_range(start, stop, step);
653 long new_start = start + (len - 1) * step;
654 long new_stop = start;
655 if (step > 0)
656 new_stop -= 1;
657 else
658 new_stop += 1;
659 return int_range_iter(new_start, new_stop, -step);
660 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000661
Guido van Rossum805365e2007-05-07 22:24:25 +0000662 it = PyObject_New(longrangeiterobject, &Pylongrangeiter_Type);
663 if (it == NULL)
664 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000665
Guido van Rossum805365e2007-05-07 22:24:25 +0000666 /* start + (len - 1) * step */
667 len = range_length_obj(range);
668 if (!len)
669 goto create_failure;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000670
Guido van Rossum805365e2007-05-07 22:24:25 +0000671 one = PyLong_FromLong(1);
672 if (!one)
673 goto create_failure;
674
675 diff = PyNumber_Subtract(len, one);
676 Py_DECREF(one);
677 if (!diff)
678 goto create_failure;
679
680 product = PyNumber_Multiply(len, range->step);
681 if (!product)
682 goto create_failure;
683
684 sum = PyNumber_Add(range->start, product);
685 Py_DECREF(product);
686 it->start = sum;
687 if (!it->start)
688 goto create_failure;
689 it->step = PyNumber_Negative(range->step);
690 if (!it->step) {
691 Py_DECREF(it->start);
692 PyObject_Del(it);
693 return NULL;
694 }
695
696 /* Steal reference to len. */
697 it->len = len;
698
699 it->index = PyLong_FromLong(0);
700 if (!it->index) {
701 Py_DECREF(it);
702 return NULL;
703 }
704
705 return (PyObject *)it;
706
707create_failure:
708 Py_XDECREF(len);
709 PyObject_Del(it);
710 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000711}