1 /* -----------------------------------------------------------------------------
2 * See the LICENSE file for information on copyright, usage and redistribution
3 * of SWIG, and the README file for authors - http://www.swig.org/release.html.
7 * SWIG typemaps for std::vector types
8 * ----------------------------------------------------------------------------- */
10 %include <std_common.i>
12 // ------------------------------------------------------------------------
15 // The aim of all that follows would be to integrate std::vector with
16 // Perl as much as possible, namely, to allow the user to pass and
17 // be returned Perl arrays.
18 // const declarations are used to guess the intent of the function being
19 // exported; therefore, the following rationale is applied:
21 // -- f(std::vector<T>), f(const std::vector<T>&), f(const std::vector<T>*):
22 // the parameter being read-only, either a Perl sequence or a
23 // previously wrapped std::vector<T> can be passed.
24 // -- f(std::vector<T>&), f(std::vector<T>*):
25 // the parameter must be modified; therefore, only a wrapped std::vector
27 // -- std::vector<T> f():
28 // the vector is returned by copy; therefore, a Perl sequence of T:s
29 // is returned which is most easily used in other Perl functions
30 // -- std::vector<T>& f(), std::vector<T>* f(), const std::vector<T>& f(),
31 // const std::vector<T>* f():
32 // the vector is returned by reference; therefore, a wrapped std::vector
34 // ------------------------------------------------------------------------
46 template<class T> class vector {
47 %typemap(in) vector<T> (std::vector<T>* v) {
48 if (SWIG_ConvertPtr($input,(void **) &v,
49 $&1_descriptor,1) != -1) {
51 } else if (SvROK($input)) {
52 AV *av = (AV *)SvRV($input);
53 if (SvTYPE(av) != SVt_PVAV)
54 SWIG_croak("Type error in argument $argnum of $symname. "
55 "Expected an array of " #T);
57 I32 len = av_len(av) + 1;
59 for (int i=0; i<len; i++) {
60 tv = av_fetch(av, i, 0);
61 if (SWIG_ConvertPtr(*tv, (void **)&obj,
62 $descriptor(T *),0) != -1) {
65 SWIG_croak("Type error in argument $argnum of "
67 "Expected an array of " #T);
71 SWIG_croak("Type error in argument $argnum of $symname. "
72 "Expected an array of " #T);
75 %typemap(in) const vector<T>& (std::vector<T> temp,
77 const vector<T>* (std::vector<T> temp,
79 if (SWIG_ConvertPtr($input,(void **) &v,
80 $1_descriptor,1) != -1) {
82 } else if (SvROK($input)) {
83 AV *av = (AV *)SvRV($input);
84 if (SvTYPE(av) != SVt_PVAV)
85 SWIG_croak("Type error in argument $argnum of $symname. "
86 "Expected an array of " #T);
88 I32 len = av_len(av) + 1;
90 for (int i=0; i<len; i++) {
91 tv = av_fetch(av, i, 0);
92 if (SWIG_ConvertPtr(*tv, (void **)&obj,
93 $descriptor(T *),0) != -1) {
96 SWIG_croak("Type error in argument $argnum of "
98 "Expected an array of " #T);
103 SWIG_croak("Type error in argument $argnum of $symname. "
104 "Expected an array of " #T);
107 %typemap(out) vector<T> {
108 size_t len = $1.size();
109 SV **svs = new SV*[len];
110 for (size_t i=0; i<len; i++) {
111 T* ptr = new T($1[i]);
112 svs[i] = sv_newmortal();
113 SWIG_MakePtr(svs[i], (void*) ptr,
114 $descriptor(T *), $shadow|$owner);
116 AV *myav = av_make(len, svs);
118 $result = newRV_noinc((SV*) myav);
122 %typecheck(SWIG_TYPECHECK_VECTOR) vector<T> {
124 /* wrapped vector? */
126 if (SWIG_ConvertPtr($input,(void **) &v,
127 $&1_descriptor,0) != -1) {
129 } else if (SvROK($input)) {
130 /* native sequence? */
131 AV *av = (AV *)SvRV($input);
132 if (SvTYPE(av) == SVt_PVAV) {
133 I32 len = av_len(av) + 1;
135 /* an empty sequence can be of any type */
138 /* check the first element only */
140 SV **tv = av_fetch(av, 0, 0);
141 if (SWIG_ConvertPtr(*tv, (void **)&obj,
142 $descriptor(T *),0) != -1)
153 %typecheck(SWIG_TYPECHECK_VECTOR) const vector<T>&,
156 /* wrapped vector? */
158 if (SWIG_ConvertPtr($input,(void **) &v,
159 $1_descriptor,0) != -1) {
161 } else if (SvROK($input)) {
162 /* native sequence? */
163 AV *av = (AV *)SvRV($input);
164 if (SvTYPE(av) == SVt_PVAV) {
165 I32 len = av_len(av) + 1;
167 /* an empty sequence can be of any type */
170 /* check the first element only */
172 SV **tv = av_fetch(av, 0, 0);
173 if (SWIG_ConvertPtr(*tv, (void **)&obj,
174 $descriptor(T *),0) != -1)
186 vector(unsigned int size = 0);
187 vector(unsigned int size, const T& value);
188 vector(const vector<T> &);
190 unsigned int size() const;
193 %rename(push) push_back;
194 void push_back(const T& x);
196 T pop() throw (std::out_of_range) {
197 if (self->size() == 0)
198 throw std::out_of_range("pop from empty vector");
203 T& get(int i) throw (std::out_of_range) {
204 int size = int(self->size());
208 throw std::out_of_range("vector index out of range");
210 void set(int i, const T& x) throw (std::out_of_range) {
211 int size = int(self->size());
215 throw std::out_of_range("vector index out of range");
220 // specializations for pointers
221 template<class T> class vector<T*> {
222 %typemap(in) vector<T*> (std::vector<T*>* v) {
223 int res = SWIG_ConvertPtr($input,(void **) &v, $&1_descriptor,0);
226 } else if (SvROK($input)) {
227 AV *av = (AV *)SvRV($input);
228 if (SvTYPE(av) != SVt_PVAV)
229 SWIG_croak("Type error in argument $argnum of $symname. "
230 "Expected an array of " #T);
231 I32 len = av_len(av) + 1;
232 for (int i=0; i<len; i++) {
234 SV **tv = av_fetch(av, i, 0);
235 int res = SWIG_ConvertPtr(*tv, &v, $descriptor(T *),0);
236 if (SWIG_IsOK(res)) {
237 $1.push_back(%static_cast(v, T *));
239 SWIG_croak("Type error in argument $argnum of "
241 "Expected an array of " #T);
245 SWIG_croak("Type error in argument $argnum of $symname. "
246 "Expected an array of " #T);
249 %typemap(in) const vector<T *>& (std::vector<T *> temp,std::vector<T *>* v),
250 const vector<T *>* (std::vector<T *> temp,std::vector<T *>* v) {
251 int res = SWIG_ConvertPtr($input,(void **) &v, $1_descriptor,0);
252 if (SWIG_IsOK(res)) {
254 } else if (SvROK($input)) {
255 AV *av = (AV *)SvRV($input);
256 if (SvTYPE(av) != SVt_PVAV)
257 SWIG_croak("Type error in argument $argnum of $symname. "
258 "Expected an array of " #T);
259 I32 len = av_len(av) + 1;
260 for (int i=0; i<len; i++) {
262 SV **tv = av_fetch(av, i, 0);
263 int res = SWIG_ConvertPtr(*tv, &v, $descriptor(T *),0);
264 if (SWIG_IsOK(res)) {
265 temp.push_back(%static_cast(v, T *));
267 SWIG_croak("Type error in argument $argnum of "
269 "Expected an array of " #T);
274 SWIG_croak("Type error in argument $argnum of $symname. "
275 "Expected an array of " #T);
278 %typemap(out) vector<T *> {
279 size_t len = $1.size();
280 SV **svs = new SV*[len];
281 for (size_t i=0; i<len; i++) {
282 T *x = (($1_type &)$1)[i];
283 svs[i] = sv_newmortal();
284 sv_setsv(svs[i], SWIG_NewPointerObj(x, $descriptor(T *), 0));
286 AV *myav = av_make(len, svs);
288 $result = newRV_noinc((SV*) myav);
292 %typecheck(SWIG_TYPECHECK_VECTOR) vector<T *> {
294 /* wrapped vector? */
296 int res = SWIG_ConvertPtr($input,(void **) &v, $&1_descriptor,0);
297 if (SWIG_IsOK(res)) {
299 } else if (SvROK($input)) {
300 /* native sequence? */
301 AV *av = (AV *)SvRV($input);
302 if (SvTYPE(av) == SVt_PVAV) {
303 I32 len = av_len(av) + 1;
305 /* an empty sequence can be of any type */
308 /* check the first element only */
310 SV **tv = av_fetch(av, 0, 0);
311 int res = SWIG_ConvertPtr(*tv, &v, $descriptor(T *),0);
323 %typecheck(SWIG_TYPECHECK_VECTOR) const vector<T *>&,const vector<T *>* {
325 /* wrapped vector? */
327 int res = SWIG_ConvertPtr($input,%as_voidptrptr(&v), $1_descriptor,0);
328 if (SWIG_IsOK(res)) {
330 } else if (SvROK($input)) {
331 /* native sequence? */
332 AV *av = (AV *)SvRV($input);
333 if (SvTYPE(av) == SVt_PVAV) {
334 I32 len = av_len(av) + 1;
336 /* an empty sequence can be of any type */
339 /* check the first element only */
341 SV **tv = av_fetch(av, 0, 0);
342 int res = SWIG_ConvertPtr(*tv, &v, $descriptor(T *),0);
355 vector(unsigned int size = 0);
356 vector(unsigned int size, T *value);
357 vector(const vector<T *> &);
359 unsigned int size() const;
362 %rename(push) push_back;
363 void push_back(T *x);
365 T *pop() throw (std::out_of_range) {
366 if (self->size() == 0)
367 throw std::out_of_range("pop from empty vector");
372 T *get(int i) throw (std::out_of_range) {
373 int size = int(self->size());
377 throw std::out_of_range("vector index out of range");
379 void set(int i, T *x) throw (std::out_of_range) {
380 int size = int(self->size());
384 throw std::out_of_range("vector index out of range");
390 // specializations for built-ins
392 %define specialize_std_vector(T,CHECK_T,TO_T,FROM_T)
393 template<> class vector<T> {
394 %typemap(in) vector<T> (std::vector<T>* v) {
395 if (SWIG_ConvertPtr($input,(void **) &v,
396 $&1_descriptor,1) != -1){
398 } else if (SvROK($input)) {
399 AV *av = (AV *)SvRV($input);
400 if (SvTYPE(av) != SVt_PVAV)
401 SWIG_croak("Type error in argument $argnum of $symname. "
402 "Expected an array of " #T);
404 I32 len = av_len(av) + 1;
405 for (int i=0; i<len; i++) {
406 tv = av_fetch(av, i, 0);
408 $1.push_back((T)TO_T(*tv));
410 SWIG_croak("Type error in argument $argnum of "
412 "Expected an array of " #T);
416 SWIG_croak("Type error in argument $argnum of $symname. "
417 "Expected an array of " #T);
420 %typemap(in) const vector<T>& (std::vector<T> temp,
422 const vector<T>* (std::vector<T> temp,
424 if (SWIG_ConvertPtr($input,(void **) &v,
425 $1_descriptor,1) != -1) {
427 } else if (SvROK($input)) {
428 AV *av = (AV *)SvRV($input);
429 if (SvTYPE(av) != SVt_PVAV)
430 SWIG_croak("Type error in argument $argnum of $symname. "
431 "Expected an array of " #T);
433 I32 len = av_len(av) + 1;
434 for (int i=0; i<len; i++) {
435 tv = av_fetch(av, i, 0);
437 temp.push_back((T)TO_T(*tv));
439 SWIG_croak("Type error in argument $argnum of "
441 "Expected an array of " #T);
446 SWIG_croak("Type error in argument $argnum of $symname. "
447 "Expected an array of " #T);
450 %typemap(out) vector<T> {
451 size_t len = $1.size();
452 SV **svs = new SV*[len];
453 for (size_t i=0; i<len; i++) {
454 svs[i] = sv_newmortal();
455 FROM_T(svs[i], $1[i]);
457 AV *myav = av_make(len, svs);
459 $result = newRV_noinc((SV*) myav);
463 %typecheck(SWIG_TYPECHECK_VECTOR) vector<T> {
465 /* wrapped vector? */
467 if (SWIG_ConvertPtr($input,(void **) &v,
468 $&1_descriptor,0) != -1) {
470 } else if (SvROK($input)) {
471 /* native sequence? */
472 AV *av = (AV *)SvRV($input);
473 if (SvTYPE(av) == SVt_PVAV) {
474 I32 len = av_len(av) + 1;
476 /* an empty sequence can be of any type */
479 /* check the first element only */
480 SV **tv = av_fetch(av, 0, 0);
492 %typecheck(SWIG_TYPECHECK_VECTOR) const vector<T>&,
495 /* wrapped vector? */
497 if (SWIG_ConvertPtr($input,(void **) &v,
498 $1_descriptor,0) != -1) {
500 } else if (SvROK($input)) {
501 /* native sequence? */
502 AV *av = (AV *)SvRV($input);
503 if (SvTYPE(av) == SVt_PVAV) {
504 I32 len = av_len(av) + 1;
506 /* an empty sequence can be of any type */
509 /* check the first element only */
510 SV **tv = av_fetch(av, 0, 0);
523 vector(unsigned int size = 0);
524 vector(unsigned int size, T value);
525 vector(const vector<T> &);
527 unsigned int size() const;
530 %rename(push) push_back;
533 T pop() throw (std::out_of_range) {
534 if (self->size() == 0)
535 throw std::out_of_range("pop from empty vector");
540 T get(int i) throw (std::out_of_range) {
541 int size = int(self->size());
545 throw std::out_of_range("vector index out of range");
547 void set(int i, T x) throw (std::out_of_range) {
548 int size = int(self->size());
552 throw std::out_of_range("vector index out of range");
558 specialize_std_vector(bool,SvIOK,SvIVX,sv_setiv);
559 specialize_std_vector(char,SvIOK,SvIVX,sv_setiv);
560 specialize_std_vector(int,SvIOK,SvIVX,sv_setiv);
561 specialize_std_vector(short,SvIOK,SvIVX,sv_setiv);
562 specialize_std_vector(long,SvIOK,SvIVX,sv_setiv);
563 specialize_std_vector(unsigned char,SvIOK,SvIVX,sv_setiv);
564 specialize_std_vector(unsigned int,SvIOK,SvIVX,sv_setiv);
565 specialize_std_vector(unsigned short,SvIOK,SvIVX,sv_setiv);
566 specialize_std_vector(unsigned long,SvIOK,SvIVX,sv_setiv);
567 specialize_std_vector(float,SvNIOK,SwigSvToNumber,sv_setnv);
568 specialize_std_vector(double,SvNIOK,SwigSvToNumber,sv_setnv);
569 specialize_std_vector(std::string,SvPOK,SwigSvToString,SwigSvFromString);