@@ -1682,6 +1682,8 @@ static char list_doc[] =
16821682"list() -> new list\n"
16831683"list(sequence) -> new list initialized from sequence's items" ;
16841684
1685+ staticforward PyObject * list_iter (PyObject * seq );
1686+
16851687PyTypeObject PyList_Type = {
16861688 PyObject_HEAD_INIT (& PyType_Type )
16871689 0 ,
@@ -1710,7 +1712,7 @@ PyTypeObject PyList_Type = {
17101712 (inquiry )list_clear , /* tp_clear */
17111713 list_richcompare , /* tp_richcompare */
17121714 0 , /* tp_weaklistoffset */
1713- 0 , /* tp_iter */
1715+ list_iter , /* tp_iter */
17141716 0 , /* tp_iternext */
17151717 list_methods , /* tp_methods */
17161718 0 , /* tp_members */
@@ -1811,3 +1813,118 @@ static PyTypeObject immutable_list_type = {
18111813 0 , /* tp_init */
18121814 /* NOTE: This is *not* the standard list_type struct! */
18131815};
1816+
1817+
1818+ /*********************** List Iterator **************************/
1819+
1820+ typedef struct {
1821+ PyObject_HEAD
1822+ long it_index ;
1823+ PyObject * it_seq ;
1824+ } listiterobject ;
1825+
1826+ PyTypeObject PyListIter_Type ;
1827+
1828+ PyObject *
1829+ list_iter (PyObject * seq )
1830+ {
1831+ listiterobject * it ;
1832+
1833+ if (!PyList_Check (seq )) {
1834+ PyErr_BadInternalCall ();
1835+ return NULL ;
1836+ }
1837+ it = PyObject_GC_New (listiterobject , & PyListIter_Type );
1838+ if (it == NULL )
1839+ return NULL ;
1840+ it -> it_index = 0 ;
1841+ Py_INCREF (seq );
1842+ it -> it_seq = seq ;
1843+ _PyObject_GC_TRACK (it );
1844+ return (PyObject * )it ;
1845+ }
1846+
1847+ static void
1848+ listiter_dealloc (listiterobject * it )
1849+ {
1850+ _PyObject_GC_UNTRACK (it );
1851+ Py_DECREF (it -> it_seq );
1852+ PyObject_GC_Del (it );
1853+ }
1854+
1855+ static int
1856+ listiter_traverse (listiterobject * it , visitproc visit , void * arg )
1857+ {
1858+ return visit (it -> it_seq , arg );
1859+ }
1860+
1861+
1862+ static PyObject *
1863+ listiter_getiter (PyObject * it )
1864+ {
1865+ Py_INCREF (it );
1866+ return it ;
1867+ }
1868+
1869+ static PyObject *
1870+ listiter_next (PyObject * it )
1871+ {
1872+ PyObject * seq ;
1873+ PyObject * item ;
1874+
1875+ assert (PyList_Check (it ));
1876+ seq = ((listiterobject * )it )-> it_seq ;
1877+
1878+ if (((listiterobject * )it )-> it_index < PyList_GET_SIZE (seq )) {
1879+ item = ((PyListObject * )(seq ))-> ob_item [((listiterobject * )it )-> it_index ++ ];
1880+ Py_INCREF (item );
1881+ return item ;
1882+ }
1883+ return NULL ;
1884+ }
1885+
1886+ static PyMethodDef listiter_methods [] = {
1887+ {"next" , (PyCFunction )listiter_next , METH_NOARGS ,
1888+ "it.next() -- get the next value, or raise StopIteration" },
1889+ {NULL , NULL } /* sentinel */
1890+ };
1891+
1892+ PyTypeObject PyListIter_Type = {
1893+ PyObject_HEAD_INIT (& PyType_Type )
1894+ 0 , /* ob_size */
1895+ "listiterator" , /* tp_name */
1896+ sizeof (listiterobject ), /* tp_basicsize */
1897+ 0 , /* tp_itemsize */
1898+ /* methods */
1899+ (destructor )listiter_dealloc , /* tp_dealloc */
1900+ 0 , /* tp_print */
1901+ 0 , /* tp_getattr */
1902+ 0 , /* tp_setattr */
1903+ 0 , /* tp_compare */
1904+ 0 , /* tp_repr */
1905+ 0 , /* tp_as_number */
1906+ 0 , /* tp_as_sequence */
1907+ 0 , /* tp_as_mapping */
1908+ 0 , /* tp_hash */
1909+ 0 , /* tp_call */
1910+ 0 , /* tp_str */
1911+ PyObject_GenericGetAttr , /* tp_getattro */
1912+ 0 , /* tp_setattro */
1913+ 0 , /* tp_as_buffer */
1914+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC ,/* tp_flags */
1915+ 0 , /* tp_doc */
1916+ (traverseproc )listiter_traverse , /* tp_traverse */
1917+ 0 , /* tp_clear */
1918+ 0 , /* tp_richcompare */
1919+ 0 , /* tp_weaklistoffset */
1920+ (getiterfunc )listiter_getiter , /* tp_iter */
1921+ (iternextfunc )listiter_next , /* tp_iternext */
1922+ listiter_methods , /* tp_methods */
1923+ 0 , /* tp_members */
1924+ 0 , /* tp_getset */
1925+ 0 , /* tp_base */
1926+ 0 , /* tp_dict */
1927+ 0 , /* tp_descr_get */
1928+ 0 , /* tp_descr_set */
1929+ };
1930+
0 commit comments