@@ -2349,6 +2349,11 @@ list_nohash(PyObject *self)
23492349 return -1 ;
23502350}
23512351
2352+ static PyObject * list_iter (PyObject * seq );
2353+ static PyObject * list_reversed (PyListObject * seq , PyObject * unused );
2354+
2355+ PyDoc_STRVAR (reversed_doc ,
2356+ "L.__reversed__() -- return a reverse iterator over the list" );
23522357PyDoc_STRVAR (append_doc ,
23532358"L.append(object) -- append object to end" );
23542359PyDoc_STRVAR (extend_doc ,
@@ -2373,6 +2378,7 @@ PyDoc_STRVAR(sorted_doc,
23732378cmp(x, y) -> -1, 0, 1" );
23742379
23752380static PyMethodDef list_methods [] = {
2381+ {"__reversed__" ,(PyCFunction )list_reversed , METH_NOARGS , reversed_doc },
23762382 {"append" , (PyCFunction )listappend , METH_O , append_doc },
23772383 {"insert" , (PyCFunction )listinsert , METH_VARARGS , insert_doc },
23782384 {"extend" , (PyCFunction )listextend , METH_O , extend_doc },
@@ -2404,8 +2410,6 @@ PyDoc_STRVAR(list_doc,
24042410"list() -> new list\n"
24052411"list(sequence) -> new list initialized from sequence's items" );
24062412
2407- static PyObject * list_iter (PyObject * seq );
2408-
24092413static PyObject *
24102414list_subscript (PyListObject * self , PyObject * item )
24112415{
@@ -2760,3 +2764,93 @@ PyTypeObject PyListIter_Type = {
27602764 0 , /* tp_descr_get */
27612765 0 , /* tp_descr_set */
27622766};
2767+
2768+ /*********************** List Reverse Iterator **************************/
2769+
2770+ typedef struct {
2771+ PyObject_HEAD
2772+ long it_index ;
2773+ PyListObject * it_seq ;
2774+ } listreviterobject ;
2775+
2776+ PyTypeObject PyListRevIter_Type ;
2777+
2778+ static PyObject *
2779+ list_reversed (PyListObject * seq , PyObject * unused )
2780+ {
2781+ listreviterobject * it ;
2782+
2783+ it = PyObject_GC_New (listreviterobject , & PyListRevIter_Type );
2784+ if (it == NULL )
2785+ return NULL ;
2786+ assert (PyList_Check (seq ));
2787+ it -> it_index = PyList_GET_SIZE (seq ) - 1 ;
2788+ Py_INCREF (seq );
2789+ it -> it_seq = seq ;
2790+ PyObject_GC_Track (it );
2791+ return (PyObject * )it ;
2792+ }
2793+
2794+ static void
2795+ listreviter_dealloc (listreviterobject * it )
2796+ {
2797+ PyObject_GC_UnTrack (it );
2798+ Py_XDECREF (it -> it_seq );
2799+ PyObject_GC_Del (it );
2800+ }
2801+
2802+ static int
2803+ listreviter_traverse (listreviterobject * it , visitproc visit , void * arg )
2804+ {
2805+ if (it -> it_seq == NULL )
2806+ return 0 ;
2807+ return visit ((PyObject * )it -> it_seq , arg );
2808+ }
2809+
2810+ static PyObject *
2811+ listreviter_next (listreviterobject * it )
2812+ {
2813+ PyObject * item = NULL ;
2814+
2815+ assert (PyList_Check (it -> it_seq ));
2816+ if (it -> it_index >= 0 ) {
2817+ assert (it -> it_index < PyList_GET_SIZE (it -> it_seq ));
2818+ item = PyList_GET_ITEM (it -> it_seq , it -> it_index );
2819+ it -> it_index -- ;
2820+ Py_INCREF (item );
2821+ }
2822+ return item ;
2823+ }
2824+
2825+ PyTypeObject PyListRevIter_Type = {
2826+ PyObject_HEAD_INIT (& PyType_Type )
2827+ 0 , /* ob_size */
2828+ "listreverseiterator" , /* tp_name */
2829+ sizeof (listreviterobject ), /* tp_basicsize */
2830+ 0 , /* tp_itemsize */
2831+ /* methods */
2832+ (destructor )listreviter_dealloc , /* tp_dealloc */
2833+ 0 , /* tp_print */
2834+ 0 , /* tp_getattr */
2835+ 0 , /* tp_setattr */
2836+ 0 , /* tp_compare */
2837+ 0 , /* tp_repr */
2838+ 0 , /* tp_as_number */
2839+ 0 , /* tp_as_sequence */
2840+ 0 , /* tp_as_mapping */
2841+ 0 , /* tp_hash */
2842+ 0 , /* tp_call */
2843+ 0 , /* tp_str */
2844+ PyObject_GenericGetAttr , /* tp_getattro */
2845+ 0 , /* tp_setattro */
2846+ 0 , /* tp_as_buffer */
2847+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC ,/* tp_flags */
2848+ 0 , /* tp_doc */
2849+ (traverseproc )listreviter_traverse , /* tp_traverse */
2850+ 0 , /* tp_clear */
2851+ 0 , /* tp_richcompare */
2852+ 0 , /* tp_weaklistoffset */
2853+ PyObject_SelfIter , /* tp_iter */
2854+ (iternextfunc )listreviter_next , /* tp_iternext */
2855+ 0 ,
2856+ };
0 commit comments