Skip to content

Commit d8e1333

Browse files
Removed unneeded iterator base class
Now the iterator is checked for validity there's no need for a separate class for ones believed to be valid.
1 parent 9ceb5cd commit d8e1333

14 files changed

Lines changed: 2052 additions & 4102 deletions

File tree

src/interface/shared/data_iterator.i

Lines changed: 44 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -22,30 +22,26 @@
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 "
3838
Python wrapper for an :class:`" #container_type "` iterator. It has most of
3939
the methods of :class:`" #datum_type "` allowing easy access to the
4040
data 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
4542
KEEP_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 {
5854
protected:
5955
Exiv2::container_type::iterator ptr;
6056
Exiv2::container_type::iterator end;
6157
Exiv2::container_type::iterator safe_ptr;
6258
public:
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

Comments
 (0)