@@ -2625,7 +2625,7 @@ map_dump(MapObject *self)
26252625static int
26262626map_baseiter_tp_clear (MapIterator * it )
26272627{
2628- Py_CLEAR (it -> hi_obj );
2628+ Py_CLEAR (it -> mi_obj );
26292629 return 0 ;
26302630}
26312631
@@ -2640,7 +2640,7 @@ map_baseiter_tp_dealloc(MapIterator *it)
26402640static int
26412641map_baseiter_tp_traverse (MapIterator * it , visitproc visit , void * arg )
26422642{
2643- Py_VISIT (it -> hi_obj );
2643+ Py_VISIT (it -> mi_obj );
26442644 return 0 ;
26452645}
26462646
@@ -2649,15 +2649,15 @@ map_baseiter_tp_iternext(MapIterator *it)
26492649{
26502650 PyObject * key ;
26512651 PyObject * val ;
2652- map_iter_t res = map_iterator_next (& it -> hi_iter , & key , & val );
2652+ map_iter_t res = map_iterator_next (& it -> mi_iter , & key , & val );
26532653
26542654 switch (res ) {
26552655 case I_END :
26562656 PyErr_SetNone (PyExc_StopIteration );
26572657 return NULL ;
26582658
26592659 case I_ITEM : {
2660- return (* (it -> hi_yield ))(key , val );
2660+ return (* (it -> mi_yield ))(key , val );
26612661 }
26622662
26632663 default : {
@@ -2666,37 +2666,86 @@ map_baseiter_tp_iternext(MapIterator *it)
26662666 }
26672667}
26682668
2669+ static int
2670+ map_baseview_tp_clear (MapView * view )
2671+ {
2672+ Py_CLEAR (view -> mv_obj );
2673+ Py_CLEAR (view -> mv_itertype );
2674+ return 0 ;
2675+ }
2676+
2677+ static void
2678+ map_baseview_tp_dealloc (MapView * view )
2679+ {
2680+ PyObject_GC_UnTrack (view );
2681+ (void )map_baseview_tp_clear (view );
2682+ PyObject_GC_Del (view );
2683+ }
2684+
2685+ static int
2686+ map_baseview_tp_traverse (MapView * view , visitproc visit , void * arg )
2687+ {
2688+ Py_VISIT (view -> mv_obj );
2689+ return 0 ;
2690+ }
2691+
26692692static Py_ssize_t
2670- map_baseiter_tp_len ( MapIterator * it )
2693+ map_baseview_tp_len ( MapView * view )
26712694{
2672- return it -> hi_obj -> h_count ;
2695+ return view -> mv_obj -> h_count ;
26732696}
26742697
2675- static PyMappingMethods MapIterator_as_mapping = {
2676- (lenfunc )map_baseiter_tp_len ,
2698+ static PyMappingMethods MapView_as_mapping = {
2699+ (lenfunc )map_baseview_tp_len ,
26772700};
26782701
26792702static PyObject *
2680- map_baseiter_new (PyTypeObject * type , binaryfunc yield , MapObject * o )
2703+ map_baseview_newiter (PyTypeObject * type , binaryfunc yield , MapObject * map )
26812704{
2682- MapIterator * it = PyObject_GC_New (MapIterator , type );
2683- if (it == NULL ) {
2705+ MapIterator * iter = PyObject_GC_New (MapIterator , type );
2706+ if (iter == NULL ) {
2707+ return NULL ;
2708+ }
2709+
2710+ Py_INCREF (map );
2711+ iter -> mi_obj = map ;
2712+ iter -> mi_yield = yield ;
2713+ map_iterator_init (& iter -> mi_iter , map -> h_root );
2714+
2715+ PyObject_GC_Track (iter );
2716+ return (PyObject * )iter ;
2717+ }
2718+
2719+ static PyObject *
2720+ map_baseview_iter (MapView * view )
2721+ {
2722+ return map_baseview_newiter (
2723+ view -> mv_itertype , view -> mv_yield , view -> mv_obj );
2724+ }
2725+
2726+ static PyObject *
2727+ map_baseview_new (PyTypeObject * type , binaryfunc yield ,
2728+ MapObject * o , PyTypeObject * itertype )
2729+ {
2730+ MapView * view = PyObject_GC_New (MapView , type );
2731+ if (view == NULL ) {
26842732 return NULL ;
26852733 }
26862734
26872735 Py_INCREF (o );
2688- it -> hi_obj = o ;
2689- it -> hi_yield = yield ;
2736+ view -> mv_obj = o ;
2737+ view -> mv_yield = yield ;
26902738
2691- map_iterator_init (& it -> hi_iter , o -> h_root );
2739+ Py_INCREF (itertype );
2740+ view -> mv_itertype = itertype ;
26922741
2693- return (PyObject * )it ;
2742+ PyObject_GC_Track (view );
2743+ return (PyObject * )view ;
26942744}
26952745
26962746#define ITERATOR_TYPE_SHARED_SLOTS \
26972747 .tp_basicsize = sizeof(MapIterator), \
26982748 .tp_itemsize = 0, \
2699- .tp_as_mapping = &MapIterator_as_mapping, \
27002749 .tp_dealloc = (destructor)map_baseiter_tp_dealloc, \
27012750 .tp_getattro = PyObject_GenericGetAttr, \
27022751 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, \
@@ -2706,12 +2755,30 @@ map_baseiter_new(PyTypeObject *type, binaryfunc yield, MapObject *o)
27062755 .tp_iternext = (iternextfunc)map_baseiter_tp_iternext,
27072756
27082757
2758+ #define VIEW_TYPE_SHARED_SLOTS \
2759+ .tp_basicsize = sizeof(MapView), \
2760+ .tp_itemsize = 0, \
2761+ .tp_as_mapping = &MapView_as_mapping, \
2762+ .tp_dealloc = (destructor)map_baseview_tp_dealloc, \
2763+ .tp_getattro = PyObject_GenericGetAttr, \
2764+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, \
2765+ .tp_traverse = (traverseproc)map_baseview_tp_traverse, \
2766+ .tp_clear = (inquiry)map_baseview_tp_clear, \
2767+ .tp_iter = (getiterfunc)map_baseview_iter, \
2768+
2769+
27092770/////////////////////////////////// _MapItems_Type
27102771
27112772
27122773PyTypeObject _MapItems_Type = {
27132774 PyVarObject_HEAD_INIT (NULL , 0 )
27142775 "items" ,
2776+ VIEW_TYPE_SHARED_SLOTS
2777+ };
2778+
2779+ PyTypeObject _MapItemsIter_Type = {
2780+ PyVarObject_HEAD_INIT (NULL , 0 )
2781+ "items_iterator" ,
27152782 ITERATOR_TYPE_SHARED_SLOTS
27162783};
27172784
@@ -2722,10 +2789,11 @@ map_iter_yield_items(PyObject *key, PyObject *val)
27222789}
27232790
27242791static PyObject *
2725- map_new_iteritems (MapObject * o )
2792+ map_new_items_view (MapObject * o )
27262793{
2727- return map_baseiter_new (
2728- & _MapItems_Type , map_iter_yield_items , o );
2794+ return map_baseview_new (
2795+ & _MapItems_Type , map_iter_yield_items , o ,
2796+ & _MapItemsIter_Type );
27292797}
27302798
27312799
@@ -2735,6 +2803,12 @@ map_new_iteritems(MapObject *o)
27352803PyTypeObject _MapKeys_Type = {
27362804 PyVarObject_HEAD_INIT (NULL , 0 )
27372805 "keys" ,
2806+ VIEW_TYPE_SHARED_SLOTS
2807+ };
2808+
2809+ PyTypeObject _MapKeysIter_Type = {
2810+ PyVarObject_HEAD_INIT (NULL , 0 )
2811+ "keys_iterator" ,
27382812 ITERATOR_TYPE_SHARED_SLOTS
27392813};
27402814
@@ -2746,19 +2820,32 @@ map_iter_yield_keys(PyObject *key, PyObject *val)
27462820}
27472821
27482822static PyObject *
2749- map_new_iterkeys (MapObject * o )
2823+ map_new_keys_iter (MapObject * o )
27502824{
2751- return map_baseiter_new (
2752- & _MapKeys_Type , map_iter_yield_keys , o );
2825+ return map_baseview_newiter (
2826+ & _MapKeysIter_Type , map_iter_yield_keys , o );
27532827}
27542828
2829+ static PyObject *
2830+ map_new_keys_view (MapObject * o )
2831+ {
2832+ return map_baseview_new (
2833+ & _MapKeys_Type , map_iter_yield_keys , o ,
2834+ & _MapKeysIter_Type );
2835+ }
27552836
27562837/////////////////////////////////// _MapValues_Type
27572838
27582839
27592840PyTypeObject _MapValues_Type = {
27602841 PyVarObject_HEAD_INIT (NULL , 0 )
27612842 "values" ,
2843+ VIEW_TYPE_SHARED_SLOTS
2844+ };
2845+
2846+ PyTypeObject _MapValuesIter_Type = {
2847+ PyVarObject_HEAD_INIT (NULL , 0 )
2848+ "values_iterator" ,
27622849 ITERATOR_TYPE_SHARED_SLOTS
27632850};
27642851
@@ -2770,10 +2857,11 @@ map_iter_yield_values(PyObject *key, PyObject *val)
27702857}
27712858
27722859static PyObject *
2773- map_new_itervalues (MapObject * o )
2860+ map_new_values_view (MapObject * o )
27742861{
2775- return map_baseiter_new (
2776- & _MapValues_Type , map_iter_yield_values , o );
2862+ return map_baseview_new (
2863+ & _MapValues_Type , map_iter_yield_values , o ,
2864+ & _MapValuesIter_Type );
27772865}
27782866
27792867
@@ -2922,7 +3010,7 @@ map_tp_len(BaseMapObject *self)
29223010static PyObject *
29233011map_tp_iter (MapObject * self )
29243012{
2925- return map_new_iterkeys (self );
3013+ return map_new_keys_iter (self );
29263014}
29273015
29283016static PyObject *
@@ -3041,19 +3129,19 @@ map_py_update(MapObject *self, PyObject *args, PyObject *kwds)
30413129static PyObject *
30423130map_py_items (MapObject * self , PyObject * args )
30433131{
3044- return map_new_iteritems (self );
3132+ return map_new_items_view (self );
30453133}
30463134
30473135static PyObject *
30483136map_py_values (MapObject * self , PyObject * args )
30493137{
3050- return map_new_itervalues (self );
3138+ return map_new_values_view (self );
30513139}
30523140
30533141static PyObject *
30543142map_py_keys (MapObject * self , PyObject * args )
30553143{
3056- return map_new_iterkeys (self );
3144+ return map_new_keys_view (self );
30573145}
30583146
30593147static PyObject *
@@ -3844,7 +3932,10 @@ PyInit__map(void)
38443932 (PyType_Ready (& _Map_CollisionNode_Type ) < 0 ) ||
38453933 (PyType_Ready (& _MapKeys_Type ) < 0 ) ||
38463934 (PyType_Ready (& _MapValues_Type ) < 0 ) ||
3847- (PyType_Ready (& _MapItems_Type ) < 0 ))
3935+ (PyType_Ready (& _MapItems_Type ) < 0 ) ||
3936+ (PyType_Ready (& _MapKeysIter_Type ) < 0 ) ||
3937+ (PyType_Ready (& _MapValuesIter_Type ) < 0 ) ||
3938+ (PyType_Ready (& _MapItemsIter_Type ) < 0 ))
38483939 {
38493940 return 0 ;
38503941 }
0 commit comments