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.

384 lines
13 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. * C# implementation
  9. * The C# wrapper is made to look and feel like a typesafe C# System.Collections.ArrayList
  10. * All the methods in IList are defined, but we don't derive from IList as this is a typesafe collection.
  11. * Warning: heavy macro usage in this file. Use swig -E to get a sane view on the real file contents!
  12. *
  13. * Very often the C# generated code will not compile as the C++ template type is not the same as the C#
  14. * proxy type, so use the SWIG_STD_VECTOR_SPECIALIZE or SWIG_STD_VECTOR_SPECIALIZE_MINIMUM macro, eg
  15. *
  16. * SWIG_STD_VECTOR_SPECIALIZE_MINIMUM(Klass, SomeNamespace::Klass)
  17. * %template(VectKlass) std::vector<SomeNamespace::Klass>;
  18. * ----------------------------------------------------------------------------- */
  19. // Warning: Use the typemaps here in the expectation that the macros they are in will change name.
  20. %include <std_common.i>
  21. // MACRO for use within the std::vector class body
  22. // CSTYPE and CTYPE respectively correspond to the types in the cstype and ctype typemaps
  23. %define SWIG_STD_VECTOR_MINIMUM(CSTYPE, CTYPE...)
  24. %typemap(csinterfaces) std::vector<CTYPE > "IDisposable, System.Collections.IEnumerable";
  25. %typemap(cscode) std::vector<CTYPE > %{
  26. public $csclassname(System.Collections.ICollection c) : this() {
  27. if (c == null)
  28. throw new ArgumentNullException("c");
  29. foreach (CSTYPE element in c) {
  30. this.Add(element);
  31. }
  32. }
  33. public bool IsFixedSize {
  34. get {
  35. return false;
  36. }
  37. }
  38. public bool IsReadOnly {
  39. get {
  40. return false;
  41. }
  42. }
  43. public CSTYPE this[int index] {
  44. get {
  45. return getitem(index);
  46. }
  47. set {
  48. setitem(index, value);
  49. }
  50. }
  51. public int Capacity {
  52. get {
  53. return (int)capacity();
  54. }
  55. set {
  56. if (value < size())
  57. throw new ArgumentOutOfRangeException("Capacity");
  58. reserve((uint)value);
  59. }
  60. }
  61. public int Count {
  62. get {
  63. return (int)size();
  64. }
  65. }
  66. public bool IsSynchronized {
  67. get {
  68. return false;
  69. }
  70. }
  71. public void CopyTo(System.Array array) {
  72. CopyTo(0, array, 0, this.Count);
  73. }
  74. public void CopyTo(System.Array array, int arrayIndex) {
  75. CopyTo(0, array, arrayIndex, this.Count);
  76. }
  77. public void CopyTo(int index, System.Array array, int arrayIndex, int count) {
  78. if (array == null)
  79. throw new ArgumentNullException("array");
  80. if (index < 0)
  81. throw new ArgumentOutOfRangeException("index", "Value is less than zero");
  82. if (arrayIndex < 0)
  83. throw new ArgumentOutOfRangeException("arrayIndex", "Value is less than zero");
  84. if (count < 0)
  85. throw new ArgumentOutOfRangeException("count", "Value is less than zero");
  86. if (array.Rank > 1)
  87. throw new ArgumentException("Multi dimensional array.");
  88. if (index+count > this.Count || arrayIndex+count > array.Length)
  89. throw new ArgumentException("Number of elements to copy is too large.");
  90. for (int i=0; i<count; i++)
  91. array.SetValue(getitemcopy(index+i), arrayIndex+i);
  92. }
  93. // Type-safe version of IEnumerable.GetEnumerator
  94. System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
  95. return new $csclassnameEnumerator(this);
  96. }
  97. public $csclassnameEnumerator GetEnumerator() {
  98. return new $csclassnameEnumerator(this);
  99. }
  100. // Type-safe enumerator
  101. /// Note that the IEnumerator documentation requires an InvalidOperationException to be thrown
  102. /// whenever the collection is modified. This has been done for changes in the size of the
  103. /// collection but not when one of the elements of the collection is modified as it is a bit
  104. /// tricky to detect unmanaged code that modifies the collection under our feet.
  105. public sealed class $csclassnameEnumerator : System.Collections.IEnumerator {
  106. private $csclassname collectionRef;
  107. private int currentIndex;
  108. private object currentObject;
  109. private int currentSize;
  110. public $csclassnameEnumerator($csclassname collection) {
  111. collectionRef = collection;
  112. currentIndex = -1;
  113. currentObject = null;
  114. currentSize = collectionRef.Count;
  115. }
  116. // Type-safe iterator Current
  117. public CSTYPE Current {
  118. get {
  119. if (currentIndex == -1)
  120. throw new InvalidOperationException("Enumeration not started.");
  121. if (currentIndex > currentSize - 1)
  122. throw new InvalidOperationException("Enumeration finished.");
  123. if (currentObject == null)
  124. throw new InvalidOperationException("Collection modified.");
  125. return (CSTYPE)currentObject;
  126. }
  127. }
  128. // Type-unsafe IEnumerator.Current
  129. object System.Collections.IEnumerator.Current {
  130. get {
  131. return Current;
  132. }
  133. }
  134. public bool MoveNext() {
  135. int size = collectionRef.Count;
  136. bool moveOkay = (currentIndex+1 < size) && (size == currentSize);
  137. if (moveOkay) {
  138. currentIndex++;
  139. currentObject = collectionRef[currentIndex];
  140. } else {
  141. currentObject = null;
  142. }
  143. return moveOkay;
  144. }
  145. public void Reset() {
  146. currentIndex = -1;
  147. currentObject = null;
  148. if (collectionRef.Count != currentSize) {
  149. throw new InvalidOperationException("Collection modified.");
  150. }
  151. }
  152. }
  153. %}
  154. public:
  155. typedef size_t size_type;
  156. typedef CTYPE value_type;
  157. typedef const value_type& const_reference;
  158. %rename(Clear) clear;
  159. void clear();
  160. %rename(Add) push_back;
  161. void push_back(const value_type& x);
  162. size_type size() const;
  163. size_type capacity() const;
  164. void reserve(size_type n);
  165. %newobject GetRange(int index, int count);
  166. %newobject Repeat(const value_type& value, int count);
  167. vector();
  168. %extend {
  169. vector(int capacity) throw (std::out_of_range) {
  170. std::vector<CTYPE >* pv = 0;
  171. if (capacity >= 0) {
  172. pv = new std::vector<CTYPE >();
  173. pv->reserve(capacity);
  174. } else {
  175. throw std::out_of_range("capacity");
  176. }
  177. return pv;
  178. }
  179. CTYPE getitemcopy(int index) throw (std::out_of_range) {
  180. if (index>=0 && index<(int)self->size())
  181. return (*self)[index];
  182. else
  183. throw std::out_of_range("index");
  184. }
  185. const_reference getitem(int index) throw (std::out_of_range) {
  186. if (index>=0 && index<(int)self->size())
  187. return (*self)[index];
  188. else
  189. throw std::out_of_range("index");
  190. }
  191. void setitem(int index, const value_type& val) throw (std::out_of_range) {
  192. if (index>=0 && index<(int)self->size())
  193. (*self)[index] = val;
  194. else
  195. throw std::out_of_range("index");
  196. }
  197. // Takes a deep copy of the elements unlike ArrayList.AddRange
  198. void AddRange(const std::vector<CTYPE >& values) {
  199. self->insert(self->end(), values.begin(), values.end());
  200. }
  201. // Takes a deep copy of the elements unlike ArrayList.GetRange
  202. std::vector<CTYPE > *GetRange(int index, int count) throw (std::out_of_range, std::invalid_argument) {
  203. if (index < 0)
  204. throw std::out_of_range("index");
  205. if (count < 0)
  206. throw std::out_of_range("count");
  207. if (index >= (int)self->size()+1 || index+count > (int)self->size())
  208. throw std::invalid_argument("invalid range");
  209. return new std::vector<CTYPE >(self->begin()+index, self->begin()+index+count);
  210. }
  211. void Insert(int index, const value_type& x) throw (std::out_of_range) {
  212. if (index>=0 && index<(int)self->size()+1)
  213. self->insert(self->begin()+index, x);
  214. else
  215. throw std::out_of_range("index");
  216. }
  217. // Takes a deep copy of the elements unlike ArrayList.InsertRange
  218. void InsertRange(int index, const std::vector<CTYPE >& values) throw (std::out_of_range) {
  219. if (index>=0 && index<(int)self->size()+1)
  220. self->insert(self->begin()+index, values.begin(), values.end());
  221. else
  222. throw std::out_of_range("index");
  223. }
  224. void RemoveAt(int index) throw (std::out_of_range) {
  225. if (index>=0 && index<(int)self->size())
  226. self->erase(self->begin() + index);
  227. else
  228. throw std::out_of_range("index");
  229. }
  230. void RemoveRange(int index, int count) throw (std::out_of_range, std::invalid_argument) {
  231. if (index < 0)
  232. throw std::out_of_range("index");
  233. if (count < 0)
  234. throw std::out_of_range("count");
  235. if (index >= (int)self->size()+1 || index+count > (int)self->size())
  236. throw std::invalid_argument("invalid range");
  237. self->erase(self->begin()+index, self->begin()+index+count);
  238. }
  239. static std::vector<CTYPE > *Repeat(const value_type& value, int count) throw (std::out_of_range) {
  240. if (count < 0)
  241. throw std::out_of_range("count");
  242. return new std::vector<CTYPE >(count, value);
  243. }
  244. void Reverse() {
  245. std::reverse(self->begin(), self->end());
  246. }
  247. void Reverse(int index, int count) throw (std::out_of_range, std::invalid_argument) {
  248. if (index < 0)
  249. throw std::out_of_range("index");
  250. if (count < 0)
  251. throw std::out_of_range("count");
  252. if (index >= (int)self->size()+1 || index+count > (int)self->size())
  253. throw std::invalid_argument("invalid range");
  254. std::reverse(self->begin()+index, self->begin()+index+count);
  255. }
  256. // Takes a deep copy of the elements unlike ArrayList.SetRange
  257. void SetRange(int index, const std::vector<CTYPE >& values) throw (std::out_of_range) {
  258. if (index < 0)
  259. throw std::out_of_range("index");
  260. if (index+values.size() > self->size())
  261. throw std::out_of_range("index");
  262. std::copy(values.begin(), values.end(), self->begin()+index);
  263. }
  264. }
  265. %enddef
  266. // Extra methods added to the collection class if operator== is defined for the class being wrapped
  267. // CSTYPE and CTYPE respectively correspond to the types in the cstype and ctype typemaps
  268. %define SWIG_STD_VECTOR_EXTRA_OP_EQUALS_EQUALS(CSTYPE, CTYPE...)
  269. %extend {
  270. bool Contains(const value_type& value) {
  271. return std::find(self->begin(), self->end(), value) != self->end();
  272. }
  273. int IndexOf(const value_type& value) {
  274. int index = -1;
  275. std::vector<CTYPE >::iterator it = std::find(self->begin(), self->end(), value);
  276. if (it != self->end())
  277. index = (int)(it - self->begin());
  278. return index;
  279. }
  280. int LastIndexOf(const value_type& value) {
  281. int index = -1;
  282. std::vector<CTYPE >::reverse_iterator rit = std::find(self->rbegin(), self->rend(), value);
  283. if (rit != self->rend())
  284. index = (int)(self->rend() - 1 - rit);
  285. return index;
  286. }
  287. void Remove(const value_type& value) {
  288. std::vector<CTYPE >::iterator it = std::find(self->begin(), self->end(), value);
  289. if (it != self->end())
  290. self->erase(it);
  291. }
  292. }
  293. %enddef
  294. // Macros for std::vector class specializations
  295. // CSTYPE and CTYPE respectively correspond to the types in the cstype and ctype typemaps
  296. %define SWIG_STD_VECTOR_SPECIALIZE(CSTYPE, CTYPE...)
  297. namespace std {
  298. template<> class vector<CTYPE > {
  299. SWIG_STD_VECTOR_MINIMUM(CSTYPE, CTYPE)
  300. SWIG_STD_VECTOR_EXTRA_OP_EQUALS_EQUALS(CSTYPE, CTYPE)
  301. };
  302. }
  303. %enddef
  304. %define SWIG_STD_VECTOR_SPECIALIZE_MINIMUM(CSTYPE, CTYPE...)
  305. namespace std {
  306. template<> class vector<CTYPE > {
  307. SWIG_STD_VECTOR_MINIMUM(CSTYPE, CTYPE)
  308. };
  309. }
  310. %enddef
  311. %{
  312. #include <vector>
  313. #include <algorithm>
  314. #include <stdexcept>
  315. %}
  316. %csmethodmodifiers std::vector::getitemcopy "private"
  317. %csmethodmodifiers std::vector::getitem "private"
  318. %csmethodmodifiers std::vector::setitem "private"
  319. %csmethodmodifiers std::vector::size "private"
  320. %csmethodmodifiers std::vector::capacity "private"
  321. %csmethodmodifiers std::vector::reserve "private"
  322. namespace std {
  323. // primary (unspecialized) class template for std::vector
  324. // does not require operator== to be defined
  325. template<class T> class vector {
  326. SWIG_STD_VECTOR_MINIMUM(T, T)
  327. };
  328. // specializations for pointers
  329. template<class T> class vector<T*> {
  330. SWIG_STD_VECTOR_MINIMUM(T, T*)
  331. };
  332. template<class T> class vector<const T*> {
  333. SWIG_STD_VECTOR_MINIMUM(T, const T*)
  334. };
  335. }
  336. // template specializations for std::vector
  337. // these provide extra collections methods as operator== is defined
  338. SWIG_STD_VECTOR_SPECIALIZE(bool, bool)
  339. SWIG_STD_VECTOR_SPECIALIZE(char, char)
  340. SWIG_STD_VECTOR_SPECIALIZE(sbyte, signed char)
  341. SWIG_STD_VECTOR_SPECIALIZE(byte, unsigned char)
  342. SWIG_STD_VECTOR_SPECIALIZE(short, short)
  343. SWIG_STD_VECTOR_SPECIALIZE(ushort, unsigned short)
  344. SWIG_STD_VECTOR_SPECIALIZE(int, int)
  345. SWIG_STD_VECTOR_SPECIALIZE(uint, unsigned int)
  346. SWIG_STD_VECTOR_SPECIALIZE(int, long)
  347. SWIG_STD_VECTOR_SPECIALIZE(uint, unsigned long)
  348. SWIG_STD_VECTOR_SPECIALIZE(long, long long)
  349. SWIG_STD_VECTOR_SPECIALIZE(ulong, unsigned long long)
  350. SWIG_STD_VECTOR_SPECIALIZE(float, float)
  351. SWIG_STD_VECTOR_SPECIALIZE(double, double)
  352. SWIG_STD_VECTOR_SPECIALIZE(string, std::string) // also requires a %include <std_string.i>