PageRenderTime 32ms CodeModel.GetById 15ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 1ms

/trunk/Lib/guile/std_vector.i

#
Swig | 410 lines | 371 code | 10 blank | 29 comment | 0 complexity | 161546e2da65cc77a13edb880d8323cc MD5 | raw file
  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
 41namespace std {
 42    
 43    template<class T> class vector {
 44        %typemap(in) vector<T> {
 45            if (gh_vector_p($input)) {
 46                unsigned long size = gh_vector_length($input);
 47                $1 = std::vector<T >(size);
 48                for (unsigned long i=0; i<size; i++) {
 49                    SCM o = gh_vector_ref($input,gh_ulong2scm(i));
 50                    (($1_type &)$1)[i] =
 51                        *((T*) SWIG_MustGetPtr(o,$descriptor(T *),$argnum, 0));
 52                }
 53            } else if (gh_null_p($input)) {
 54                $1 = std::vector<T >();
 55            } else if (gh_pair_p($input)) {
 56                SCM head, tail;
 57                $1 = std::vector<T >();
 58                tail = $input;
 59                while (!gh_null_p(tail)) {
 60                    head = gh_car(tail);
 61                    tail = gh_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 (gh_vector_p($input)) {
 74                unsigned long size = gh_vector_length($input);
 75                temp = std::vector<T >(size);
 76                $1 = &temp;
 77                for (unsigned long i=0; i<size; i++) {
 78                    SCM o = gh_vector_ref($input,gh_ulong2scm(i));
 79                    temp[i] = *((T*) SWIG_MustGetPtr(o,
 80                                                     $descriptor(T *),
 81                                                     $argnum, 0));
 82                }
 83            } else if (gh_null_p($input)) {
 84                temp = std::vector<T >();
 85                $1 = &temp;
 86            } else if (gh_pair_p($input)) {
 87                temp = std::vector<T >();
 88                $1 = &temp;
 89                SCM head, tail;
 90                tail = $input;
 91                while (!gh_null_p(tail)) {
 92                    head = gh_car(tail);
 93                    tail = gh_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 = gh_make_vector(gh_long2scm($1.size()),SCM_UNSPECIFIED);
104            for (unsigned int i=0; i<$1.size(); i++) {
105                T* x = new T((($1_type &)$1)[i]);
106                gh_vector_set_x($result,gh_long2scm(i),
107                                SWIG_NewPointerObj(x, $descriptor(T *), 1));
108            }
109        }
110        %typecheck(SWIG_TYPECHECK_VECTOR) vector<T> {
111            /* native sequence? */
112            if (gh_vector_p($input)) {
113                unsigned int size = gh_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 = gh_vector_ref($input,gh_ulong2scm(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 (gh_null_p($input)) {
128                /* again, an empty sequence can be of any type */
129                $1 = 1;
130            } else if (gh_pair_p($input)) {
131                /* check the first element only */
132                T* x;
133                SCM head = gh_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 (gh_vector_p($input)) {
153                unsigned int size = gh_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 = gh_vector_ref($input,gh_ulong2scm(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 (gh_null_p($input)) {
168                /* again, an empty sequence can be of any type */
169                $1 = 1;
170            } else if (gh_pair_p($input)) {
171                /* check the first element only */
172                T* x;
173                SCM head = gh_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 (gh_vector_p($input)) {
234                unsigned long size = gh_vector_length($input);
235                $1 = std::vector<T >(size);
236                for (unsigned long i=0; i<size; i++) {
237                    SCM o = gh_vector_ref($input,gh_ulong2scm(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 (gh_null_p($input)) {
244                $1 = std::vector<T >();
245            } else if (gh_pair_p($input)) {
246                SCM v = gh_list_to_vector($input);
247                unsigned long size = gh_vector_length(v);
248                $1 = std::vector<T >(size);
249                for (unsigned long i=0; i<size; i++) {
250                    SCM o = gh_vector_ref(v,gh_ulong2scm(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 (gh_vector_p($input)) {
264                unsigned long size = gh_vector_length($input);
265                temp = std::vector<T >(size);
266                $1 = &temp;
267                for (unsigned long i=0; i<size; i++) {
268                    SCM o = gh_vector_ref($input,gh_ulong2scm(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 (gh_null_p($input)) {
275                temp = std::vector<T >();
276                $1 = &temp;
277            } else if (gh_pair_p($input)) {
278                SCM v = gh_list_to_vector($input);
279                unsigned long size = gh_vector_length(v);
280                temp = std::vector<T >(size);
281                $1 = &temp;
282                for (unsigned long i=0; i<size; i++) {
283                    SCM o = gh_vector_ref(v,gh_ulong2scm(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 = gh_make_vector(gh_long2scm($1.size()),SCM_UNSPECIFIED);
295            for (unsigned int i=0; i<$1.size(); i++) {
296                SCM x = CONVERT_TO((($1_type &)$1)[i]);
297                gh_vector_set_x($result,gh_long2scm(i),x);
298            }
299        }
300        %typecheck(SWIG_TYPECHECK_VECTOR) vector<T> {
301            /* native sequence? */
302            if (gh_vector_p($input)) {
303                unsigned int size = gh_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 = gh_vector_ref($input,gh_ulong2scm(0));
311                    $1 = CHECK(o) ? 1 : 0;
312                }
313            } else if (gh_null_p($input)) {
314                /* again, an empty sequence can be of any type */
315                $1 = 1;
316            } else if (gh_pair_p($input)) {
317                /* check the first element only */
318                T* x;
319                SCM head = gh_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 (gh_vector_p($input)) {
332                unsigned int size = gh_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 = gh_vector_ref($input,gh_ulong2scm(0));
340                    $1 = CHECK(o) ? 1 : 0;
341                }
342            } else if (gh_null_p($input)) {
343                /* again, an empty sequence can be of any type */
344                $1 = 1;
345            } else if (gh_pair_p($input)) {
346                /* check the first element only */
347                T* x;
348                SCM head = gh_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,gh_boolean_p,gh_scm2bool,SWIG_bool2scm);
398    specialize_stl_vector(char,gh_number_p,gh_scm2long,gh_long2scm);
399    specialize_stl_vector(int,gh_number_p,gh_scm2long,gh_long2scm);
400    specialize_stl_vector(long,gh_number_p,gh_scm2long,gh_long2scm);
401    specialize_stl_vector(short,gh_number_p,gh_scm2long,gh_long2scm);
402    specialize_stl_vector(unsigned char,gh_number_p,gh_scm2ulong,gh_ulong2scm);
403    specialize_stl_vector(unsigned int,gh_number_p,gh_scm2ulong,gh_ulong2scm);
404    specialize_stl_vector(unsigned long,gh_number_p,gh_scm2ulong,gh_ulong2scm);
405    specialize_stl_vector(unsigned short,gh_number_p,gh_scm2ulong,gh_ulong2scm);
406    specialize_stl_vector(float,gh_number_p,gh_scm2double,gh_double2scm);
407    specialize_stl_vector(double,gh_number_p,gh_scm2double,gh_double2scm);
408    specialize_stl_vector(std::string,gh_string_p,SWIG_scm2string,SWIG_string2scm);
409}
410