blob: ea264d6a13fa4cd23eccbf5ecddbdfdd066335a4 [file] [log] [blame]
Vince Harronb46a6ee2015-06-02 18:58:48 -07001/* -----------------------------------------------------------------------------
2 * std_list.i
3 *
4 * SWIG typemaps for std::list types
5 * ----------------------------------------------------------------------------- */
6
7%include <std_common.i>
8%include <exception.i>
9
10// containers
11
12
13// ------------------------------------------------------------------------
14// std::list
15//
16// The aim of all that follows would be to integrate std::list with
17// Perl as much as possible, namely, to allow the user to pass and
18// be returned Perl arrays.
19// const declarations are used to guess the intent of the function being
20// exported; therefore, the following rationale is applied:
21//
22// -- f(std::list<T>), f(const std::list<T>&), f(const std::list<T>*):
23// the parameter being read-only, either a Perl sequence or a
24// previously wrapped std::list<T> can be passed.
25// -- f(std::list<T>&), f(std::list<T>*):
26// the parameter must be modified; therefore, only a wrapped std::list
27// can be passed.
28// -- std::list<T> f():
29// the list is returned by copy; therefore, a Perl sequence of T:s
30// is returned which is most easily used in other Perl functions
31// -- std::list<T>& f(), std::list<T>* f(), const std::list<T>& f(),
32// const std::list<T>* f():
33// the list is returned by reference; therefore, a wrapped std::list
34// is returned
35// ------------------------------------------------------------------------
36
37%{
38#include <list>
39#include <algorithm>
40#include <stdexcept>
41%}
42
43// exported class
44
45namespace std {
46
47 template<class T> class list {
48 %typemap(in) list<T> (std::list<T>* v) {
49 if (SWIG_ConvertPtr($input,(void **) &v,
50 $&1_descriptor,1) != -1) {
51 $1 = *v;
52 } else if (SvROK($input)) {
53 AV *av = (AV *)SvRV($input);
54 if (SvTYPE(av) != SVt_PVAV)
55 SWIG_croak("Type error in argument $argnum of $symname. "
56 "Expected an array of " #T);
57 SV **tv;
58 I32 len = av_len(av) + 1;
59 T* obj;
60 for (int i=0; i<len; i++) {
61 tv = av_fetch(av, i, 0);
62 if (SWIG_ConvertPtr(*tv, (void **)&obj,
63 $descriptor(T *),0) != -1) {
64 $1.push_back(*obj);
65 } else {
66 SWIG_croak("Type error in argument $argnum of "
67 "$symname. "
68 "Expected an array of " #T);
69 }
70 }
71 } else {
72 SWIG_croak("Type error in argument $argnum of $symname. "
73 "Expected an array of " #T);
74 }
75 }
76 %typemap(in) const list<T>& (std::list<T> temp,
77 std::list<T>* v),
78 const list<T>* (std::list<T> temp,
79 std::list<T>* v) {
80 if (SWIG_ConvertPtr($input,(void **) &v,
81 $1_descriptor,1) != -1) {
82 $1 = v;
83 } else if (SvROK($input)) {
84 AV *av = (AV *)SvRV($input);
85 if (SvTYPE(av) != SVt_PVAV)
86 SWIG_croak("Type error in argument $argnum of $symname. "
87 "Expected an array of " #T);
88 SV **tv;
89 I32 len = av_len(av) + 1;
90 T* obj;
91 for (int i=0; i<len; i++) {
92 tv = av_fetch(av, i, 0);
93 if (SWIG_ConvertPtr(*tv, (void **)&obj,
94 $descriptor(T *),0) != -1) {
95 temp.push_back(*obj);
96 } else {
97 SWIG_croak("Type error in argument $argnum of "
98 "$symname. "
99 "Expected an array of " #T);
100 }
101 }
102 $1 = &temp;
103 } else {
104 SWIG_croak("Type error in argument $argnum of $symname. "
105 "Expected an array of " #T);
106 }
107 }
108 %typemap(out) list<T> {
109 std::list<T>::const_iterator i;
110 unsigned int j;
111 int len = $1.size();
112 SV **svs = new SV*[len];
113 for (i=$1.begin(), j=0; i!=$1.end(); i++, j++) {
114 T* ptr = new T(*i);
115 svs[j] = sv_newmortal();
116 SWIG_MakePtr(svs[j], (void*) ptr,
117 $descriptor(T *), $shadow|$owner);
118 }
119 AV *myav = av_make(len, svs);
120 delete[] svs;
121 $result = newRV_noinc((SV*) myav);
122 sv_2mortal($result);
123 argvi++;
124 }
125 %typecheck(SWIG_TYPECHECK_LIST) list<T> {
126 {
127 /* wrapped list? */
128 std::list<T >* v;
129 if (SWIG_ConvertPtr($input,(void **) &v,
130 $1_&descriptor,0) != -1) {
131 $1 = 1;
132 } else if (SvROK($input)) {
133 /* native sequence? */
134 AV *av = (AV *)SvRV($input);
135 if (SvTYPE(av) == SVt_PVAV) {
136 SV **tv;
137 I32 len = av_len(av) + 1;
138 if (len == 0) {
139 /* an empty sequence can be of any type */
140 $1 = 1;
141 } else {
142 /* check the first element only */
143 T* obj;
144 tv = av_fetch(av, 0, 0);
145 if (SWIG_ConvertPtr(*tv, (void **)&obj,
146 $descriptor(T *),0) != -1)
147 $1 = 1;
148 else
149 $1 = 0;
150 }
151 }
152 } else {
153 $1 = 0;
154 }
155 }
156 }
157 %typecheck(SWIG_TYPECHECK_LIST) const list<T>&,
158 const list<T>* {
159 {
160 /* wrapped list? */
161 std::list<T >* v;
162 if (SWIG_ConvertPtr($input,(void **) &v,
163 $1_descriptor,0) != -1) {
164 $1 = 1;
165 } else if (SvROK($input)) {
166 /* native sequence? */
167 AV *av = (AV *)SvRV($input);
168 if (SvTYPE(av) == SVt_PVAV) {
169 SV **tv;
170 I32 len = av_len(av) + 1;
171 if (len == 0) {
172 /* an empty sequence can be of any type */
173 $1 = 1;
174 } else {
175 /* check the first element only */
176 T* obj;
177 tv = av_fetch(av, 0, 0);
178 if (SWIG_ConvertPtr(*tv, (void **)&obj,
179 $descriptor(T *),0) != -1)
180 $1 = 1;
181 else
182 $1 = 0;
183 }
184 }
185 } else {
186 $1 = 0;
187 }
188 }
189 }
190 public:
191 typedef size_t size_type;
192 typedef T value_type;
193 typedef const value_type& const_reference;
194
195 list();
196 list(const list<T> &);
197
198 unsigned int size() const;
199 bool empty() const;
200 void clear();
201 %rename(push) push_back;
202 void push_back(const T& x);
203 };
204
205
206 // specializations for built-ins
207
208 %define specialize_std_list(T,CHECK_T,TO_T,FROM_T)
209 template<> class list<T> {
210 %typemap(in) list<T> (std::list<T>* v) {
211 if (SWIG_ConvertPtr($input,(void **) &v,
212 $&1_descriptor,1) != -1){
213 $1 = *v;
214 } else if (SvROK($input)) {
215 AV *av = (AV *)SvRV($input);
216 if (SvTYPE(av) != SVt_PVAV)
217 SWIG_croak("Type error in argument $argnum of $symname. "
218 "Expected an array of " #T);
219 SV **tv;
220 I32 len = av_len(av) + 1;
221 for (int i=0; i<len; i++) {
222 tv = av_fetch(av, i, 0);
223 if (CHECK_T(*tv)) {
224 $1.push_back(TO_T(*tv));
225 } else {
226 SWIG_croak("Type error in argument $argnum of "
227 "$symname. "
228 "Expected an array of " #T);
229 }
230 }
231 } else {
232 SWIG_croak("Type error in argument $argnum of $symname. "
233 "Expected an array of " #T);
234 }
235 }
236 %typemap(in) const list<T>& (std::list<T> temp,
237 std::list<T>* v),
238 const list<T>* (std::list<T> temp,
239 std::list<T>* v) {
240 if (SWIG_ConvertPtr($input,(void **) &v,
241 $1_descriptor,1) != -1) {
242 $1 = v;
243 } else if (SvROK($input)) {
244 AV *av = (AV *)SvRV($input);
245 if (SvTYPE(av) != SVt_PVAV)
246 SWIG_croak("Type error in argument $argnum of $symname. "
247 "Expected an array of " #T);
248 SV **tv;
249 I32 len = av_len(av) + 1;
250 T* obj;
251 for (int i=0; i<len; i++) {
252 tv = av_fetch(av, i, 0);
253 if (CHECK_T(*tv)) {
254 temp.push_back(TO_T(*tv));
255 } else {
256 SWIG_croak("Type error in argument $argnum of "
257 "$symname. "
258 "Expected an array of " #T);
259 }
260 }
261 $1 = &temp;
262 } else {
263 SWIG_croak("Type error in argument $argnum of $symname. "
264 "Expected an array of " #T);
265 }
266 }
267 %typemap(out) list<T> {
268 std::list<T>::const_iterator i;
269 unsigned int j;
270 int len = $1.size();
271 SV **svs = new SV*[len];
272 for (i=$1.begin(), j=0; i!=$1.end(); i++, j++) {
273 svs[j] = sv_newmortal();
274 FROM_T(svs[j], *i);
275 }
276 AV *myav = av_make(len, svs);
277 delete[] svs;
278 $result = newRV_noinc((SV*) myav);
279 sv_2mortal($result);
280 argvi++;
281 }
282 %typecheck(SWIG_TYPECHECK_LIST) list<T> {
283 {
284 /* wrapped list? */
285 std::list<T >* v;
286 if (SWIG_ConvertPtr($input,(void **) &v,
287 $1_&descriptor,0) != -1) {
288 $1 = 1;
289 } else if (SvROK($input)) {
290 /* native sequence? */
291 AV *av = (AV *)SvRV($input);
292 if (SvTYPE(av) == SVt_PVAV) {
293 SV **tv;
294 I32 len = av_len(av) + 1;
295 if (len == 0) {
296 /* an empty sequence can be of any type */
297 $1 = 1;
298 } else {
299 /* check the first element only */
300 tv = av_fetch(av, 0, 0);
301 if (CHECK_T(*tv))
302 $1 = 1;
303 else
304 $1 = 0;
305 }
306 }
307 } else {
308 $1 = 0;
309 }
310 }
311 }
312 %typecheck(SWIG_TYPECHECK_LIST) const list<T>&,
313 const list<T>* {
314 {
315 /* wrapped list? */
316 std::list<T >* v;
317 if (SWIG_ConvertPtr($input,(void **) &v,
318 $1_descriptor,0) != -1) {
319 $1 = 1;
320 } else if (SvROK($input)) {
321 /* native sequence? */
322 AV *av = (AV *)SvRV($input);
323 if (SvTYPE(av) == SVt_PVAV) {
324 SV **tv;
325 I32 len = av_len(av) + 1;
326 if (len == 0) {
327 /* an empty sequence can be of any type */
328 $1 = 1;
329 } else {
330 /* check the first element only */
331 tv = av_fetch(av, 0, 0);
332 if (CHECK_T(*tv))
333 $1 = 1;
334 else
335 $1 = 0;
336 }
337 }
338 } else {
339 $1 = 0;
340 }
341 }
342 }
343 public:
344 typedef size_t size_type;
345 typedef T value_type;
346 typedef const value_type& const_reference;
347
348 list();
349 list(const list<T> &);
350
351 unsigned int size() const;
352 bool empty() const;
353 void clear();
354 %rename(push) push_back;
355 void push_back(T x);
356 };
357 %enddef
358
359 specialize_std_list(bool,SvIOK,SvIVX,sv_setiv);
360 specialize_std_list(char,SvIOK,SvIVX,sv_setiv);
361 specialize_std_list(int,SvIOK,SvIVX,sv_setiv);
362 specialize_std_list(short,SvIOK,SvIVX,sv_setiv);
363 specialize_std_list(long,SvIOK,SvIVX,sv_setiv);
364 specialize_std_list(unsigned char,SvIOK,SvIVX,sv_setiv);
365 specialize_std_list(unsigned int,SvIOK,SvIVX,sv_setiv);
366 specialize_std_list(unsigned short,SvIOK,SvIVX,sv_setiv);
367 specialize_std_list(unsigned long,SvIOK,SvIVX,sv_setiv);
368 specialize_std_list(float,SvNIOK,SwigSvToNumber,sv_setnv);
369 specialize_std_list(double,SvNIOK,SwigSvToNumber,sv_setnv);
370 specialize_std_list(std::string,SvPOK,SvPVX,SwigSvFromString);
371
372}
373