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.

422 lines
15 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. %include <std_common.i>
  8. // ------------------------------------------------------------------------
  9. // std::vector
  10. //
  11. // The aim of all that follows would be to integrate std::vector with
  12. // Tcl as much as possible, namely, to allow the user to pass and
  13. // be returned Tcl lists.
  14. // const declarations are used to guess the intent of the function being
  15. // exported; therefore, the following rationale is applied:
  16. //
  17. // -- f(std::vector<T>), f(const std::vector<T>&), f(const std::vector<T>*):
  18. // the parameter being read-only, either a Tcl list or a
  19. // previously wrapped std::vector<T> can be passed.
  20. // -- f(std::vector<T>&), f(std::vector<T>*):
  21. // the parameter must be modified; therefore, only a wrapped std::vector
  22. // can be passed.
  23. // -- std::vector<T> f():
  24. // the vector is returned by copy; therefore, a Tcl list of T:s
  25. // is returned which is most easily used in other Tcl functions procs
  26. // -- std::vector<T>& f(), std::vector<T>* f(), const std::vector<T>& f(),
  27. // const std::vector<T>* f():
  28. // the vector is returned by reference; therefore, a wrapped std::vector
  29. // is returned
  30. // ------------------------------------------------------------------------
  31. %{
  32. #include <vector>
  33. #include <algorithm>
  34. #include <stdexcept>
  35. #include <string>
  36. Tcl_Obj* SwigString_FromString(const std::string &s) {
  37. return Tcl_NewStringObj(s.data(), (int)s.length());
  38. }
  39. int Tcl_GetBoolFromObj(Tcl_Interp *interp, Tcl_Obj *o, bool *val) {
  40. int v;
  41. int res = Tcl_GetBooleanFromObj(interp, o, &v);
  42. if (res == TCL_OK) {
  43. *val = v ? true : false;
  44. }
  45. return res;
  46. }
  47. int SwigString_AsString(Tcl_Interp *interp, Tcl_Obj *o, std::string *val) {
  48. int len;
  49. const char* temp = Tcl_GetStringFromObj(o, &len);
  50. if (temp == NULL)
  51. return TCL_ERROR;
  52. val->assign(temp, len);
  53. return TCL_OK;
  54. }
  55. // behaviour of this is such as the real Tcl_GetIntFromObj
  56. template <typename Type>
  57. int SwigInt_As(Tcl_Interp *interp, Tcl_Obj *o, Type *val) {
  58. int temp_val, return_val;
  59. return_val = Tcl_GetIntFromObj(interp, o, &temp_val);
  60. *val = (Type) temp_val;
  61. return return_val;
  62. }
  63. // behaviour of this is such as the real Tcl_GetDoubleFromObj
  64. template <typename Type>
  65. int SwigDouble_As(Tcl_Interp *interp, Tcl_Obj *o, Type *val) {
  66. int return_val;
  67. double temp_val;
  68. return_val = Tcl_GetDoubleFromObj(interp, o, &temp_val);
  69. *val = (Type) temp_val;
  70. return return_val;
  71. }
  72. %}
  73. // exported class
  74. namespace std {
  75. template<class T> class vector {
  76. %typemap(in) vector<T> (std::vector<T> *v) {
  77. Tcl_Obj **listobjv;
  78. int nitems;
  79. int i;
  80. T* temp;
  81. if (SWIG_ConvertPtr($input, (void **) &v, \
  82. $&1_descriptor, 0) == 0){
  83. $1 = *v;
  84. } else {
  85. // It isn't a vector<T> so it should be a list of T's
  86. if(Tcl_ListObjGetElements(interp, $input, \
  87. &nitems, &listobjv) == TCL_ERROR)
  88. return TCL_ERROR;
  89. $1 = std::vector<T>();
  90. for (i = 0; i < nitems; i++) {
  91. if ((SWIG_ConvertPtr(listobjv[i],(void **) &temp,
  92. $descriptor(T *),0)) != 0) {
  93. char message[] =
  94. "list of " #T " expected";
  95. Tcl_SetResult(interp, message, TCL_VOLATILE);
  96. return TCL_ERROR;
  97. }
  98. $1.push_back(*temp);
  99. }
  100. }
  101. }
  102. %typemap(in) const vector<T>* (std::vector<T> *v, std::vector<T> w),
  103. const vector<T>& (std::vector<T> *v, std::vector<T> w) {
  104. Tcl_Obj **listobjv;
  105. int nitems;
  106. int i;
  107. T* temp;
  108. if(SWIG_ConvertPtr($input, (void **) &v, \
  109. $&1_descriptor, 0) == 0) {
  110. $1 = v;
  111. } else {
  112. // It isn't a vector<T> so it should be a list of T's
  113. if(Tcl_ListObjGetElements(interp, $input,
  114. &nitems, &listobjv) == TCL_ERROR)
  115. return TCL_ERROR;
  116. w = std::vector<T>();
  117. for (i = 0; i < nitems; i++) {
  118. if ((SWIG_ConvertPtr(listobjv[i],(void **) &temp,
  119. $descriptor(T *),0)) != 0) {
  120. char message[] =
  121. "list of " #T " expected";
  122. Tcl_SetResult(interp, message, TCL_VOLATILE);
  123. return TCL_ERROR;
  124. }
  125. w.push_back(*temp);
  126. }
  127. $1 = &w;
  128. }
  129. }
  130. %typemap(out) vector<T> {
  131. for (unsigned int i=0; i<$1.size(); i++) {
  132. T* ptr = new T((($1_type &)$1)[i]);
  133. Tcl_ListObjAppendElement(interp, $result, \
  134. SWIG_NewInstanceObj(ptr,
  135. $descriptor(T *),
  136. 0));
  137. }
  138. }
  139. %typecheck(SWIG_TYPECHECK_VECTOR) vector<T> {
  140. Tcl_Obj **listobjv;
  141. int nitems;
  142. T* temp;
  143. std::vector<T> *v;
  144. if(SWIG_ConvertPtr($input, (void **) &v, \
  145. $&1_descriptor, 0) == 0) {
  146. /* wrapped vector */
  147. $1 = 1;
  148. } else {
  149. // It isn't a vector<T> so it should be a list of T's
  150. if(Tcl_ListObjGetElements(interp, $input,
  151. &nitems, &listobjv) == TCL_ERROR)
  152. $1 = 0;
  153. else
  154. if (nitems == 0)
  155. $1 = 1;
  156. //check the first value to see if it is of correct type
  157. else if ((SWIG_ConvertPtr(listobjv[0],
  158. (void **) &temp,
  159. $descriptor(T *),0)) != 0)
  160. $1 = 0;
  161. else
  162. $1 = 1;
  163. }
  164. }
  165. %typecheck(SWIG_TYPECHECK_VECTOR) const vector<T>&,
  166. const vector<T>* {
  167. Tcl_Obj **listobjv;
  168. int nitems;
  169. T* temp;
  170. std::vector<T> *v;
  171. if(SWIG_ConvertPtr($input, (void **) &v, \
  172. $1_descriptor, 0) == 0){
  173. /* wrapped vector */
  174. $1 = 1;
  175. } else {
  176. // It isn't a vector<T> so it should be a list of T's
  177. if(Tcl_ListObjGetElements(interp, $input,
  178. &nitems, &listobjv) == TCL_ERROR)
  179. $1 = 0;
  180. else
  181. if (nitems == 0)
  182. $1 = 1;
  183. //check the first value to see if it is of correct type
  184. else if ((SWIG_ConvertPtr(listobjv[0],
  185. (void **) &temp,
  186. $descriptor(T *),0)) != 0)
  187. $1 = 0;
  188. else
  189. $1 = 1;
  190. }
  191. }
  192. public:
  193. vector(unsigned int size = 0);
  194. vector(unsigned int size, const T& value);
  195. vector(const vector<T> &);
  196. unsigned int size() const;
  197. bool empty() const;
  198. void clear();
  199. %rename(push) push_back;
  200. void push_back(const T& x);
  201. %extend {
  202. T pop() throw (std::out_of_range) {
  203. if (self->size() == 0)
  204. throw std::out_of_range("pop from empty vector");
  205. T x = self->back();
  206. self->pop_back();
  207. return x;
  208. }
  209. T& get(int i) throw (std::out_of_range) {
  210. int size = int(self->size());
  211. if (i<0) i += 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. if (i>=0 && i<size)
  221. (*self)[i] = x;
  222. else
  223. throw std::out_of_range("vector index out of range");
  224. }
  225. }
  226. };
  227. // specializations for built-ins
  228. %define specialize_std_vector(T, CONVERT_FROM, CONVERT_TO)
  229. template<> class vector<T> {
  230. %typemap(in) vector<T> (std::vector<T> *v){
  231. Tcl_Obj **listobjv;
  232. int nitems;
  233. int i;
  234. T temp;
  235. if(SWIG_ConvertPtr($input, (void **) &v, \
  236. $&1_descriptor, 0) == 0) {
  237. $1 = *v;
  238. } else {
  239. // It isn't a vector<T> so it should be a list of T's
  240. if(Tcl_ListObjGetElements(interp, $input,
  241. &nitems, &listobjv) == TCL_ERROR)
  242. return TCL_ERROR;
  243. $1 = std::vector<T>();
  244. for (i = 0; i < nitems; i++) {
  245. if (CONVERT_FROM(interp, listobjv[i], &temp) == TCL_ERROR)
  246. return TCL_ERROR;
  247. $1.push_back(temp);
  248. }
  249. }
  250. }
  251. %typemap(in) const vector<T>& (std::vector<T> *v,std::vector<T> w),
  252. const vector<T>* (std::vector<T> *v,std::vector<T> w) {
  253. Tcl_Obj **listobjv;
  254. int nitems;
  255. int i;
  256. T temp;
  257. if(SWIG_ConvertPtr($input, (void **) &v, \
  258. $1_descriptor, 0) == 0) {
  259. $1 = v;
  260. } else {
  261. // It isn't a vector<T> so it should be a list of T's
  262. if(Tcl_ListObjGetElements(interp, $input,
  263. &nitems, &listobjv) == TCL_ERROR)
  264. return TCL_ERROR;
  265. w = std::vector<T>();
  266. for (i = 0; i < nitems; i++) {
  267. if (CONVERT_FROM(interp, listobjv[i], &temp) == TCL_ERROR)
  268. return TCL_ERROR;
  269. w.push_back(temp);
  270. }
  271. $1 = &w;
  272. }
  273. }
  274. %typemap(out) vector<T> {
  275. for (unsigned int i=0; i<$1.size(); i++) {
  276. Tcl_ListObjAppendElement(interp, $result, \
  277. CONVERT_TO((($1_type &)$1)[i]));
  278. }
  279. }
  280. %typecheck(SWIG_TYPECHECK_VECTOR) vector<T> {
  281. Tcl_Obj **listobjv;
  282. int nitems;
  283. T temp;
  284. std::vector<T> *v;
  285. if(SWIG_ConvertPtr($input, (void **) &v, \
  286. $&1_descriptor, 0) == 0){
  287. /* wrapped vector */
  288. $1 = 1;
  289. } else {
  290. // It isn't a vector<T> so it should be a list of T's
  291. if(Tcl_ListObjGetElements(interp, $input,
  292. &nitems, &listobjv) == TCL_ERROR)
  293. $1 = 0;
  294. else
  295. if (nitems == 0)
  296. $1 = 1;
  297. //check the first value to see if it is of correct type
  298. if (CONVERT_FROM(interp, listobjv[0], &temp) == TCL_ERROR)
  299. $1 = 0;
  300. else
  301. $1 = 1;
  302. }
  303. }
  304. %typecheck(SWIG_TYPECHECK_VECTOR) const vector<T>&,
  305. const vector<T>*{
  306. Tcl_Obj **listobjv;
  307. int nitems;
  308. T temp;
  309. std::vector<T> *v;
  310. if(SWIG_ConvertPtr($input, (void **) &v, \
  311. $1_descriptor, 0) == 0){
  312. /* wrapped vector */
  313. $1 = 1;
  314. } else {
  315. // It isn't a vector<T> so it should be a list of T's
  316. if(Tcl_ListObjGetElements(interp, $input,
  317. &nitems, &listobjv) == TCL_ERROR)
  318. $1 = 0;
  319. else
  320. if (nitems == 0)
  321. $1 = 1;
  322. //check the first value to see if it is of correct type
  323. if (CONVERT_FROM(interp, listobjv[0], &temp) == TCL_ERROR)
  324. $1 = 0;
  325. else
  326. $1 = 1;
  327. }
  328. }
  329. public:
  330. vector(unsigned int size = 0);
  331. vector(unsigned int size, const T& value);
  332. vector(const vector<T> &);
  333. unsigned int size() const;
  334. bool empty() const;
  335. void clear();
  336. %rename(push) push_back;
  337. void push_back(T x);
  338. %extend {
  339. T pop() throw (std::out_of_range) {
  340. if (self->size() == 0)
  341. throw std::out_of_range("pop from empty vector");
  342. T x = self->back();
  343. self->pop_back();
  344. return x;
  345. }
  346. T get(int i) throw (std::out_of_range) {
  347. int size = int(self->size());
  348. if (i<0) i += size;
  349. if (i>=0 && i<size)
  350. return (*self)[i];
  351. else
  352. throw std::out_of_range("vector index out of range");
  353. }
  354. void set(int i, T x) throw (std::out_of_range) {
  355. int size = int(self->size());
  356. if (i<0) i+= size;
  357. if (i>=0 && i<size)
  358. (*self)[i] = x;
  359. else
  360. throw std::out_of_range("vector index out of range");
  361. }
  362. }
  363. };
  364. %enddef
  365. specialize_std_vector(bool, Tcl_GetBoolFromObj, Tcl_NewBooleanObj);
  366. specialize_std_vector(char, SwigInt_As<char>,Tcl_NewIntObj);
  367. specialize_std_vector(int, Tcl_GetIntFromObj,Tcl_NewIntObj);
  368. specialize_std_vector(short, SwigInt_As<short>, Tcl_NewIntObj);
  369. specialize_std_vector(long, SwigInt_As<long>, Tcl_NewIntObj);
  370. specialize_std_vector(unsigned char,
  371. SwigInt_As<unsigned char>, Tcl_NewIntObj);
  372. specialize_std_vector(unsigned int,
  373. SwigInt_As<unsigned int>, Tcl_NewIntObj);
  374. specialize_std_vector(unsigned short,
  375. SwigInt_As<unsigned short>, Tcl_NewIntObj);
  376. specialize_std_vector(unsigned long,
  377. SwigInt_As<unsigned long>, Tcl_NewIntObj);
  378. specialize_std_vector(double, Tcl_GetDoubleFromObj, Tcl_NewDoubleObj);
  379. specialize_std_vector(float, SwigDouble_As<float>, Tcl_NewDoubleObj);
  380. specialize_std_vector(std::string,
  381. SwigString_AsString, SwigString_FromString);
  382. }