PageRenderTime 50ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/trunk/Lib/perl5/std_list.i

#
Swig | 365 lines | 328 code | 16 blank | 21 comment | 0 complexity | 975d25628fa9aa42355e83a6de59cd69 MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
  1. /* -----------------------------------------------------------------------------
  2. * std_list.i
  3. *
  4. * SWIG typemaps for std::list types
  5. * ----------------------------------------------------------------------------- */
  6. %include <std_common.i>
  7. %include <exception.i>
  8. // containers
  9. // ------------------------------------------------------------------------
  10. // std::list
  11. //
  12. // The aim of all that follows would be to integrate std::list with
  13. // Perl as much as possible, namely, to allow the user to pass and
  14. // be returned Perl arrays.
  15. // const declarations are used to guess the intent of the function being
  16. // exported; therefore, the following rationale is applied:
  17. //
  18. // -- f(std::list<T>), f(const std::list<T>&), f(const std::list<T>*):
  19. // the parameter being read-only, either a Perl sequence or a
  20. // previously wrapped std::list<T> can be passed.
  21. // -- f(std::list<T>&), f(std::list<T>*):
  22. // the parameter must be modified; therefore, only a wrapped std::list
  23. // can be passed.
  24. // -- std::list<T> f():
  25. // the list is returned by copy; therefore, a Perl sequence of T:s
  26. // is returned which is most easily used in other Perl functions
  27. // -- std::list<T>& f(), std::list<T>* f(), const std::list<T>& f(),
  28. // const std::list<T>* f():
  29. // the list is returned by reference; therefore, a wrapped std::list
  30. // is returned
  31. // ------------------------------------------------------------------------
  32. %{
  33. #include <list>
  34. #include <algorithm>
  35. #include <stdexcept>
  36. %}
  37. // exported class
  38. namespace std {
  39. template<class T> class list {
  40. %typemap(in) list<T> (std::list<T>* v) {
  41. if (SWIG_ConvertPtr($input,(void **) &v,
  42. $&1_descriptor,1) != -1) {
  43. $1 = *v;
  44. } else if (SvROK($input)) {
  45. AV *av = (AV *)SvRV($input);
  46. if (SvTYPE(av) != SVt_PVAV)
  47. SWIG_croak("Type error in argument $argnum of $symname. "
  48. "Expected an array of " #T);
  49. SV **tv;
  50. I32 len = av_len(av) + 1;
  51. T* obj;
  52. for (int i=0; i<len; i++) {
  53. tv = av_fetch(av, i, 0);
  54. if (SWIG_ConvertPtr(*tv, (void **)&obj,
  55. $descriptor(T *),0) != -1) {
  56. $1.push_back(*obj);
  57. } else {
  58. SWIG_croak("Type error in argument $argnum of "
  59. "$symname. "
  60. "Expected an array of " #T);
  61. }
  62. }
  63. } else {
  64. SWIG_croak("Type error in argument $argnum of $symname. "
  65. "Expected an array of " #T);
  66. }
  67. }
  68. %typemap(in) const list<T>& (std::list<T> temp,
  69. std::list<T>* v),
  70. const list<T>* (std::list<T> temp,
  71. std::list<T>* v) {
  72. if (SWIG_ConvertPtr($input,(void **) &v,
  73. $1_descriptor,1) != -1) {
  74. $1 = v;
  75. } else if (SvROK($input)) {
  76. AV *av = (AV *)SvRV($input);
  77. if (SvTYPE(av) != SVt_PVAV)
  78. SWIG_croak("Type error in argument $argnum of $symname. "
  79. "Expected an array of " #T);
  80. SV **tv;
  81. I32 len = av_len(av) + 1;
  82. T* obj;
  83. for (int i=0; i<len; i++) {
  84. tv = av_fetch(av, i, 0);
  85. if (SWIG_ConvertPtr(*tv, (void **)&obj,
  86. $descriptor(T *),0) != -1) {
  87. temp.push_back(*obj);
  88. } else {
  89. SWIG_croak("Type error in argument $argnum of "
  90. "$symname. "
  91. "Expected an array of " #T);
  92. }
  93. }
  94. $1 = &temp;
  95. } else {
  96. SWIG_croak("Type error in argument $argnum of $symname. "
  97. "Expected an array of " #T);
  98. }
  99. }
  100. %typemap(out) list<T> {
  101. std::list<T>::const_iterator i;
  102. unsigned int j;
  103. int len = $1.size();
  104. SV **svs = new SV*[len];
  105. for (i=$1.begin(), j=0; i!=$1.end(); i++, j++) {
  106. T* ptr = new T(*i);
  107. svs[j] = sv_newmortal();
  108. SWIG_MakePtr(svs[j], (void*) ptr,
  109. $descriptor(T *), $shadow|$owner);
  110. }
  111. AV *myav = av_make(len, svs);
  112. delete[] svs;
  113. $result = newRV_noinc((SV*) myav);
  114. sv_2mortal($result);
  115. argvi++;
  116. }
  117. %typecheck(SWIG_TYPECHECK_LIST) list<T> {
  118. {
  119. /* wrapped list? */
  120. std::list<T >* v;
  121. if (SWIG_ConvertPtr($input,(void **) &v,
  122. $1_&descriptor,0) != -1) {
  123. $1 = 1;
  124. } else if (SvROK($input)) {
  125. /* native sequence? */
  126. AV *av = (AV *)SvRV($input);
  127. if (SvTYPE(av) == SVt_PVAV) {
  128. SV **tv;
  129. I32 len = av_len(av) + 1;
  130. if (len == 0) {
  131. /* an empty sequence can be of any type */
  132. $1 = 1;
  133. } else {
  134. /* check the first element only */
  135. T* obj;
  136. tv = av_fetch(av, 0, 0);
  137. if (SWIG_ConvertPtr(*tv, (void **)&obj,
  138. $descriptor(T *),0) != -1)
  139. $1 = 1;
  140. else
  141. $1 = 0;
  142. }
  143. }
  144. } else {
  145. $1 = 0;
  146. }
  147. }
  148. }
  149. %typecheck(SWIG_TYPECHECK_LIST) const list<T>&,
  150. const list<T>* {
  151. {
  152. /* wrapped list? */
  153. std::list<T >* v;
  154. if (SWIG_ConvertPtr($input,(void **) &v,
  155. $1_descriptor,0) != -1) {
  156. $1 = 1;
  157. } else if (SvROK($input)) {
  158. /* native sequence? */
  159. AV *av = (AV *)SvRV($input);
  160. if (SvTYPE(av) == SVt_PVAV) {
  161. SV **tv;
  162. I32 len = av_len(av) + 1;
  163. if (len == 0) {
  164. /* an empty sequence can be of any type */
  165. $1 = 1;
  166. } else {
  167. /* check the first element only */
  168. T* obj;
  169. tv = av_fetch(av, 0, 0);
  170. if (SWIG_ConvertPtr(*tv, (void **)&obj,
  171. $descriptor(T *),0) != -1)
  172. $1 = 1;
  173. else
  174. $1 = 0;
  175. }
  176. }
  177. } else {
  178. $1 = 0;
  179. }
  180. }
  181. }
  182. public:
  183. list();
  184. list(const list<T> &);
  185. unsigned int size() const;
  186. bool empty() const;
  187. void clear();
  188. %rename(push) push_back;
  189. void push_back(const T& x);
  190. };
  191. // specializations for built-ins
  192. %define specialize_std_list(T,CHECK_T,TO_T,FROM_T)
  193. template<> class list<T> {
  194. %typemap(in) list<T> (std::list<T>* v) {
  195. if (SWIG_ConvertPtr($input,(void **) &v,
  196. $&1_descriptor,1) != -1){
  197. $1 = *v;
  198. } else if (SvROK($input)) {
  199. AV *av = (AV *)SvRV($input);
  200. if (SvTYPE(av) != SVt_PVAV)
  201. SWIG_croak("Type error in argument $argnum of $symname. "
  202. "Expected an array of " #T);
  203. SV **tv;
  204. I32 len = av_len(av) + 1;
  205. for (int i=0; i<len; i++) {
  206. tv = av_fetch(av, i, 0);
  207. if (CHECK_T(*tv)) {
  208. $1.push_back(TO_T(*tv));
  209. } else {
  210. SWIG_croak("Type error in argument $argnum of "
  211. "$symname. "
  212. "Expected an array of " #T);
  213. }
  214. }
  215. } else {
  216. SWIG_croak("Type error in argument $argnum of $symname. "
  217. "Expected an array of " #T);
  218. }
  219. }
  220. %typemap(in) const list<T>& (std::list<T> temp,
  221. std::list<T>* v),
  222. const list<T>* (std::list<T> temp,
  223. std::list<T>* v) {
  224. if (SWIG_ConvertPtr($input,(void **) &v,
  225. $1_descriptor,1) != -1) {
  226. $1 = v;
  227. } else if (SvROK($input)) {
  228. AV *av = (AV *)SvRV($input);
  229. if (SvTYPE(av) != SVt_PVAV)
  230. SWIG_croak("Type error in argument $argnum of $symname. "
  231. "Expected an array of " #T);
  232. SV **tv;
  233. I32 len = av_len(av) + 1;
  234. T* obj;
  235. for (int i=0; i<len; i++) {
  236. tv = av_fetch(av, i, 0);
  237. if (CHECK_T(*tv)) {
  238. temp.push_back(TO_T(*tv));
  239. } else {
  240. SWIG_croak("Type error in argument $argnum of "
  241. "$symname. "
  242. "Expected an array of " #T);
  243. }
  244. }
  245. $1 = &temp;
  246. } else {
  247. SWIG_croak("Type error in argument $argnum of $symname. "
  248. "Expected an array of " #T);
  249. }
  250. }
  251. %typemap(out) list<T> {
  252. std::list<T>::const_iterator i;
  253. unsigned int j;
  254. int len = $1.size();
  255. SV **svs = new SV*[len];
  256. for (i=$1.begin(), j=0; i!=$1.end(); i++, j++) {
  257. svs[j] = sv_newmortal();
  258. FROM_T(svs[j], *i);
  259. }
  260. AV *myav = av_make(len, svs);
  261. delete[] svs;
  262. $result = newRV_noinc((SV*) myav);
  263. sv_2mortal($result);
  264. argvi++;
  265. }
  266. %typecheck(SWIG_TYPECHECK_LIST) list<T> {
  267. {
  268. /* wrapped list? */
  269. std::list<T >* v;
  270. if (SWIG_ConvertPtr($input,(void **) &v,
  271. $1_&descriptor,0) != -1) {
  272. $1 = 1;
  273. } else if (SvROK($input)) {
  274. /* native sequence? */
  275. AV *av = (AV *)SvRV($input);
  276. if (SvTYPE(av) == SVt_PVAV) {
  277. SV **tv;
  278. I32 len = av_len(av) + 1;
  279. if (len == 0) {
  280. /* an empty sequence can be of any type */
  281. $1 = 1;
  282. } else {
  283. /* check the first element only */
  284. tv = av_fetch(av, 0, 0);
  285. if (CHECK_T(*tv))
  286. $1 = 1;
  287. else
  288. $1 = 0;
  289. }
  290. }
  291. } else {
  292. $1 = 0;
  293. }
  294. }
  295. }
  296. %typecheck(SWIG_TYPECHECK_LIST) const list<T>&,
  297. const list<T>* {
  298. {
  299. /* wrapped list? */
  300. std::list<T >* v;
  301. if (SWIG_ConvertPtr($input,(void **) &v,
  302. $1_descriptor,0) != -1) {
  303. $1 = 1;
  304. } else if (SvROK($input)) {
  305. /* native sequence? */
  306. AV *av = (AV *)SvRV($input);
  307. if (SvTYPE(av) == SVt_PVAV) {
  308. SV **tv;
  309. I32 len = av_len(av) + 1;
  310. if (len == 0) {
  311. /* an empty sequence can be of any type */
  312. $1 = 1;
  313. } else {
  314. /* check the first element only */
  315. tv = av_fetch(av, 0, 0);
  316. if (CHECK_T(*tv))
  317. $1 = 1;
  318. else
  319. $1 = 0;
  320. }
  321. }
  322. } else {
  323. $1 = 0;
  324. }
  325. }
  326. }
  327. public:
  328. list();
  329. list(const list<T> &);
  330. unsigned int size() const;
  331. bool empty() const;
  332. void clear();
  333. %rename(push) push_back;
  334. void push_back(T x);
  335. };
  336. %enddef
  337. specialize_std_list(bool,SvIOK,SvIVX,sv_setiv);
  338. specialize_std_list(char,SvIOK,SvIVX,sv_setiv);
  339. specialize_std_list(int,SvIOK,SvIVX,sv_setiv);
  340. specialize_std_list(short,SvIOK,SvIVX,sv_setiv);
  341. specialize_std_list(long,SvIOK,SvIVX,sv_setiv);
  342. specialize_std_list(unsigned char,SvIOK,SvIVX,sv_setiv);
  343. specialize_std_list(unsigned int,SvIOK,SvIVX,sv_setiv);
  344. specialize_std_list(unsigned short,SvIOK,SvIVX,sv_setiv);
  345. specialize_std_list(unsigned long,SvIOK,SvIVX,sv_setiv);
  346. specialize_std_list(float,SvNIOK,SwigSvToNumber,sv_setnv);
  347. specialize_std_list(double,SvNIOK,SwigSvToNumber,sv_setnv);
  348. specialize_std_list(std::string,SvPOK,SvPVX,SwigSvFromString);
  349. }