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