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.
7 * SWIG typemaps for std::map< K, T >
9 * The C# wrapper is made to look and feel like a C# System.Collections.Generic.IDictionary<>.
11 * Using this wrapper is fairly simple. For example, to create a map from integers to doubles use:
13 * %include <std_map.i>
14 * %template(MapIntDouble) std::map<int, double>
17 * 1) For .NET 1 compatibility, define SWIG_DOTNET_1 when compiling the C# code. In this case
18 * the C# wrapper has only basic functionality.
19 * 2) IEnumerable<> is implemented in the proxy class which is useful for using LINQ with
20 * C++ std::map wrappers.
22 * Warning: heavy macro usage in this file. Use swig -E to get a sane view on the real file contents!
23 * ----------------------------------------------------------------------------- */
31 /* K is the C++ key type, T is the C++ value type */
32 %define SWIG_STD_MAP_INTERNAL(K, T)
34 %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";
35 %typemap(cscode) std::map<K, T > %{
37 public $typemap(cstype, T) this[$typemap(cstype, K) key] {
47 public bool TryGetValue($typemap(cstype, K) key, out $typemap(cstype, T) value) {
48 if (this.ContainsKey(key)) {
52 value = default($typemap(cstype, T));
62 public bool IsReadOnly {
70 public System.Collections.Generic.ICollection<$typemap(cstype, K)> Keys {
72 System.Collections.Generic.ICollection<$typemap(cstype, K)> keys = new System.Collections.Generic.List<$typemap(cstype, K)>();
73 IntPtr iter = create_iterator_begin();
76 keys.Add(get_next_key(iter));
78 } catch (ArgumentOutOfRangeException) {
84 public System.Collections.Generic.ICollection<$typemap(cstype, T)> Values {
86 System.Collections.Generic.ICollection<$typemap(cstype, T)> vals = new System.Collections.Generic.List<$typemap(cstype, T)>();
87 foreach (System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)> pair in this) {
94 public void Add(System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)> item) {
95 Add(item.Key, item.Value);
98 public bool Remove(System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)> item) {
100 return Remove(item.Key);
106 public bool Contains(System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)> item) {
107 if (this[item.Key] == item.Value) {
114 public void CopyTo(System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)>[] array) {
118 public void CopyTo(System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)>[] array, int arrayIndex) {
120 throw new ArgumentNullException("array");
122 throw new ArgumentOutOfRangeException("arrayIndex", "Value is less than zero");
124 throw new ArgumentException("Multi dimensional array.", "array");
125 if (arrayIndex+this.Count > array.Length)
126 throw new ArgumentException("Number of elements to copy is too large.");
128 System.Collections.Generic.IList<$typemap(cstype, K)> keyList = new System.Collections.Generic.List<$typemap(cstype, K)>(this.Keys);
129 for (int i = 0; i < keyList.Count; i++) {
130 $typemap(cstype, K) currentKey = keyList[i];
131 array.SetValue(new System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)>(currentKey, this[currentKey]), arrayIndex+i);
135 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() {
136 return new $csclassnameEnumerator(this);
139 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
140 return new $csclassnameEnumerator(this);
143 public $csclassnameEnumerator GetEnumerator() {
144 return new $csclassnameEnumerator(this);
147 // Type-safe enumerator
148 /// Note that the IEnumerator documentation requires an InvalidOperationException to be thrown
149 /// whenever the collection is modified. This has been done for changes in the size of the
150 /// collection but not when one of the elements of the collection is modified as it is a bit
151 /// tricky to detect unmanaged code that modifies the collection under our feet.
152 public sealed class $csclassnameEnumerator : System.Collections.IEnumerator,
153 System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)>>
155 private $csclassname collectionRef;
156 private System.Collections.Generic.IList<$typemap(cstype, K)> keyCollection;
157 private int currentIndex;
158 private object currentObject;
159 private int currentSize;
161 public $csclassnameEnumerator($csclassname collection) {
162 collectionRef = collection;
163 keyCollection = new System.Collections.Generic.List<$typemap(cstype, K)>(collection.Keys);
165 currentObject = null;
166 currentSize = collectionRef.Count;
169 // Type-safe iterator Current
170 public System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)> Current {
172 if (currentIndex == -1)
173 throw new InvalidOperationException("Enumeration not started.");
174 if (currentIndex > currentSize - 1)
175 throw new InvalidOperationException("Enumeration finished.");
176 if (currentObject == null)
177 throw new InvalidOperationException("Collection modified.");
178 return (System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)>)currentObject;
182 // Type-unsafe IEnumerator.Current
183 object System.Collections.IEnumerator.Current {
189 public bool MoveNext() {
190 int size = collectionRef.Count;
191 bool moveOkay = (currentIndex+1 < size) && (size == currentSize);
194 $typemap(cstype, K) currentKey = keyCollection[currentIndex];
195 currentObject = new System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)>(currentKey, collectionRef[currentKey]);
197 currentObject = null;
202 public void Reset() {
204 currentObject = null;
205 if (collectionRef.Count != currentSize) {
206 throw new InvalidOperationException("Collection modified.");
210 public void Dispose() {
212 currentObject = null;
221 map(const map< K, T > &other);
224 typedef T mapped_type;
225 typedef size_t size_type;
226 size_type size() const;
228 %rename(Clear) clear;
231 const mapped_type& getitem(const key_type& key) throw (std::out_of_range) {
232 std::map< K,T >::iterator iter = $self->find(key);
233 if (iter != $self->end())
236 throw std::out_of_range("key not found");
239 void setitem(const key_type& key, const mapped_type& x) {
243 bool ContainsKey(const key_type& key) {
244 std::map< K, T >::iterator iter = $self->find(key);
245 return iter != $self->end();
248 void Add(const key_type& key, const mapped_type& val) throw (std::out_of_range) {
249 std::map< K, T >::iterator iter = $self->find(key);
250 if (iter != $self->end())
251 throw std::out_of_range("key already exists");
252 $self->insert(std::pair< K, T >(key, val));
255 bool Remove(const key_type& key) {
256 std::map< K, T >::iterator iter = $self->find(key);
257 if (iter != $self->end()) {
264 // create_iterator_begin() and get_next_key() work together to provide a collection of keys to C#
265 %apply void *VOID_INT_PTR { std::map< K, T >::iterator *create_iterator_begin }
266 %apply void *VOID_INT_PTR { std::map< K, T >::iterator *swigiterator }
268 std::map< K, T >::iterator *create_iterator_begin() {
269 return new std::map< K, T >::iterator($self->begin());
272 const key_type& get_next_key(std::map< K, T >::iterator *swigiterator) throw (std::out_of_range) {
273 std::map< K, T >::iterator iter = *swigiterator;
274 if (iter == $self->end()) {
276 throw std::out_of_range("no more map elements");
279 return (*iter).first;
286 %csmethodmodifiers std::map::size "private"
287 %csmethodmodifiers std::map::getitem "private"
288 %csmethodmodifiers std::map::setitem "private"
289 %csmethodmodifiers std::map::create_iterator_begin "private"
290 %csmethodmodifiers std::map::get_next_key "private"
292 // Default implementation
294 template<class K, class T> class map {
295 SWIG_STD_MAP_INTERNAL(K, T)
300 // Legacy macros (deprecated)
301 %define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO)
302 #warning specialize_std_map_on_key ignored - macro is deprecated and no longer necessary
305 %define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO)
306 #warning specialize_std_map_on_value ignored - macro is deprecated and no longer necessary
309 %define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO)
310 #warning specialize_std_map_on_both ignored - macro is deprecated and no longer necessary