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