diff options
-rw-r--r-- | tests/libsample/CMakeLists.txt | 1 | ||||
-rw-r--r-- | tests/libsample/mapuser.cpp | 41 | ||||
-rw-r--r-- | tests/libsample/mapuser.h | 28 | ||||
-rw-r--r-- | tests/samplebinding/CMakeLists.txt | 1 | ||||
-rw-r--r-- | tests/samplebinding/global.h | 1 | ||||
-rw-r--r-- | tests/samplebinding/map_conversions.h | 43 | ||||
-rwxr-xr-x | tests/samplebinding/map_test.py | 46 | ||||
-rw-r--r-- | tests/samplebinding/typesystem_sample.xml | 5 |
8 files changed, 166 insertions, 0 deletions
diff --git a/tests/libsample/CMakeLists.txt b/tests/libsample/CMakeLists.txt index a630b3cb4..83c480776 100644 --- a/tests/libsample/CMakeLists.txt +++ b/tests/libsample/CMakeLists.txt @@ -9,6 +9,7 @@ implicitconv.cpp kindergarten.cpp listuser.cpp modifications.cpp +mapuser.cpp pairuser.cpp point.cpp reference.cpp diff --git a/tests/libsample/mapuser.cpp b/tests/libsample/mapuser.cpp new file mode 100644 index 000000000..d028b7cb9 --- /dev/null +++ b/tests/libsample/mapuser.cpp @@ -0,0 +1,41 @@ +#include <iostream> +#include "mapuser.h" + +using namespace std; + +std::map<const char*, std::pair<Complex, int> > +MapUser::callCreateMap() +{ + return createMap(); +} + + +std::map<const char*, std::pair<Complex, int> > +MapUser::createMap() +{ + std::map<const char*, std::pair<Complex, int> > retval; + + std::pair<const char *, std::pair<Complex, int> > + item0("zero", std::pair<Complex, int>(Complex(1.2, 3.4), 2)); + retval.insert(item0); + + std::pair<const char *, std::pair<Complex, int> > + item1("one", std::pair<Complex, int>(Complex(5.6, 7.8), 3)); + retval.insert(item1); + + std::pair<const char *, std::pair<Complex, int> > + item2("two", std::pair<Complex, int>(Complex(9.1, 2.3), 5)); + retval.insert(item2); + + return retval; +} + +void +MapUser::showMap(std::map<const char*, int> mapping) +{ + std::map<const char*, int>::iterator it; + cout << __FUNCTION__ << endl; + for (it = mapping.begin() ; it != mapping.end(); it++) + cout << (*it).first << " => " << (*it).second << endl; +} + diff --git a/tests/libsample/mapuser.h b/tests/libsample/mapuser.h new file mode 100644 index 000000000..a5ddfe056 --- /dev/null +++ b/tests/libsample/mapuser.h @@ -0,0 +1,28 @@ +#ifndef MAPUSER_H +#define MAPUSER_H + +#include <map> +#include <list> +#include <utility> +#include "complex.h" + +class MapUser +{ +public: + MapUser() {} + ~MapUser() {} + + virtual std::map<const char*, std::pair<Complex, int> > createMap(); + std::map<const char*, std::pair<Complex, int> > callCreateMap(); + + void showMap(std::map<const char*, int> mapping); + + void setMap(std::map<const char*, std::list<int> > map) { m_map = map; } + std::map<const char*, std::list<int> > getMap() { return m_map; } + +private: + std::map<const char*, std::list<int> > m_map; +}; + +#endif // MAPUSER_H + diff --git a/tests/samplebinding/CMakeLists.txt b/tests/samplebinding/CMakeLists.txt index e89d7d765..e371a4a5b 100644 --- a/tests/samplebinding/CMakeLists.txt +++ b/tests/samplebinding/CMakeLists.txt @@ -11,6 +11,7 @@ ${CMAKE_CURRENT_BINARY_DIR}/sample/derived_wrapper.cpp ${CMAKE_CURRENT_BINARY_DIR}/sample/implicitconv_wrapper.cpp ${CMAKE_CURRENT_BINARY_DIR}/sample/listuser_wrapper.cpp ${CMAKE_CURRENT_BINARY_DIR}/sample/modifications_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/sample/mapuser_wrapper.cpp ${CMAKE_CURRENT_BINARY_DIR}/sample/pairuser_wrapper.cpp ${CMAKE_CURRENT_BINARY_DIR}/sample/point_wrapper.cpp ${CMAKE_CURRENT_BINARY_DIR}/sample/reference_wrapper.cpp diff --git a/tests/samplebinding/global.h b/tests/samplebinding/global.h index b5ae6a8a0..57c13c27e 100644 --- a/tests/samplebinding/global.h +++ b/tests/samplebinding/global.h @@ -7,6 +7,7 @@ #include "kindergarten.h" #include "pairuser.h" #include "listuser.h" +#include "mapuser.h" #include "samplenamespace.h" #include "modifications.h" #include "implicitconv.h" diff --git a/tests/samplebinding/map_conversions.h b/tests/samplebinding/map_conversions.h new file mode 100644 index 000000000..b1591b57c --- /dev/null +++ b/tests/samplebinding/map_conversions.h @@ -0,0 +1,43 @@ +template <typename StdMap> +struct Converter_std_map +{ + static PyObject* toPython(ValueHolder<StdMap> holder) + { + PyObject* result = PyDict_New(); + typedef typename StdMap::iterator IT; + IT it; + + for (it = holder.value.begin(); it != holder.value.end(); it++) { + ValueHolder<typename StdMap::key_type> h_key((*it).first); + ValueHolder<typename StdMap::mapped_type> h_val((*it).second); + PyDict_SetItem(result, + Converter<typename StdMap::key_type>::toPython(h_key), + Converter<typename StdMap::mapped_type>::toPython(h_val)); + } + + return result; + } + static StdMap toCpp(PyObject* pyobj) + { + StdMap result; + + PyObject* key; + PyObject* value; + Py_ssize_t pos = 0; + + Py_INCREF(pyobj); + + while (PyDict_Next(pyobj, &pos, &key, &value)) { + result.insert(typename StdMap::value_type( + Converter<typename StdMap::key_type>::toCpp(key), + Converter<typename StdMap::mapped_type>::toCpp(value))); + } + + Py_DECREF(pyobj); + + return result; + } +}; + +template<typename KT, typename VT> +struct Converter<std::map<KT, VT> > : Converter_std_map<std::map<KT, VT> > {}; diff --git a/tests/samplebinding/map_test.py b/tests/samplebinding/map_test.py new file mode 100755 index 000000000..d2ac4eaad --- /dev/null +++ b/tests/samplebinding/map_test.py @@ -0,0 +1,46 @@ +#!/usr/bin/python + +'''Test cases for std::map container conversions''' + +import sys +import unittest + +from sample import MapUser + +class ExtendedMapUser(MapUser): + def __init__(self): + MapUser.__init__(self) + self.create_map_called = False + + def createMap(self): + self.create_map_called = True + return {'two' : (complex(2.2, 2.2), 2), + 'three' : (complex(3.3, 3.3), 3), + 'five' : (complex(5.5, 5.5), 5), + 'seven' : (complex(7.7, 7.7), 7)} + +class MapConversionTest(unittest.TestCase): + '''Test case for std::map container conversions''' + + def testReimplementedVirtualMethodCall(self): + '''Test if a Python override of a virtual method is correctly called from C++.''' + mu = ExtendedMapUser() + map_ = mu.callCreateMap() + self.assert_(mu.create_map_called) + self.assertEqual(type(map_), dict) + for key, value in map_.items(): + self.assertEqual(type(key), str) + self.assertEqual(type(value[0]), complex) + self.assertEqual(type(value[1]), int) + + def testConversionInBothDirections(self): + '''Test converting a map from Python to C++ and back again.''' + mu = MapUser() + map_ = {'odds' : [2, 4, 6], 'evens' : [3, 5, 7], 'primes' : [3, 4, 6]} + mu.setMap(map_) + result = mu.getMap() + self.assertEqual(result, map_) + +if __name__ == '__main__': + unittest.main() + diff --git a/tests/samplebinding/typesystem_sample.xml b/tests/samplebinding/typesystem_sample.xml index c049ea9eb..b091373cc 100644 --- a/tests/samplebinding/typesystem_sample.xml +++ b/tests/samplebinding/typesystem_sample.xml @@ -17,6 +17,10 @@ <conversion-rule file="list_conversions.h"/> <include file-name="list" location="global"/> </container-type> + <container-type name="std::map" type="map"> + <conversion-rule file="map_conversions.h"/> + <include file-name="map" location="global"/> + </container-type> <enum-type name="Abstract::PrintFormat"/> <enum-type name="PolymorphicFuncEnum"/> @@ -200,6 +204,7 @@ <value-type name="Point"/> <value-type name="Size"/> + <value-type name="MapUser"/> <value-type name="PairUser"/> <value-type name="ListUser"/> |