remove old metaclass demos
[python/dscho.git] / Objects / rangeobject.c
blob01114bb6adb37fc765105ffc81663a95eab2924d
1 /* Range object implementation */
3 #include "Python.h"
5 /* Support objects whose length is > PY_SSIZE_T_MAX.
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.
12 typedef struct {
13 PyObject_HEAD
14 PyObject *start;
15 PyObject *stop;
16 PyObject *step;
17 } rangeobject;
19 /* Helper function for validating step. Always returns a new reference or
20 NULL on error.
22 static PyObject *
23 validate_step(PyObject *step)
25 /* No step specified, use a step of 1. */
26 if (!step)
27 return PyLong_FromLong(1);
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();
36 else if (istep == 0) {
37 PyErr_SetString(PyExc_ValueError,
38 "range() arg 3 must not be zero");
39 Py_CLEAR(step);
43 return step;
46 /* 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)
51 static PyObject *
52 range_new(PyTypeObject *type, PyObject *args, PyObject *kw)
54 rangeobject *obj = NULL;
55 PyObject *start = NULL, *stop = NULL, *step = NULL;
57 if (!_PyArg_NoKeywords("range()", kw))
58 return NULL;
60 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 = PyLong_FromLong(0);
67 step = PyLong_FromLong(1);
68 if (!start || !step)
69 goto Fail;
71 else {
72 if (!PyArg_UnpackTuple(args, "range", 2, 3,
73 &start, &stop, &step))
74 goto Fail;
76 /* 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;
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;
92 Fail:
93 Py_XDECREF(start);
94 Py_XDECREF(stop);
95 Py_XDECREF(step);
96 return NULL;
99 PyDoc_STRVAR(range_doc,
100 "range([start,] stop[, step]) -> range object\n\
102 Returns an iterator that generates the numbers in the range on demand.");
104 static void
105 range_dealloc(rangeobject *r)
107 Py_DECREF(r->start);
108 Py_DECREF(r->stop);
109 Py_DECREF(r->step);
110 PyObject_Del(r);
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.
116 * Arguments MUST return 1 with either PyLong_Check() or
117 * PyLong_Check(). Return -1 when there is an error.
119 static PyObject*
120 range_length_obj(rangeobject *r)
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;
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 */
134 PyObject *zero = PyLong_FromLong(0);
135 if (zero == NULL)
136 return NULL;
137 cmp_result = PyObject_RichCompareBool(r->step, zero, Py_GT);
138 Py_DECREF(zero);
139 if (cmp_result == -1)
140 return NULL;
142 if (cmp_result == 1) {
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;
155 /* if (lo >= hi), return length of 0. */
156 if (PyObject_RichCompareBool(lo, hi, Py_GE) == 1) {
157 Py_XDECREF(step);
158 return PyLong_FromLong(0);
161 if ((one = PyLong_FromLong(1L)) == NULL)
162 goto Fail;
164 if ((tmp1 = PyNumber_Subtract(hi, lo)) == NULL)
165 goto Fail;
167 if ((diff = PyNumber_Subtract(tmp1, one)) == NULL)
168 goto Fail;
170 if ((tmp2 = PyNumber_FloorDivide(diff, step)) == NULL)
171 goto Fail;
173 if ((result = PyNumber_Add(tmp2, one)) == NULL)
174 goto Fail;
176 Py_DECREF(tmp2);
177 Py_DECREF(diff);
178 Py_DECREF(step);
179 Py_DECREF(tmp1);
180 Py_DECREF(one);
181 return result;
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;
192 static Py_ssize_t
193 range_length(rangeobject *r)
195 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);
201 return result;
204 /* range(...)[x] is necessary for: seq[:] = range(...) */
206 static PyObject *
207 range_item(rangeobject *r, Py_ssize_t i)
209 Py_ssize_t len = range_length(r);
210 PyObject *rem, *incr, *result;
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 "range object index out of range");
218 return NULL;
221 /* XXX(nnorwitz): optimize for short ints. */
222 rem = PyLong_FromSsize_t(i);
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;
234 static PyObject *
235 range_repr(rangeobject *r)
237 Py_ssize_t istep;
239 /* Check for special case values for printing. We don't always
240 need the step value. We don't care about errors
241 (it means overflow), so clear the errors. */
242 istep = PyNumber_AsSsize_t(r->step, NULL);
243 if (istep != 1 || (istep == -1 && PyErr_Occurred())) {
244 PyErr_Clear();
247 if (istep == 1)
248 return PyUnicode_FromFormat("range(%R, %R)", r->start, r->stop);
249 else
250 return PyUnicode_FromFormat("range(%R, %R, %R)",
251 r->start, r->stop, r->step);
254 /* Pickling support */
255 static PyObject *
256 range_reduce(rangeobject *r, PyObject *args)
258 return Py_BuildValue("(O(OOO))", Py_TYPE(r),
259 r->start, r->stop, r->step);
262 static PySequenceMethods range_as_sequence = {
263 (lenfunc)range_length, /* sq_length */
264 0, /* sq_concat */
265 0, /* sq_repeat */
266 (ssizeargfunc)range_item, /* sq_item */
267 0, /* sq_slice */
270 static PyObject * range_iter(PyObject *seq);
271 static PyObject * range_reverse(PyObject *seq);
273 PyDoc_STRVAR(reverse_doc,
274 "Returns a reverse iterator.");
276 static PyMethodDef range_methods[] = {
277 {"__reversed__", (PyCFunction)range_reverse, METH_NOARGS,
278 reverse_doc},
279 {"__reduce__", (PyCFunction)range_reduce, METH_VARARGS},
280 {NULL, NULL} /* sentinel */
283 PyTypeObject PyRange_Type = {
284 PyVarObject_HEAD_INIT(&PyType_Type, 0)
285 "range", /* Name of this type */
286 sizeof(rangeobject), /* Basic object size */
287 0, /* Item size for varobject */
288 (destructor)range_dealloc, /* tp_dealloc */
289 0, /* tp_print */
290 0, /* tp_getattr */
291 0, /* tp_setattr */
292 0, /* tp_reserved */
293 (reprfunc)range_repr, /* tp_repr */
294 0, /* tp_as_number */
295 &range_as_sequence, /* tp_as_sequence */
296 0, /* tp_as_mapping */
297 0, /* tp_hash */
298 0, /* tp_call */
299 0, /* tp_str */
300 PyObject_GenericGetAttr, /* tp_getattro */
301 0, /* tp_setattro */
302 0, /* tp_as_buffer */
303 Py_TPFLAGS_DEFAULT, /* tp_flags */
304 range_doc, /* tp_doc */
305 0, /* tp_traverse */
306 0, /* tp_clear */
307 0, /* tp_richcompare */
308 0, /* tp_weaklistoffset */
309 range_iter, /* tp_iter */
310 0, /* tp_iternext */
311 range_methods, /* tp_methods */
312 0, /* tp_members */
313 0, /* tp_getset */
314 0, /* tp_base */
315 0, /* tp_dict */
316 0, /* tp_descr_get */
317 0, /* tp_descr_set */
318 0, /* tp_dictoffset */
319 0, /* tp_init */
320 0, /* tp_alloc */
321 range_new, /* tp_new */
324 /*********************** range Iterator **************************/
326 /* There are 2 types of iterators, one for C longs, the other for
327 Python longs (ie, PyObjects). This should make iteration fast
328 in the normal case, but possible for any numeric value.
331 typedef struct {
332 PyObject_HEAD
333 long index;
334 long start;
335 long step;
336 long len;
337 } rangeiterobject;
339 static PyObject *
340 rangeiter_next(rangeiterobject *r)
342 if (r->index < r->len)
343 return PyLong_FromLong(r->start + (r->index++) * r->step);
344 return NULL;
347 static PyObject *
348 rangeiter_len(rangeiterobject *r)
350 return PyLong_FromLong(r->len - r->index);
353 typedef struct {
354 PyObject_HEAD
355 PyObject *index;
356 PyObject *start;
357 PyObject *step;
358 PyObject *len;
359 } longrangeiterobject;
361 static PyObject *
362 longrangeiter_len(longrangeiterobject *r, PyObject *no_args)
364 return PyNumber_Subtract(r->len, r->index);
367 static PyObject *rangeiter_new(PyTypeObject *, PyObject *args, PyObject *kw);
369 PyDoc_STRVAR(length_hint_doc,
370 "Private method returning an estimate of len(list(it)).");
372 static PyMethodDef rangeiter_methods[] = {
373 {"__length_hint__", (PyCFunction)rangeiter_len, METH_NOARGS,
374 length_hint_doc},
375 {NULL, NULL} /* sentinel */
378 PyTypeObject PyRangeIter_Type = {
379 PyVarObject_HEAD_INIT(&PyType_Type, 0)
380 "range_iterator", /* tp_name */
381 sizeof(rangeiterobject), /* tp_basicsize */
382 0, /* tp_itemsize */
383 /* methods */
384 (destructor)PyObject_Del, /* tp_dealloc */
385 0, /* tp_print */
386 0, /* tp_getattr */
387 0, /* tp_setattr */
388 0, /* tp_reserved */
389 0, /* tp_repr */
390 0, /* tp_as_number */
391 0, /* tp_as_sequence */
392 0, /* tp_as_mapping */
393 0, /* tp_hash */
394 0, /* tp_call */
395 0, /* tp_str */
396 PyObject_GenericGetAttr, /* tp_getattro */
397 0, /* tp_setattro */
398 0, /* tp_as_buffer */
399 Py_TPFLAGS_DEFAULT, /* tp_flags */
400 0, /* tp_doc */
401 0, /* tp_traverse */
402 0, /* tp_clear */
403 0, /* tp_richcompare */
404 0, /* tp_weaklistoffset */
405 PyObject_SelfIter, /* tp_iter */
406 (iternextfunc)rangeiter_next, /* tp_iternext */
407 rangeiter_methods, /* tp_methods */
408 0, /* tp_members */
409 0, /* tp_getset */
410 0, /* tp_base */
411 0, /* tp_dict */
412 0, /* tp_descr_get */
413 0, /* tp_descr_set */
414 0, /* tp_dictoffset */
415 0, /* tp_init */
416 0, /* tp_alloc */
417 rangeiter_new, /* tp_new */
420 /* Return number of items in range/xrange (lo, hi, step). step > 0
421 * required. Return a value < 0 if & only if the true value is too
422 * large to fit in a signed long.
424 static long
425 get_len_of_range(long lo, long hi, long step)
427 /* -------------------------------------------------------------
428 If lo >= hi, the range is empty.
429 Else if n values are in the range, the last one is
430 lo + (n-1)*step, which must be <= hi-1. Rearranging,
431 n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives
432 the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so
433 the RHS is non-negative and so truncation is the same as the
434 floor. Letting M be the largest positive long, the worst case
435 for the RHS numerator is hi=M, lo=-M-1, and then
436 hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough
437 precision to compute the RHS exactly.
438 ---------------------------------------------------------------*/
439 long n = 0;
440 if (lo < hi) {
441 unsigned long uhi = (unsigned long)hi;
442 unsigned long ulo = (unsigned long)lo;
443 unsigned long diff = uhi - ulo - 1;
444 n = (long)(diff / (unsigned long)step + 1);
446 return n;
449 static PyObject *
450 int_range_iter(long start, long stop, long step)
452 rangeiterobject *it = PyObject_New(rangeiterobject, &PyRangeIter_Type);
453 if (it == NULL)
454 return NULL;
455 it->start = start;
456 it->step = step;
457 if (step > 0)
458 it->len = get_len_of_range(start, stop, step);
459 else
460 it->len = get_len_of_range(stop, start, -step);
461 it->index = 0;
462 return (PyObject *)it;
465 static PyObject *
466 rangeiter_new(PyTypeObject *type, PyObject *args, PyObject *kw)
468 long start, stop, step;
470 if (!_PyArg_NoKeywords("rangeiter()", kw))
471 return NULL;
473 if (!PyArg_ParseTuple(args, "lll;rangeiter() requires 3 int arguments",
474 &start, &stop, &step))
475 return NULL;
477 return int_range_iter(start, stop, step);
480 static PyMethodDef longrangeiter_methods[] = {
481 {"__length_hint__", (PyCFunction)longrangeiter_len, METH_NOARGS,
482 length_hint_doc},
483 {NULL, NULL} /* sentinel */
486 static void
487 longrangeiter_dealloc(longrangeiterobject *r)
489 Py_XDECREF(r->index);
490 Py_XDECREF(r->start);
491 Py_XDECREF(r->step);
492 Py_XDECREF(r->len);
493 PyObject_Del(r);
496 static PyObject *
497 longrangeiter_next(longrangeiterobject *r)
499 PyObject *one, *product, *new_index, *result;
500 if (PyObject_RichCompareBool(r->index, r->len, Py_LT) != 1)
501 return NULL;
503 one = PyLong_FromLong(1);
504 if (!one)
505 return NULL;
507 product = PyNumber_Multiply(r->index, r->step);
508 if (!product) {
509 Py_DECREF(one);
510 return NULL;
513 new_index = PyNumber_Add(r->index, one);
514 Py_DECREF(one);
515 if (!new_index) {
516 Py_DECREF(product);
517 return NULL;
520 result = PyNumber_Add(r->start, product);
521 Py_DECREF(product);
522 if (result) {
523 Py_DECREF(r->index);
524 r->index = new_index;
527 return result;
530 PyTypeObject PyLongRangeIter_Type = {
531 PyVarObject_HEAD_INIT(&PyType_Type, 0)
532 "longrange_iterator", /* tp_name */
533 sizeof(longrangeiterobject), /* tp_basicsize */
534 0, /* tp_itemsize */
535 /* methods */
536 (destructor)longrangeiter_dealloc, /* tp_dealloc */
537 0, /* tp_print */
538 0, /* tp_getattr */
539 0, /* tp_setattr */
540 0, /* tp_reserved */
541 0, /* tp_repr */
542 0, /* tp_as_number */
543 0, /* tp_as_sequence */
544 0, /* tp_as_mapping */
545 0, /* tp_hash */
546 0, /* tp_call */
547 0, /* tp_str */
548 PyObject_GenericGetAttr, /* tp_getattro */
549 0, /* tp_setattro */
550 0, /* tp_as_buffer */
551 Py_TPFLAGS_DEFAULT, /* tp_flags */
552 0, /* tp_doc */
553 0, /* tp_traverse */
554 0, /* tp_clear */
555 0, /* tp_richcompare */
556 0, /* tp_weaklistoffset */
557 PyObject_SelfIter, /* tp_iter */
558 (iternextfunc)longrangeiter_next, /* tp_iternext */
559 longrangeiter_methods, /* tp_methods */
563 static PyObject *
564 range_iter(PyObject *seq)
566 rangeobject *r = (rangeobject *)seq;
567 longrangeiterobject *it;
568 PyObject *tmp, *len;
569 long lstart, lstop, lstep;
571 assert(PyRange_Check(seq));
573 /* If all three fields convert to long, use the int version */
574 lstart = PyLong_AsLong(r->start);
575 if (lstart != -1 || !PyErr_Occurred()) {
576 lstop = PyLong_AsLong(r->stop);
577 if (lstop != -1 || !PyErr_Occurred()) {
578 lstep = PyLong_AsLong(r->step);
579 if (lstep != -1 || !PyErr_Occurred())
580 return int_range_iter(lstart, lstop, lstep);
583 /* Some conversion failed, so there is an error set. Clear it,
584 and try again with a long range. */
585 PyErr_Clear();
587 it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
588 if (it == NULL)
589 return NULL;
591 /* Do all initialization here, so we can DECREF on failure. */
592 it->start = r->start;
593 it->step = r->step;
594 Py_INCREF(it->start);
595 Py_INCREF(it->step);
597 it->len = it->index = NULL;
599 /* Calculate length: (r->stop - r->start) / r->step */
600 tmp = PyNumber_Subtract(r->stop, r->start);
601 if (!tmp)
602 goto create_failure;
603 len = PyNumber_FloorDivide(tmp, r->step);
604 Py_DECREF(tmp);
605 if (!len)
606 goto create_failure;
607 it->len = len;
608 it->index = PyLong_FromLong(0);
609 if (!it->index)
610 goto create_failure;
612 return (PyObject *)it;
614 create_failure:
615 Py_DECREF(it);
616 return NULL;
619 static PyObject *
620 range_reverse(PyObject *seq)
622 rangeobject *range = (rangeobject*) seq;
623 longrangeiterobject *it;
624 PyObject *one, *sum, *diff, *len = NULL, *product;
625 long lstart, lstop, lstep;
627 /* XXX(nnorwitz): do the calc for the new start/stop first,
628 then if they fit, call the proper iter()?
630 assert(PyRange_Check(seq));
632 /* If all three fields convert to long, use the int version */
633 lstart = PyLong_AsLong(range->start);
634 if (lstart != -1 || !PyErr_Occurred()) {
635 lstop = PyLong_AsLong(range->stop);
636 if (lstop != -1 || !PyErr_Occurred()) {
637 lstep = PyLong_AsLong(range->step);
638 if (lstep != -1 || !PyErr_Occurred()) {
639 /* XXX(nnorwitz): need to check for overflow and simplify. */
640 long len = get_len_of_range(lstart, lstop, lstep);
641 long new_start = lstart + (len - 1) * lstep;
642 long new_stop = lstart;
643 if (lstep > 0)
644 new_stop -= 1;
645 else
646 new_stop += 1;
647 return int_range_iter(new_start, new_stop, -lstep);
651 PyErr_Clear();
653 it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
654 if (it == NULL)
655 return NULL;
657 /* start + (len - 1) * step */
658 len = range_length_obj(range);
659 if (!len)
660 goto create_failure;
662 one = PyLong_FromLong(1);
663 if (!one)
664 goto create_failure;
666 diff = PyNumber_Subtract(len, one);
667 Py_DECREF(one);
668 if (!diff)
669 goto create_failure;
671 product = PyNumber_Multiply(len, range->step);
672 if (!product)
673 goto create_failure;
675 sum = PyNumber_Add(range->start, product);
676 Py_DECREF(product);
677 it->start = sum;
678 if (!it->start)
679 goto create_failure;
680 it->step = PyNumber_Negative(range->step);
681 if (!it->step) {
682 Py_DECREF(it->start);
683 PyObject_Del(it);
684 return NULL;
687 /* Steal reference to len. */
688 it->len = len;
690 it->index = PyLong_FromLong(0);
691 if (!it->index) {
692 Py_DECREF(it);
693 return NULL;
696 return (PyObject *)it;
698 create_failure:
699 Py_XDECREF(len);
700 PyObject_Del(it);
701 return NULL;