import source from 1.3.40
[external/swig.git] / Lib / mzscheme / std_vector.i
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
44 namespace 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