blob: d28fb3a401b6f0e43433811a9bf4af002b5c0538 [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"
Thomas Woutersefafcea2001-07-09 12:30:54 +00005
Guido van Rossum12d12c51993-10-26 17:58:25 +00006typedef struct {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00007 PyObject_HEAD
Guido van Rossum12d12c51993-10-26 17:58:25 +00008 long start;
9 long step;
10 long len;
Guido van Rossum12d12c51993-10-26 17:58:25 +000011} rangeobject;
12
Thomas Woutersefafcea2001-07-09 12:30:54 +000013PyObject *
14PyRange_New(long start, long len, long step, int reps)
15{
Fred Draked9018322002-05-02 19:56:55 +000016 rangeobject *obj;
Guido van Rossum12d12c51993-10-26 17:58:25 +000017
Fred Draked9018322002-05-02 19:56:55 +000018 if (reps != 1) {
19 PyErr_SetString(PyExc_ValueError,
20 "PyRange_New's 'repetitions' argument must be 1");
21 return NULL;
22 }
23
24 obj = PyObject_New(rangeobject, &PyRange_Type);
Guido van Rossum9e8f4ea2000-12-14 14:59:53 +000025 if (obj == NULL)
26 return NULL;
27
Fred Draked9018322002-05-02 19:56:55 +000028 if (len == 0) {
Guido van Rossum65e0b992001-01-15 18:58:56 +000029 start = 0;
30 len = 0;
31 step = 1;
Guido van Rossum65e0b992001-01-15 18:58:56 +000032 }
33 else {
34 long last = start + (len - 1) * step;
35 if ((step > 0) ?
Thomas Woutersefafcea2001-07-09 12:30:54 +000036 (last > (PyInt_GetMax() - step)) :
37 (last < (-1 - PyInt_GetMax() - step))) {
Guido van Rossum65e0b992001-01-15 18:58:56 +000038 PyErr_SetString(PyExc_OverflowError,
39 "integer addition");
40 return NULL;
Thomas Woutersefafcea2001-07-09 12:30:54 +000041 }
Guido van Rossum65e0b992001-01-15 18:58:56 +000042 }
Guido van Rossum12d12c51993-10-26 17:58:25 +000043 obj->start = start;
44 obj->len = len;
45 obj->step = step;
Guido van Rossum12d12c51993-10-26 17:58:25 +000046
Guido van Rossumc0b618a1997-05-02 03:12:38 +000047 return (PyObject *) obj;
Guido van Rossum12d12c51993-10-26 17:58:25 +000048}
49
Guido van Rossumc0b618a1997-05-02 03:12:38 +000050static PyObject *
Fred Drake45cfbcc2000-07-09 06:21:27 +000051range_item(rangeobject *r, int i)
Guido van Rossum12d12c51993-10-26 17:58:25 +000052{
Fred Draked9018322002-05-02 19:56:55 +000053 if (i < 0 || i >= r->len) {
54 PyErr_SetString(PyExc_IndexError,
Guido van Rossum5dadf7e1999-01-09 21:40:35 +000055 "xrange object index out of range");
Fred Draked9018322002-05-02 19:56:55 +000056 return NULL;
57 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +000058 return PyInt_FromLong(r->start + (i % r->len) * r->step);
Guido van Rossum12d12c51993-10-26 17:58:25 +000059}
60
61static int
Fred Drake45cfbcc2000-07-09 06:21:27 +000062range_length(rangeobject *r)
Guido van Rossum12d12c51993-10-26 17:58:25 +000063{
Fred Draked9018322002-05-02 19:56:55 +000064 return r->len;
Guido van Rossum7d6aa511993-12-21 22:50:31 +000065}
66
Guido van Rossumc0b618a1997-05-02 03:12:38 +000067static PyObject *
Fred Drake45cfbcc2000-07-09 06:21:27 +000068range_repr(rangeobject *r)
Guido van Rossum12d12c51993-10-26 17:58:25 +000069{
Barry Warsaw7ce36942001-08-24 18:34:26 +000070 PyObject *rtn;
71
Tim Peters72d421b2000-08-04 03:05:40 +000072 if (r->start == 0 && r->step == 1)
Barry Warsaw7ce36942001-08-24 18:34:26 +000073 rtn = PyString_FromFormat("xrange(%ld)",
74 r->start + r->len * r->step);
Tim Peters72d421b2000-08-04 03:05:40 +000075
76 else if (r->step == 1)
Barry Warsaw7ce36942001-08-24 18:34:26 +000077 rtn = PyString_FromFormat("xrange(%ld, %ld)",
78 r->start,
79 r->start + r->len * r->step);
Tim Peters72d421b2000-08-04 03:05:40 +000080
81 else
Barry Warsaw7ce36942001-08-24 18:34:26 +000082 rtn = PyString_FromFormat("xrange(%ld, %ld, %ld)",
83 r->start,
84 r->start + r->len * r->step,
85 r->step);
Barry Warsaw7ce36942001-08-24 18:34:26 +000086 return rtn;
Thomas Woutersefafcea2001-07-09 12:30:54 +000087}
88
Guido van Rossumc0b618a1997-05-02 03:12:38 +000089static PySequenceMethods range_as_sequence = {
Fred Draked9018322002-05-02 19:56:55 +000090 (inquiry)range_length, /* sq_length */
91 0, /* sq_concat */
92 0, /* sq_repeat */
93 (intargfunc)range_item, /* sq_item */
94 0, /* sq_slice */
Guido van Rossum12d12c51993-10-26 17:58:25 +000095};
96
Guido van Rossumc0b618a1997-05-02 03:12:38 +000097PyTypeObject PyRange_Type = {
98 PyObject_HEAD_INIT(&PyType_Type)
Fred Draked9018322002-05-02 19:56:55 +000099 0, /* Number of items for varobject */
100 "xrange", /* Name of this type */
101 sizeof(rangeobject), /* Basic object size */
102 0, /* Item size for varobject */
103 (destructor)PyObject_Del, /* tp_dealloc */
104 0, /* tp_print */
105 0, /* tp_getattr */
106 0, /* tp_setattr */
107 0, /* tp_compare */
108 (reprfunc)range_repr, /* tp_repr */
109 0, /* tp_as_number */
110 &range_as_sequence, /* tp_as_sequence */
111 0, /* tp_as_mapping */
112 0, /* tp_hash */
113 0, /* tp_call */
114 0, /* tp_str */
115 0, /* tp_getattro */
116 0, /* tp_setattro */
117 0, /* tp_as_buffer */
118 Py_TPFLAGS_DEFAULT, /* tp_flags */
119 0, /* tp_doc */
Guido van Rossum12d12c51993-10-26 17:58:25 +0000120};