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