PageRenderTime 53ms CodeModel.GetById 24ms app.highlight 20ms RepoModel.GetById 1ms app.codeStats 0ms

/tags/rel-1-3-15/SWIG/Lib/ruby/std_vector.i

#
Swig | 373 lines | 338 code | 19 blank | 16 comment | 0 complexity | 19c5776f9326ad3bdb8426a132aa5ef2 MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
  1//
  2// SWIG typemaps for std::vector
  3// Luigi Ballabio
  4// Apr 8, 2002
  5//
  6// Ruby implementation
  7
  8%include std_common.i
  9%include exception.i
 10
 11%exception std::vector::__getitem__ {
 12    try {
 13        $action
 14    } catch (std::out_of_range& e) {
 15        SWIG_exception(SWIG_IndexError,const_cast<char*>(e.what()));
 16    }
 17}
 18
 19%exception std::vector::__setitem__ {
 20    try {
 21        $action
 22    } catch (std::out_of_range& e) {
 23        SWIG_exception(SWIG_IndexError,const_cast<char*>(e.what()));
 24    }
 25}
 26
 27%exception std::vector::pop  {
 28    try {
 29        $action
 30    } catch (std::out_of_range& e) {
 31        SWIG_exception(SWIG_IndexError,const_cast<char*>(e.what()));
 32    }
 33}
 34
 35
 36// ------------------------------------------------------------------------
 37// std::vector
 38// 
 39// The aim of all that follows would be to integrate std::vector with 
 40// Ruby as much as possible, namely, to allow the user to pass and 
 41// be returned Ruby arrays
 42// const declarations are used to guess the intent of the function being
 43// exported; therefore, the following rationale is applied:
 44// 
 45//   -- f(std::vector<T>), f(const std::vector<T>&), f(const std::vector<T>*):
 46//      the parameter being read-only, either a Ruby array or a
 47//      previously wrapped std::vector<T> can be passed.
 48//   -- f(std::vector<T>&), f(std::vector<T>*):
 49//      the parameter must be modified; therefore, only a wrapped std::vector
 50//      can be passed.
 51//   -- std::vector<T> f():
 52//      the vector is returned by copy; therefore, a Ruby array of T:s 
 53//      is returned which is most easily used in other Ruby functions
 54//   -- std::vector<T>& f(), std::vector<T>* f(), const std::vector<T>& f(),
 55//      const std::vector<T>* f():
 56//      the vector is returned by reference; therefore, a wrapped std::vector
 57//      is returned
 58// ------------------------------------------------------------------------
 59
 60%{
 61#include <vector>
 62#include <algorithm>
 63#include <stdexcept>
 64%}
 65
 66// exported class
 67
 68namespace std {
 69
 70    %mixin vector "Enumerable";
 71
 72    template<class T> class vector {
 73        %typemap(in) vector<T> {
 74            if (rb_obj_is_kind_of($input,rb_cArray)) {
 75                unsigned int size = RARRAY($input)->len;
 76                $1 = std::vector<T >(size);
 77                for (unsigned int i=0; i<size; i++) {
 78                    VALUE o = RARRAY($input)->ptr[i];
 79                    T* x;
 80		    SWIG_ConvertPtr(o, (void **) &x, $descriptor(T *), 1);
 81                    (($1_type &)$1)[i] = *x;
 82                }
 83            } else {
 84	        void *ptr;
 85                SWIG_ConvertPtr($input, &ptr, $&1_descriptor, 1);
 86                $1 = *(($&1_type) ptr);
 87            }
 88        }
 89        %typemap(in) const vector<T>& (std::vector<T> temp),
 90                     const vector<T>* (std::vector<T> temp) {
 91            if (rb_obj_is_kind_of($input,rb_cArray)) {
 92                unsigned int size = RARRAY($input)->len;
 93                temp = std::vector<T >(size);
 94                $1 = &temp;
 95                for (unsigned int i=0; i<size; i++) {
 96                    VALUE o = RARRAY($input)->ptr[i];
 97                    T* x;
 98                    SWIG_ConvertPtr(o, (void **) &x, $descriptor(T *), 1);
 99                    temp[i] = *x;
100                }
101            } else {
102                SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 1);
103            }
104        }
105        %typemap(out) vector<T> {
106            $result = rb_ary_new2($1.size());
107            for (unsigned int i=0; i<$1.size(); i++) {
108                T* x = new T((($1_type &)$1)[i]);
109                rb_ary_store($result,i,
110                             SWIG_NewPointerObj((void *) x, 
111                                                $descriptor(T *), 1));
112            }
113        }
114        %typecheck(SWIG_TYPECHECK_VECTOR) vector<T> {
115            /* native sequence? */
116            if (rb_obj_is_kind_of($input,rb_cArray)) {
117                unsigned int size = RARRAY($input)->len;
118                if (size == 0) {
119                    /* an empty sequence can be of any type */
120                    $1 = 1;
121                } else {
122                    /* check the first element only */
123                    T* x;
124                    VALUE o = RARRAY($input)->ptr[0];
125                    if ((SWIG_ConvertPtr(o,(void **) &x, 
126                                         $descriptor(T *),0)) != -1)
127                        $1 = 1;
128                    else
129                        $1 = 0;
130                }
131            } else {
132                /* wrapped vector? */
133                std::vector<T >* v;
134                if (SWIG_ConvertPtr($input,(void **) &v, 
135                                    $&1_descriptor,0) != -1)
136                    $1 = 1;
137                else
138                    $1 = 0;
139            }
140        }
141        %typecheck(SWIG_TYPECHECK_VECTOR) const vector<T>&,
142                                          const vector<T>* {
143            /* native sequence? */
144            if (rb_obj_is_kind_of($input,rb_cArray)) {
145                unsigned int size = RARRAY($input)->len;
146                if (size == 0) {
147                    /* an empty sequence can be of any type */
148                    $1 = 1;
149                } else {
150                    /* check the first element only */
151                    T* x;
152                    VALUE o = RARRAY($input)->ptr[0];
153                    if ((SWIG_ConvertPtr(o,(void **) &x, 
154                                         $descriptor(T *),0)) != -1)
155                        $1 = 1;
156                    else
157                        $1 = 0;
158                }
159            } else {
160                /* wrapped vector? */
161                std::vector<T >* v;
162                if (SWIG_ConvertPtr($input,(void **) &v, 
163                                    $1_descriptor,1) != -1)
164                    $1 = 1;
165                else
166                    $1 = 0;
167            }
168        }
169      public:
170        vector();
171        vector(unsigned int size, const T& value=T());
172        vector(const vector<T> &);
173
174        %rename(__len__) size;
175        unsigned int size() const;
176        %rename("empty?") empty;
177        bool empty() const;
178        %rename("clear!") clear;
179        void clear();
180        %rename(push) push_back;
181        void push_back(const T& x);
182        %extend {
183            T pop() {
184                if (self->size() == 0)
185                    throw std::out_of_range("pop from empty vector");
186                T x = self->back();
187                self->pop_back();
188                return x;
189            }
190            T& __getitem__(int i) {
191                int size = int(self->size());
192                if (i<0) i += size;
193                if (i>=0 && i<size)
194                    return (*self)[i];
195                else
196                    throw std::out_of_range("vector index out of range");
197            }
198            void __setitem__(int i, const T& x) {
199                int size = int(self->size());
200                if (i<0) i+= size;
201                if (i>=0 && i<size)
202                    (*self)[i] = x;
203                else
204                    throw std::out_of_range("vector index out of range");
205            }
206            void each() {
207                swig_type_info* type = SWIG_TypeQuery(#T " *");
208                for (unsigned int i=0; i<self->size(); i++) {
209                    T* x = new T((*self)[i]);
210                    rb_yield(SWIG_NewPointerObj((void *) x, type, 1));
211                }
212            }
213        }
214    };
215
216
217    // specializations for built-ins
218
219    %define specialize_std_vector(T,CHECK,CONVERT_FROM,CONVERT_TO)
220    %mixin vector<T> "Enumerable";
221    template<> class vector<T> {
222        %typemap(in) vector<T> {
223            if (rb_obj_is_kind_of($input,rb_cArray)) {
224                unsigned int size = RARRAY($input)->len;
225                $1 = std::vector<T >(size);
226                for (unsigned int i=0; i<size; i++) {
227                    VALUE o = RARRAY($input)->ptr[i];
228                    if (CHECK(o))
229                        (($1_type &)$1)[i] = (T)(CONVERT_FROM(o));
230                    else
231                        rb_raise(rb_eTypeError,
232                                 "wrong argument type"
233                                 " (expected vector<" #T ">)");
234                }
235            } else {
236	        void *ptr;
237                SWIG_ConvertPtr($input, &ptr, $&1_descriptor, 1);
238                $1 = *(($&1_type) ptr);
239            }
240        }
241        %typemap(in) const vector<T>& (std::vector<T> temp),
242                     const vector<T>* (std::vector<T> temp) {
243            if (rb_obj_is_kind_of($input,rb_cArray)) {
244                unsigned int size = RARRAY($input)->len;
245                temp = std::vector<T >(size);
246                $1 = &temp;
247                for (unsigned int i=0; i<size; i++) {
248                    VALUE o = RARRAY($input)->ptr[i];
249                    if (CHECK(o))
250                        temp[i] = (T)(CONVERT_FROM(o));
251                    else
252                        rb_raise(rb_eTypeError,
253                                 "wrong argument type"
254                                 " (expected vector<" #T ">)");
255                }
256            } else {
257                SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 1);
258            }
259        }
260        %typemap(out) vector<T> {
261            $result = rb_ary_new2($1.size());
262            for (unsigned int i=0; i<$1.size(); i++)
263                rb_ary_store($result,i,CONVERT_TO((($1_type &)$1)[i]));
264        }
265        %typecheck(SWIG_TYPECHECK_VECTOR) vector<T> {
266            /* native sequence? */
267            if (rb_obj_is_kind_of($input,rb_cArray)) {
268                unsigned int size = RARRAY($input)->len;
269                if (size == 0) {
270                    /* an empty sequence can be of any type */
271                    $1 = 1;
272                } else {
273                    /* check the first element only */
274                    VALUE o = RARRAY($input)->ptr[0];
275                    if (CHECK(o))
276                        $1 = 1;
277                    else
278                        $1 = 0;
279                }
280            } else {
281                /* wrapped vector? */
282                std::vector<T >* v;
283                if (SWIG_ConvertPtr($input,(void **) &v, 
284                                    $&1_descriptor,0) != -1)
285                    $1 = 1;
286                else
287                    $1 = 0;
288            }
289        }
290        %typecheck(SWIG_TYPECHECK_VECTOR) const vector<T>&,
291                                          const vector<T>* {
292            /* native sequence? */
293            if (rb_obj_is_kind_of($input,rb_cArray)) {
294                unsigned int size = RARRAY($input)->len;
295                if (size == 0) {
296                    /* an empty sequence can be of any type */
297                    $1 = 1;
298                } else {
299                    /* check the first element only */
300                    VALUE o = RARRAY($input)->ptr[0];
301                    if (CHECK(o))
302                        $1 = 1;
303                    else
304                        $1 = 0;
305                }
306            } else {
307                /* wrapped vector? */
308                std::vector<T >* v;
309                if (SWIG_ConvertPtr($input,(void **) &v, 
310                                    $1_descriptor,1) != -1)
311                    $1 = 1;
312                else
313                    $1 = 0;
314            }
315        }
316      public:
317        vector();
318        vector(unsigned int size, const T& value=T());
319        vector(const vector<T> &);
320
321        %rename(__len__) size;
322        unsigned int size() const;
323        %rename("empty?") empty;
324        bool empty() const;
325        %rename("clear!") clear;
326        void clear();
327        %rename(push) push_back;
328        void push_back(T x);
329        %extend {
330            T pop() {
331                if (self->size() == 0)
332                    throw std::out_of_range("pop from empty vector");
333                T x = self->back();
334                self->pop_back();
335                return x;
336            }
337            T __getitem__(int i) {
338                int size = int(self->size());
339                if (i<0) i += size;
340                if (i>=0 && i<size)
341                    return (*self)[i];
342                else
343                    throw std::out_of_range("vector index out of range");
344            }
345            void __setitem__(int i, T x) {
346                int size = int(self->size());
347                if (i<0) i+= size;
348                if (i>=0 && i<size)
349                    (*self)[i] = x;
350                else
351                    throw std::out_of_range("vector index out of range");
352            }
353            void each() {
354                for (unsigned int i=0; i<self->size(); i++)
355                    rb_yield(CONVERT_TO((*self)[i]));
356            }
357        }
358    };
359    %enddef
360
361    specialize_std_vector(bool,SWIG_BOOL_P,SWIG_RB2BOOL,SWIG_BOOL2RB);
362    specialize_std_vector(int,FIXNUM_P,FIX2INT,INT2NUM);
363    specialize_std_vector(short,FIXNUM_P,FIX2INT,INT2NUM);
364    specialize_std_vector(long,FIXNUM_P,FIX2INT,INT2NUM);
365    specialize_std_vector(unsigned int,FIXNUM_P,FIX2INT,INT2NUM);
366    specialize_std_vector(unsigned short,FIXNUM_P,FIX2INT,INT2NUM);
367    specialize_std_vector(unsigned long,FIXNUM_P,FIX2INT,INT2NUM);
368    specialize_std_vector(double,SWIG_FLOAT_P,SWIG_NUM2DBL,rb_float_new);
369    specialize_std_vector(float,SWIG_FLOAT_P,SWIG_NUM2DBL,rb_float_new);
370    specialize_std_vector(std::string,SWIG_STRING_P,SWIG_RB2STR,SWIG_STR2RB);
371
372}
373