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