PageRenderTime 78ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 1ms

/trunk/Lib/perl5/std_vector.i

#
Swig | 568 lines | 524 code | 15 blank | 29 comment | 0 complexity | 4fe15ce6b786561f7f191e5e629a0f73 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 types
  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. // Perl as much as possible, namely, to allow the user to pass and
  12. // be returned Perl arrays.
  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 Perl 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 Perl sequence of T:s
  24. // is returned which is most easily used in other Perl 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> (std::vector<T>* v) {
  39. if (SWIG_ConvertPtr($input,(void **) &v,
  40. $&1_descriptor,1) != -1) {
  41. $1 = *v;
  42. } else if (SvROK($input)) {
  43. AV *av = (AV *)SvRV($input);
  44. if (SvTYPE(av) != SVt_PVAV)
  45. SWIG_croak("Type error in argument $argnum of $symname. "
  46. "Expected an array of " #T);
  47. SV **tv;
  48. I32 len = av_len(av) + 1;
  49. T* obj;
  50. for (int i=0; i<len; i++) {
  51. tv = av_fetch(av, i, 0);
  52. if (SWIG_ConvertPtr(*tv, (void **)&obj,
  53. $descriptor(T *),0) != -1) {
  54. $1.push_back(*obj);
  55. } else {
  56. SWIG_croak("Type error in argument $argnum of "
  57. "$symname. "
  58. "Expected an array of " #T);
  59. }
  60. }
  61. } else {
  62. SWIG_croak("Type error in argument $argnum of $symname. "
  63. "Expected an array of " #T);
  64. }
  65. }
  66. %typemap(in) const vector<T>& (std::vector<T> temp,
  67. std::vector<T>* v),
  68. const vector<T>* (std::vector<T> temp,
  69. std::vector<T>* v) {
  70. if (SWIG_ConvertPtr($input,(void **) &v,
  71. $1_descriptor,1) != -1) {
  72. $1 = v;
  73. } else if (SvROK($input)) {
  74. AV *av = (AV *)SvRV($input);
  75. if (SvTYPE(av) != SVt_PVAV)
  76. SWIG_croak("Type error in argument $argnum of $symname. "
  77. "Expected an array of " #T);
  78. SV **tv;
  79. I32 len = av_len(av) + 1;
  80. T* obj;
  81. for (int i=0; i<len; i++) {
  82. tv = av_fetch(av, i, 0);
  83. if (SWIG_ConvertPtr(*tv, (void **)&obj,
  84. $descriptor(T *),0) != -1) {
  85. temp.push_back(*obj);
  86. } else {
  87. SWIG_croak("Type error in argument $argnum of "
  88. "$symname. "
  89. "Expected an array of " #T);
  90. }
  91. }
  92. $1 = &temp;
  93. } else {
  94. SWIG_croak("Type error in argument $argnum of $symname. "
  95. "Expected an array of " #T);
  96. }
  97. }
  98. %typemap(out) vector<T> {
  99. size_t len = $1.size();
  100. SV **svs = new SV*[len];
  101. for (size_t i=0; i<len; i++) {
  102. T* ptr = new T($1[i]);
  103. svs[i] = sv_newmortal();
  104. SWIG_MakePtr(svs[i], (void*) ptr,
  105. $descriptor(T *), $shadow|$owner);
  106. }
  107. AV *myav = av_make(len, svs);
  108. delete[] svs;
  109. $result = newRV_noinc((SV*) myav);
  110. sv_2mortal($result);
  111. argvi++;
  112. }
  113. %typecheck(SWIG_TYPECHECK_VECTOR) vector<T> {
  114. {
  115. /* wrapped vector? */
  116. std::vector<T >* v;
  117. if (SWIG_ConvertPtr($input,(void **) &v,
  118. $&1_descriptor,0) != -1) {
  119. $1 = 1;
  120. } else if (SvROK($input)) {
  121. /* native sequence? */
  122. AV *av = (AV *)SvRV($input);
  123. if (SvTYPE(av) == SVt_PVAV) {
  124. I32 len = av_len(av) + 1;
  125. if (len == 0) {
  126. /* an empty sequence can be of any type */
  127. $1 = 1;
  128. } else {
  129. /* check the first element only */
  130. T* obj;
  131. SV **tv = av_fetch(av, 0, 0);
  132. if (SWIG_ConvertPtr(*tv, (void **)&obj,
  133. $descriptor(T *),0) != -1)
  134. $1 = 1;
  135. else
  136. $1 = 0;
  137. }
  138. }
  139. } else {
  140. $1 = 0;
  141. }
  142. }
  143. }
  144. %typecheck(SWIG_TYPECHECK_VECTOR) const vector<T>&,
  145. const vector<T>* {
  146. {
  147. /* wrapped vector? */
  148. std::vector<T >* v;
  149. if (SWIG_ConvertPtr($input,(void **) &v,
  150. $1_descriptor,0) != -1) {
  151. $1 = 1;
  152. } else if (SvROK($input)) {
  153. /* native sequence? */
  154. AV *av = (AV *)SvRV($input);
  155. if (SvTYPE(av) == SVt_PVAV) {
  156. I32 len = av_len(av) + 1;
  157. if (len == 0) {
  158. /* an empty sequence can be of any type */
  159. $1 = 1;
  160. } else {
  161. /* check the first element only */
  162. T* obj;
  163. SV **tv = av_fetch(av, 0, 0);
  164. if (SWIG_ConvertPtr(*tv, (void **)&obj,
  165. $descriptor(T *),0) != -1)
  166. $1 = 1;
  167. else
  168. $1 = 0;
  169. }
  170. }
  171. } else {
  172. $1 = 0;
  173. }
  174. }
  175. }
  176. public:
  177. vector(unsigned int size = 0);
  178. vector(unsigned int size, const T& value);
  179. vector(const vector<T> &);
  180. unsigned int size() const;
  181. bool empty() const;
  182. void clear();
  183. %rename(push) push_back;
  184. void push_back(const T& x);
  185. %extend {
  186. T pop() throw (std::out_of_range) {
  187. if (self->size() == 0)
  188. throw std::out_of_range("pop from empty vector");
  189. T x = self->back();
  190. self->pop_back();
  191. return x;
  192. }
  193. T& get(int i) throw (std::out_of_range) {
  194. int size = int(self->size());
  195. if (i>=0 && i<size)
  196. return (*self)[i];
  197. else
  198. throw std::out_of_range("vector index out of range");
  199. }
  200. void set(int i, const T& x) throw (std::out_of_range) {
  201. int size = int(self->size());
  202. if (i>=0 && i<size)
  203. (*self)[i] = x;
  204. else
  205. throw std::out_of_range("vector index out of range");
  206. }
  207. }
  208. };
  209. // specializations for pointers
  210. template<class T> class vector<T*> {
  211. %typemap(in) vector<T*> (std::vector<T*>* v) {
  212. int res = SWIG_ConvertPtr($input,(void **) &v, $&1_descriptor,0);
  213. if (SWIG_IsOK(res)){
  214. $1 = *v;
  215. } else if (SvROK($input)) {
  216. AV *av = (AV *)SvRV($input);
  217. if (SvTYPE(av) != SVt_PVAV)
  218. SWIG_croak("Type error in argument $argnum of $symname. "
  219. "Expected an array of " #T);
  220. I32 len = av_len(av) + 1;
  221. for (int i=0; i<len; i++) {
  222. void *v;
  223. SV **tv = av_fetch(av, i, 0);
  224. int res = SWIG_ConvertPtr(*tv, &v, $descriptor(T *),0);
  225. if (SWIG_IsOK(res)) {
  226. $1.push_back(%static_cast(v, T *));
  227. } else {
  228. SWIG_croak("Type error in argument $argnum of "
  229. "$symname. "
  230. "Expected an array of " #T);
  231. }
  232. }
  233. } else {
  234. SWIG_croak("Type error in argument $argnum of $symname. "
  235. "Expected an array of " #T);
  236. }
  237. }
  238. %typemap(in) const vector<T *>& (std::vector<T *> temp,std::vector<T *>* v),
  239. const vector<T *>* (std::vector<T *> temp,std::vector<T *>* v) {
  240. int res = SWIG_ConvertPtr($input,(void **) &v, $1_descriptor,0);
  241. if (SWIG_IsOK(res)) {
  242. $1 = v;
  243. } else if (SvROK($input)) {
  244. AV *av = (AV *)SvRV($input);
  245. if (SvTYPE(av) != SVt_PVAV)
  246. SWIG_croak("Type error in argument $argnum of $symname. "
  247. "Expected an array of " #T);
  248. I32 len = av_len(av) + 1;
  249. for (int i=0; i<len; i++) {
  250. void *v;
  251. SV **tv = av_fetch(av, i, 0);
  252. int res = SWIG_ConvertPtr(*tv, &v, $descriptor(T *),0);
  253. if (SWIG_IsOK(res)) {
  254. temp.push_back(%static_cast(v, T *));
  255. } else {
  256. SWIG_croak("Type error in argument $argnum of "
  257. "$symname. "
  258. "Expected an array of " #T);
  259. }
  260. }
  261. $1 = &temp;
  262. } else {
  263. SWIG_croak("Type error in argument $argnum of $symname. "
  264. "Expected an array of " #T);
  265. }
  266. }
  267. %typemap(out) vector<T *> {
  268. size_t len = $1.size();
  269. SV **svs = new SV*[len];
  270. for (size_t i=0; i<len; i++) {
  271. T *x = (($1_type &)$1)[i];
  272. svs[i] = sv_newmortal();
  273. sv_setsv(svs[i], SWIG_NewPointerObj(x, $descriptor(T *), 0));
  274. }
  275. AV *myav = av_make(len, svs);
  276. delete[] svs;
  277. $result = newRV_noinc((SV*) myav);
  278. sv_2mortal($result);
  279. argvi++;
  280. }
  281. %typecheck(SWIG_TYPECHECK_VECTOR) vector<T *> {
  282. {
  283. /* wrapped vector? */
  284. std::vector<T *>* v;
  285. int res = SWIG_ConvertPtr($input,(void **) &v, $&1_descriptor,0);
  286. if (SWIG_IsOK(res)) {
  287. $1 = 1;
  288. } else if (SvROK($input)) {
  289. /* native sequence? */
  290. AV *av = (AV *)SvRV($input);
  291. if (SvTYPE(av) == SVt_PVAV) {
  292. I32 len = av_len(av) + 1;
  293. if (len == 0) {
  294. /* an empty sequence can be of any type */
  295. $1 = 1;
  296. } else {
  297. /* check the first element only */
  298. void *v;
  299. SV **tv = av_fetch(av, 0, 0);
  300. int res = SWIG_ConvertPtr(*tv, &v, $descriptor(T *),0);
  301. if (SWIG_IsOK(res))
  302. $1 = 1;
  303. else
  304. $1 = 0;
  305. }
  306. }
  307. } else {
  308. $1 = 0;
  309. }
  310. }
  311. }
  312. %typecheck(SWIG_TYPECHECK_VECTOR) const vector<T *>&,const vector<T *>* {
  313. {
  314. /* wrapped vector? */
  315. std::vector<T *> *v;
  316. int res = SWIG_ConvertPtr($input,%as_voidptrptr(&v), $1_descriptor,0);
  317. if (SWIG_IsOK(res)) {
  318. $1 = 1;
  319. } else if (SvROK($input)) {
  320. /* native sequence? */
  321. AV *av = (AV *)SvRV($input);
  322. if (SvTYPE(av) == SVt_PVAV) {
  323. I32 len = av_len(av) + 1;
  324. if (len == 0) {
  325. /* an empty sequence can be of any type */
  326. $1 = 1;
  327. } else {
  328. /* check the first element only */
  329. void *v;
  330. SV **tv = av_fetch(av, 0, 0);
  331. int res = SWIG_ConvertPtr(*tv, &v, $descriptor(T *),0);
  332. if (SWIG_IsOK(res))
  333. $1 = 1;
  334. else
  335. $1 = 0;
  336. }
  337. }
  338. } else {
  339. $1 = 0;
  340. }
  341. }
  342. }
  343. public:
  344. vector(unsigned int size = 0);
  345. vector(unsigned int size, T *value);
  346. vector(const vector<T *> &);
  347. unsigned int size() const;
  348. bool empty() const;
  349. void clear();
  350. %rename(push) push_back;
  351. void push_back(T *x);
  352. %extend {
  353. T *pop() throw (std::out_of_range) {
  354. if (self->size() == 0)
  355. throw std::out_of_range("pop from empty vector");
  356. T *x = self->back();
  357. self->pop_back();
  358. return x;
  359. }
  360. T *get(int i) throw (std::out_of_range) {
  361. int size = int(self->size());
  362. if (i>=0 && i<size)
  363. return (*self)[i];
  364. else
  365. throw std::out_of_range("vector index out of range");
  366. }
  367. void set(int i, T *x) throw (std::out_of_range) {
  368. int size = int(self->size());
  369. if (i>=0 && i<size)
  370. (*self)[i] = x;
  371. else
  372. throw std::out_of_range("vector index out of range");
  373. }
  374. }
  375. };
  376. // specializations for built-ins
  377. %define specialize_std_vector(T,CHECK_T,TO_T,FROM_T)
  378. template<> class vector<T> {
  379. %typemap(in) vector<T> (std::vector<T>* v) {
  380. if (SWIG_ConvertPtr($input,(void **) &v,
  381. $&1_descriptor,1) != -1){
  382. $1 = *v;
  383. } else if (SvROK($input)) {
  384. AV *av = (AV *)SvRV($input);
  385. if (SvTYPE(av) != SVt_PVAV)
  386. SWIG_croak("Type error in argument $argnum of $symname. "
  387. "Expected an array of " #T);
  388. SV **tv;
  389. I32 len = av_len(av) + 1;
  390. for (int i=0; i<len; i++) {
  391. tv = av_fetch(av, i, 0);
  392. if (CHECK_T(*tv)) {
  393. $1.push_back((T)TO_T(*tv));
  394. } else {
  395. SWIG_croak("Type error in argument $argnum of "
  396. "$symname. "
  397. "Expected an array of " #T);
  398. }
  399. }
  400. } else {
  401. SWIG_croak("Type error in argument $argnum of $symname. "
  402. "Expected an array of " #T);
  403. }
  404. }
  405. %typemap(in) const vector<T>& (std::vector<T> temp,
  406. std::vector<T>* v),
  407. const vector<T>* (std::vector<T> temp,
  408. std::vector<T>* v) {
  409. if (SWIG_ConvertPtr($input,(void **) &v,
  410. $1_descriptor,1) != -1) {
  411. $1 = v;
  412. } else if (SvROK($input)) {
  413. AV *av = (AV *)SvRV($input);
  414. if (SvTYPE(av) != SVt_PVAV)
  415. SWIG_croak("Type error in argument $argnum of $symname. "
  416. "Expected an array of " #T);
  417. SV **tv;
  418. I32 len = av_len(av) + 1;
  419. for (int i=0; i<len; i++) {
  420. tv = av_fetch(av, i, 0);
  421. if (CHECK_T(*tv)) {
  422. temp.push_back((T)TO_T(*tv));
  423. } else {
  424. SWIG_croak("Type error in argument $argnum of "
  425. "$symname. "
  426. "Expected an array of " #T);
  427. }
  428. }
  429. $1 = &temp;
  430. } else {
  431. SWIG_croak("Type error in argument $argnum of $symname. "
  432. "Expected an array of " #T);
  433. }
  434. }
  435. %typemap(out) vector<T> {
  436. size_t len = $1.size();
  437. SV **svs = new SV*[len];
  438. for (size_t i=0; i<len; i++) {
  439. svs[i] = sv_newmortal();
  440. FROM_T(svs[i], $1[i]);
  441. }
  442. AV *myav = av_make(len, svs);
  443. delete[] svs;
  444. $result = newRV_noinc((SV*) myav);
  445. sv_2mortal($result);
  446. argvi++;
  447. }
  448. %typecheck(SWIG_TYPECHECK_VECTOR) vector<T> {
  449. {
  450. /* wrapped vector? */
  451. std::vector<T >* v;
  452. if (SWIG_ConvertPtr($input,(void **) &v,
  453. $&1_descriptor,0) != -1) {
  454. $1 = 1;
  455. } else if (SvROK($input)) {
  456. /* native sequence? */
  457. AV *av = (AV *)SvRV($input);
  458. if (SvTYPE(av) == SVt_PVAV) {
  459. I32 len = av_len(av) + 1;
  460. if (len == 0) {
  461. /* an empty sequence can be of any type */
  462. $1 = 1;
  463. } else {
  464. /* check the first element only */
  465. SV **tv = av_fetch(av, 0, 0);
  466. if (CHECK_T(*tv))
  467. $1 = 1;
  468. else
  469. $1 = 0;
  470. }
  471. }
  472. } else {
  473. $1 = 0;
  474. }
  475. }
  476. }
  477. %typecheck(SWIG_TYPECHECK_VECTOR) const vector<T>&,
  478. const vector<T>* {
  479. {
  480. /* wrapped vector? */
  481. std::vector<T >* v;
  482. if (SWIG_ConvertPtr($input,(void **) &v,
  483. $1_descriptor,0) != -1) {
  484. $1 = 1;
  485. } else if (SvROK($input)) {
  486. /* native sequence? */
  487. AV *av = (AV *)SvRV($input);
  488. if (SvTYPE(av) == SVt_PVAV) {
  489. I32 len = av_len(av) + 1;
  490. if (len == 0) {
  491. /* an empty sequence can be of any type */
  492. $1 = 1;
  493. } else {
  494. /* check the first element only */
  495. SV **tv = av_fetch(av, 0, 0);
  496. if (CHECK_T(*tv))
  497. $1 = 1;
  498. else
  499. $1 = 0;
  500. }
  501. }
  502. } else {
  503. $1 = 0;
  504. }
  505. }
  506. }
  507. public:
  508. vector(unsigned int size = 0);
  509. vector(unsigned int size, T value);
  510. vector(const vector<T> &);
  511. unsigned int size() const;
  512. bool empty() const;
  513. void clear();
  514. %rename(push) push_back;
  515. void push_back(T x);
  516. %extend {
  517. T pop() throw (std::out_of_range) {
  518. if (self->size() == 0)
  519. throw std::out_of_range("pop from empty vector");
  520. T x = self->back();
  521. self->pop_back();
  522. return x;
  523. }
  524. T get(int i) throw (std::out_of_range) {
  525. int size = int(self->size());
  526. if (i>=0 && i<size)
  527. return (*self)[i];
  528. else
  529. throw std::out_of_range("vector index out of range");
  530. }
  531. void set(int i, T x) throw (std::out_of_range) {
  532. int size = int(self->size());
  533. if (i>=0 && i<size)
  534. (*self)[i] = x;
  535. else
  536. throw std::out_of_range("vector index out of range");
  537. }
  538. }
  539. };
  540. %enddef
  541. specialize_std_vector(bool,SvIOK,SvIVX,sv_setiv);
  542. specialize_std_vector(char,SvIOK,SvIVX,sv_setiv);
  543. specialize_std_vector(int,SvIOK,SvIVX,sv_setiv);
  544. specialize_std_vector(short,SvIOK,SvIVX,sv_setiv);
  545. specialize_std_vector(long,SvIOK,SvIVX,sv_setiv);
  546. specialize_std_vector(unsigned char,SvIOK,SvIVX,sv_setiv);
  547. specialize_std_vector(unsigned int,SvIOK,SvIVX,sv_setiv);
  548. specialize_std_vector(unsigned short,SvIOK,SvIVX,sv_setiv);
  549. specialize_std_vector(unsigned long,SvIOK,SvIVX,sv_setiv);
  550. specialize_std_vector(float,SvNIOK,SwigSvToNumber,sv_setnv);
  551. specialize_std_vector(double,SvNIOK,SwigSvToNumber,sv_setnv);
  552. specialize_std_vector(std::string,SvPOK,SwigSvToString,SwigSvFromString);
  553. }