2222// Macros to wrap data iterators
2323%define DATA_ITERATOR_CLASSES (container_type, datum_type)
2424%feature(" python:slot" , " tp_str" , functype=" reprfunc" )
25- container_type##_iterator_base ::__str__;
25+ container_type##_iterator ::__str__;
2626%feature(" python:slot" , " tp_iter" , functype=" getiterfunc" )
27- container_type##_iterator_base ::__iter__;
27+ container_type##_iterator ::__iter__;
2828%feature(" python:slot" , " tp_iternext" , functype=" iternextfunc" )
29- container_type##_iterator_base ::__next__;
30- %noexception container_type##_iterator_base ::__iter__;
31- %noexception container_type##_iterator_base ::operator ==;
32- %noexception container_type##_iterator_base ::operator !=;
33- %ignore container_type##_iterator_base ::size;
34- %ignore container_type##_iterator_base ::##container_type##_iterator_base ;
35- %ignore container_type##_iterator_base ::operator *;
36- %ignore container_type##_iterator_base ::valid;
29+ container_type##_iterator ::__next__;
30+ %noexception container_type##_iterator ::__iter__;
31+ %noexception container_type##_iterator ::operator ==;
32+ %noexception container_type##_iterator ::operator !=;
33+ %ignore container_type##_iterator ::size;
34+ %ignore container_type##_iterator ::##container_type##_iterator ;
35+ %ignore container_type##_iterator ::operator *;
36+ %ignore container_type##_iterator ::valid;
3737%feature(" docstring" ) container_type##_iterator "
3838Python wrapper for an :class:`" #container_type " ` iterator. It has most of
3939the methods of :class:`" #datum_type " ` allowing easy access to the
4040data it points to."
41- %feature(" docstring" ) container_type##_iterator_base "
42- Python wrapper for an :class:`" #container_type " ` iterator that points to
43- the 'end' value and can not be dereferenced."
4441// Creating a new iterator keeps a reference to the current one
4542KEEP_REFERENCE (container_type##_iterator*)
46- KEEP_REFERENCE (container_type##_iterator_base*)
4743// Detect end of iteration
48- %exception container_type##_iterator_base ::__next__ %{
44+ %exception container_type##_iterator ::__next__ %{
4945 $action
5046 if (!result) {
5147 PyErr_SetNone (PyExc_StopIteration);
@@ -54,19 +50,19 @@ KEEP_REFERENCE(container_type##_iterator_base*)
5450%}
5551%inline %{
5652// Base class implements all methods except dereferencing
57- class container_type ##_iterator_base {
53+ class container_type ##_iterator {
5854protected:
5955 Exiv2::container_type::iterator ptr;
6056 Exiv2::container_type::iterator end;
6157 Exiv2::container_type::iterator safe_ptr;
6258public:
63- container_type##_iterator_base (Exiv2::container_type::iterator ptr,
64- Exiv2::container_type::iterator end) {
59+ container_type##_iterator (Exiv2::container_type::iterator ptr,
60+ Exiv2::container_type::iterator end) {
6561 this ->ptr = ptr;
6662 this ->end = end;
6763 safe_ptr = ptr;
6864 }
69- container_type##_iterator_base * __iter__ () { return this ; }
65+ container_type##_iterator * __iter__ () { return this ; }
7066 Exiv2::datum_type* __next__ () {
7167 if (!valid ())
7268 return NULL ;
@@ -77,10 +73,10 @@ public:
7773 return result;
7874 }
7975 Exiv2::container_type::iterator operator *() const { return ptr; }
80- bool operator ==(const container_type##_iterator_base &other) const {
76+ bool operator ==(const container_type##_iterator &other) const {
8177 return *other == ptr;
8278 }
83- bool operator !=(const container_type##_iterator_base &other) const {
79+ bool operator !=(const container_type##_iterator &other) const {
8480 return *other != ptr;
8581 }
8682 std::string __str__ () {
@@ -97,36 +93,40 @@ public:
9793 return safe_ptr->size ();
9894 return 0 ;
9995 }
100- };
101- // Derived class can be dereferenced, giving Python access to all datum
102- // methods.
103- class container_type ##_iterator : public container_type##_iterator_base {
104- public:
96+ // Dereference operator gives access to all datum methods
10597 Exiv2::datum_type* operator ->() const { return &(*safe_ptr); }
10698};
99+ // Bypass validity check for some methods
100+ #define NOCHECK_delete_ ##container_type##_iterator
101+ #define NOCHECK_ ##container_type##_iterator___iter__
102+ #define NOCHECK_ ##container_type##_iterator___next__
103+ #define NOCHECK_ ##container_type##_iterator___eq__
104+ #define NOCHECK_ ##container_type##_iterator___ne__
105+ #define NOCHECK_ ##container_type##_iterator___str__
106+ #define NOCHECK_ ##container_type##_iterator__invalidate
107107%}
108108%enddef // DATA_ITERATOR_CLASSES
109109
110110// Declare typemaps for data iterators.
111111%define DATA_ITERATOR_TYPEMAPS (container_type)
112112%typemap(in) Exiv2::container_type::iterator
113- (container_type##_iterator_base *argp=NULL ) %{
113+ (container_type##_iterator *argp=NULL ) %{
114114 {
115- container_type##_iterator_base * arg$argnum = NULL ;
116- $typemap (in, container_type##_iterator_base *)
115+ container_type##_iterator * arg$argnum = NULL ;
116+ $typemap (in, container_type##_iterator *)
117117 argp = arg$argnum;
118118 }
119119 $1 = **argp;
120120%}
121121#if SWIG_VERSION < 0x040400
122122// erase() invalidates the iterator
123123%typemap(in) (Exiv2::container_type::iterator pos)
124- (container_type##_iterator_base *argp=NULL ),
124+ (container_type##_iterator *argp=NULL ),
125125 (Exiv2::container_type::iterator beg)
126- (container_type##_iterator_base *argp=NULL ) {
126+ (container_type##_iterator *argp=NULL ) {
127127 {
128- container_type##_iterator_base * arg$argnum = NULL ;
129- $typemap (in, container_type##_iterator_base *)
128+ container_type##_iterator * arg$argnum = NULL ;
129+ $typemap (in, container_type##_iterator *)
130130 argp = arg$argnum;
131131 }
132132 $1 = **argp;
@@ -136,10 +136,10 @@ public:
136136// XmpData::eraseFamily takes an iterator reference (and invalidates it)
137137%typemap(in) Exiv2::container_type::iterator&
138138 (Exiv2::container_type::iterator it,
139- container_type##_iterator_base * argp = NULL ) {
139+ container_type##_iterator * argp = NULL ) {
140140 {
141- container_type##_iterator_base * arg$argnum = NULL ;
142- $typemap (in, container_type##_iterator_base *)
141+ container_type##_iterator * arg$argnum = NULL ;
142+ $typemap (in, container_type##_iterator *)
143143 argp = arg$argnum;
144144 }
145145 it = **argp;
@@ -148,12 +148,14 @@ public:
148148 argp->_invalidate ();
149149#endif
150150}
151- // Check validity of pointer before dereferencing
151+ // Check validity of iterator before dereferencing
152152%typemap(check) container_type##_iterator* self {
153- if (!$1 ->valid () && strncmp (" $symname" , " delete_" , 7 )) {
153+ %#ifndef NOCHECK_ ##$symname
154+ if (!$1 ->valid ()) {
154155 SWIG_exception_fail (SWIG_ValueError, " in method '" " $symname"
155156 " ', invalid iterator cannot be dereferenced" );
156157 }
158+ %#endif
157159}
158160
159161// Functions to store weak references to iterators (swig >= v4.4)
@@ -213,23 +215,19 @@ static int store_iterator_weakref(PyObject* py_self, PyObject* iterator) {
213215}
214216#endif // SWIG_VERSION
215217
216- // Return types depend on validity of iterator
217- %typemap(out) container_type##_iterator_base* {
218+ %typemap(out) container_type##_iterator* {
218219 $result = SWIG_NewPointerObj ((void *)$1 ,
219- $1 ->valid () ? $descriptor (container_type##_iterator*) :
220- $descriptor (container_type##_iterator_base*), 0 );
220+ $descriptor (container_type##_iterator*), 0 );
221221}
222222// Assumes arg1 is the base class parent
223223#if SWIG_VERSION >= 0x040400
224224%typemap(out, fragment=" iterator_weakref_funcs" ) Exiv2::container_type::iterator {
225225#else
226226%typemap (out) Exiv2::container_type::iterator {
227227#endif
228- container_type##_iterator_base * tmp = new container_type##_iterator_base ($1 , arg1->end ());
228+ container_type##_iterator * tmp = new container_type##_iterator ($1 , arg1->end ());
229229 $result = SWIG_NewPointerObj ((void *)tmp,
230- tmp->valid () ? $descriptor (container_type##_iterator*) :
231- $descriptor (container_type##_iterator_base*),
232- SWIG_POINTER_OWN );
230+ $descriptor (container_type##_iterator*), SWIG_POINTER_OWN );
233231#if SWIG_VERSION >= 0x040400
234232 if (tmp->valid ()) {
235233 // Keep weak reference to the Python iterator
0 commit comments