/trunk/Lib/perl5/std_list.i
Swig | 365 lines | 328 code | 16 blank | 21 comment | 0 complexity | 975d25628fa9aa42355e83a6de59cd69 MD5 | raw file
1/* ----------------------------------------------------------------------------- 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 list(); 192 list(const list<T> &); 193 194 unsigned int size() const; 195 bool empty() const; 196 void clear(); 197 %rename(push) push_back; 198 void push_back(const T& x); 199 }; 200 201 202 // specializations for built-ins 203 204 %define specialize_std_list(T,CHECK_T,TO_T,FROM_T) 205 template<> class list<T> { 206 %typemap(in) list<T> (std::list<T>* v) { 207 if (SWIG_ConvertPtr($input,(void **) &v, 208 $&1_descriptor,1) != -1){ 209 $1 = *v; 210 } else if (SvROK($input)) { 211 AV *av = (AV *)SvRV($input); 212 if (SvTYPE(av) != SVt_PVAV) 213 SWIG_croak("Type error in argument $argnum of $symname. " 214 "Expected an array of " #T); 215 SV **tv; 216 I32 len = av_len(av) + 1; 217 for (int i=0; i<len; i++) { 218 tv = av_fetch(av, i, 0); 219 if (CHECK_T(*tv)) { 220 $1.push_back(TO_T(*tv)); 221 } else { 222 SWIG_croak("Type error in argument $argnum of " 223 "$symname. " 224 "Expected an array of " #T); 225 } 226 } 227 } else { 228 SWIG_croak("Type error in argument $argnum of $symname. " 229 "Expected an array of " #T); 230 } 231 } 232 %typemap(in) const list<T>& (std::list<T> temp, 233 std::list<T>* v), 234 const list<T>* (std::list<T> temp, 235 std::list<T>* v) { 236 if (SWIG_ConvertPtr($input,(void **) &v, 237 $1_descriptor,1) != -1) { 238 $1 = v; 239 } else if (SvROK($input)) { 240 AV *av = (AV *)SvRV($input); 241 if (SvTYPE(av) != SVt_PVAV) 242 SWIG_croak("Type error in argument $argnum of $symname. " 243 "Expected an array of " #T); 244 SV **tv; 245 I32 len = av_len(av) + 1; 246 T* obj; 247 for (int i=0; i<len; i++) { 248 tv = av_fetch(av, i, 0); 249 if (CHECK_T(*tv)) { 250 temp.push_back(TO_T(*tv)); 251 } else { 252 SWIG_croak("Type error in argument $argnum of " 253 "$symname. " 254 "Expected an array of " #T); 255 } 256 } 257 $1 = &temp; 258 } else { 259 SWIG_croak("Type error in argument $argnum of $symname. " 260 "Expected an array of " #T); 261 } 262 } 263 %typemap(out) list<T> { 264 std::list<T>::const_iterator i; 265 unsigned int j; 266 int len = $1.size(); 267 SV **svs = new SV*[len]; 268 for (i=$1.begin(), j=0; i!=$1.end(); i++, j++) { 269 svs[j] = sv_newmortal(); 270 FROM_T(svs[j], *i); 271 } 272 AV *myav = av_make(len, svs); 273 delete[] svs; 274 $result = newRV_noinc((SV*) myav); 275 sv_2mortal($result); 276 argvi++; 277 } 278 %typecheck(SWIG_TYPECHECK_LIST) list<T> { 279 { 280 /* wrapped list? */ 281 std::list<T >* v; 282 if (SWIG_ConvertPtr($input,(void **) &v, 283 $1_&descriptor,0) != -1) { 284 $1 = 1; 285 } else if (SvROK($input)) { 286 /* native sequence? */ 287 AV *av = (AV *)SvRV($input); 288 if (SvTYPE(av) == SVt_PVAV) { 289 SV **tv; 290 I32 len = av_len(av) + 1; 291 if (len == 0) { 292 /* an empty sequence can be of any type */ 293 $1 = 1; 294 } else { 295 /* check the first element only */ 296 tv = av_fetch(av, 0, 0); 297 if (CHECK_T(*tv)) 298 $1 = 1; 299 else 300 $1 = 0; 301 } 302 } 303 } else { 304 $1 = 0; 305 } 306 } 307 } 308 %typecheck(SWIG_TYPECHECK_LIST) const list<T>&, 309 const list<T>* { 310 { 311 /* wrapped list? */ 312 std::list<T >* v; 313 if (SWIG_ConvertPtr($input,(void **) &v, 314 $1_descriptor,0) != -1) { 315 $1 = 1; 316 } else if (SvROK($input)) { 317 /* native sequence? */ 318 AV *av = (AV *)SvRV($input); 319 if (SvTYPE(av) == SVt_PVAV) { 320 SV **tv; 321 I32 len = av_len(av) + 1; 322 if (len == 0) { 323 /* an empty sequence can be of any type */ 324 $1 = 1; 325 } else { 326 /* check the first element only */ 327 tv = av_fetch(av, 0, 0); 328 if (CHECK_T(*tv)) 329 $1 = 1; 330 else 331 $1 = 0; 332 } 333 } 334 } else { 335 $1 = 0; 336 } 337 } 338 } 339 public: 340 list(); 341 list(const list<T> &); 342 343 unsigned int size() const; 344 bool empty() const; 345 void clear(); 346 %rename(push) push_back; 347 void push_back(T x); 348 }; 349 %enddef 350 351 specialize_std_list(bool,SvIOK,SvIVX,sv_setiv); 352 specialize_std_list(char,SvIOK,SvIVX,sv_setiv); 353 specialize_std_list(int,SvIOK,SvIVX,sv_setiv); 354 specialize_std_list(short,SvIOK,SvIVX,sv_setiv); 355 specialize_std_list(long,SvIOK,SvIVX,sv_setiv); 356 specialize_std_list(unsigned char,SvIOK,SvIVX,sv_setiv); 357 specialize_std_list(unsigned int,SvIOK,SvIVX,sv_setiv); 358 specialize_std_list(unsigned short,SvIOK,SvIVX,sv_setiv); 359 specialize_std_list(unsigned long,SvIOK,SvIVX,sv_setiv); 360 specialize_std_list(float,SvNIOK,SwigSvToNumber,sv_setnv); 361 specialize_std_list(double,SvNIOK,SwigSvToNumber,sv_setnv); 362 specialize_std_list(std::string,SvPOK,SvPVX,SwigSvFromString); 363 364} 365