diff --git a/CHANGES.current b/CHANGES.current index 214c34386..b200a912d 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,8 +1,12 @@ Version 1.3.40 (in progress) ============================ +2009-05-11: wsfulton + [C#] Improved std::map wrappers based on patch from Yuval Baror. The C# proxy + now implements System.Collections.Generic.IDictionary<>. + 2009-05-14: bhy - [Python] Fix the wrong pointer value returned by SwigPyObject_repr(). + [Python] Fix the wrong pointer value returned by SwigPyObject_repr(). 2009-05-13: mutandiz (Mikel Bancroft) [allegrocl] Minor tweak when wrapping in -nocwrap mode. diff --git a/Examples/test-suite/csharp/li_std_map_runme.cs b/Examples/test-suite/csharp/li_std_map_runme.cs new file mode 100644 index 000000000..56ea197f1 --- /dev/null +++ b/Examples/test-suite/csharp/li_std_map_runme.cs @@ -0,0 +1,239 @@ +/* ----------------------------------------------------------------------------- + * See the LICENSE file for information on copyright, usage and redistribution + * of SWIG, and the README file for authors - http://www.swig.org/release.html. + * + * li_std_map_runme.cs + * + * SWIG C# tester for std_map.i + * Implementation by Yuval Baror (http://yuval.bar-or.org) + * + * This class tests all the functionality of the std_map.i wrapper. + * Upon successful testing, the main function doesn't print out anything. + * If any error is found - it will be printed on the screen. + * ----------------------------------------------------------------------------- */ + +using System; +using System.Collections.Generic; +using li_std_mapNamespace; + +public class li_std_map_runme { + + private static readonly int collectionSize = 20; + private static readonly int midCollection = collectionSize / 2; + + public static void Main() + { + // Set up an int int map + IntIntMap iimap = new IntIntMap(); + for (int i = 0; i < collectionSize; i++) + { + int val = i * 18; + iimap.Add(i, val); + } + + // Count property test + if (iimap.Count != collectionSize) + throw new Exception("Count test failed"); + + // IsReadOnly property test + if (iimap.IsReadOnly) + throw new Exception("IsReadOnly test failed"); + + // Item indexing test + iimap[0] = 200; + if (iimap[0] != 200) + throw new Exception("Item property test failed"); + iimap[0] = 0 * 18; + + // ContainsKey() test + for (int i = 0; i < collectionSize; i++) + { + if (!iimap.ContainsKey(i)) + throw new Exception("ContainsKey test " + i + " failed"); + } + + // ContainsKey() test + for (int i = 0; i < collectionSize; i++) + { + if (!iimap.Contains(new KeyValuePair(i, i * 18))) + throw new Exception("Contains test " + i + " failed"); + } + + // TryGetValue() test + int value; + bool rc = iimap.TryGetValue(3, out value); + if (rc != true || value != (3 * 18)) + throw new Exception("TryGetValue test 1 failed"); + + rc = iimap.TryGetValue(-1, out value); + if (rc != false) + throw new Exception("TryGetValue test 2 failed"); + + // Keys and Values test + { + IList keys = new List(iimap.Keys); + IList values = new List(iimap.Values); + if (keys.Count != collectionSize) + throw new Exception("Keys count test failed"); + + if (values.Count != collectionSize) + throw new Exception("Values count test failed"); + + for (int i = 0; i < keys.Count; i++) + { + if (iimap[keys[i]] != values[i]) + throw new Exception("Keys and values test failed for index " + i); + } + } + + // Add and Remove test + for (int i = 100; i < 103; i++) + { + iimap.Add(i, i * 18); + if (!iimap.ContainsKey(i) || iimap[i] != (i * 18)) + throw new Exception("Add test failed for index " + i); + + iimap.Remove(i); + if (iimap.ContainsKey(i)) + throw new Exception("Remove test failed for index " + i); + } + + for (int i = 200; i < 203; i++) + { + iimap.Add(new KeyValuePair(i, i * 18)); + if (!iimap.ContainsKey(i) || iimap[i] != (i * 18)) + throw new Exception("Add explicit test failed for index " + i); + + iimap.Remove(new KeyValuePair(i, i * 18)); + if (iimap.ContainsKey(i)) + throw new Exception("Remove explicit test failed for index " + i); + } + + // Duplicate key test + try + { + iimap.Add(3, 0); + throw new Exception("Adding duplicate key test failed"); + } + catch (ArgumentException) + { + } + + // CopyTo() test + { + KeyValuePair[] outputarray = new KeyValuePair[collectionSize]; + iimap.CopyTo(outputarray); + foreach (KeyValuePair val in outputarray) + { + if (iimap[val.Key] != val.Value) + throw new Exception("CopyTo (1) test failed, index:" + val.Key); + } + } + { + KeyValuePair[] outputarray = new KeyValuePair[midCollection + collectionSize]; + iimap.CopyTo(outputarray, midCollection); + for (int i = midCollection; i < midCollection + collectionSize; i++) + { + KeyValuePair val = outputarray[i]; + if (iimap[val.Key] != val.Value) + throw new Exception("CopyTo (2) test failed, index:" + val.Key); + } + } + { + KeyValuePair[] outputarray = new KeyValuePair[collectionSize - 1]; + try + { + iimap.CopyTo(outputarray); + throw new Exception("CopyTo (4) test failed"); + } + catch (ArgumentException) + { + } + } + + // Clear test + iimap.Clear(); + if (iimap.Count != 0) + throw new Exception("Clear test failed"); + + // Test wrapped methods + for (int i = 1; i <= 5; i++) + { + iimap[i] = i; + } + double avg = li_std_map.keyAverage(iimap); + if (avg != 3.0) + throw new Exception("Wrapped method keyAverage test failed. Got " + avg); + + // Test a map with a new specialized type (Struct) + { + IntStructMap ismap = new IntStructMap(); + for (int i = 0; i < 10; i++) + { + ismap.Add(i, new Struct(i * 10.1)); + } + + if (ismap.Count != 10) + throw new Exception("Count test on specialized map failed"); + + foreach (KeyValuePair p in ismap) + { + if ((p.Key * 10.1) != p.Value.num) + throw new Exception("Iteration test on specialized map failed for index " + p.Key); + } + } + + // Test a map of pointers + { + IntStructPtrMap ispmap = new IntStructPtrMap(); + for (int i = 0; i < 10; i++) + { + ispmap.Add(i, new Struct(i * 10.1)); + } + + if (ispmap.Count != 10) + throw new Exception("Count test on specialized pointer map failed"); + + foreach (KeyValuePair p in ispmap) + { + if ((p.Key * 10.1) != p.Value.num) + throw new Exception("Iteration test on specialized pointer map failed for index " + p.Key); + } + } + { + IntStructConstPtrMap iscpmap = new IntStructConstPtrMap(); + for (int i = 0; i < 10; i++) + { + iscpmap.Add(i, new Struct(i * 10.1)); + } + + if (iscpmap.Count != 10) + throw new Exception("Count test on specialized const pointer map failed"); + + foreach (KeyValuePair p in iscpmap) + { + if ((p.Key * 10.1) != p.Value.num) + throw new Exception("Iteration test on specialized const pointer map failed for index " + p.Key); + } + } + + // Test non-specialized map + { + StructIntMap limap = new StructIntMap(); + Struct s7 = new Struct(7); + Struct s8 = new Struct(8); + limap.set(s7 , 8); + if (limap.get(s7) != 8) + throw new Exception("Assignment test on non-specialized map failed"); + + if (!limap.has_key(s7)) + throw new Exception("Key test (1) on non-specialized map failed"); + + if (limap.has_key(s8)) + throw new Exception("Key test (2) on non-specialized map failed"); + } + + // All done + } +} + diff --git a/Examples/test-suite/li_std_map.i b/Examples/test-suite/li_std_map.i index 847a6e0b2..39e034bfa 100644 --- a/Examples/test-suite/li_std_map.i +++ b/Examples/test-suite/li_std_map.i @@ -1,40 +1,84 @@ -/** - * @file li_std_map.i - * @author gga - * @date Mon Apr 30 15:03:58 2007 - * - * @brief a test of map containers. - * Languages should define swig::LANGUAGE_OBJ to be - * an entity of their native pointer type which can be - * included in a STL container. - * - * For example: - * swig::LANGUAGE_OBJ is GC_VALUE in Ruby - * swig::LANGUAGE_OBJ is SwigPtr_PyObject in python - * - * - */ - %module("templatereduce") li_std_map - %feature("trackobjects"); -%include std_pair.i -%include std_map.i +%include "std_pair.i" +%include "std_map.i" +%include "std_string.i" +// Declare some maps to play around with +%template(IntIntMap) std::map; +%template(StringIntMap) std::map; + +%ignore Struct::operator<; +%ignore Struct::operator==; + +// Add an inline function to test %inline %{ -struct A{ - int val; - - A(int v = 0): val(v) - { - } +double keyAverage(std::map m) { + if (m.size() == 0) { + return 0.0; + } + + double a = 0.0; + for (std::map::iterator i = m.begin(); i != m.end(); i++) { + a += i->first; + } + + return a / m.size(); +} + +struct Struct { + double num; + Struct() : num(0.0) {} + Struct(double d) : num(d) {} + bool operator<(const Struct &other) const { return num < other.num; } + bool operator==(const Struct &other) const { return num == other.num; } }; + %} -namespace std -{ +#if defined(SWIGCSHARP) + +// Specialize some more non-default map types +SWIG_STD_MAP_SPECIALIZED(int, int *, int, SWIGTYPE_p_int) +SWIG_STD_MAP_SPECIALIZED(int, const int *, int, SWIGTYPE_p_int) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(int, Struct) +SWIG_STD_MAP_SPECIALIZED(int, Struct *, int, Struct) +SWIG_STD_MAP_SPECIALIZED(int, const Struct *, int, Struct) +SWIG_STD_MAP_SPECIALIZED(Struct *, int, Struct, int) + +#endif + +//#if !defined(SWIGR) + +// Test out some maps with pointer types +%template(IntIntPtrMap) std::map; +%template(IntConstIntPtrMap) std::map; + +//#endif + + +// Test out some maps with non-basic types and non-basic pointer types +%template(IntStructMap) std::map; +%template(IntStructPtrMap) std::map; +%template(IntStructConstPtrMap) std::map; +%template(StructPtrIntMap) std::map; + +// Test out a non-specialized map +%template(StructIntMap) std::map; + +// Additional map definitions for Ruby, Python and Octave tests +%inline %{ + struct A{ + int val; + + A(int v = 0): val(v) { + } + }; +%} + +namespace std { %template(pairii) pair; %template(pairAA) pair; %template(pairA) pair; @@ -58,25 +102,14 @@ namespace std } +%inline { + std::pair p_identa(std::pair p) { + return p; + } - -%inline -{ -std::pair -p_identa(std::pair p) { - return p; -} - -std::map m_identa(const std::map& v) -{ - return v; -} - + std::map m_identa(const std::map& v) { + return v; + } } - -namespace std -{ -%template(mapii) map; -} diff --git a/Examples/test-suite/octave/li_std_map_runme.m b/Examples/test-suite/octave/li_std_map_runme.m index e74fc79fc..f37c78012 100644 --- a/Examples/test-suite/octave/li_std_map_runme.m +++ b/Examples/test-suite/octave/li_std_map_runme.m @@ -49,7 +49,7 @@ for k in pm, endif endfor -mii = li_std_map.mapii(); +mii = li_std_map.IntIntMap(); mii{1} = 1; mii{1} = 2; diff --git a/Examples/test-suite/python/li_std_map_runme.py b/Examples/test-suite/python/li_std_map_runme.py index 461421a54..ae75bdda0 100644 --- a/Examples/test-suite/python/li_std_map_runme.py +++ b/Examples/test-suite/python/li_std_map_runme.py @@ -48,7 +48,7 @@ for k in pm: -mii = li_std_map.mapii() +mii = li_std_map.IntIntMap() mii[1] = 1 mii[1] = 2 diff --git a/Examples/test-suite/ruby/li_std_map_runme.rb b/Examples/test-suite/ruby/li_std_map_runme.rb index bd93b9170..0ec8cac84 100755 --- a/Examples/test-suite/ruby/li_std_map_runme.rb +++ b/Examples/test-suite/ruby/li_std_map_runme.rb @@ -43,7 +43,7 @@ m.each_key { |k| pm[k] = m[k] } m.each_key { |k| swig_assert_equal("pm[#{k.inspect}]", "m[#{k.inspect}]", binding) } EOF -mii = Li_std_map::Mapii.new +mii = Li_std_map::IntIntMap.new mii[1] = 1 mii[1] = 2 diff --git a/Lib/csharp/csharp.swg b/Lib/csharp/csharp.swg index 94f76a3ad..fe459547c 100644 --- a/Lib/csharp/csharp.swg +++ b/Lib/csharp/csharp.swg @@ -803,6 +803,19 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) { /* Array reference typemaps */ %apply SWIGTYPE & { SWIGTYPE ((&)[ANY]) } +/* Marshal C/C++ pointer to IntPtr */ +%typemap(ctype) void *VOID_INT_PTR "void *" +%typemap(imtype) void *VOID_INT_PTR "IntPtr" +%typemap(cstype) void *VOID_INT_PTR "IntPtr" +%typemap(in) void *VOID_INT_PTR %{ $1 = ($1_ltype)$input; %} +%typemap(out) void *VOID_INT_PTR %{ $result = (void *)$1; %} +%typemap(csin) void *VOID_INT_PTR "$csinput" +%typemap(csout, excode=SWIGEXCODE) void *VOID_INT_PTR { + IntPtr ret = $imcall;$excode + return ret; + } + + /* Typemaps used for the generation of proxy and type wrapper class code */ %typemap(csbase) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "" %typemap(csclassmodifiers) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "public class" diff --git a/Lib/csharp/std_map.i b/Lib/csharp/std_map.i index c35f21dc7..69ddb2cbb 100644 --- a/Lib/csharp/std_map.i +++ b/Lib/csharp/std_map.i @@ -5,13 +5,36 @@ * std_map.i * * SWIG typemaps for std::map + * C# implementation by Yuval Baror (http://yuval.bar-or.org) + * + * The C# wrapper is made to look and feel like a C# System.Collections.Generic.IDictionary<>. + * + * Using this wrapper is fairly simple. For example, to create a map from integers to doubles use: + * + * %include + * %template(Map_Int_Double) std::map + * + * Very often the C# generated code will not compile as the C++ template type is not the same as the C# + * proxy type, so use the SWIG_STD_MAP_SPECIALIZED or SWIG_STD_MAP_SPECIALIZED_SIMPLE macros. For example: + * + * SWIG_STD_MAP_SPECIALIZED(MyCppKeyClass, MyCppValueClass, MyCsKeyClass, MyCsValueClass) + * %template(Map_MyCppKeyClass_MyCppValueClass) std::map; + * + * Or if the C# class names are the same as the C++ class names, you can use: + * + * SWIG_STD_MAP_SPECIALIZED_SIMPLE(MyKeyClass, MyValueClass) + * %template(Map_MyCppKeyClass_MyCppValueClass) std::map; + * + * Notes: + * 1) For .NET 1 compatibility, define SWIG_DOTNET_1 when compiling the C# code. In this case + * the C# wrapper has only basic functionality. + * 2) IEnumerable<> is implemented in the proxy class which is useful for using LINQ with + * C++ std::map wrappers. + * + * Warning: heavy macro usage in this file. Use swig -E to get a sane view on the real file contents! * ----------------------------------------------------------------------------- */ -%include - -// ------------------------------------------------------------------------ -// std::map -// ------------------------------------------------------------------------ +//%include %{ #include @@ -19,157 +42,585 @@ #include %} -// exported class +// A minimal implementation to be used when no specialization exists. +%define SWIG_STD_MAP_MINIMAL_INTERNAL(K, T) + public: + map(); + map(const map &); + + typedef size_t size_type; +// size_type size() const; + bool empty() const; + %rename(Clear) clear; + void clear(); + %extend { + T get(const K& key) throw (std::out_of_range) { + std::map::iterator i = self->find(key); + if (i != self->end()) + return i->second; + else + throw std::out_of_range("key not found"); + } + + void set(const K& key, const T& x) { + (*self)[key] = x; + } + + void del(const K& key) throw (std::out_of_range) { + std::map::iterator i = self->find(key); + if (i != self->end()) + self->erase(i); + else + throw std::out_of_range("key not found"); + } + + bool has_key(const K& key) { + std::map::iterator i = self->find(key); + return i != self->end(); + } + } + +%enddef + +/* The specialized std::map implementation + * K is the C++ key type + * T is the C++ value type + * CSKEYTYPE is the C# key type + * CSVALUETYPE is the C# value type + */ +%define SWIG_STD_MAP_SPECIALIZED_INTERNAL(K, T, CSKEYTYPE, CSVALUETYPE) +// add typemaps here +%typemap(csinterfaces) std::map "IDisposable \n#if !SWIG_DOTNET_1\n , System.Collections.Generic.IDictionary\n#endif\n"; +%typemap(cscode) std::map %{ + + public CSVALUETYPE this[CSKEYTYPE key] { + get { + return getitem(key); + } + + set { + setitem(key, value); + } + } + + public bool TryGetValue(CSKEYTYPE key, out CSVALUETYPE value) { + if (this.ContainsKey(key)) { + value = this[key]; + return true; + } + value = default(CSVALUETYPE); + return false; + } + + public int Count { + get { + return (int)size(); + } + } + + public bool IsReadOnly { + get { + return false; + } + } + +#if !SWIG_DOTNET_1 + + public System.Collections.Generic.ICollection Keys { + get { + System.Collections.Generic.ICollection keys = new System.Collections.Generic.List(); + IntPtr iter = create_iterator_begin(); + try { + while (true) { + keys.Add(get_next_key(iter)); + } + } catch (ArgumentOutOfRangeException) { + } + return keys; + } + } + + public System.Collections.Generic.ICollection Values { + get { + System.Collections.Generic.ICollection vals = new System.Collections.Generic.List(); + foreach (System.Collections.Generic.KeyValuePair pair in this) { + vals.Add(pair.Value); + } + return vals; + } + } + + public void Add(System.Collections.Generic.KeyValuePair item) { + Add(item.Key, item.Value); + } + + public bool Remove(System.Collections.Generic.KeyValuePair item) { + if (Contains(item)) { + return Remove(item.Key); + } else { + return false; + } + } + + public bool Contains(System.Collections.Generic.KeyValuePair item) { + if (this[item.Key] == item.Value) { + return true; + } else { + return false; + } + } + + public void CopyTo(System.Collections.Generic.KeyValuePair[] array) { + CopyTo(array, 0); + } + + public void CopyTo(System.Collections.Generic.KeyValuePair[] array, int arrayIndex) { + if (array == null) + throw new ArgumentNullException("array"); + if (arrayIndex < 0) + throw new ArgumentOutOfRangeException("arrayIndex", "Value is less than zero"); + if (array.Rank > 1) + throw new ArgumentException("Multi dimensional array.", "array"); + if (arrayIndex+this.Count > array.Length) + throw new ArgumentException("Number of elements to copy is too large."); + + System.Collections.Generic.IList keyList = new System.Collections.Generic.List(this.Keys); + for (int i = 0; i < keyList.Count; i++) { + CSKEYTYPE currentKey = keyList[i]; + array.SetValue(new System.Collections.Generic.KeyValuePair(currentKey, this[currentKey]), arrayIndex+i); + } + } + + System.Collections.Generic.IEnumerator> System.Collections.Generic.IEnumerable>.GetEnumerator() { + return new $csclassnameEnumerator(this); + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { + return new $csclassnameEnumerator(this); + } + + public $csclassnameEnumerator GetEnumerator() { + return new $csclassnameEnumerator(this); + } + + // Type-safe enumerator + /// Note that the IEnumerator documentation requires an InvalidOperationException to be thrown + /// whenever the collection is modified. This has been done for changes in the size of the + /// collection but not when one of the elements of the collection is modified as it is a bit + /// tricky to detect unmanaged code that modifies the collection under our feet. + public sealed class $csclassnameEnumerator : System.Collections.IEnumerator, + System.Collections.Generic.IEnumerator> + { + private $csclassname collectionRef; + private System.Collections.Generic.IList keyCollection; + private int currentIndex; + private object currentObject; + private int currentSize; + + public $csclassnameEnumerator($csclassname collection) { + collectionRef = collection; + keyCollection = new System.Collections.Generic.List(collection.Keys); + currentIndex = -1; + currentObject = null; + currentSize = collectionRef.Count; + } + + // Type-safe iterator Current + public System.Collections.Generic.KeyValuePair Current { + get { + if (currentIndex == -1) + throw new InvalidOperationException("Enumeration not started."); + if (currentIndex > currentSize - 1) + throw new InvalidOperationException("Enumeration finished."); + if (currentObject == null) + throw new InvalidOperationException("Collection modified."); + return (System.Collections.Generic.KeyValuePair)currentObject; + } + } + + // Type-unsafe IEnumerator.Current + object System.Collections.IEnumerator.Current { + get { + return Current; + } + } + + public bool MoveNext() { + int size = collectionRef.Count; + bool moveOkay = (currentIndex+1 < size) && (size == currentSize); + if (moveOkay) { + currentIndex++; + CSKEYTYPE currentKey = keyCollection[currentIndex]; + currentObject = new System.Collections.Generic.KeyValuePair(currentKey, collectionRef[currentKey]); + } else { + currentObject = null; + } + return moveOkay; + } + + public void Reset() { + currentIndex = -1; + currentObject = null; + if (collectionRef.Count != currentSize) { + throw new InvalidOperationException("Collection modified."); + } + } + + public void Dispose() { + currentIndex = -1; + currentObject = null; + } + } +#endif + +%} + + public: + + map(); + map(const map &); + + typedef size_t size_type; + size_type size() const; + bool empty() const; + %rename(Clear) clear; + void clear(); + %extend { + T getitem(K key) throw (std::out_of_range) { + std::map::iterator i = self->find(key); + if (i != self->end()) + return i->second; + else + throw std::out_of_range("key not found"); + } + + void setitem(K key, T x) { + (*self)[key] = x; + } + + // create_iterator_begin() and get_next_key() work together to provide a collection of keys to C# + %apply void *VOID_INT_PTR { std::map::iterator *std::map::create_iterator_begin } + %apply void *VOID_INT_PTR { std::map::iterator *swigiterator } + + std::map::iterator *create_iterator_begin() { + return new std::map::iterator(self->begin()); + } + + K get_next_key(std::map::iterator *swigiterator) throw (std::out_of_range) { + std::map::iterator iter = *swigiterator; + if (iter == self->end()) { + delete swigiterator; + throw std::out_of_range("no more map elements"); + } + (*swigiterator)++; + return (*iter).first; + } + + bool ContainsKey(K key) { + std::map::iterator iter = self->find(key); + if (iter != self->end()) { + return true; + } + return false; + } + + void Add(K key, T val) throw (std::out_of_range) { + std::map::iterator iter = self->find(key); + if (iter != self->end()) { + throw std::out_of_range("key already exists"); + } + self->insert(std::pair(key, val)); + } + + bool Remove(K key) { + std::map::iterator iter = self->find(key); + if (iter != self->end()) { + self->erase(iter); + return true; + } + return false; + } + } + +%enddef + + +%csmethodmodifiers std::map::size "private" +%csmethodmodifiers std::map::getitem "private" +%csmethodmodifiers std::map::setitem "private" +%csmethodmodifiers std::map::create_iterator_begin "private" +%csmethodmodifiers std::map::get_next_key "private" + + +%define SWIG_STD_MAP_SPECIALIZED(K, T, CSKEY, CSVAL) namespace std { - - template class map { - // add typemaps here - public: - map(); - map(const map &); - - unsigned int size() const; - bool empty() const; - void clear(); - %extend { - T& get(const K& key) throw (std::out_of_range) { - std::map::iterator i = self->find(key); - if (i != self->end()) - return i->second; - else - throw std::out_of_range("key not found"); - } - void set(const K& key, const T& x) { - (*self)[key] = x; - } - void del(const K& key) throw (std::out_of_range) { - std::map::iterator i = self->find(key); - if (i != self->end()) - self->erase(i); - else - throw std::out_of_range("key not found"); - } - bool has_key(const K& key) { - std::map::iterator i = self->find(key); - return i != self->end(); - } - } - }; - - - // specializations for built-ins - - %define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO) - - template class map { - // add typemaps here - public: - map(); - map(const map &); - - unsigned int size() const; - bool empty() const; - void clear(); - %extend { - T& get(K key) throw (std::out_of_range) { - std::map::iterator i = self->find(key); - if (i != self->end()) - return i->second; - else - throw std::out_of_range("key not found"); - } - void set(K key, const T& x) { - (*self)[key] = x; - } - void del(K key) throw (std::out_of_range) { - std::map::iterator i = self->find(key); - if (i != self->end()) - self->erase(i); - else - throw std::out_of_range("key not found"); - } - bool has_key(K key) { - std::map::iterator i = self->find(key); - return i != self->end(); - } - } - }; - %enddef - - %define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO) - template class map { - // add typemaps here - public: - map(); - map(const map &); - - unsigned int size() const; - bool empty() const; - void clear(); - %extend { - T get(const K& key) throw (std::out_of_range) { - std::map::iterator i = self->find(key); - if (i != self->end()) - return i->second; - else - throw std::out_of_range("key not found"); - } - void set(const K& key, T x) { - (*self)[key] = x; - } - void del(const K& key) throw (std::out_of_range) { - std::map::iterator i = self->find(key); - if (i != self->end()) - self->erase(i); - else - throw std::out_of_range("key not found"); - } - bool has_key(const K& key) { - std::map::iterator i = self->find(key); - return i != self->end(); - } - } - }; - %enddef - - %define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, - T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO) - template<> class map { - // add typemaps here - public: - map(); - map(const map &); - - unsigned int size() const; - bool empty() const; - void clear(); - %extend { - T get(K key) throw (std::out_of_range) { - std::map::iterator i = self->find(key); - if (i != self->end()) - return i->second; - else - throw std::out_of_range("key not found"); - } - void set(K key, T x) { - (*self)[key] = x; - } - void del(K key) throw (std::out_of_range) { - std::map::iterator i = self->find(key); - if (i != self->end()) - self->erase(i); - else - throw std::out_of_range("key not found"); - } - bool has_key(K key) { - std::map::iterator i = self->find(key); - return i != self->end(); - } - } - }; - %enddef - - // add specializations here - + template<> class map { + SWIG_STD_MAP_SPECIALIZED_INTERNAL(K, T, CSKEY, CSVAL) + }; } +%enddef + + +%define SWIG_STD_MAP_SPECIALIZED_SIMPLE(K, T) + SWIG_STD_MAP_SPECIALIZED(K, T, K, T) +%enddef + +// Backwards compatibility macros +%define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO) + template class map { + SWIG_STD_MAP_MINIMAL_INTERNAL(K, T) + }; +%enddef + +%define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO) + template class map { + SWIG_STD_MAP_MINIMAL_INTERNAL(K, T) + }; +%enddef + +%define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, + T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO) + template<> class map { + SWIG_STD_MAP_MINIMAL_INTERNAL(K, T) + }; +%enddef + +// exported class +namespace std { + // Regular implementation + template class map { + SWIG_STD_MAP_MINIMAL_INTERNAL(K, T) + }; +} + +// specializations for built-ins +SWIG_STD_MAP_SPECIALIZED(std::string, std::string, string, string) +SWIG_STD_MAP_SPECIALIZED(std::string, bool, string, bool) +SWIG_STD_MAP_SPECIALIZED(std::string, int, string, int) +SWIG_STD_MAP_SPECIALIZED(std::string, unsigned long long, string, ulong) +SWIG_STD_MAP_SPECIALIZED(std::string, unsigned long, string, uint) +SWIG_STD_MAP_SPECIALIZED(std::string, unsigned short, string, ushort) +SWIG_STD_MAP_SPECIALIZED(std::string, long long, string, long) +SWIG_STD_MAP_SPECIALIZED(std::string, unsigned int, string, uint) +SWIG_STD_MAP_SPECIALIZED(std::string, unsigned char, string, byte) +SWIG_STD_MAP_SPECIALIZED(std::string, signed char, string, sbyte) +SWIG_STD_MAP_SPECIALIZED(std::string, double, string, double) +SWIG_STD_MAP_SPECIALIZED(std::string, short, string, short) +SWIG_STD_MAP_SPECIALIZED(std::string, float, string, float) +SWIG_STD_MAP_SPECIALIZED(std::string, char, string, char) +SWIG_STD_MAP_SPECIALIZED(std::string, long, string, int) +SWIG_STD_MAP_SPECIALIZED(bool, std::string, bool, string) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(bool, bool) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(bool, int) +SWIG_STD_MAP_SPECIALIZED(bool, unsigned long long, bool, ulong) +SWIG_STD_MAP_SPECIALIZED(bool, unsigned long, bool, uint) +SWIG_STD_MAP_SPECIALIZED(bool, unsigned short, bool, ushort) +SWIG_STD_MAP_SPECIALIZED(bool, long long, bool, long) +SWIG_STD_MAP_SPECIALIZED(bool, unsigned int, bool, uint) +SWIG_STD_MAP_SPECIALIZED(bool, unsigned char, bool, byte) +SWIG_STD_MAP_SPECIALIZED(bool, signed char, bool, sbyte) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(bool, double) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(bool, short) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(bool, float) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(bool, char) +SWIG_STD_MAP_SPECIALIZED(bool, long, bool, int) +SWIG_STD_MAP_SPECIALIZED(int, std::string, int, string) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(int, bool) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(int, int) +SWIG_STD_MAP_SPECIALIZED(int, unsigned long long, int, ulong) +SWIG_STD_MAP_SPECIALIZED(int, unsigned long, int, uint) +SWIG_STD_MAP_SPECIALIZED(int, unsigned short, int, ushort) +SWIG_STD_MAP_SPECIALIZED(int, long long, int, long) +SWIG_STD_MAP_SPECIALIZED(int, unsigned int, int, uint) +SWIG_STD_MAP_SPECIALIZED(int, unsigned char, int, byte) +SWIG_STD_MAP_SPECIALIZED(int, signed char, int, sbyte) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(int, double) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(int, short) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(int, float) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(int, char) +SWIG_STD_MAP_SPECIALIZED(int, long, int, int) +SWIG_STD_MAP_SPECIALIZED(unsigned long long, std::string, ulong, string) +SWIG_STD_MAP_SPECIALIZED(unsigned long long, bool, ulong, bool) +SWIG_STD_MAP_SPECIALIZED(unsigned long long, int, ulong, int) +SWIG_STD_MAP_SPECIALIZED(unsigned long long, unsigned long long, ulong, ulong) +SWIG_STD_MAP_SPECIALIZED(unsigned long long, unsigned long, ulong, uint) +SWIG_STD_MAP_SPECIALIZED(unsigned long long, unsigned short, ulong, ushort) +SWIG_STD_MAP_SPECIALIZED(unsigned long long, long long, ulong, long) +SWIG_STD_MAP_SPECIALIZED(unsigned long long, unsigned int, ulong, uint) +SWIG_STD_MAP_SPECIALIZED(unsigned long long, unsigned char, ulong, byte) +SWIG_STD_MAP_SPECIALIZED(unsigned long long, signed char, ulong, sbyte) +SWIG_STD_MAP_SPECIALIZED(unsigned long long, double, ulong, double) +SWIG_STD_MAP_SPECIALIZED(unsigned long long, short, ulong, short) +SWIG_STD_MAP_SPECIALIZED(unsigned long long, float, ulong, float) +SWIG_STD_MAP_SPECIALIZED(unsigned long long, char, ulong, char) +SWIG_STD_MAP_SPECIALIZED(unsigned long long, long, ulong, int) +SWIG_STD_MAP_SPECIALIZED(unsigned long, std::string, uint, string) +SWIG_STD_MAP_SPECIALIZED(unsigned long, bool, uint, bool) +SWIG_STD_MAP_SPECIALIZED(unsigned long, int, uint, int) +SWIG_STD_MAP_SPECIALIZED(unsigned long, unsigned long long, uint, ulong) +SWIG_STD_MAP_SPECIALIZED(unsigned long, unsigned long, uint, uint) +SWIG_STD_MAP_SPECIALIZED(unsigned long, unsigned short, uint, ushort) +SWIG_STD_MAP_SPECIALIZED(unsigned long, long long, uint, long) +SWIG_STD_MAP_SPECIALIZED(unsigned long, unsigned int, uint, uint) +SWIG_STD_MAP_SPECIALIZED(unsigned long, unsigned char, uint, byte) +SWIG_STD_MAP_SPECIALIZED(unsigned long, signed char, uint, sbyte) +SWIG_STD_MAP_SPECIALIZED(unsigned long, double, uint, double) +SWIG_STD_MAP_SPECIALIZED(unsigned long, short, uint, short) +SWIG_STD_MAP_SPECIALIZED(unsigned long, float, uint, float) +SWIG_STD_MAP_SPECIALIZED(unsigned long, char, uint, char) +SWIG_STD_MAP_SPECIALIZED(unsigned long, long, uint, int) +SWIG_STD_MAP_SPECIALIZED(unsigned short, std::string, ushort, string) +SWIG_STD_MAP_SPECIALIZED(unsigned short, bool, ushort, bool) +SWIG_STD_MAP_SPECIALIZED(unsigned short, int, ushort, int) +SWIG_STD_MAP_SPECIALIZED(unsigned short, unsigned long long, ushort, ulong) +SWIG_STD_MAP_SPECIALIZED(unsigned short, unsigned long, ushort, uint) +SWIG_STD_MAP_SPECIALIZED(unsigned short, unsigned short, ushort, ushort) +SWIG_STD_MAP_SPECIALIZED(unsigned short, long long, ushort, long) +SWIG_STD_MAP_SPECIALIZED(unsigned short, unsigned int, ushort, uint) +SWIG_STD_MAP_SPECIALIZED(unsigned short, unsigned char, ushort, byte) +SWIG_STD_MAP_SPECIALIZED(unsigned short, signed char, ushort, sbyte) +SWIG_STD_MAP_SPECIALIZED(unsigned short, double, ushort, double) +SWIG_STD_MAP_SPECIALIZED(unsigned short, short, ushort, short) +SWIG_STD_MAP_SPECIALIZED(unsigned short, float, ushort, float) +SWIG_STD_MAP_SPECIALIZED(unsigned short, char, ushort, char) +SWIG_STD_MAP_SPECIALIZED(unsigned short, long, ushort, int) +SWIG_STD_MAP_SPECIALIZED(long long, std::string, long, string) +SWIG_STD_MAP_SPECIALIZED(long long, bool, long, bool) +SWIG_STD_MAP_SPECIALIZED(long long, int, long, int) +SWIG_STD_MAP_SPECIALIZED(long long, unsigned long long, long, ulong) +SWIG_STD_MAP_SPECIALIZED(long long, unsigned long, long, uint) +SWIG_STD_MAP_SPECIALIZED(long long, unsigned short, long, ushort) +SWIG_STD_MAP_SPECIALIZED(long long, long long, long, long) +SWIG_STD_MAP_SPECIALIZED(long long, unsigned int, long, uint) +SWIG_STD_MAP_SPECIALIZED(long long, unsigned char, long, byte) +SWIG_STD_MAP_SPECIALIZED(long long, signed char, long, sbyte) +SWIG_STD_MAP_SPECIALIZED(long long, double, long, double) +SWIG_STD_MAP_SPECIALIZED(long long, short, long, short) +SWIG_STD_MAP_SPECIALIZED(long long, float, long, float) +SWIG_STD_MAP_SPECIALIZED(long long, char, long, char) +SWIG_STD_MAP_SPECIALIZED(long long, long, long, int) +SWIG_STD_MAP_SPECIALIZED(unsigned int, std::string, uint, string) +SWIG_STD_MAP_SPECIALIZED(unsigned int, bool, uint, bool) +SWIG_STD_MAP_SPECIALIZED(unsigned int, int, uint, int) +SWIG_STD_MAP_SPECIALIZED(unsigned int, unsigned long long, uint, ulong) +SWIG_STD_MAP_SPECIALIZED(unsigned int, unsigned long, uint, uint) +SWIG_STD_MAP_SPECIALIZED(unsigned int, unsigned short, uint, ushort) +SWIG_STD_MAP_SPECIALIZED(unsigned int, long long, uint, long) +SWIG_STD_MAP_SPECIALIZED(unsigned int, unsigned int, uint, uint) +SWIG_STD_MAP_SPECIALIZED(unsigned int, unsigned char, uint, byte) +SWIG_STD_MAP_SPECIALIZED(unsigned int, signed char, uint, sbyte) +SWIG_STD_MAP_SPECIALIZED(unsigned int, double, uint, double) +SWIG_STD_MAP_SPECIALIZED(unsigned int, short, uint, short) +SWIG_STD_MAP_SPECIALIZED(unsigned int, float, uint, float) +SWIG_STD_MAP_SPECIALIZED(unsigned int, char, uint, char) +SWIG_STD_MAP_SPECIALIZED(unsigned int, long, uint, int) +SWIG_STD_MAP_SPECIALIZED(unsigned char, std::string, byte, string) +SWIG_STD_MAP_SPECIALIZED(unsigned char, bool, byte, bool) +SWIG_STD_MAP_SPECIALIZED(unsigned char, int, byte, int) +SWIG_STD_MAP_SPECIALIZED(unsigned char, unsigned long long, byte, ulong) +SWIG_STD_MAP_SPECIALIZED(unsigned char, unsigned long, byte, uint) +SWIG_STD_MAP_SPECIALIZED(unsigned char, unsigned short, byte, ushort) +SWIG_STD_MAP_SPECIALIZED(unsigned char, long long, byte, long) +SWIG_STD_MAP_SPECIALIZED(unsigned char, unsigned int, byte, uint) +SWIG_STD_MAP_SPECIALIZED(unsigned char, unsigned char, byte, byte) +SWIG_STD_MAP_SPECIALIZED(unsigned char, signed char, byte, sbyte) +SWIG_STD_MAP_SPECIALIZED(unsigned char, double, byte, double) +SWIG_STD_MAP_SPECIALIZED(unsigned char, short, byte, short) +SWIG_STD_MAP_SPECIALIZED(unsigned char, float, byte, float) +SWIG_STD_MAP_SPECIALIZED(unsigned char, char, byte, char) +SWIG_STD_MAP_SPECIALIZED(unsigned char, long, byte, int) +SWIG_STD_MAP_SPECIALIZED(signed char, std::string, sbyte, string) +SWIG_STD_MAP_SPECIALIZED(signed char, bool, sbyte, bool) +SWIG_STD_MAP_SPECIALIZED(signed char, int, sbyte, int) +SWIG_STD_MAP_SPECIALIZED(signed char, unsigned long long, sbyte, ulong) +SWIG_STD_MAP_SPECIALIZED(signed char, unsigned long, sbyte, uint) +SWIG_STD_MAP_SPECIALIZED(signed char, unsigned short, sbyte, ushort) +SWIG_STD_MAP_SPECIALIZED(signed char, long long, sbyte, long) +SWIG_STD_MAP_SPECIALIZED(signed char, unsigned int, sbyte, uint) +SWIG_STD_MAP_SPECIALIZED(signed char, unsigned char, sbyte, byte) +SWIG_STD_MAP_SPECIALIZED(signed char, signed char, sbyte, sbyte) +SWIG_STD_MAP_SPECIALIZED(signed char, double, sbyte, double) +SWIG_STD_MAP_SPECIALIZED(signed char, short, sbyte, short) +SWIG_STD_MAP_SPECIALIZED(signed char, float, sbyte, float) +SWIG_STD_MAP_SPECIALIZED(signed char, char, sbyte, char) +SWIG_STD_MAP_SPECIALIZED(signed char, long, sbyte, int) +SWIG_STD_MAP_SPECIALIZED(double, std::string, double, string) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(double, bool) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(double, int) +SWIG_STD_MAP_SPECIALIZED(double, unsigned long long, double, ulong) +SWIG_STD_MAP_SPECIALIZED(double, unsigned long, double, uint) +SWIG_STD_MAP_SPECIALIZED(double, unsigned short, double, ushort) +SWIG_STD_MAP_SPECIALIZED(double, long long, double, long) +SWIG_STD_MAP_SPECIALIZED(double, unsigned int, double, uint) +SWIG_STD_MAP_SPECIALIZED(double, unsigned char, double, byte) +SWIG_STD_MAP_SPECIALIZED(double, signed char, double, sbyte) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(double, double) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(double, short) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(double, float) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(double, char) +SWIG_STD_MAP_SPECIALIZED(double, long, double, int) +SWIG_STD_MAP_SPECIALIZED(short, std::string, short, string) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(short, bool) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(short, int) +SWIG_STD_MAP_SPECIALIZED(short, unsigned long long, short, ulong) +SWIG_STD_MAP_SPECIALIZED(short, unsigned long, short, uint) +SWIG_STD_MAP_SPECIALIZED(short, unsigned short, short, ushort) +SWIG_STD_MAP_SPECIALIZED(short, long long, short, long) +SWIG_STD_MAP_SPECIALIZED(short, unsigned int, short, uint) +SWIG_STD_MAP_SPECIALIZED(short, unsigned char, short, byte) +SWIG_STD_MAP_SPECIALIZED(short, signed char, short, sbyte) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(short, double) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(short, short) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(short, float) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(short, char) +SWIG_STD_MAP_SPECIALIZED(short, long, short, int) +SWIG_STD_MAP_SPECIALIZED(float, std::string, float, string) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(float, bool) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(float, int) +SWIG_STD_MAP_SPECIALIZED(float, unsigned long long, float, ulong) +SWIG_STD_MAP_SPECIALIZED(float, unsigned long, float, uint) +SWIG_STD_MAP_SPECIALIZED(float, unsigned short, float, ushort) +SWIG_STD_MAP_SPECIALIZED(float, long long, float, long) +SWIG_STD_MAP_SPECIALIZED(float, unsigned int, float, uint) +SWIG_STD_MAP_SPECIALIZED(float, unsigned char, float, byte) +SWIG_STD_MAP_SPECIALIZED(float, signed char, float, sbyte) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(float, double) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(float, short) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(float, float) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(float, char) +SWIG_STD_MAP_SPECIALIZED(float, long, float, int) +SWIG_STD_MAP_SPECIALIZED(char, std::string, char, string) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(char, bool) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(char, int) +SWIG_STD_MAP_SPECIALIZED(char, unsigned long long, char, ulong) +SWIG_STD_MAP_SPECIALIZED(char, unsigned long, char, uint) +SWIG_STD_MAP_SPECIALIZED(char, unsigned short, char, ushort) +SWIG_STD_MAP_SPECIALIZED(char, long long, char, long) +SWIG_STD_MAP_SPECIALIZED(char, unsigned int, char, uint) +SWIG_STD_MAP_SPECIALIZED(char, unsigned char, char, byte) +SWIG_STD_MAP_SPECIALIZED(char, signed char, char, sbyte) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(char, double) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(char, short) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(char, float) +SWIG_STD_MAP_SPECIALIZED_SIMPLE(char, char) +SWIG_STD_MAP_SPECIALIZED(char, long, char, int) +SWIG_STD_MAP_SPECIALIZED(long, std::string, int, string) +SWIG_STD_MAP_SPECIALIZED(long, bool, int, bool) +SWIG_STD_MAP_SPECIALIZED(long, int, int, int) +SWIG_STD_MAP_SPECIALIZED(long, unsigned long long, int, ulong) +SWIG_STD_MAP_SPECIALIZED(long, unsigned long, int, uint) +SWIG_STD_MAP_SPECIALIZED(long, unsigned short, int, ushort) +SWIG_STD_MAP_SPECIALIZED(long, long long, int, long) +SWIG_STD_MAP_SPECIALIZED(long, unsigned int, int, uint) +SWIG_STD_MAP_SPECIALIZED(long, unsigned char, int, byte) +SWIG_STD_MAP_SPECIALIZED(long, signed char, int, sbyte) +SWIG_STD_MAP_SPECIALIZED(long, double, int, double) +SWIG_STD_MAP_SPECIALIZED(long, short, int, short) +SWIG_STD_MAP_SPECIALIZED(long, float, int, float) +SWIG_STD_MAP_SPECIALIZED(long, char, int, char) +SWIG_STD_MAP_SPECIALIZED(long, long, int, int) + +// add specializations here + +