PageRenderTime 59ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/trunk/Lib/guile/std_vector.i

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