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