PageRenderTime 70ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/trunk/Lib/csharp/std_map.i

#
Swig | 311 lines | 243 code | 47 blank | 21 comment | 0 complexity | ce1c72acc4927315e88ca0e846076d26 MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
  1. /* -----------------------------------------------------------------------------
  2. * std_map.i
  3. *
  4. * SWIG typemaps for std::map< K, T >
  5. *
  6. * The C# wrapper is made to look and feel like a C# System.Collections.Generic.IDictionary<>.
  7. *
  8. * Using this wrapper is fairly simple. For example, to create a map from integers to doubles use:
  9. *
  10. * %include <std_map.i>
  11. * %template(MapIntDouble) std::map<int, double>
  12. *
  13. * Notes:
  14. * 1) For .NET 1 compatibility, define SWIG_DOTNET_1 when compiling the C# code. In this case
  15. * the C# wrapper has only basic functionality.
  16. * 2) IEnumerable<> is implemented in the proxy class which is useful for using LINQ with
  17. * C++ std::map wrappers.
  18. *
  19. * Warning: heavy macro usage in this file. Use swig -E to get a sane view on the real file contents!
  20. * ----------------------------------------------------------------------------- */
  21. %{
  22. #include <map>
  23. #include <algorithm>
  24. #include <stdexcept>
  25. %}
  26. /* K is the C++ key type, T is the C++ value type */
  27. %define SWIG_STD_MAP_INTERNAL(K, T)
  28. %typemap(csinterfaces) std::map< K, T > "IDisposable \n#if !SWIG_DOTNET_1\n , System.Collections.Generic.IDictionary<$typemap(cstype, K), $typemap(cstype, T)>\n#endif\n";
  29. %typemap(cscode) std::map<K, T > %{
  30. public $typemap(cstype, T) this[$typemap(cstype, K) key] {
  31. get {
  32. return getitem(key);
  33. }
  34. set {
  35. setitem(key, value);
  36. }
  37. }
  38. public bool TryGetValue($typemap(cstype, K) key, out $typemap(cstype, T) value) {
  39. if (this.ContainsKey(key)) {
  40. value = this[key];
  41. return true;
  42. }
  43. value = default($typemap(cstype, T));
  44. return false;
  45. }
  46. public int Count {
  47. get {
  48. return (int)size();
  49. }
  50. }
  51. public bool IsReadOnly {
  52. get {
  53. return false;
  54. }
  55. }
  56. #if !SWIG_DOTNET_1
  57. public System.Collections.Generic.ICollection<$typemap(cstype, K)> Keys {
  58. get {
  59. System.Collections.Generic.ICollection<$typemap(cstype, K)> keys = new System.Collections.Generic.List<$typemap(cstype, K)>();
  60. int size = this.Count;
  61. if (size > 0) {
  62. IntPtr iter = create_iterator_begin();
  63. for (int i = 0; i < size; i++) {
  64. keys.Add(get_next_key(iter));
  65. }
  66. destroy_iterator(iter);
  67. }
  68. return keys;
  69. }
  70. }
  71. public System.Collections.Generic.ICollection<$typemap(cstype, T)> Values {
  72. get {
  73. System.Collections.Generic.ICollection<$typemap(cstype, T)> vals = new System.Collections.Generic.List<$typemap(cstype, T)>();
  74. foreach (System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)> pair in this) {
  75. vals.Add(pair.Value);
  76. }
  77. return vals;
  78. }
  79. }
  80. public void Add(System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)> item) {
  81. Add(item.Key, item.Value);
  82. }
  83. public bool Remove(System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)> item) {
  84. if (Contains(item)) {
  85. return Remove(item.Key);
  86. } else {
  87. return false;
  88. }
  89. }
  90. public bool Contains(System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)> item) {
  91. if (this[item.Key] == item.Value) {
  92. return true;
  93. } else {
  94. return false;
  95. }
  96. }
  97. public void CopyTo(System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)>[] array) {
  98. CopyTo(array, 0);
  99. }
  100. public void CopyTo(System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)>[] array, int arrayIndex) {
  101. if (array == null)
  102. throw new ArgumentNullException("array");
  103. if (arrayIndex < 0)
  104. throw new ArgumentOutOfRangeException("arrayIndex", "Value is less than zero");
  105. if (array.Rank > 1)
  106. throw new ArgumentException("Multi dimensional array.", "array");
  107. if (arrayIndex+this.Count > array.Length)
  108. throw new ArgumentException("Number of elements to copy is too large.");
  109. System.Collections.Generic.IList<$typemap(cstype, K)> keyList = new System.Collections.Generic.List<$typemap(cstype, K)>(this.Keys);
  110. for (int i = 0; i < keyList.Count; i++) {
  111. $typemap(cstype, K) currentKey = keyList[i];
  112. array.SetValue(new System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)>(currentKey, this[currentKey]), arrayIndex+i);
  113. }
  114. }
  115. System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)>> System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)>>.GetEnumerator() {
  116. return new $csclassnameEnumerator(this);
  117. }
  118. System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
  119. return new $csclassnameEnumerator(this);
  120. }
  121. public $csclassnameEnumerator GetEnumerator() {
  122. return new $csclassnameEnumerator(this);
  123. }
  124. // Type-safe enumerator
  125. /// Note that the IEnumerator documentation requires an InvalidOperationException to be thrown
  126. /// whenever the collection is modified. This has been done for changes in the size of the
  127. /// collection but not when one of the elements of the collection is modified as it is a bit
  128. /// tricky to detect unmanaged code that modifies the collection under our feet.
  129. public sealed class $csclassnameEnumerator : System.Collections.IEnumerator,
  130. System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)>>
  131. {
  132. private $csclassname collectionRef;
  133. private System.Collections.Generic.IList<$typemap(cstype, K)> keyCollection;
  134. private int currentIndex;
  135. private object currentObject;
  136. private int currentSize;
  137. public $csclassnameEnumerator($csclassname collection) {
  138. collectionRef = collection;
  139. keyCollection = new System.Collections.Generic.List<$typemap(cstype, K)>(collection.Keys);
  140. currentIndex = -1;
  141. currentObject = null;
  142. currentSize = collectionRef.Count;
  143. }
  144. // Type-safe iterator Current
  145. public System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)> Current {
  146. get {
  147. if (currentIndex == -1)
  148. throw new InvalidOperationException("Enumeration not started.");
  149. if (currentIndex > currentSize - 1)
  150. throw new InvalidOperationException("Enumeration finished.");
  151. if (currentObject == null)
  152. throw new InvalidOperationException("Collection modified.");
  153. return (System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)>)currentObject;
  154. }
  155. }
  156. // Type-unsafe IEnumerator.Current
  157. object System.Collections.IEnumerator.Current {
  158. get {
  159. return Current;
  160. }
  161. }
  162. public bool MoveNext() {
  163. int size = collectionRef.Count;
  164. bool moveOkay = (currentIndex+1 < size) && (size == currentSize);
  165. if (moveOkay) {
  166. currentIndex++;
  167. $typemap(cstype, K) currentKey = keyCollection[currentIndex];
  168. currentObject = new System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)>(currentKey, collectionRef[currentKey]);
  169. } else {
  170. currentObject = null;
  171. }
  172. return moveOkay;
  173. }
  174. public void Reset() {
  175. currentIndex = -1;
  176. currentObject = null;
  177. if (collectionRef.Count != currentSize) {
  178. throw new InvalidOperationException("Collection modified.");
  179. }
  180. }
  181. public void Dispose() {
  182. currentIndex = -1;
  183. currentObject = null;
  184. }
  185. }
  186. #endif
  187. %}
  188. public:
  189. map();
  190. map(const map< K, T > &other);
  191. typedef K key_type;
  192. typedef T mapped_type;
  193. typedef size_t size_type;
  194. size_type size() const;
  195. bool empty() const;
  196. %rename(Clear) clear;
  197. void clear();
  198. %extend {
  199. const mapped_type& getitem(const key_type& key) throw (std::out_of_range) {
  200. std::map< K,T >::iterator iter = $self->find(key);
  201. if (iter != $self->end())
  202. return iter->second;
  203. else
  204. throw std::out_of_range("key not found");
  205. }
  206. void setitem(const key_type& key, const mapped_type& x) {
  207. (*$self)[key] = x;
  208. }
  209. bool ContainsKey(const key_type& key) {
  210. std::map< K, T >::iterator iter = $self->find(key);
  211. return iter != $self->end();
  212. }
  213. void Add(const key_type& key, const mapped_type& val) throw (std::out_of_range) {
  214. std::map< K, T >::iterator iter = $self->find(key);
  215. if (iter != $self->end())
  216. throw std::out_of_range("key already exists");
  217. $self->insert(std::pair< K, T >(key, val));
  218. }
  219. bool Remove(const key_type& key) {
  220. std::map< K, T >::iterator iter = $self->find(key);
  221. if (iter != $self->end()) {
  222. $self->erase(iter);
  223. return true;
  224. }
  225. return false;
  226. }
  227. // create_iterator_begin(), get_next_key() and destroy_iterator work together to provide a collection of keys to C#
  228. %apply void *VOID_INT_PTR { std::map< K, T >::iterator *create_iterator_begin }
  229. %apply void *VOID_INT_PTR { std::map< K, T >::iterator *swigiterator }
  230. std::map< K, T >::iterator *create_iterator_begin() {
  231. return new std::map< K, T >::iterator($self->begin());
  232. }
  233. const key_type& get_next_key(std::map< K, T >::iterator *swigiterator) {
  234. std::map< K, T >::iterator iter = *swigiterator;
  235. (*swigiterator)++;
  236. return (*iter).first;
  237. }
  238. void destroy_iterator(std::map< K, T >::iterator *swigiterator) {
  239. delete swigiterator;
  240. }
  241. }
  242. %enddef
  243. %csmethodmodifiers std::map::size "private"
  244. %csmethodmodifiers std::map::getitem "private"
  245. %csmethodmodifiers std::map::setitem "private"
  246. %csmethodmodifiers std::map::create_iterator_begin "private"
  247. %csmethodmodifiers std::map::get_next_key "private"
  248. %csmethodmodifiers std::map::destroy_iterator "private"
  249. // Default implementation
  250. namespace std {
  251. template<class K, class T> class map {
  252. SWIG_STD_MAP_INTERNAL(K, T)
  253. };
  254. }
  255. // Legacy macros (deprecated)
  256. %define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO)
  257. #warning "specialize_std_map_on_key ignored - macro is deprecated and no longer necessary"
  258. %enddef
  259. %define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO)
  260. #warning "specialize_std_map_on_value ignored - macro is deprecated and no longer necessary"
  261. %enddef
  262. %define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO)
  263. #warning "specialize_std_map_on_both ignored - macro is deprecated and no longer necessary"
  264. %enddef