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_vector.i 6 * 7 * SWIG typemaps for std::vector 8 * ----------------------------------------------------------------------------- */ 9 10%include <std_common.i> 11 12// ------------------------------------------------------------------------ 13// std::vector 14// 15// The aim of all that follows would be to integrate std::vector with 16// MzScheme as much as possible, namely, to allow the user to pass and 17// be returned MzScheme vectors or lists. 18// const declarations are used to guess the intent of the function being 19// exported; therefore, the following rationale is applied: 20// 21// -- f(std::vector<T>), f(const std::vector<T>&), f(const std::vector<T>*): 22// the parameter being read-only, either a MzScheme 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 26// can be passed. 27// -- std::vector<T> f(): 28// the vector is returned by copy; therefore, a MzScheme vector of T:s 29// is returned which is most easily used in other MzScheme 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 33// is returned 34// ------------------------------------------------------------------------ 35 36%{ 37#include <vector> 38#include <algorithm> 39#include <stdexcept> 40%} 41 42// exported class 43 44namespace std { 45 46 template<class T> class vector { 47 %typemap(in) vector<T> { 48 if (SCHEME_VECTORP($input)) { 49 unsigned int size = SCHEME_VEC_SIZE($input); 50 $1 = std::vector<T >(size); 51 Scheme_Object** items = SCHEME_VEC_ELS($input); 52 for (unsigned int i=0; i<size; i++) { 53 (($1_type &)$1)[i] = 54 *((T*) SWIG_MustGetPtr(items[i], 55 $descriptor(T *), 56 $argnum, 0)); 57 } 58 } else if (SCHEME_NULLP($input)) { 59 $1 = std::vector<T >(); 60 } else if (SCHEME_PAIRP($input)) { 61 Scheme_Object *head, *tail; 62 $1 = std::vector<T >(); 63 tail = $input; 64 while (!SCHEME_NULLP(tail)) { 65 head = scheme_car(tail); 66 tail = scheme_cdr(tail); 67 $1.push_back(*((T*)SWIG_MustGetPtr(head, 68 $descriptor(T *), 69 $argnum, 0))); 70 } 71 } else { 72 $1 = *(($&1_type) 73 SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0)); 74 } 75 } 76 %typemap(in) const vector<T>& (std::vector<T> temp), 77 const vector<T>* (std::vector<T> temp) { 78 if (SCHEME_VECTORP($input)) { 79 unsigned int size = SCHEME_VEC_SIZE($input); 80 temp = std::vector<T >(size); 81 $1 = &temp; 82 Scheme_Object** items = SCHEME_VEC_ELS($input); 83 for (unsigned int i=0; i<size; i++) { 84 temp[i] = *((T*) SWIG_MustGetPtr(items[i], 85 $descriptor(T *), 86 $argnum, 0)); 87 } 88 } else if (SCHEME_NULLP($input)) { 89 temp = std::vector<T >(); 90 $1 = &temp; 91 } else if (SCHEME_PAIRP($input)) { 92 temp = std::vector<T >(); 93 $1 = &temp; 94 Scheme_Object *head, *tail; 95 tail = $input; 96 while (!SCHEME_NULLP(tail)) { 97 head = scheme_car(tail); 98 tail = scheme_cdr(tail); 99 temp.push_back(*((T*) SWIG_MustGetPtr(head, 100 $descriptor(T *), 101 $argnum, 0))); 102 } 103 } else { 104 $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum, 0); 105 } 106 } 107 %typemap(out) vector<T> { 108 $result = scheme_make_vector($1.size(),scheme_undefined); 109 Scheme_Object** els = SCHEME_VEC_ELS($result); 110 for (unsigned int i=0; i<$1.size(); i++) { 111 T* x = new T((($1_type &)$1)[i]); 112 els[i] = SWIG_NewPointerObj(x,$descriptor(T *), 1); 113 } 114 } 115 %typecheck(SWIG_TYPECHECK_VECTOR) vector<T> { 116 /* native sequence? */ 117 if (SCHEME_VECTORP($input)) { 118 unsigned int size = SCHEME_VEC_SIZE($input); 119 if (size == 0) { 120 /* an empty sequence can be of any type */ 121 $1 = 1; 122 } else { 123 /* check the first element only */ 124 T* x; 125 Scheme_Object** items = SCHEME_VEC_ELS($input); 126 if (SWIG_ConvertPtr(items[0],(void**) &x, 127 $descriptor(T *), 0) != -1) 128 $1 = 1; 129 else 130 $1 = 0; 131 } 132 } else if (SCHEME_NULLP($input)) { 133 /* again, an empty sequence can be of any type */ 134 $1 = 1; 135 } else if (SCHEME_PAIRP($input)) { 136 /* check the first element only */ 137 T* x; 138 Scheme_Object *head = scheme_car($input); 139 if (SWIG_ConvertPtr(head,(void**) &x, 140 $descriptor(T *), 0) != -1) 141 $1 = 1; 142 else 143 $1 = 0; 144 } else { 145 /* wrapped vector? */ 146 std::vector<T >* v; 147 if (SWIG_ConvertPtr($input,(void **) &v, 148 $&1_descriptor, 0) != -1) 149 $1 = 1; 150 else 151 $1 = 0; 152 } 153 } 154 %typecheck(SWIG_TYPECHECK_VECTOR) const vector<T>&, 155 const vector<T>* { 156 /* native sequence? */ 157 if (SCHEME_VECTORP($input)) { 158 unsigned int size = SCHEME_VEC_SIZE($input); 159 if (size == 0) { 160 /* an empty sequence can be of any type */ 161 $1 = 1; 162 } else { 163 /* check the first element only */ 164 T* x; 165 Scheme_Object** items = SCHEME_VEC_ELS($input); 166 if (SWIG_ConvertPtr(items[0],(void**) &x, 167 $descriptor(T *), 0) != -1) 168 $1 = 1; 169 else 170 $1 = 0; 171 } 172 } else if (SCHEME_NULLP($input)) { 173 /* again, an empty sequence can be of any type */ 174 $1 = 1; 175 } else if (SCHEME_PAIRP($input)) { 176 /* check the first element only */ 177 T* x; 178 Scheme_Object *head = scheme_car($input); 179 if (SWIG_ConvertPtr(head,(void**) &x, 180 $descriptor(T *), 0) != -1) 181 $1 = 1; 182 else 183 $1 = 0; 184 } else { 185 /* wrapped vector? */ 186 std::vector<T >* v; 187 if (SWIG_ConvertPtr($input,(void **) &v, 188 $1_descriptor, 0) != -1) 189 $1 = 1; 190 else 191 $1 = 0; 192 } 193 } 194 public: 195 vector(unsigned int size = 0); 196 vector(unsigned int size, const T& value); 197 vector(const vector<T>&); 198 %rename(length) size; 199 unsigned int size() const; 200 %rename("empty?") empty; 201 bool empty() const; 202 %rename("clear!") clear; 203 void clear(); 204 %rename("set!") set; 205 %rename("pop!") pop; 206 %rename("push!") push_back; 207 void push_back(const T& x); 208 %extend { 209 T pop() throw (std::out_of_range) { 210 if (self->size() == 0) 211 throw std::out_of_range("pop from empty vector"); 212 T x = self->back(); 213 self->pop_back(); 214 return x; 215 } 216 T& ref(int i) throw (std::out_of_range) { 217 int size = int(self->size()); 218 if (i>=0 && i<size) 219 return (*self)[i]; 220 else 221 throw std::out_of_range("vector index out of range"); 222 } 223 void set(int i, const T& x) throw (std::out_of_range) { 224 int size = int(self->size()); 225 if (i>=0 && i<size) 226 (*self)[i] = x; 227 else 228 throw std::out_of_range("vector index out of range"); 229 } 230 } 231 }; 232 233 234 // specializations for built-ins 235 236 %define specialize_std_vector(T,CHECK,CONVERT_FROM,CONVERT_TO) 237 template<> class vector<T> { 238 %typemap(in) vector<T> { 239 if (SCHEME_VECTORP($input)) { 240 unsigned int size = SCHEME_VEC_SIZE($input); 241 $1 = std::vector<T >(size); 242 Scheme_Object** items = SCHEME_VEC_ELS($input); 243 for (unsigned int i=0; i<size; i++) { 244 Scheme_Object* o = items[i]; 245 if (CHECK(o)) 246 (($1_type &)$1)[i] = (T)(CONVERT_FROM(o)); 247 else 248 scheme_wrong_type(FUNC_NAME, "vector<" #T ">", 249 $argnum - 1, argc, argv); 250 } 251 } else if (SCHEME_NULLP($input)) { 252 $1 = std::vector<T >(); 253 } else if (SCHEME_PAIRP($input)) { 254 Scheme_Object *head, *tail; 255 $1 = std::vector<T >(); 256 tail = $input; 257 while (!SCHEME_NULLP(tail)) { 258 head = scheme_car(tail); 259 tail = scheme_cdr(tail); 260 if (CHECK(head)) 261 $1.push_back((T)(CONVERT_FROM(head))); 262 else 263 scheme_wrong_type(FUNC_NAME, "vector<" #T ">", 264 $argnum - 1, argc, argv); 265 } 266 } else { 267 $1 = *(($&1_type) 268 SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0)); 269 } 270 } 271 %typemap(in) const vector<T>& (std::vector<T> temp), 272 const vector<T>* (std::vector<T> temp) { 273 if (SCHEME_VECTORP($input)) { 274 unsigned int size = SCHEME_VEC_SIZE($input); 275 temp = std::vector<T >(size); 276 $1 = &temp; 277 Scheme_Object** items = SCHEME_VEC_ELS($input); 278 for (unsigned int i=0; i<size; i++) { 279 Scheme_Object* o = items[i]; 280 if (CHECK(o)) 281 temp[i] = (T)(CONVERT_FROM(o)); 282 else 283 scheme_wrong_type(FUNC_NAME, "vector<" #T ">", 284 $argnum - 1, argc, argv); 285 } 286 } else if (SCHEME_NULLP($input)) { 287 temp = std::vector<T >(); 288 $1 = &temp; 289 } else if (SCHEME_PAIRP($input)) { 290 temp = std::vector<T >(); 291 $1 = &temp; 292 Scheme_Object *head, *tail; 293 tail = $input; 294 while (!SCHEME_NULLP(tail)) { 295 head = scheme_car(tail); 296 tail = scheme_cdr(tail); 297 if (CHECK(head)) 298 temp.push_back((T)(CONVERT_FROM(head))); 299 else 300 scheme_wrong_type(FUNC_NAME, "vector<" #T ">", 301 $argnum - 1, argc, argv); 302 } 303 } else { 304 $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum - 1, 0); 305 } 306 } 307 %typemap(out) vector<T> { 308 $result = scheme_make_vector($1.size(),scheme_undefined); 309 Scheme_Object** els = SCHEME_VEC_ELS($result); 310 for (unsigned int i=0; i<$1.size(); i++) 311 els[i] = CONVERT_TO((($1_type &)$1)[i]); 312 } 313 %typecheck(SWIG_TYPECHECK_VECTOR) vector<T> { 314 /* native sequence? */ 315 if (SCHEME_VECTORP($input)) { 316 unsigned int size = SCHEME_VEC_SIZE($input); 317 if (size == 0) { 318 /* an empty sequence can be of any type */ 319 $1 = 1; 320 } else { 321 /* check the first element only */ 322 T* x; 323 Scheme_Object** items = SCHEME_VEC_ELS($input); 324 $1 = CHECK(items[0]) ? 1 : 0; 325 } 326 } else if (SCHEME_NULLP($input)) { 327 /* again, an empty sequence can be of any type */ 328 $1 = 1; 329 } else if (SCHEME_PAIRP($input)) { 330 /* check the first element only */ 331 T* x; 332 Scheme_Object *head = scheme_car($input); 333 $1 = CHECK(head) ? 1 : 0; 334 } else { 335 /* wrapped vector? */ 336 std::vector<T >* v; 337 $1 = (SWIG_ConvertPtr($input,(void **) &v, 338 $&1_descriptor, 0) != -1) ? 1 : 0; 339 } 340 } 341 %typecheck(SWIG_TYPECHECK_VECTOR) const vector<T>&, 342 const vector<T>* { 343 /* native sequence? */ 344 if (SCHEME_VECTORP($input)) { 345 unsigned int size = SCHEME_VEC_SIZE($input); 346 if (size == 0) { 347 /* an empty sequence can be of any type */ 348 $1 = 1; 349 } else { 350 /* check the first element only */ 351 T* x; 352 Scheme_Object** items = SCHEME_VEC_ELS($input); 353 $1 = CHECK(items[0]) ? 1 : 0; 354 } 355 } else if (SCHEME_NULLP($input)) { 356 /* again, an empty sequence can be of any type */ 357 $1 = 1; 358 } else if (SCHEME_PAIRP($input)) { 359 /* check the first element only */ 360 T* x; 361 Scheme_Object *head = scheme_car($input); 362 $1 = CHECK(head) ? 1 : 0; 363 } else { 364 /* wrapped vector? */ 365 std::vector<T >* v; 366 $1 = (SWIG_ConvertPtr($input,(void **) &v, 367 $1_descriptor, 0) != -1) ? 1 : 0; 368 } 369 } 370 public: 371 vector(unsigned int size = 0); 372 vector(unsigned int size, const T& value); 373 vector(const vector<T>&); 374 %rename(length) size; 375 unsigned int size() const; 376 %rename("empty?") empty; 377 bool empty() const; 378 %rename("clear!") clear; 379 void clear(); 380 %rename("set!") set; 381 %rename("pop!") pop; 382 %rename("push!") push_back; 383 void push_back(T x); 384 %extend { 385 T pop() throw (std::out_of_range) { 386 if (self->size() == 0) 387 throw std::out_of_range("pop from empty vector"); 388 T x = self->back(); 389 self->pop_back(); 390 return x; 391 } 392 T ref(int i) throw (std::out_of_range) { 393 int size = int(self->size()); 394 if (i>=0 && i<size) 395 return (*self)[i]; 396 else 397 throw std::out_of_range("vector index out of range"); 398 } 399 void set(int i, T x) throw (std::out_of_range) { 400 int size = int(self->size()); 401 if (i>=0 && i<size) 402 (*self)[i] = x; 403 else 404 throw std::out_of_range("vector index out of range"); 405 } 406 } 407 }; 408 %enddef 409 410 specialize_std_vector(bool,SCHEME_BOOLP,SCHEME_TRUEP,\ 411 swig_make_boolean); 412 specialize_std_vector(char,SCHEME_INTP,SCHEME_INT_VAL,\ 413 scheme_make_integer_value); 414 specialize_std_vector(int,SCHEME_INTP,SCHEME_INT_VAL,\ 415 scheme_make_integer_value); 416 specialize_std_vector(short,SCHEME_INTP,SCHEME_INT_VAL,\ 417 scheme_make_integer_value); 418 specialize_std_vector(long,SCHEME_INTP,SCHEME_INT_VAL,\ 419 scheme_make_integer_value); 420 specialize_std_vector(unsigned char,SCHEME_INTP,SCHEME_INT_VAL,\ 421 scheme_make_integer_value); 422 specialize_std_vector(unsigned int,SCHEME_INTP,SCHEME_INT_VAL,\ 423 scheme_make_integer_value); 424 specialize_std_vector(unsigned short,SCHEME_INTP,SCHEME_INT_VAL,\ 425 scheme_make_integer_value); 426 specialize_std_vector(unsigned long,SCHEME_INTP,SCHEME_INT_VAL,\ 427 scheme_make_integer_value); 428 specialize_std_vector(float,SCHEME_REALP,scheme_real_to_double,\ 429 scheme_make_double); 430 specialize_std_vector(double,SCHEME_REALP,scheme_real_to_double,\ 431 scheme_make_double); 432 specialize_std_vector(std::string,SCHEME_STRINGP,swig_scm_to_string,\ 433 swig_make_string); 434 435} 436 437