rangeobject.c revision d9018323c035b3c5127d635f237f0009a060053a
112d12c5faf4d770160b7975b54e8f9b12694e012Guido van Rossum
212d12c5faf4d770160b7975b54e8f9b12694e012Guido van Rossum/* Range object implementation */
312d12c5faf4d770160b7975b54e8f9b12694e012Guido van Rossum
4c0b618a2ccfb0fc39e07ee96dc09da77fbcce1b1Guido van Rossum#include "Python.h"
5efafcea2805436c12fd6544d9bff355cfac061d8Thomas Wouters
612d12c5faf4d770160b7975b54e8f9b12694e012Guido van Rossumtypedef struct {
7c0b618a2ccfb0fc39e07ee96dc09da77fbcce1b1Guido van Rossum	PyObject_HEAD
812d12c5faf4d770160b7975b54e8f9b12694e012Guido van Rossum	long	start;
912d12c5faf4d770160b7975b54e8f9b12694e012Guido van Rossum	long	step;
1012d12c5faf4d770160b7975b54e8f9b12694e012Guido van Rossum	long	len;
1112d12c5faf4d770160b7975b54e8f9b12694e012Guido van Rossum} rangeobject;
1212d12c5faf4d770160b7975b54e8f9b12694e012Guido van Rossum
13c0b618a2ccfb0fc39e07ee96dc09da77fbcce1b1Guido van RossumPyObject *
14efafcea2805436c12fd6544d9bff355cfac061d8Thomas WoutersPyRange_New(long start, long len, long step, int reps)
1512d12c5faf4d770160b7975b54e8f9b12694e012Guido van Rossum{
16d9018323c035b3c5127d635f237f0009a060053aFred Drake	rangeobject *obj;
1712d12c5faf4d770160b7975b54e8f9b12694e012Guido van Rossum
18d9018323c035b3c5127d635f237f0009a060053aFred Drake	if (reps != 1) {
19d9018323c035b3c5127d635f237f0009a060053aFred Drake		PyErr_SetString(PyExc_ValueError,
20d9018323c035b3c5127d635f237f0009a060053aFred Drake			"PyRange_New's 'repetitions' argument must be 1");
21d9018323c035b3c5127d635f237f0009a060053aFred Drake		return NULL;
22d9018323c035b3c5127d635f237f0009a060053aFred Drake	}
23d9018323c035b3c5127d635f237f0009a060053aFred Drake
24d9018323c035b3c5127d635f237f0009a060053aFred Drake	obj = PyObject_New(rangeobject, &PyRange_Type);
259e8f4ea0aa469e5818b859836a332cfed8f81af7Guido van Rossum	if (obj == NULL)
269e8f4ea0aa469e5818b859836a332cfed8f81af7Guido van Rossum		return NULL;
279e8f4ea0aa469e5818b859836a332cfed8f81af7Guido van Rossum
28d9018323c035b3c5127d635f237f0009a060053aFred Drake	if (len == 0) {
2965e0b99b611a42fd6548b2783a234f32630e6f1bGuido van Rossum		start = 0;
3065e0b99b611a42fd6548b2783a234f32630e6f1bGuido van Rossum		len = 0;
3165e0b99b611a42fd6548b2783a234f32630e6f1bGuido van Rossum		step = 1;
3265e0b99b611a42fd6548b2783a234f32630e6f1bGuido van Rossum	}
3365e0b99b611a42fd6548b2783a234f32630e6f1bGuido van Rossum	else {
3465e0b99b611a42fd6548b2783a234f32630e6f1bGuido van Rossum		long last = start + (len - 1) * step;
3565e0b99b611a42fd6548b2783a234f32630e6f1bGuido van Rossum		if ((step > 0) ?
36efafcea2805436c12fd6544d9bff355cfac061d8Thomas Wouters		    (last > (PyInt_GetMax() - step)) :
37efafcea2805436c12fd6544d9bff355cfac061d8Thomas Wouters		    (last < (-1 - PyInt_GetMax() - step))) {
3865e0b99b611a42fd6548b2783a234f32630e6f1bGuido van Rossum			PyErr_SetString(PyExc_OverflowError,
3965e0b99b611a42fd6548b2783a234f32630e6f1bGuido van Rossum					"integer addition");
4065e0b99b611a42fd6548b2783a234f32630e6f1bGuido van Rossum			return NULL;
41efafcea2805436c12fd6544d9bff355cfac061d8Thomas Wouters		}
4265e0b99b611a42fd6548b2783a234f32630e6f1bGuido van Rossum	}
4312d12c5faf4d770160b7975b54e8f9b12694e012Guido van Rossum	obj->start = start;
4412d12c5faf4d770160b7975b54e8f9b12694e012Guido van Rossum	obj->len   = len;
4512d12c5faf4d770160b7975b54e8f9b12694e012Guido van Rossum	obj->step  = step;
4612d12c5faf4d770160b7975b54e8f9b12694e012Guido van Rossum
47c0b618a2ccfb0fc39e07ee96dc09da77fbcce1b1Guido van Rossum	return (PyObject *) obj;
4812d12c5faf4d770160b7975b54e8f9b12694e012Guido van Rossum}
4912d12c5faf4d770160b7975b54e8f9b12694e012Guido van Rossum
50c0b618a2ccfb0fc39e07ee96dc09da77fbcce1b1Guido van Rossumstatic PyObject *
5145cfbcccc287ae52656737466ca071ca18f603c7Fred Drakerange_item(rangeobject *r, int i)
5212d12c5faf4d770160b7975b54e8f9b12694e012Guido van Rossum{
53d9018323c035b3c5127d635f237f0009a060053aFred Drake	if (i < 0 || i >= r->len) {
54d9018323c035b3c5127d635f237f0009a060053aFred Drake		PyErr_SetString(PyExc_IndexError,
555dadf7e976c55ac3960f79aaa5741ab37a10cdf4Guido van Rossum				"xrange object index out of range");
56d9018323c035b3c5127d635f237f0009a060053aFred Drake		return NULL;
57d9018323c035b3c5127d635f237f0009a060053aFred Drake	}
58c0b618a2ccfb0fc39e07ee96dc09da77fbcce1b1Guido van Rossum	return PyInt_FromLong(r->start + (i % r->len) * r->step);
5912d12c5faf4d770160b7975b54e8f9b12694e012Guido van Rossum}
6012d12c5faf4d770160b7975b54e8f9b12694e012Guido van Rossum
6112d12c5faf4d770160b7975b54e8f9b12694e012Guido van Rossumstatic int
6245cfbcccc287ae52656737466ca071ca18f603c7Fred Drakerange_length(rangeobject *r)
6312d12c5faf4d770160b7975b54e8f9b12694e012Guido van Rossum{
64d9018323c035b3c5127d635f237f0009a060053aFred Drake	return r->len;
657d6aa51b56c6337ad5b1cb880f7c075290777f51Guido van Rossum}
667d6aa51b56c6337ad5b1cb880f7c075290777f51Guido van Rossum
67c0b618a2ccfb0fc39e07ee96dc09da77fbcce1b1Guido van Rossumstatic PyObject *
6845cfbcccc287ae52656737466ca071ca18f603c7Fred Drakerange_repr(rangeobject *r)
6912d12c5faf4d770160b7975b54e8f9b12694e012Guido van Rossum{
707ce3694a527afe425a2b9df65c049b0ef4e75960Barry Warsaw	PyObject *rtn;
717ce3694a527afe425a2b9df65c049b0ef4e75960Barry Warsaw
7272d421b75ca05f54ff4f5df4aac5291d6c568ae8Tim Peters	if (r->start == 0 && r->step == 1)
737ce3694a527afe425a2b9df65c049b0ef4e75960Barry Warsaw		rtn = PyString_FromFormat("xrange(%ld)",
747ce3694a527afe425a2b9df65c049b0ef4e75960Barry Warsaw					  r->start + r->len * r->step);
7572d421b75ca05f54ff4f5df4aac5291d6c568ae8Tim Peters
7672d421b75ca05f54ff4f5df4aac5291d6c568ae8Tim Peters	else if (r->step == 1)
777ce3694a527afe425a2b9df65c049b0ef4e75960Barry Warsaw		rtn = PyString_FromFormat("xrange(%ld, %ld)",
787ce3694a527afe425a2b9df65c049b0ef4e75960Barry Warsaw					  r->start,
797ce3694a527afe425a2b9df65c049b0ef4e75960Barry Warsaw					  r->start + r->len * r->step);
8072d421b75ca05f54ff4f5df4aac5291d6c568ae8Tim Peters
8172d421b75ca05f54ff4f5df4aac5291d6c568ae8Tim Peters	else
827ce3694a527afe425a2b9df65c049b0ef4e75960Barry Warsaw		rtn = PyString_FromFormat("xrange(%ld, %ld, %ld)",
837ce3694a527afe425a2b9df65c049b0ef4e75960Barry Warsaw					  r->start,
847ce3694a527afe425a2b9df65c049b0ef4e75960Barry Warsaw					  r->start + r->len * r->step,
857ce3694a527afe425a2b9df65c049b0ef4e75960Barry Warsaw					  r->step);
867ce3694a527afe425a2b9df65c049b0ef4e75960Barry Warsaw	return rtn;
87efafcea2805436c12fd6544d9bff355cfac061d8Thomas Wouters}
88efafcea2805436c12fd6544d9bff355cfac061d8Thomas Wouters
89c0b618a2ccfb0fc39e07ee96dc09da77fbcce1b1Guido van Rossumstatic PySequenceMethods range_as_sequence = {
90d9018323c035b3c5127d635f237f0009a060053aFred Drake	(inquiry)range_length,	/* sq_length */
91d9018323c035b3c5127d635f237f0009a060053aFred Drake	0,			/* sq_concat */
92d9018323c035b3c5127d635f237f0009a060053aFred Drake	0,			/* sq_repeat */
93d9018323c035b3c5127d635f237f0009a060053aFred Drake	(intargfunc)range_item, /* sq_item */
94d9018323c035b3c5127d635f237f0009a060053aFred Drake	0,			/* sq_slice */
9512d12c5faf4d770160b7975b54e8f9b12694e012Guido van Rossum};
9612d12c5faf4d770160b7975b54e8f9b12694e012Guido van Rossum
97c0b618a2ccfb0fc39e07ee96dc09da77fbcce1b1Guido van RossumPyTypeObject PyRange_Type = {
98c0b618a2ccfb0fc39e07ee96dc09da77fbcce1b1Guido van Rossum	PyObject_HEAD_INIT(&PyType_Type)
99d9018323c035b3c5127d635f237f0009a060053aFred Drake	0,				/* Number of items for varobject */
100d9018323c035b3c5127d635f237f0009a060053aFred Drake	"xrange",			/* Name of this type */
101d9018323c035b3c5127d635f237f0009a060053aFred Drake	sizeof(rangeobject),		/* Basic object size */
102d9018323c035b3c5127d635f237f0009a060053aFred Drake	0,				/* Item size for varobject */
103d9018323c035b3c5127d635f237f0009a060053aFred Drake	(destructor)PyObject_Del,	/* tp_dealloc */
104d9018323c035b3c5127d635f237f0009a060053aFred Drake	0,				/* tp_print */
105d9018323c035b3c5127d635f237f0009a060053aFred Drake	0,				/* tp_getattr */
106d9018323c035b3c5127d635f237f0009a060053aFred Drake	0,				/* tp_setattr */
107d9018323c035b3c5127d635f237f0009a060053aFred Drake	0,				/* tp_compare */
108d9018323c035b3c5127d635f237f0009a060053aFred Drake	(reprfunc)range_repr,		/* tp_repr */
109d9018323c035b3c5127d635f237f0009a060053aFred Drake	0,				/* tp_as_number */
110d9018323c035b3c5127d635f237f0009a060053aFred Drake	&range_as_sequence,		/* tp_as_sequence */
111d9018323c035b3c5127d635f237f0009a060053aFred Drake	0,				/* tp_as_mapping */
112d9018323c035b3c5127d635f237f0009a060053aFred Drake	0,				/* tp_hash */
113d9018323c035b3c5127d635f237f0009a060053aFred Drake	0,				/* tp_call */
114d9018323c035b3c5127d635f237f0009a060053aFred Drake	0,				/* tp_str */
115d9018323c035b3c5127d635f237f0009a060053aFred Drake	0,				/* tp_getattro */
116d9018323c035b3c5127d635f237f0009a060053aFred Drake	0,				/* tp_setattro */
117d9018323c035b3c5127d635f237f0009a060053aFred Drake	0,				/* tp_as_buffer */
118d9018323c035b3c5127d635f237f0009a060053aFred Drake	Py_TPFLAGS_DEFAULT,		/* tp_flags */
119d9018323c035b3c5127d635f237f0009a060053aFred Drake	0,				/* tp_doc */
12012d12c5faf4d770160b7975b54e8f9b12694e012Guido van Rossum};
121