1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
|
// Macro to construct iterable objects.
%define sb_iterator(TYPE, PREFIX, VALUE_TYPE)
#if !SWIGRUBY
#if SWIGJAVA
%typemap(javainterfaces) TYPE##Iterator "java.util.Iterator<"#VALUE_TYPE">"
%typemap(javacode) TYPE##Iterator %{
@Override
public void remove() {
throw new UnsupportedOperationException();
}
%}
#endif
// Basic types
%inline %{
typedef struct {
PREFIX##_t *ptr;
} TYPE##Iterator;
%}
// Exception to end iteration
#if SWIGJAVA
%exception TYPE##Iterator##::next() {
if (!arg1->ptr) {
jclass cls = (*jenv)->FindClass(jenv, "java/util/NoSuchElementException");
(*jenv)->ThrowNew(jenv, cls, NULL);
return $null;
}
$action;
}
#elif SWIGPYTHON
%exception TYPE##Iterator##::next() {
if (!arg1->ptr) {
SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void());
SWIG_fail;
}
$action;
}
%exception TYPE##Iterator##::__next__() {
if (!arg1->ptr) {
SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void());
SWIG_fail;
}
$action;
}
#endif
// Implementation of the iterator itself
%extend TYPE##Iterator {
TYPE##Iterator(PREFIX##_t *ptr) {
TYPE##Iterator *iter = (TYPE##Iterator *)ckd_malloc(sizeof *iter);
iter->ptr = ptr;
return iter;
}
~TYPE##Iterator() {
if ($self->ptr)
PREFIX##_free($self->ptr);
ckd_free($self);
}
#if SWIGJAVA
%newobject next;
VALUE_TYPE * next() {
if ($self->ptr) {
VALUE_TYPE *value = ##VALUE_TYPE##_fromIter($self->ptr);
$self->ptr = ##PREFIX##_next($self->ptr);
return value;
}
return NULL;
}
bool hasNext() {
return $self->ptr != NULL;
}
#elif SWIGJAVASCRIPT
%newobject next;
VALUE_TYPE * next() {
if ($self->ptr) {
VALUE_TYPE *value = ##VALUE_TYPE##_fromIter($self->ptr);
$self->ptr = ##PREFIX##_next($self->ptr);
return value;
}
return NULL;
}
#elif SWIGPYTHON
// Python2
%newobject next;
VALUE_TYPE * next() {
if ($self->ptr) {
VALUE_TYPE *value = ##VALUE_TYPE##_fromIter($self->ptr);
$self->ptr = ##PREFIX##_next($self->ptr);
return value;
}
return NULL;
}
// Python3
%newobject __next__;
VALUE_TYPE * __next__() {
if ($self->ptr) {
VALUE_TYPE *value = ##VALUE_TYPE##_fromIter($self->ptr);
$self->ptr = ##PREFIX##_next($self->ptr);
return value;
}
return NULL;
}
#endif
}
#endif // SWIGRUBY
%enddef
%define sb_iterable(TYPE, ITER_TYPE, PREFIX, INIT_PREFIX, VALUE_TYPE)
// Methods to retrieve the iterator from the container
#if SWIGJAVA
%typemap(javainterfaces) TYPE "Iterable<"#VALUE_TYPE">"
#endif
%extend TYPE {
#if SWIGRUBY
void each() {
##PREFIX##_t *iter = INIT_PREFIX##($self);
while (iter) {
VALUE_TYPE *value = ##VALUE_TYPE##_fromIter(iter);
rb_yield(SWIG_NewPointerObj(SWIG_as_voidptr(value), SWIGTYPE_p_##VALUE_TYPE##, 0 | 0 ));
iter = PREFIX##_next(iter);
}
return;
}
void each(int count) {
##PREFIX##_t *iter = INIT_PREFIX##($self);
int cnt = 0;
while (iter && cnt < count) {
VALUE_TYPE *value = ##VALUE_TYPE##_fromIter(iter);
rb_yield(SWIG_NewPointerObj(SWIG_as_voidptr(value), SWIGTYPE_p_##VALUE_TYPE##, 0 | 0 ));
iter = PREFIX##_next(iter);
cnt++;
}
if (iter)
PREFIX##_free(iter);
return;
}
#elif SWIGJAVA
%newobject iterator;
ITER_TYPE##Iterator * iterator() {
return new_##ITER_TYPE##Iterator(INIT_PREFIX##($self));
}
#else /* PYTHON, JS */
%newobject __iter__;
ITER_TYPE##Iterator * __iter__() {
return new_##ITER_TYPE##Iterator(INIT_PREFIX##($self));
}
#endif
}
%enddef
|