blob: 0b0966f622632ec4cc9e9ff1b8b7b28cca2471a1 [file] [log] [blame]
Guido van Rossum12d12c51993-10-26 17:58:25 +00001
2/* Range object implementation */
3
Guido van Rossumc0b618a1997-05-02 03:12:38 +00004#include "Python.h"
Fred Drake0b796fa2000-11-08 19:42:43 +00005#include "structmember.h"
6#include <string.h>
Guido van Rossum12d12c51993-10-26 17:58:25 +00007
8typedef struct {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00009 PyObject_HEAD
Guido van Rossum12d12c51993-10-26 17:58:25 +000010 long start;
11 long step;
12 long len;
Guido van Rossum12d12c51993-10-26 17:58:25 +000013} rangeobject;
14
Guido van Rossumc0b618a1997-05-02 03:12:38 +000015PyObject *
Guido van Rossum3f561662001-07-05 13:27:48 +000016PyRange_New(long start, long len, long step)
Guido van Rossum12d12c51993-10-26 17:58:25 +000017{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000018 rangeobject *obj = PyObject_NEW(rangeobject, &PyRange_Type);
Guido van Rossum12d12c51993-10-26 17:58:25 +000019
Guido van Rossum9e8f4ea2000-12-14 14:59:53 +000020 if (obj == NULL)
21 return NULL;
22
Guido van Rossum3f561662001-07-05 13:27:48 +000023 if (len == 0) {
Guido van Rossum65e0b992001-01-15 18:58:56 +000024 start = 0;
25 len = 0;
26 step = 1;
Guido van Rossum65e0b992001-01-15 18:58:56 +000027 }
28 else {
29 long last = start + (len - 1) * step;
30 if ((step > 0) ?
31 (last > (PyInt_GetMax() - step))
32 :(last < (-1 - PyInt_GetMax() - step))) {
33 PyErr_SetString(PyExc_OverflowError,
34 "integer addition");
35 return NULL;
Guido van Rossum65e0b992001-01-15 18:58:56 +000036 }
37 }
38
Guido van Rossum12d12c51993-10-26 17:58:25 +000039 obj->start = start;
40 obj->len = len;
41 obj->step = step;
Guido van Rossum12d12c51993-10-26 17:58:25 +000042
Guido van Rossumc0b618a1997-05-02 03:12:38 +000043 return (PyObject *) obj;
Guido van Rossum12d12c51993-10-26 17:58:25 +000044}
45
46static void
Fred Drake45cfbcc2000-07-09 06:21:27 +000047range_dealloc(rangeobject *r)
Guido van Rossum12d12c51993-10-26 17:58:25 +000048{
Guido van Rossumb18618d2000-05-03 23:44:39 +000049 PyObject_DEL(r);
Guido van Rossum12d12c51993-10-26 17:58:25 +000050}
51
Guido van Rossumc0b618a1997-05-02 03:12:38 +000052static PyObject *
Fred Drake45cfbcc2000-07-09 06:21:27 +000053range_item(rangeobject *r, int i)
Guido van Rossum12d12c51993-10-26 17:58:25 +000054{
Guido van Rossum3f561662001-07-05 13:27:48 +000055 if (i < 0 || i >= r->len) {
56 PyErr_SetString(PyExc_IndexError,
Guido van Rossum5dadf7e1999-01-09 21:40:35 +000057 "xrange object index out of range");
Guido van Rossum3f561662001-07-05 13:27:48 +000058 return NULL;
59 }
Guido van Rossum12d12c51993-10-26 17:58:25 +000060
Guido van Rossumc0b618a1997-05-02 03:12:38 +000061 return PyInt_FromLong(r->start + (i % r->len) * r->step);
Guido van Rossum12d12c51993-10-26 17:58:25 +000062}
63
64static int
Fred Drake45cfbcc2000-07-09 06:21:27 +000065range_length(rangeobject *r)
Guido van Rossum12d12c51993-10-26 17:58:25 +000066{
Guido van Rossum3f561662001-07-05 13:27:48 +000067 return r->len;
Guido van Rossum7d6aa511993-12-21 22:50:31 +000068}
69
Guido van Rossumc0b618a1997-05-02 03:12:38 +000070static PyObject *
Fred Drake45cfbcc2000-07-09 06:21:27 +000071range_repr(rangeobject *r)
Guido van Rossum12d12c51993-10-26 17:58:25 +000072{
Tim Peters72d421b2000-08-04 03:05:40 +000073 /* buffers must be big enough to hold 3 longs + an int +
74 * a bit of "(xrange(...) * ...)" text.
75 */
76 char buf1[250];
Fred Drake2b83b462000-08-03 17:43:02 +000077
Tim Peters72d421b2000-08-04 03:05:40 +000078 if (r->start == 0 && r->step == 1)
Fred Drakec76e0e52000-08-04 02:34:41 +000079 sprintf(buf1, "xrange(%ld)", r->start + r->len * r->step);
Tim Peters72d421b2000-08-04 03:05:40 +000080
81 else if (r->step == 1)
82 sprintf(buf1, "xrange(%ld, %ld)",
83 r->start,
84 r->start + r->len * r->step);
85
86 else
87 sprintf(buf1, "xrange(%ld, %ld, %ld)",
Fred Drakec76e0e52000-08-04 02:34:41 +000088 r->start,
89 r->start + r->len * r->step,
90 r->step);
Tim Peters72d421b2000-08-04 03:05:40 +000091
Guido van Rossum3f561662001-07-05 13:27:48 +000092 return PyString_FromString(buf1);
Fred Drake56780252000-06-15 14:50:20 +000093}
94
Guido van Rossumc0b618a1997-05-02 03:12:38 +000095static PySequenceMethods range_as_sequence = {
Fred Drake0b796fa2000-11-08 19:42:43 +000096 (inquiry)range_length, /*sq_length*/
Guido van Rossum3f561662001-07-05 13:27:48 +000097 0, /*sq_concat*/
98 0, /*sq_repeat*/
99 (intargfunc)range_item, /*sq_item*/
100 0, /*sq_slice*/
Fred Drake0b796fa2000-11-08 19:42:43 +0000101 0, /*sq_ass_item*/
102 0, /*sq_ass_slice*/
Guido van Rossum3f561662001-07-05 13:27:48 +0000103 0, /*sq_contains*/
Guido van Rossum12d12c51993-10-26 17:58:25 +0000104};
105
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000106PyTypeObject PyRange_Type = {
107 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum12d12c51993-10-26 17:58:25 +0000108 0, /* Number of items for varobject */
Guido van Rossum2586bf01993-11-01 16:21:44 +0000109 "xrange", /* Name of this type */
Guido van Rossum12d12c51993-10-26 17:58:25 +0000110 sizeof(rangeobject), /* Basic object size */
111 0, /* Item size for varobject */
Guido van Rossum03093a21994-09-28 15:51:32 +0000112 (destructor)range_dealloc, /*tp_dealloc*/
Fred Drake2b83b462000-08-03 17:43:02 +0000113 0, /*tp_print*/
Guido van Rossum3f561662001-07-05 13:27:48 +0000114 0, /*tp_getattr*/
Guido van Rossum12d12c51993-10-26 17:58:25 +0000115 0, /*tp_setattr*/
Guido van Rossum3f561662001-07-05 13:27:48 +0000116 0, /*tp_compare*/
Fred Drake2b83b462000-08-03 17:43:02 +0000117 (reprfunc)range_repr, /*tp_repr*/
Guido van Rossum12d12c51993-10-26 17:58:25 +0000118 0, /*tp_as_number*/
119 &range_as_sequence, /*tp_as_sequence*/
120 0, /*tp_as_mapping*/
Fred Drake56780252000-06-15 14:50:20 +0000121 0, /*tp_hash*/
122 0, /*tp_call*/
123 0, /*tp_str*/
124 0, /*tp_getattro*/
125 0, /*tp_setattro*/
126 0, /*tp_as_buffer*/
127 Py_TPFLAGS_DEFAULT, /*tp_flags*/
Guido van Rossum12d12c51993-10-26 17:58:25 +0000128};