blob: 0fee40f6841f9732117cc24f37130ea9808bfcac [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 Rossum12d12c51993-10-26 17:58:25 +00005typedef struct {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00006 PyObject_HEAD
Guido van Rossum12d12c51993-10-26 17:58:25 +00007 long start;
8 long step;
9 long len;
Guido van Rossum12d12c51993-10-26 17:58:25 +000010} rangeobject;
11
Mark Dickinson009ae862009-11-15 12:31:13 +000012/* Return number of items in range (lo, hi, step). step != 0
13 * required. The result always fits in an unsigned long.
Raymond Hettingerc4c453f2002-06-05 23:12:45 +000014 */
Mark Dickinson009ae862009-11-15 12:31:13 +000015static unsigned long
Raymond Hettingerc4c453f2002-06-05 23:12:45 +000016get_len_of_range(long lo, long hi, long step)
17{
Mark Dickinson009ae862009-11-15 12:31:13 +000018 /* -------------------------------------------------------------
19 If step > 0 and lo >= hi, or step < 0 and lo <= hi, the range is empty.
20 Else for step > 0, if n values are in the range, the last one is
21 lo + (n-1)*step, which must be <= hi-1. Rearranging,
22 n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives
23 the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so
24 the RHS is non-negative and so truncation is the same as the
25 floor. Letting M be the largest positive long, the worst case
26 for the RHS numerator is hi=M, lo=-M-1, and then
27 hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough
28 precision to compute the RHS exactly. The analysis for step < 0
29 is similar.
30 ---------------------------------------------------------------*/
31 assert(step != 0);
32 if (step > 0 && lo < hi)
33 return 1UL + (hi - 1UL - lo) / step;
34 else if (step < 0 && lo > hi)
35 return 1UL + (lo - 1UL - hi) / (0UL - step);
36 else
37 return 0UL;
Raymond Hettingerc4c453f2002-06-05 23:12:45 +000038}
39
40static PyObject *
41range_new(PyTypeObject *type, PyObject *args, PyObject *kw)
42{
Tim Petersfeec4532004-08-08 07:17:39 +000043 rangeobject *obj;
Raymond Hettingerc4c453f2002-06-05 23:12:45 +000044 long ilow = 0, ihigh = 0, istep = 1;
Mark Dickinson009ae862009-11-15 12:31:13 +000045 unsigned long n;
Raymond Hettingerc4c453f2002-06-05 23:12:45 +000046
Georg Brandl02c42872005-08-26 06:42:30 +000047 if (!_PyArg_NoKeywords("xrange()", kw))
48 return NULL;
49
Raymond Hettingerc4c453f2002-06-05 23:12:45 +000050 if (PyTuple_Size(args) <= 1) {
51 if (!PyArg_ParseTuple(args,
52 "l;xrange() requires 1-3 int arguments",
53 &ihigh))
54 return NULL;
55 }
56 else {
57 if (!PyArg_ParseTuple(args,
58 "ll|l;xrange() requires 1-3 int arguments",
59 &ilow, &ihigh, &istep))
60 return NULL;
61 }
62 if (istep == 0) {
63 PyErr_SetString(PyExc_ValueError, "xrange() arg 3 must not be zero");
64 return NULL;
65 }
Mark Dickinson009ae862009-11-15 12:31:13 +000066 n = get_len_of_range(ilow, ihigh, istep);
67 if (n > (unsigned long)LONG_MAX || (long)n > PY_SSIZE_T_MAX) {
Raymond Hettingerc4c453f2002-06-05 23:12:45 +000068 PyErr_SetString(PyExc_OverflowError,
69 "xrange() result has too many items");
70 return NULL;
71 }
Tim Petersfeec4532004-08-08 07:17:39 +000072
73 obj = PyObject_New(rangeobject, &PyRange_Type);
74 if (obj == NULL)
75 return NULL;
76 obj->start = ilow;
Mark Dickinson009ae862009-11-15 12:31:13 +000077 obj->len = (long)n;
Tim Petersfeec4532004-08-08 07:17:39 +000078 obj->step = istep;
79 return (PyObject *) obj;
Raymond Hettingerc4c453f2002-06-05 23:12:45 +000080}
81
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000082PyDoc_STRVAR(range_doc,
Raymond Hettingerc4c453f2002-06-05 23:12:45 +000083"xrange([start,] stop[, step]) -> xrange object\n\
84\n\
85Like range(), but instead of returning a list, returns an object that\n\
Raymond Hettingerd2bef822002-12-11 07:14:03 +000086generates the numbers in the range on demand. For looping, this is \n\
87slightly faster than range() and more memory efficient.");
Raymond Hettingerc4c453f2002-06-05 23:12:45 +000088
Guido van Rossumc0b618a1997-05-02 03:12:38 +000089static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +000090range_item(rangeobject *r, Py_ssize_t i)
Guido van Rossum12d12c51993-10-26 17:58:25 +000091{
Fred Draked9018322002-05-02 19:56:55 +000092 if (i < 0 || i >= r->len) {
93 PyErr_SetString(PyExc_IndexError,
Guido van Rossum5dadf7e1999-01-09 21:40:35 +000094 "xrange object index out of range");
Fred Draked9018322002-05-02 19:56:55 +000095 return NULL;
96 }
Mark Dickinson009ae862009-11-15 12:31:13 +000097 /* do calculation entirely using unsigned longs, to avoid
98 undefined behaviour due to signed overflow. */
99 return PyInt_FromLong((long)(r->start + (unsigned long)i * r->step));
Guido van Rossum12d12c51993-10-26 17:58:25 +0000100}
101
Martin v. Löwis18e16552006-02-15 17:27:45 +0000102static Py_ssize_t
Fred Drake45cfbcc2000-07-09 06:21:27 +0000103range_length(rangeobject *r)
Guido van Rossum12d12c51993-10-26 17:58:25 +0000104{
Martin v. Löwis18e16552006-02-15 17:27:45 +0000105 return (Py_ssize_t)(r->len);
Guido van Rossum7d6aa511993-12-21 22:50:31 +0000106}
107
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000108static PyObject *
Fred Drake45cfbcc2000-07-09 06:21:27 +0000109range_repr(rangeobject *r)
Guido van Rossum12d12c51993-10-26 17:58:25 +0000110{
Barry Warsaw7ce36942001-08-24 18:34:26 +0000111 PyObject *rtn;
Tim Petersd976ab72004-08-08 06:29:10 +0000112
Tim Peters72d421b2000-08-04 03:05:40 +0000113 if (r->start == 0 && r->step == 1)
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000114 rtn = PyString_FromFormat("xrange(%ld)",
Barry Warsaw7ce36942001-08-24 18:34:26 +0000115 r->start + r->len * r->step);
Tim Peters72d421b2000-08-04 03:05:40 +0000116
117 else if (r->step == 1)
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000118 rtn = PyString_FromFormat("xrange(%ld, %ld)",
Barry Warsaw7ce36942001-08-24 18:34:26 +0000119 r->start,
120 r->start + r->len * r->step);
Tim Peters72d421b2000-08-04 03:05:40 +0000121
122 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000123 rtn = PyString_FromFormat("xrange(%ld, %ld, %ld)",
Barry Warsaw7ce36942001-08-24 18:34:26 +0000124 r->start,
125 r->start + r->len * r->step,
126 r->step);
Barry Warsaw7ce36942001-08-24 18:34:26 +0000127 return rtn;
Thomas Woutersefafcea2001-07-09 12:30:54 +0000128}
129
Alexandre Vassalotti1f2f61a2008-06-10 03:34:53 +0000130/* Pickling support */
131static PyObject *
Alexandre Vassalotti602d8db2008-06-10 04:01:23 +0000132range_reduce(rangeobject *r, PyObject *args)
Alexandre Vassalotti1f2f61a2008-06-10 03:34:53 +0000133{
Alexandre Vassalotti602d8db2008-06-10 04:01:23 +0000134 return Py_BuildValue("(O(iii))", Py_TYPE(r),
Alexandre Vassalotti1f2f61a2008-06-10 03:34:53 +0000135 r->start,
136 r->start + r->len * r->step,
137 r->step);
138}
139
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000140static PySequenceMethods range_as_sequence = {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000141 (lenfunc)range_length, /* sq_length */
Fred Draked9018322002-05-02 19:56:55 +0000142 0, /* sq_concat */
143 0, /* sq_repeat */
Martin v. Löwis18e16552006-02-15 17:27:45 +0000144 (ssizeargfunc)range_item, /* sq_item */
Fred Draked9018322002-05-02 19:56:55 +0000145 0, /* sq_slice */
Guido van Rossum12d12c51993-10-26 17:58:25 +0000146};
147
Jeremy Hylton938ace62002-07-17 16:30:39 +0000148static PyObject * range_iter(PyObject *seq);
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000149static PyObject * range_reverse(PyObject *seq);
150
151PyDoc_STRVAR(reverse_doc,
152"Returns a reverse iterator.");
153
154static PyMethodDef range_methods[] = {
155 {"__reversed__", (PyCFunction)range_reverse, METH_NOARGS, reverse_doc},
Alexandre Vassalotti602d8db2008-06-10 04:01:23 +0000156 {"__reduce__", (PyCFunction)range_reduce, METH_VARARGS},
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000157 {NULL, NULL} /* sentinel */
158};
Raymond Hettinger48165d42002-06-05 20:08:48 +0000159
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000160PyTypeObject PyRange_Type = {
161 PyObject_HEAD_INIT(&PyType_Type)
Georg Brandl347b3002006-03-30 11:57:00 +0000162 0, /* Number of items for varobject */
163 "xrange", /* Name of this type */
164 sizeof(rangeobject), /* Basic object size */
165 0, /* Item size for varobject */
166 (destructor)PyObject_Del, /* tp_dealloc */
167 0, /* tp_print */
168 0, /* tp_getattr */
169 0, /* tp_setattr */
170 0, /* tp_compare */
171 (reprfunc)range_repr, /* tp_repr */
172 0, /* tp_as_number */
173 &range_as_sequence, /* tp_as_sequence */
174 0, /* tp_as_mapping */
175 0, /* tp_hash */
176 0, /* tp_call */
177 0, /* tp_str */
178 PyObject_GenericGetAttr, /* tp_getattro */
179 0, /* tp_setattro */
180 0, /* tp_as_buffer */
181 Py_TPFLAGS_DEFAULT, /* tp_flags */
182 range_doc, /* tp_doc */
183 0, /* tp_traverse */
184 0, /* tp_clear */
185 0, /* tp_richcompare */
186 0, /* tp_weaklistoffset */
187 range_iter, /* tp_iter */
188 0, /* tp_iternext */
189 range_methods, /* tp_methods */
190 0, /* tp_members */
191 0, /* tp_getset */
192 0, /* tp_base */
193 0, /* tp_dict */
194 0, /* tp_descr_get */
195 0, /* tp_descr_set */
196 0, /* tp_dictoffset */
197 0, /* tp_init */
198 0, /* tp_alloc */
199 range_new, /* tp_new */
Guido van Rossum12d12c51993-10-26 17:58:25 +0000200};
Raymond Hettinger48165d42002-06-05 20:08:48 +0000201
202/*********************** Xrange Iterator **************************/
203
204typedef struct {
205 PyObject_HEAD
206 long index;
207 long start;
208 long step;
209 long len;
210} rangeiterobject;
211
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000212static PyObject *
Raymond Hettinger48165d42002-06-05 20:08:48 +0000213rangeiter_next(rangeiterobject *r)
214{
Tim Petersd976ab72004-08-08 06:29:10 +0000215 if (r->index < r->len)
Raymond Hettinger48165d42002-06-05 20:08:48 +0000216 return PyInt_FromLong(r->start + (r->index++) * r->step);
Raymond Hettinger48165d42002-06-05 20:08:48 +0000217 return NULL;
218}
219
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000220static PyObject *
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000221rangeiter_len(rangeiterobject *r)
222{
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000223 return PyInt_FromLong(r->len - r->index);
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000224}
225
Armin Rigof5b3e362006-02-11 21:32:43 +0000226PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000227
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000228static PyMethodDef rangeiter_methods[] = {
Armin Rigof5b3e362006-02-11 21:32:43 +0000229 {"__length_hint__", (PyCFunction)rangeiter_len, METH_NOARGS, length_hint_doc},
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000230 {NULL, NULL} /* sentinel */
231};
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000232
Neal Norwitz56f46f82002-06-06 14:58:21 +0000233static PyTypeObject Pyrangeiter_Type = {
Raymond Hettinger48165d42002-06-05 20:08:48 +0000234 PyObject_HEAD_INIT(&PyType_Type)
235 0, /* ob_size */
Neal Norwitz56f46f82002-06-06 14:58:21 +0000236 "rangeiterator", /* tp_name */
237 sizeof(rangeiterobject), /* tp_basicsize */
Raymond Hettinger48165d42002-06-05 20:08:48 +0000238 0, /* tp_itemsize */
239 /* methods */
240 (destructor)PyObject_Del, /* tp_dealloc */
241 0, /* tp_print */
242 0, /* tp_getattr */
243 0, /* tp_setattr */
244 0, /* tp_compare */
245 0, /* tp_repr */
246 0, /* tp_as_number */
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000247 0, /* tp_as_sequence */
Raymond Hettinger48165d42002-06-05 20:08:48 +0000248 0, /* tp_as_mapping */
249 0, /* tp_hash */
250 0, /* tp_call */
251 0, /* tp_str */
252 PyObject_GenericGetAttr, /* tp_getattro */
253 0, /* tp_setattro */
254 0, /* tp_as_buffer */
255 Py_TPFLAGS_DEFAULT, /* tp_flags */
256 0, /* tp_doc */
257 0, /* tp_traverse */
258 0, /* tp_clear */
259 0, /* tp_richcompare */
260 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +0000261 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger48165d42002-06-05 20:08:48 +0000262 (iternextfunc)rangeiter_next, /* tp_iternext */
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000263 rangeiter_methods, /* tp_methods */
264 0,
Raymond Hettinger48165d42002-06-05 20:08:48 +0000265};
Martin v. Löwis72d20672006-04-11 09:04:12 +0000266
267static PyObject *
268range_iter(PyObject *seq)
269{
270 rangeiterobject *it;
271
272 if (!PyRange_Check(seq)) {
273 PyErr_BadInternalCall();
274 return NULL;
275 }
276 it = PyObject_New(rangeiterobject, &Pyrangeiter_Type);
277 if (it == NULL)
278 return NULL;
279 it->index = 0;
280 it->start = ((rangeobject *)seq)->start;
281 it->step = ((rangeobject *)seq)->step;
282 it->len = ((rangeobject *)seq)->len;
283 return (PyObject *)it;
284}
285
286static PyObject *
287range_reverse(PyObject *seq)
288{
289 rangeiterobject *it;
290 long start, step, len;
291
292 if (!PyRange_Check(seq)) {
293 PyErr_BadInternalCall();
294 return NULL;
295 }
296 it = PyObject_New(rangeiterobject, &Pyrangeiter_Type);
297 if (it == NULL)
298 return NULL;
299
300 start = ((rangeobject *)seq)->start;
301 step = ((rangeobject *)seq)->step;
302 len = ((rangeobject *)seq)->len;
303
304 it->index = 0;
Martin v. Löwis72d20672006-04-11 09:04:12 +0000305 it->len = len;
Mark Dickinson009ae862009-11-15 12:31:13 +0000306 /* the casts below guard against signed overflow by turning it
307 into unsigned overflow instead. The correctness of this
308 code still depends on conversion from unsigned long to long
309 wrapping modulo ULONG_MAX+1, which isn't guaranteed (see
310 C99 6.3.1.3p3) but seems to hold in practice for all
311 platforms we're likely to meet.
312
313 If step == LONG_MIN then we still end up with LONG_MIN
314 after negation; but this works out, since we've still got
315 the correct value modulo ULONG_MAX+1, and the range_item
316 calculation is also done modulo ULONG_MAX+1.
317 */
318 it->start = (long)(start + (unsigned long)(len-1) * step);
319 it->step = (long)(-(unsigned long)step);
Martin v. Löwis72d20672006-04-11 09:04:12 +0000320
321 return (PyObject *)it;
322}