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.

436 lines
18 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
  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. // MzScheme as much as possible, namely, to allow the user to pass and
  15. // be returned MzScheme vectors or lists.
  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 MzScheme 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 MzScheme vector of T:s
  27. // is returned which is most easily used in other MzScheme 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> {
  42. if (SCHEME_VECTORP($input)) {
  43. unsigned int size = SCHEME_VEC_SIZE($input);
  44. $1 = std::vector<T >(size);
  45. Scheme_Object** items = SCHEME_VEC_ELS($input);
  46. for (unsigned int i=0; i<size; i++) {
  47. (($1_type &)$1)[i] =
  48. *((T*) SWIG_MustGetPtr(items[i],
  49. $descriptor(T *),
  50. $argnum, 0));
  51. }
  52. } else if (SCHEME_NULLP($input)) {
  53. $1 = std::vector<T >();
  54. } else if (SCHEME_PAIRP($input)) {
  55. Scheme_Object *head, *tail;
  56. $1 = std::vector<T >();
  57. tail = $input;
  58. while (!SCHEME_NULLP(tail)) {
  59. head = scheme_car(tail);
  60. tail = scheme_cdr(tail);
  61. $1.push_back(*((T*)SWIG_MustGetPtr(head,
  62. $descriptor(T *),
  63. $argnum, 0)));
  64. }
  65. } else {
  66. $1 = *(($&1_type)
  67. SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0));
  68. }
  69. }
  70. %typemap(in) const vector<T>& (std::vector<T> temp),
  71. const vector<T>* (std::vector<T> temp) {
  72. if (SCHEME_VECTORP($input)) {
  73. unsigned int size = SCHEME_VEC_SIZE($input);
  74. temp = std::vector<T >(size);
  75. $1 = &temp;
  76. Scheme_Object** items = SCHEME_VEC_ELS($input);
  77. for (unsigned int i=0; i<size; i++) {
  78. temp[i] = *((T*) SWIG_MustGetPtr(items[i],
  79. $descriptor(T *),
  80. $argnum, 0));
  81. }
  82. } else if (SCHEME_NULLP($input)) {
  83. temp = std::vector<T >();
  84. $1 = &temp;
  85. } else if (SCHEME_PAIRP($input)) {
  86. temp = std::vector<T >();
  87. $1 = &temp;
  88. Scheme_Object *head, *tail;
  89. tail = $input;
  90. while (!SCHEME_NULLP(tail)) {
  91. head = scheme_car(tail);
  92. tail = scheme_cdr(tail);
  93. temp.push_back(*((T*) SWIG_MustGetPtr(head,
  94. $descriptor(T *),
  95. $argnum, 0)));
  96. }
  97. } else {
  98. $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum, 0);
  99. }
  100. }
  101. %typemap(out) vector<T> {
  102. $result = scheme_make_vector($1.size(),scheme_undefined);
  103. Scheme_Object** els = SCHEME_VEC_ELS($result);
  104. for (unsigned int i=0; i<$1.size(); i++) {
  105. T* x = new T((($1_type &)$1)[i]);
  106. els[i] = SWIG_NewPointerObj(x,$descriptor(T *), 1);
  107. }
  108. }
  109. %typecheck(SWIG_TYPECHECK_VECTOR) vector<T> {
  110. /* native sequence? */
  111. if (SCHEME_VECTORP($input)) {
  112. unsigned int size = SCHEME_VEC_SIZE($input);
  113. if (size == 0) {
  114. /* an empty sequence can be of any type */
  115. $1 = 1;
  116. } else {
  117. /* check the first element only */
  118. T* x;
  119. Scheme_Object** items = SCHEME_VEC_ELS($input);
  120. if (SWIG_ConvertPtr(items[0],(void**) &x,
  121. $descriptor(T *), 0) != -1)
  122. $1 = 1;
  123. else
  124. $1 = 0;
  125. }
  126. } else if (SCHEME_NULLP($input)) {
  127. /* again, an empty sequence can be of any type */
  128. $1 = 1;
  129. } else if (SCHEME_PAIRP($input)) {
  130. /* check the first element only */
  131. T* x;
  132. Scheme_Object *head = scheme_car($input);
  133. if (SWIG_ConvertPtr(head,(void**) &x,
  134. $descriptor(T *), 0) != -1)
  135. $1 = 1;
  136. else
  137. $1 = 0;
  138. } else {
  139. /* wrapped vector? */
  140. std::vector<T >* v;
  141. if (SWIG_ConvertPtr($input,(void **) &v,
  142. $&1_descriptor, 0) != -1)
  143. $1 = 1;
  144. else
  145. $1 = 0;
  146. }
  147. }
  148. %typecheck(SWIG_TYPECHECK_VECTOR) const vector<T>&,
  149. const vector<T>* {
  150. /* native sequence? */
  151. if (SCHEME_VECTORP($input)) {
  152. unsigned int size = SCHEME_VEC_SIZE($input);
  153. if (size == 0) {
  154. /* an empty sequence can be of any type */
  155. $1 = 1;
  156. } else {
  157. /* check the first element only */
  158. T* x;
  159. Scheme_Object** items = SCHEME_VEC_ELS($input);
  160. if (SWIG_ConvertPtr(items[0],(void**) &x,
  161. $descriptor(T *), 0) != -1)
  162. $1 = 1;
  163. else
  164. $1 = 0;
  165. }
  166. } else if (SCHEME_NULLP($input)) {
  167. /* again, an empty sequence can be of any type */
  168. $1 = 1;
  169. } else if (SCHEME_PAIRP($input)) {
  170. /* check the first element only */
  171. T* x;
  172. Scheme_Object *head = scheme_car($input);
  173. if (SWIG_ConvertPtr(head,(void**) &x,
  174. $descriptor(T *), 0) != -1)
  175. $1 = 1;
  176. else
  177. $1 = 0;
  178. } else {
  179. /* wrapped vector? */
  180. std::vector<T >* v;
  181. if (SWIG_ConvertPtr($input,(void **) &v,
  182. $1_descriptor, 0) != -1)
  183. $1 = 1;
  184. else
  185. $1 = 0;
  186. }
  187. }
  188. public:
  189. vector(unsigned int size = 0);
  190. vector(unsigned int size, const T& value);
  191. vector(const vector<T>&);
  192. %rename(length) size;
  193. unsigned int size() const;
  194. %rename("empty?") empty;
  195. bool empty() const;
  196. %rename("clear!") clear;
  197. void clear();
  198. %rename("set!") set;
  199. %rename("pop!") pop;
  200. %rename("push!") push_back;
  201. void push_back(const T& x);
  202. %extend {
  203. T pop() throw (std::out_of_range) {
  204. if (self->size() == 0)
  205. throw std::out_of_range("pop from empty vector");
  206. T x = self->back();
  207. self->pop_back();
  208. return x;
  209. }
  210. T& ref(int i) throw (std::out_of_range) {
  211. int size = int(self->size());
  212. if (i>=0 && i<size)
  213. return (*self)[i];
  214. else
  215. throw std::out_of_range("vector index out of range");
  216. }
  217. void set(int i, const T& x) throw (std::out_of_range) {
  218. int size = int(self->size());
  219. if (i>=0 && i<size)
  220. (*self)[i] = x;
  221. else
  222. throw std::out_of_range("vector index out of range");
  223. }
  224. }
  225. };
  226. // specializations for built-ins
  227. %define specialize_std_vector(T,CHECK,CONVERT_FROM,CONVERT_TO)
  228. template<> class vector<T> {
  229. %typemap(in) vector<T> {
  230. if (SCHEME_VECTORP($input)) {
  231. unsigned int size = SCHEME_VEC_SIZE($input);
  232. $1 = std::vector<T >(size);
  233. Scheme_Object** items = SCHEME_VEC_ELS($input);
  234. for (unsigned int i=0; i<size; i++) {
  235. Scheme_Object* o = items[i];
  236. if (CHECK(o))
  237. (($1_type &)$1)[i] = (T)(CONVERT_FROM(o));
  238. else
  239. scheme_wrong_type(FUNC_NAME, "vector<" #T ">",
  240. $argnum - 1, argc, argv);
  241. }
  242. } else if (SCHEME_NULLP($input)) {
  243. $1 = std::vector<T >();
  244. } else if (SCHEME_PAIRP($input)) {
  245. Scheme_Object *head, *tail;
  246. $1 = std::vector<T >();
  247. tail = $input;
  248. while (!SCHEME_NULLP(tail)) {
  249. head = scheme_car(tail);
  250. tail = scheme_cdr(tail);
  251. if (CHECK(head))
  252. $1.push_back((T)(CONVERT_FROM(head)));
  253. else
  254. scheme_wrong_type(FUNC_NAME, "vector<" #T ">",
  255. $argnum - 1, argc, argv);
  256. }
  257. } else {
  258. $1 = *(($&1_type)
  259. SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0));
  260. }
  261. }
  262. %typemap(in) const vector<T>& (std::vector<T> temp),
  263. const vector<T>* (std::vector<T> temp) {
  264. if (SCHEME_VECTORP($input)) {
  265. unsigned int size = SCHEME_VEC_SIZE($input);
  266. temp = std::vector<T >(size);
  267. $1 = &temp;
  268. Scheme_Object** items = SCHEME_VEC_ELS($input);
  269. for (unsigned int i=0; i<size; i++) {
  270. Scheme_Object* o = items[i];
  271. if (CHECK(o))
  272. temp[i] = (T)(CONVERT_FROM(o));
  273. else
  274. scheme_wrong_type(FUNC_NAME, "vector<" #T ">",
  275. $argnum - 1, argc, argv);
  276. }
  277. } else if (SCHEME_NULLP($input)) {
  278. temp = std::vector<T >();
  279. $1 = &temp;
  280. } else if (SCHEME_PAIRP($input)) {
  281. temp = std::vector<T >();
  282. $1 = &temp;
  283. Scheme_Object *head, *tail;
  284. tail = $input;
  285. while (!SCHEME_NULLP(tail)) {
  286. head = scheme_car(tail);
  287. tail = scheme_cdr(tail);
  288. if (CHECK(head))
  289. temp.push_back((T)(CONVERT_FROM(head)));
  290. else
  291. scheme_wrong_type(FUNC_NAME, "vector<" #T ">",
  292. $argnum - 1, argc, argv);
  293. }
  294. } else {
  295. $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum - 1, 0);
  296. }
  297. }
  298. %typemap(out) vector<T> {
  299. $result = scheme_make_vector($1.size(),scheme_undefined);
  300. Scheme_Object** els = SCHEME_VEC_ELS($result);
  301. for (unsigned int i=0; i<$1.size(); i++)
  302. els[i] = CONVERT_TO((($1_type &)$1)[i]);
  303. }
  304. %typecheck(SWIG_TYPECHECK_VECTOR) vector<T> {
  305. /* native sequence? */
  306. if (SCHEME_VECTORP($input)) {
  307. unsigned int size = SCHEME_VEC_SIZE($input);
  308. if (size == 0) {
  309. /* an empty sequence can be of any type */
  310. $1 = 1;
  311. } else {
  312. /* check the first element only */
  313. T* x;
  314. Scheme_Object** items = SCHEME_VEC_ELS($input);
  315. $1 = CHECK(items[0]) ? 1 : 0;
  316. }
  317. } else if (SCHEME_NULLP($input)) {
  318. /* again, an empty sequence can be of any type */
  319. $1 = 1;
  320. } else if (SCHEME_PAIRP($input)) {
  321. /* check the first element only */
  322. T* x;
  323. Scheme_Object *head = scheme_car($input);
  324. $1 = CHECK(head) ? 1 : 0;
  325. } else {
  326. /* wrapped vector? */
  327. std::vector<T >* v;
  328. $1 = (SWIG_ConvertPtr($input,(void **) &v,
  329. $&1_descriptor, 0) != -1) ? 1 : 0;
  330. }
  331. }
  332. %typecheck(SWIG_TYPECHECK_VECTOR) const vector<T>&,
  333. const vector<T>* {
  334. /* native sequence? */
  335. if (SCHEME_VECTORP($input)) {
  336. unsigned int size = SCHEME_VEC_SIZE($input);
  337. if (size == 0) {
  338. /* an empty sequence can be of any type */
  339. $1 = 1;
  340. } else {
  341. /* check the first element only */
  342. T* x;
  343. Scheme_Object** items = SCHEME_VEC_ELS($input);
  344. $1 = CHECK(items[0]) ? 1 : 0;
  345. }
  346. } else if (SCHEME_NULLP($input)) {
  347. /* again, an empty sequence can be of any type */
  348. $1 = 1;
  349. } else if (SCHEME_PAIRP($input)) {
  350. /* check the first element only */
  351. T* x;
  352. Scheme_Object *head = scheme_car($input);
  353. $1 = CHECK(head) ? 1 : 0;
  354. } else {
  355. /* wrapped vector? */
  356. std::vector<T >* v;
  357. $1 = (SWIG_ConvertPtr($input,(void **) &v,
  358. $1_descriptor, 0) != -1) ? 1 : 0;
  359. }
  360. }
  361. public:
  362. vector(unsigned int size = 0);
  363. vector(unsigned int size, const T& value);
  364. vector(const vector<T>&);
  365. %rename(length) size;
  366. unsigned int size() const;
  367. %rename("empty?") empty;
  368. bool empty() const;
  369. %rename("clear!") clear;
  370. void clear();
  371. %rename("set!") set;
  372. %rename("pop!") pop;
  373. %rename("push!") push_back;
  374. void push_back(T x);
  375. %extend {
  376. T pop() throw (std::out_of_range) {
  377. if (self->size() == 0)
  378. throw std::out_of_range("pop from empty vector");
  379. T x = self->back();
  380. self->pop_back();
  381. return x;
  382. }
  383. T ref(int i) throw (std::out_of_range) {
  384. int size = int(self->size());
  385. if (i>=0 && i<size)
  386. return (*self)[i];
  387. else
  388. throw std::out_of_range("vector index out of range");
  389. }
  390. void set(int i, T x) throw (std::out_of_range) {
  391. int size = int(self->size());
  392. if (i>=0 && i<size)
  393. (*self)[i] = x;
  394. else
  395. throw std::out_of_range("vector index out of range");
  396. }
  397. }
  398. };
  399. %enddef
  400. specialize_std_vector(bool,SCHEME_BOOLP,SCHEME_TRUEP,\
  401. swig_make_boolean);
  402. specialize_std_vector(char,SCHEME_INTP,SCHEME_INT_VAL,\
  403. scheme_make_integer_value);
  404. specialize_std_vector(int,SCHEME_INTP,SCHEME_INT_VAL,\
  405. scheme_make_integer_value);
  406. specialize_std_vector(short,SCHEME_INTP,SCHEME_INT_VAL,\
  407. scheme_make_integer_value);
  408. specialize_std_vector(long,SCHEME_INTP,SCHEME_INT_VAL,\
  409. scheme_make_integer_value);
  410. specialize_std_vector(unsigned char,SCHEME_INTP,SCHEME_INT_VAL,\
  411. scheme_make_integer_value);
  412. specialize_std_vector(unsigned int,SCHEME_INTP,SCHEME_INT_VAL,\
  413. scheme_make_integer_value);
  414. specialize_std_vector(unsigned short,SCHEME_INTP,SCHEME_INT_VAL,\
  415. scheme_make_integer_value);
  416. specialize_std_vector(unsigned long,SCHEME_INTP,SCHEME_INT_VAL,\
  417. scheme_make_integer_value);
  418. specialize_std_vector(float,SCHEME_REALP,scheme_real_to_double,\
  419. scheme_make_double);
  420. specialize_std_vector(double,SCHEME_REALP,scheme_real_to_double,\
  421. scheme_make_double);
  422. specialize_std_vector(std::string,SCHEME_STRINGP,swig_scm_to_string,\
  423. swig_make_string);
  424. }