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 // Guile as much as possible, namely, to allow the user to pass and 14 // be returned Guile 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 Guile 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 Guile vector of T:s 26 // is returned which is most easily used in other Guile 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 (scm_is_vector($input)) { 46 unsigned long size = scm_c_vector_length($input); 47 $1 = std::vector<T >(size); 48 for (unsigned long i=0; i<size; i++) { 49 SCM o = scm_vector_ref($input,scm_from_ulong(i)); 50 (($1_type &)$1)[i] = 51 *((T*) SWIG_MustGetPtr(o,$descriptor(T *),$argnum, 0)); 52 } 53 } else if (scm_is_null($input)) { 54 $1 = std::vector<T >(); 55 } else if (scm_is_pair($input)) { 56 SCM head, tail; 57 $1 = std::vector<T >(); 58 tail = $input; 59 while (!scm_is_null(tail)) { 60 head = SCM_CAR(tail); 61 tail = SCM_CDR(tail); 62 $1.push_back(*((T*)SWIG_MustGetPtr(head, 63 $descriptor(T *), 64 $argnum, 0))); 65 } 66 } else { 67 $1 = *(($&1_type) 68 SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0)); 69 } 70 } 71 %typemap(in) const vector<T>& (std::vector<T> temp), 72 const vector<T>* (std::vector<T> temp) { 73 if (scm_is_vector($input)) { 74 unsigned long size = scm_c_vector_length($input); 75 temp = std::vector<T >(size); 76 $1 = &temp; 77 for (unsigned long i=0; i<size; i++) { 78 SCM o = scm_vector_ref($input,scm_from_ulong(i)); 79 temp[i] = *((T*) SWIG_MustGetPtr(o, 80 $descriptor(T *), 81 $argnum, 0)); 82 } 83 } else if (scm_is_null($input)) { 84 temp = std::vector<T >(); 85 $1 = &temp; 86 } else if (scm_is_pair($input)) { 87 temp = std::vector<T >(); 88 $1 = &temp; 89 SCM head, tail; 90 tail = $input; 91 while (!scm_is_null(tail)) { 92 head = SCM_CAR(tail); 93 tail = SCM_CDR(tail); 94 temp.push_back(*((T*) SWIG_MustGetPtr(head, 95 $descriptor(T *), 96 $argnum, 0))); 97 } 98 } else { 99 $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum, 0); 100 } 101 } 102 %typemap(out) vector<T> { 103 $result = scm_make_vector(scm_from_long($1.size()),SCM_UNSPECIFIED); 104 for (unsigned int i=0; i<$1.size(); i++) { 105 T* x = new T((($1_type &)$1)[i]); 106 scm_vector_set_x($result,scm_from_long(i), 107 SWIG_NewPointerObj(x, $descriptor(T *), 1)); 108 } 109 } 110 %typecheck(SWIG_TYPECHECK_VECTOR) vector<T> { 111 /* native sequence? */ 112 if (scm_is_vector($input)) { 113 unsigned int size = scm_c_vector_length($input); 114 if (size == 0) { 115 /* an empty sequence can be of any type */ 116 $1 = 1; 117 } else { 118 /* check the first element only */ 119 SCM o = scm_vector_ref($input,scm_from_ulong(0)); 120 T* x; 121 if (SWIG_ConvertPtr(o,(void**) &x, 122 $descriptor(T *), 0) != -1) 123 $1 = 1; 124 else 125 $1 = 0; 126 } 127 } else if (scm_is_null($input)) { 128 /* again, an empty sequence can be of any type */ 129 $1 = 1; 130 } else if (scm_is_pair($input)) { 131 /* check the first element only */ 132 T* x; 133 SCM head = SCM_CAR($input); 134 if (SWIG_ConvertPtr(head,(void**) &x, 135 $descriptor(T *), 0) != -1) 136 $1 = 1; 137 else 138 $1 = 0; 139 } else { 140 /* wrapped vector? */ 141 std::vector<T >* v; 142 if (SWIG_ConvertPtr($input,(void **) &v, 143 $&1_descriptor, 0) != -1) 144 $1 = 1; 145 else 146 $1 = 0; 147 } 148 } 149 %typecheck(SWIG_TYPECHECK_VECTOR) const vector<T>&, 150 const vector<T>* { 151 /* native sequence? */ 152 if (scm_is_vector($input)) { 153 unsigned int size = scm_c_vector_length($input); 154 if (size == 0) { 155 /* an empty sequence can be of any type */ 156 $1 = 1; 157 } else { 158 /* check the first element only */ 159 T* x; 160 SCM o = scm_vector_ref($input,scm_from_ulong(0)); 161 if (SWIG_ConvertPtr(o,(void**) &x, 162 $descriptor(T *), 0) != -1) 163 $1 = 1; 164 else 165 $1 = 0; 166 } 167 } else if (scm_is_null($input)) { 168 /* again, an empty sequence can be of any type */ 169 $1 = 1; 170 } else if (scm_is_pair($input)) { 171 /* check the first element only */ 172 T* x; 173 SCM head = SCM_CAR($input); 174 if (SWIG_ConvertPtr(head,(void**) &x, 175 $descriptor(T *), 0) != -1) 176 $1 = 1; 177 else 178 $1 = 0; 179 } else { 180 /* wrapped vector? */ 181 std::vector<T >* v; 182 if (SWIG_ConvertPtr($input,(void **) &v, 183 $1_descriptor, 0) != -1) 184 $1 = 1; 185 else 186 $1 = 0; 187 } 188 } 189 public: 190 vector(unsigned int size = 0); 191 vector(unsigned int size, const T& value); 192 vector(const vector<T>&); 193 %rename(length) size; 194 unsigned int size() const; 195 %rename("empty?") empty; 196 bool empty() const; 197 %rename("clear!") clear; 198 void clear(); 199 %rename("set!") set; 200 %rename("pop!") pop; 201 %rename("push!") push_back; 202 void push_back(const T& x); 203 %extend { 204 T pop() throw (std::out_of_range) { 205 if (self->size() == 0) 206 throw std::out_of_range("pop from empty vector"); 207 T x = self->back(); 208 self->pop_back(); 209 return x; 210 } 211 const T& ref(int i) throw (std::out_of_range) { 212 int size = int(self->size()); 213 if (i>=0 && i<size) 214 return (*self)[i]; 215 else 216 throw std::out_of_range("vector index out of range"); 217 } 218 void set(int i, const T& x) throw (std::out_of_range) { 219 int size = int(self->size()); 220 if (i>=0 && i<size) 221 (*self)[i] = x; 222 else 223 throw std::out_of_range("vector index out of range"); 224 } 225 } 226 }; 227 228 229 // specializations for built-ins 230 %define specialize_stl_vector(T,CHECK,CONVERT_FROM,CONVERT_TO) 231 template<> class vector<T> { 232 %typemap(in) vector<T> { 233 if (scm_is_vector($input)) { 234 unsigned long size = scm_c_vector_length($input); 235 $1 = std::vector<T >(size); 236 for (unsigned long i=0; i<size; i++) { 237 SCM o = scm_vector_ref($input,scm_from_ulong(i)); 238 if (CHECK(o)) 239 (($1_type &)$1)[i] = (T)(CONVERT_FROM(o)); 240 else 241 scm_wrong_type_arg(FUNC_NAME, $argnum, $input); 242 } 243 } else if (scm_is_null($input)) { 244 $1 = std::vector<T >(); 245 } else if (scm_is_pair($input)) { 246 SCM v = scm_vector($input); 247 unsigned long size = scm_c_vector_length(v); 248 $1 = std::vector<T >(size); 249 for (unsigned long i=0; i<size; i++) { 250 SCM o = scm_vector_ref(v,scm_from_ulong(i)); 251 if (CHECK(o)) 252 (($1_type &)$1)[i] = (T)(CONVERT_FROM(o)); 253 else 254 scm_wrong_type_arg(FUNC_NAME, $argnum, $input); 255 } 256 } else { 257 $1 = *(($&1_type) 258 SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0)); 259 } 260 } 261 %typemap(in) const vector<T>& (std::vector<T> temp), 262 const vector<T>* (std::vector<T> temp) { 263 if (scm_is_vector($input)) { 264 unsigned long size = scm_c_vector_length($input); 265 temp = std::vector<T >(size); 266 $1 = &temp; 267 for (unsigned long i=0; i<size; i++) { 268 SCM o = scm_vector_ref($input,scm_from_ulong(i)); 269 if (CHECK(o)) 270 temp[i] = (T)(CONVERT_FROM(o)); 271 else 272 scm_wrong_type_arg(FUNC_NAME, $argnum, $input); 273 } 274 } else if (scm_is_null($input)) { 275 temp = std::vector<T >(); 276 $1 = &temp; 277 } else if (scm_is_pair($input)) { 278 SCM v = scm_vector($input); 279 unsigned long size = scm_c_vector_length(v); 280 temp = std::vector<T >(size); 281 $1 = &temp; 282 for (unsigned long i=0; i<size; i++) { 283 SCM o = scm_vector_ref(v,scm_from_ulong(i)); 284 if (CHECK(o)) 285 temp[i] = (T)(CONVERT_FROM(o)); 286 else 287 scm_wrong_type_arg(FUNC_NAME, $argnum, $input); 288 } 289 } else { 290 $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum, 0); 291 } 292 } 293 %typemap(out) vector<T> { 294 $result = scm_make_vector(scm_from_long($1.size()),SCM_UNSPECIFIED); 295 for (unsigned int i=0; i<$1.size(); i++) { 296 SCM x = CONVERT_TO((($1_type &)$1)[i]); 297 scm_vector_set_x($result,scm_from_long(i),x); 298 } 299 } 300 %typecheck(SWIG_TYPECHECK_VECTOR) vector<T> { 301 /* native sequence? */ 302 if (scm_is_vector($input)) { 303 unsigned int size = scm_c_vector_length($input); 304 if (size == 0) { 305 /* an empty sequence can be of any type */ 306 $1 = 1; 307 } else { 308 /* check the first element only */ 309 T* x; 310 SCM o = scm_vector_ref($input,scm_from_ulong(0)); 311 $1 = CHECK(o) ? 1 : 0; 312 } 313 } else if (scm_is_null($input)) { 314 /* again, an empty sequence can be of any type */ 315 $1 = 1; 316 } else if (scm_is_pair($input)) { 317 /* check the first element only */ 318 T* x; 319 SCM head = SCM_CAR($input); 320 $1 = CHECK(head) ? 1 : 0; 321 } else { 322 /* wrapped vector? */ 323 std::vector<T >* v; 324 $1 = (SWIG_ConvertPtr($input,(void **) &v, 325 $&1_descriptor, 0) != -1) ? 1 : 0; 326 } 327 } 328 %typecheck(SWIG_TYPECHECK_VECTOR) const vector<T>&, 329 const vector<T>* { 330 /* native sequence? */ 331 if (scm_is_vector($input)) { 332 unsigned int size = scm_c_vector_length($input); 333 if (size == 0) { 334 /* an empty sequence can be of any type */ 335 $1 = 1; 336 } else { 337 /* check the first element only */ 338 T* x; 339 SCM o = scm_vector_ref($input,scm_from_ulong(0)); 340 $1 = CHECK(o) ? 1 : 0; 341 } 342 } else if (scm_is_null($input)) { 343 /* again, an empty sequence can be of any type */ 344 $1 = 1; 345 } else if (scm_is_pair($input)) { 346 /* check the first element only */ 347 T* x; 348 SCM head = SCM_CAR($input); 349 $1 = CHECK(head) ? 1 : 0; 350 } else { 351 /* wrapped vector? */ 352 std::vector<T >* v; 353 $1 = (SWIG_ConvertPtr($input,(void **) &v, 354 $1_descriptor, 0) != -1) ? 1 : 0; 355 } 356 } 357 public: 358 vector(unsigned int size = 0); 359 vector(unsigned int size, const T& value); 360 vector(const vector<T>&); 361 %rename(length) size; 362 unsigned int size() const; 363 %rename("empty?") empty; 364 bool empty() const; 365 %rename("clear!") clear; 366 void clear(); 367 %rename("set!") set; 368 %rename("pop!") pop; 369 %rename("push!") push_back; 370 void push_back(T x); 371 %extend { 372 T pop() throw (std::out_of_range) { 373 if (self->size() == 0) 374 throw std::out_of_range("pop from empty vector"); 375 T x = self->back(); 376 self->pop_back(); 377 return x; 378 } 379 T ref(int i) throw (std::out_of_range) { 380 int size = int(self->size()); 381 if (i>=0 && i<size) 382 return (*self)[i]; 383 else 384 throw std::out_of_range("vector index out of range"); 385 } 386 void set(int i, T x) throw (std::out_of_range) { 387 int size = int(self->size()); 388 if (i>=0 && i<size) 389 (*self)[i] = x; 390 else 391 throw std::out_of_range("vector index out of range"); 392 } 393 } 394 }; 395 %enddef 396 397 specialize_stl_vector(bool,scm_is_bool,scm_is_true,SWIG_bool2scm); 398 specialize_stl_vector(char,scm_is_number,scm_to_long,scm_from_long); 399 specialize_stl_vector(int,scm_is_number,scm_to_long,scm_from_long); 400 specialize_stl_vector(long,scm_is_number,scm_to_long,scm_from_long); 401 specialize_stl_vector(short,scm_is_number,scm_to_long,scm_from_long); 402 specialize_stl_vector(unsigned char,scm_is_number,scm_to_ulong,scm_from_ulong); 403 specialize_stl_vector(unsigned int,scm_is_number,scm_to_ulong,scm_from_ulong); 404 specialize_stl_vector(unsigned long,scm_is_number,scm_to_ulong,scm_from_ulong); 405 specialize_stl_vector(unsigned short,scm_is_number,scm_to_ulong,scm_from_ulong); 406 specialize_stl_vector(float,scm_is_number,scm_to_double,scm_from_double); 407 specialize_stl_vector(double,scm_is_number,scm_to_double,scm_from_double); 408 specialize_stl_vector(std::string,scm_is_string,SWIG_scm2string,SWIG_string2scm); 409 } 410 411