/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