Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

571 lines
22 KiB

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