summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcelo Lira <marcelo.lira@openbossa.org>2010-03-02 17:10:32 -0300
committerMarcelo Lira <marcelo.lira@openbossa.org>2010-03-02 17:10:32 -0300
commitcff48628063b8cf145c01a0f84c19fabd75682db (patch)
tree163131831d13fd56e3c46bc2c3c1c138772d9139
parentddc5bef058932584f5da644b606fad74707a63c7 (diff)
downloadshiboken-cff48628063b8cf145c01a0f84c19fabd75682db.tar.gz
shiboken-cff48628063b8cf145c01a0f84c19fabd75682db.tar.xz
shiboken-cff48628063b8cf145c01a0f84c19fabd75682db.zip
Adds support for extensible converters for value type classes.
Value type classes without implicit conversions use the default implementation provided by ValueTypeConverter. This commit updates ValueTypeConverter to check for extended conversions, since even a class without implicit conversions in one module could get some conversion operators in another. CppGenerator now writes 'isConvertible' calls to all object and value types checks leaving the door open to extended conversions.
-rw-r--r--cppgenerator.cpp4
-rw-r--r--libshiboken/conversions.h28
2 files changed, 25 insertions, 7 deletions
diff --git a/cppgenerator.cpp b/cppgenerator.cpp
index 915d0ef7..1480d7d1 100644
--- a/cppgenerator.cpp
+++ b/cppgenerator.cpp
@@ -1054,9 +1054,7 @@ void CppGenerator::writeInvalidCppObjectCheck(QTextStream& s, QString pyArgName,
void CppGenerator::writeTypeCheck(QTextStream& s, const AbstractMetaType* argType, QString argumentName, bool isNumber, QString customType)
{
- bool writeIsConvertibleCheck = !implicitConversions(argType).isEmpty()
- || argType->typeEntry()->isObject()
- || argType->isValuePointer();
+ bool writeIsConvertibleCheck = argType->typeEntry()->isObject() || argType->typeEntry()->isValue();
if (writeIsConvertibleCheck || isCString(argType) || isPairContainer(argType))
s << '(';
diff --git a/libshiboken/conversions.h b/libshiboken/conversions.h
index 3c14df32..48f28048 100644
--- a/libshiboken/conversions.h
+++ b/libshiboken/conversions.h
@@ -37,6 +37,7 @@
#include <Python.h>
#include <limits>
+#include <memory>
#include "pyenum.h"
#include "basewrapper.h"
@@ -190,7 +191,14 @@ template <> struct Converter<const void*> : Converter<void*> {};
template <typename T>
struct ValueTypeConverter
{
- static inline bool isConvertible(PyObject* pyobj) { return false; }
+ // The basic version of this method also tries to use the extended 'isConvertible' method.
+ static inline bool isConvertible(PyObject* pyobj)
+ {
+ SbkBaseWrapperType* shiboType = reinterpret_cast<SbkBaseWrapperType*>(SbkType<T>());
+ if (shiboType->ext_isconvertible)
+ return shiboType->ext_isconvertible(pyobj);
+ return false;
+ }
static inline PyObject* toPython(void* cppobj) { return toPython(*reinterpret_cast<T*>(cppobj)); }
static inline PyObject* toPython(const T& cppobj)
{
@@ -198,9 +206,21 @@ struct ValueTypeConverter
SbkBaseWrapper_setContainsCppWrapper(obj, SbkTypeInfo<T>::isCppWrapper);
return obj;
}
- // Classes with implicit conversions are expected to reimplement
- // this to build T from its various implicit constructors.
- static inline T toCpp(PyObject* pyobj) { return *Converter<T*>::toCpp(pyobj); }
+ // Classes with implicit conversions are expected to reimplement 'toCpp' to build T from
+ // its various implicit constructors. Even classes without implicit conversions could
+ // get some of those via other modules defining conversion operator for them, thus
+ // the basic Converter for value types checks for extended conversion and tries to
+ // use them if it is the case.
+ static inline T toCpp(PyObject* pyobj)
+ {
+ if (isConvertible(pyobj)) {
+ SbkBaseWrapperType* shiboType = reinterpret_cast<SbkBaseWrapperType*>(SbkType<T>());
+ T* cptr = reinterpret_cast<T*>(shiboType->ext_tocpp(pyobj));
+ std::auto_ptr<T> cptr_auto_ptr(cptr);
+ return *cptr;
+ }
+ return *reinterpret_cast<T*>(reinterpret_cast<Shiboken::SbkBaseWrapper*>(pyobj)->cptr);
+ }
};
// Base converter meant to be inherited by converters for abstract classes and object types