diff options
Diffstat (limited to 'libpyside/pysideconversions.h')
-rw-r--r-- | libpyside/pysideconversions.h | 72 |
1 files changed, 71 insertions, 1 deletions
diff --git a/libpyside/pysideconversions.h b/libpyside/pysideconversions.h index 74553f8e..9539b118 100644 --- a/libpyside/pysideconversions.h +++ b/libpyside/pysideconversions.h @@ -92,6 +92,76 @@ struct QtDictConverter } }; +template <typename MultiMap> +struct QtMultiMapConverter +{ + static inline bool isConvertible(PyObject* pyObj) + { + if (PyObject_TypeCheck(pyObj, Shiboken::SbkType<MultiMap>())) + return true; + + if ((Shiboken::SbkType<MultiMap>() && Shiboken::isShibokenType(pyObj)) || !PyDict_Check(pyObj)) + return false; + + PyObject* key; + PyObject* value; + Py_ssize_t pos = 0; + + while (PyDict_Next(pyObj, &pos, &key, &value)) { + if (!Shiboken::Converter<typename MultiMap::key_type>::isConvertible(key)) { + if (PySequence_Check(value)) { + for (int i = 0, max = PySequence_Length(value); i < max; ++i) { + Shiboken::AutoDecRef item(PySequence_GetItem(value, i)); + if (!Shiboken::Converter<typename MultiMap::mapped_type>::isConvertible(value)) + return false; + } + } else if (!Shiboken::Converter<typename MultiMap::mapped_type>::isConvertible(value)) { + return false; + } + } + } + return true; + } + + static inline PyObject* toPython(const MultiMap& cppObj) + { + PyObject* result = PyDict_New(); + typename MultiMap::const_iterator it = cppObj.begin(); + + for (; it != cppObj.end(); ++it) { + Shiboken::AutoDecRef key(Shiboken::Converter<typename MultiMap::key_type>::toPython(it.key())); + Shiboken::AutoDecRef value(Shiboken::Converter<typename MultiMap::mapped_type>::toPython(it.value())); + + PyObject* values = PyDict_GetItem(result, key); + bool decRefValues = !values; + if (!values) + values = PyList_New(0); + PyList_Append(values, value); + PyDict_SetItem(result, key, values); + if (decRefValues) { + Py_DECREF(values); + } + } + + return result; + } + static inline MultiMap toCpp(PyObject* pyObj) + { + if (PyObject_TypeCheck(pyObj, Shiboken::SbkType<MultiMap>())) + return *reinterpret_cast<MultiMap*>(Shiboken::getCppPointer(pyObj, Shiboken::SbkType<MultiMap>())); + + MultiMap result; + + PyObject* key; + PyObject* value; + Py_ssize_t pos = 0; + + while (PyDict_Next(pyObj, &pos, &key, &value)) + result[Shiboken::Converter<typename MultiMap::key_type>::toCpp(key)] = Shiboken::Converter<typename MultiMap::mapped_type>::toCpp(value); + return result; + } +}; + template <typename T> struct QSequenceConverter { @@ -126,7 +196,7 @@ struct QSequenceConverter Shiboken::AutoDecRef fastSequence(PySequence_Fast(pyobj, "Invalid sequence object")); T result; for (int i = 0; i < PySequence_Size(pyobj); i++) { - PyObject* pyItem = PySequence_Fast_GET_ITEM(fastSequence, i); + PyObject* pyItem = PySequence_Fast_GET_ITEM(fastSequence.object(), i); result << Shiboken::Converter<typename T::value_type>::toCpp(pyItem); } return result; |