diff options
-rw-r--r-- | cppgenerator.cpp | 21 | ||||
-rw-r--r-- | headergenerator.cpp | 33 | ||||
-rw-r--r-- | headergenerator.h | 2 | ||||
-rw-r--r-- | libshiboken/conversions.h | 39 |
4 files changed, 47 insertions, 48 deletions
diff --git a/cppgenerator.cpp b/cppgenerator.cpp index baf62d8d4..547f9f408 100644 --- a/cppgenerator.cpp +++ b/cppgenerator.cpp @@ -2117,27 +2117,6 @@ void CppGenerator::writeTypeConverterImpl(QTextStream& s, const TypeEntry* type) const AbstractMetaClass* metaClass = classes().findClass(type->name()); bool isAbstractOrObjectType = (metaClass && metaClass->isAbstract()) || type->isObject(); - // Write Converter<T>::createWrapper function - s << "PyObject* Converter<" << type->name() << (isAbstractOrObjectType ? "*" : ""); - s << " >::createWrapper("; - QString convArg = type->name(); - if (!type->isEnum() && !type->isFlags()) { - convArg.prepend("const "); - convArg.append('*'); - } - s << convArg << " cppobj)" << endl; - - s << '{' << endl; - s << INDENT << "return " << "Shiboken::"; - if (type->isObject() || type->isValue()) { - s << "PyBaseWrapper_New((PyTypeObject*)&" << pyTypeName << ','; - } else { - // Type is enum or flag - s << "PyEnumObject_New(&" << pyTypeName << ", (long)"; - } - s << " cppobj);" << endl; - s << '}' << endl << endl; - AbstractMetaFunctionList implicitConvs = implicitConversions(type); bool hasImplicitConversions = !implicitConvs.isEmpty(); diff --git a/headergenerator.cpp b/headergenerator.cpp index 753e34554..69681c45e 100644 --- a/headergenerator.cpp +++ b/headergenerator.cpp @@ -162,14 +162,6 @@ void HeaderGenerator::writeTypeConverterDecl(QTextStream& s, const TypeEntry* ty if (hasImplicitConversions) s << INDENT << "static bool isConvertible(PyObject* pyobj);" << endl; - s << INDENT << "static PyObject* createWrapper("; - QString convArg = type->name(); - if (!type->isEnum() && !type->isFlags()) { - convArg.prepend("const "); - convArg.append('*'); - } - s << convArg << " cppobj);" << endl; - if (type->isValue() && hasImplicitConversions) { s << INDENT << "static " << type->name() << "* copyCppObject(const "; s << type->name() << "& cppobj);" << endl; @@ -212,6 +204,7 @@ void HeaderGenerator::finishGeneration() s_pts << endl; writeTypeConverterDecl(convDecl, cppEnum->typeEntry()); convDecl << endl; + writePyTypeFunction(typeFunctions, cppEnum); } foreach (AbstractMetaClass* metaClass, classes()) { @@ -234,11 +227,11 @@ void HeaderGenerator::finishGeneration() } s_pts << endl; convDecl << endl; + writePyTypeFunction(typeFunctions, cppEnum); } if (!metaClass->isNamespace()) { - // declaration/implementation of PyType function. - typeFunctions << "template<>\ninline ShiboTypeObject* PyType<" << metaClass->qualifiedCppName() << ">() { return &" << cpythonTypeName(metaClass) << "; }\n"; + writePyTypeFunction(typeFunctions, metaClass); foreach (AbstractMetaClass* innerClass, metaClass->innerClasses()) { if (shouldGenerate(innerClass)) { @@ -355,3 +348,23 @@ void HeaderGenerator::writeExportMacros(QTextStream& s) \n"; } +void HeaderGenerator::writePyTypeFunction(QTextStream& s, const AbstractMetaEnum* cppEnum) +{ + QString enumPrefix; + if (cppEnum->enclosingClass()) + enumPrefix = cppEnum->enclosingClass()->qualifiedCppName() + "::"; + s << "template<>\ninline PyTypeObject* PyType<" << enumPrefix << cppEnum->name() << " >() " + << "{ return &" << cpythonTypeName(cppEnum->typeEntry()) << "; }\n"; + + FlagsTypeEntry* flag = cppEnum->typeEntry()->flags(); + if (flag) { + s << "template<>\ninline PyTypeObject* PyType<" << flag->name() << " >() " + << "{ return &" << cpythonTypeName(flag) << "; }\n"; + } +} + +void HeaderGenerator::writePyTypeFunction(QTextStream& s, const AbstractMetaClass* cppClass) +{ + s << "template<>\ninline PyTypeObject* PyType<" << cppClass->qualifiedCppName() << " >() " + << "{ return reinterpret_cast<PyTypeObject*>(&" << cpythonTypeName(cppClass) << "); }\n"; +} diff --git a/headergenerator.h b/headergenerator.h index 5b26eae2d..7b337e1ae 100644 --- a/headergenerator.h +++ b/headergenerator.h @@ -44,6 +44,8 @@ private: void writeTypeCheckMacro(QTextStream& s, const TypeEntry* type); void writeExportMacros(QTextStream& s); void writeTypeConverterDecl(QTextStream& s, const TypeEntry* type); + void writePyTypeFunction(QTextStream& s, const AbstractMetaEnum* cppEnum); + void writePyTypeFunction(QTextStream& s, const AbstractMetaClass* cppClass); }; #endif // HEADERGENERATOR_H diff --git a/libshiboken/conversions.h b/libshiboken/conversions.h index 98efb8586..ed7d8b72b 100644 --- a/libshiboken/conversions.h +++ b/libshiboken/conversions.h @@ -47,6 +47,17 @@ namespace Shiboken { +/** +* This function template is used to get the PyObjectType of a C++ type T. +* It's main usage if handle multiple inheritance casts. +* \see SpecialCastFunction +*/ +template<typename T> +inline PyTypeObject* PyType() +{ + assert(false); // This *SHOULD* never be called. + return 0; +} // Base Conversions ---------------------------------------------------------- template <typename T> struct Converter; @@ -54,7 +65,10 @@ template <typename T> struct Converter; template <typename T> struct ConverterBase { - static PyObject* createWrapper(const T* cppobj) { return 0; } + static PyObject* createWrapper(const T* cppobj) + { + return Shiboken::PyBaseWrapper_New(PyType<T>(), cppobj);; + } static T* copyCppObject(const T& cppobj) { return 0; } static bool isConvertible(PyObject* pyobj) { return pyobj == Py_None; } @@ -66,18 +80,6 @@ struct ConverterBase static T toCpp(PyObject* pyobj) { return *Converter<T*>::toCpp(pyobj); } }; -/** -* This function template is used to get the PyObjectType of a C++ type T. -* It's main usage if handle multiple inheritance casts. -* \see SpecialCastFunction -*/ -template<typename T> -inline ShiboTypeObject* PyType() -{ - assert(false); // This *SHOULD* never be called. - return 0; -} - // Specialization meant to be used by abstract classes and object-types // (i.e. classes with private copy constructors and = operators). // Example: "struct Converter<AbstractClass* > : ConverterBase<AbstractClass* >" @@ -92,7 +94,7 @@ struct ConverterBase<T*> : ConverterBase<T> if (pyobj) Py_INCREF(pyobj); else - pyobj = Converter<T*>::createWrapper(cppobj); + pyobj = createWrapper(cppobj); return pyobj; } static T* toCpp(PyObject* pyobj) @@ -101,7 +103,7 @@ struct ConverterBase<T*> : ConverterBase<T> return 0; ShiboTypeObject* shiboType = reinterpret_cast<ShiboTypeObject*>(pyobj->ob_type); if (shiboType->mi_specialcast) - return (T*) shiboType->mi_specialcast(pyobj, PyType<T>()); + return (T*) shiboType->mi_specialcast(pyobj, reinterpret_cast<ShiboTypeObject*>(PyType<T>())); return (T*) ((Shiboken::PyBaseWrapper*) pyobj)->cptr; } }; @@ -119,7 +121,7 @@ struct Converter<T*> : Converter<T> if (pyobj) Py_INCREF(pyobj); else - pyobj = Converter<T>::createWrapper(cppobj); + pyobj = createWrapper(cppobj); return pyobj; } static T* toCpp(PyObject* pyobj) @@ -264,7 +266,10 @@ template <> struct Converter<double> : Converter_PyFloat<double> {}; template <typename CppEnum> struct Converter_CppEnum { - static PyObject* createWrapper(CppEnum cppobj); + static PyObject* createWrapper(CppEnum cppobj) + { + return PyEnumObject_New(PyType<CppEnum>(), (long)cppobj); + } static CppEnum toCpp(PyObject* pyobj) { return (CppEnum) ((Shiboken::PyEnumObject*)pyobj)->ob_ival; |