diff options
-rw-r--r-- | cppgenerator.cpp | 37 | ||||
-rw-r--r-- | cppgenerator.h | 2 | ||||
-rw-r--r-- | headergenerator.cpp | 43 | ||||
-rw-r--r-- | headergenerator.h | 5 | ||||
-rw-r--r-- | libshiboken/conversions.h | 33 |
5 files changed, 71 insertions, 49 deletions
diff --git a/cppgenerator.cpp b/cppgenerator.cpp index 53f2ac0a8..a19cc6aaf 100644 --- a/cppgenerator.cpp +++ b/cppgenerator.cpp @@ -100,9 +100,13 @@ void CppGenerator::generateClass(QTextStream &s, const AbstractMetaClass *metaCl QString converterImpl; QTextStream convImpl(&converterImpl); + QString copyCppObjectImpl; + QTextStream copyImpl(©CppObjectImpl); + if (!metaClass->isNamespace()) { Indentation indentation(INDENT); writeTypeConverterImpl(convImpl, metaClass->typeEntry()); + writeSbkCopyCppObjectFunction(copyImpl, metaClass); } QString headerfile = fileNameForClass(metaClass); @@ -262,6 +266,8 @@ void CppGenerator::generateClass(QTextStream &s, const AbstractMetaClass *metaCl s << endl << "} // extern \"C\"" << endl << endl; s << "namespace Shiboken" << endl << '{' << endl; + s << "// Copy C++ object implementation" << endl; + s << copyCppObjectImpl; s << "// Converter implementations" << endl; s << converterImpl; s << "} // namespace Shiboken" << endl << endl; @@ -2142,18 +2148,9 @@ void CppGenerator::writeTypeConverterImpl(QTextStream& s, const TypeEntry* type) s << '}' << endl << endl; } - if (!type->isValue()) - return; - - // Write Converter<T>::toPython function - s << "PyObject* Converter<" << type->name() << " >::toPython(const "; - s << type->name() << "& cppobj)" << endl; - s << '{' << endl; - s << INDENT << "return Converter<" << type->name() << " >::createWrapper(new "; - s << type->name() << "(cppobj));" << endl; - s << '}' << endl << endl; - - if (!hasImplicitConversions) + // A specialized Converter<T>::toCpp method is only need for + // value-types with implicit conversions. + if (!type->isValue() || !hasImplicitConversions) return; // Write Converter<T>::toCpp function @@ -2188,13 +2185,19 @@ void CppGenerator::writeTypeConverterImpl(QTextStream& s, const TypeEntry* type) s << INDENT << "return *" << cpythonWrapperCPtr(type, "pyobj") << ';' << endl; s << '}' << endl << endl; +} - // Write Converter<T>::copyCppObject function - s << type->name() << "* Converter<" << type->name(); - s << " >::copyCppObject(const " << type->name() << "& cppobj)" << endl; +void CppGenerator::writeSbkCopyCppObjectFunction(QTextStream& s, const AbstractMetaClass* metaClass) +{ + if (!metaClass->typeEntry()->isValue() || !shouldGenerateCppWrapper(metaClass)) + return; + s << "template<>" << endl; + s << metaClass->qualifiedCppName() << "* SbkCopyCppObject<"; + s << metaClass->qualifiedCppName() << " >(const "; + s << metaClass->qualifiedCppName() << "& cppobj)" << endl; s << '{' << endl; - s << INDENT << "return new " << type->name() << "(cppobj);" << endl; - s << '}' << endl << endl; + s << INDENT << "return new " << wrapperName(metaClass) << "(cppobj);" << endl; + s << '}' << endl; } void CppGenerator::finishGeneration() diff --git a/cppgenerator.h b/cppgenerator.h index 2dfeaa5f0..7857974a7 100644 --- a/cppgenerator.h +++ b/cppgenerator.h @@ -65,6 +65,8 @@ private: void writeTypeConverterImpl(QTextStream& s, const TypeEntry* type); + void writeSbkCopyCppObjectFunction(QTextStream& s, const AbstractMetaClass* metaClass); + /** * Writes Python to C++ conversions for arguments on Python wrappers. * If implicit conversions, and thus new object allocation, are needed, diff --git a/headergenerator.cpp b/headergenerator.cpp index f160fe870..f81693e8f 100644 --- a/headergenerator.cpp +++ b/headergenerator.cpp @@ -156,21 +156,9 @@ void HeaderGenerator::writeTypeConverterDecl(QTextStream& s, const TypeEntry* ty s << "ConverterBase"; s << '<' << type->name() << (isAbstractOrObjectType ? "*" : "") << " >" << endl; s << '{' << endl; - - bool hasImplicitConversions = !implicitConversions(type).isEmpty(); - - if (hasImplicitConversions) + if (type->isValue() && !implicitConversions(type).isEmpty()) { + s << INDENT << "static " << type->name() << " toCpp(PyObject* pyobj);" << endl; s << INDENT << "static bool isConvertible(PyObject* pyobj);" << endl; - - if (type->isValue() && hasImplicitConversions) { - s << INDENT << "static " << type->name() << "* copyCppObject(const "; - s << type->name() << "& cppobj);" << endl; - } - - if (type->isValue()) { - s << INDENT << "static PyObject* toPython(const " << type->name() << "& cppobj);" << endl; - if (hasImplicitConversions) - s << INDENT << "static " << type->name() << " toCpp(PyObject* pyobj);" << endl; } s << "};" << endl; } @@ -187,8 +175,8 @@ void HeaderGenerator::finishGeneration() QTextStream s_pts(&pythonTypeStuff); QString convertersDecl; QTextStream convDecl(&convertersDecl); - QString pyTypeFunctions; - QTextStream typeFunctions(&pyTypeFunctions); + QString sbkTypeFunctions; + QTextStream typeFunctions(&sbkTypeFunctions); Indentation indent(INDENT); @@ -204,7 +192,7 @@ void HeaderGenerator::finishGeneration() s_pts << endl; writeTypeConverterDecl(convDecl, cppEnum->typeEntry()); convDecl << endl; - writePyTypeFunction(typeFunctions, cppEnum); + writeSbkTypeFunction(typeFunctions, cppEnum); } foreach (AbstractMetaClass* metaClass, classes()) { @@ -227,11 +215,13 @@ void HeaderGenerator::finishGeneration() } s_pts << endl; convDecl << endl; - writePyTypeFunction(typeFunctions, cppEnum); + writeSbkTypeFunction(typeFunctions, cppEnum); } if (!metaClass->isNamespace()) { - writePyTypeFunction(typeFunctions, metaClass); + writeSbkTypeFunction(typeFunctions, metaClass); + + writeSbkCopyCppObjectFunction(typeFunctions, metaClass); foreach (AbstractMetaClass* innerClass, metaClass->innerClasses()) { if (shouldGenerate(innerClass)) { @@ -313,7 +303,7 @@ void HeaderGenerator::finishGeneration() s << "namespace Shiboken" << endl << '{' << endl << endl; s << "// PyType functions, to get the PyObjectType for a type T\n"; - s << pyTypeFunctions << endl; + s << sbkTypeFunctions << endl; s << "// Generated converters declarations ----------------------------------" << endl << endl; s << convertersDecl << endl; @@ -348,7 +338,7 @@ void HeaderGenerator::writeExportMacros(QTextStream& s) \n"; } -void HeaderGenerator::writePyTypeFunction(QTextStream& s, const AbstractMetaEnum* cppEnum) +void HeaderGenerator::writeSbkTypeFunction(QTextStream& s, const AbstractMetaEnum* cppEnum) { QString enumPrefix; if (cppEnum->enclosingClass()) @@ -363,8 +353,17 @@ void HeaderGenerator::writePyTypeFunction(QTextStream& s, const AbstractMetaEnum } } -void HeaderGenerator::writePyTypeFunction(QTextStream& s, const AbstractMetaClass* cppClass) +void HeaderGenerator::writeSbkTypeFunction(QTextStream& s, const AbstractMetaClass* cppClass) { s << "template<>\ninline PyTypeObject* SbkType<" << cppClass->qualifiedCppName() << " >() " << "{ return reinterpret_cast<PyTypeObject*>(&" << cpythonTypeName(cppClass) << "); }\n"; } + +void HeaderGenerator::writeSbkCopyCppObjectFunction(QTextStream& s, const AbstractMetaClass* metaClass) +{ + if (!metaClass->typeEntry()->isValue() || !shouldGenerateCppWrapper(metaClass)) + return; + s << "template<> " << metaClass->qualifiedCppName(); + s << "* SbkCopyCppObject<" << metaClass->qualifiedCppName() << ">(const "; + s << metaClass->qualifiedCppName() << "& cppobj);" << endl; +} diff --git a/headergenerator.h b/headergenerator.h index 7b337e1ae..ad1e3bd97 100644 --- a/headergenerator.h +++ b/headergenerator.h @@ -44,8 +44,9 @@ 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); + void writeSbkTypeFunction(QTextStream& s, const AbstractMetaEnum* cppEnum); + void writeSbkTypeFunction(QTextStream& s, const AbstractMetaClass* cppClass); + void writeSbkCopyCppObjectFunction(QTextStream& s, const AbstractMetaClass* metaClass); }; #endif // HEADERGENERATOR_H diff --git a/libshiboken/conversions.h b/libshiboken/conversions.h index b33d4e748..8d78bee11 100644 --- a/libshiboken/conversions.h +++ b/libshiboken/conversions.h @@ -50,7 +50,7 @@ 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. +* It's main usage is to handle multiple inheritance casts. * \see SpecialCastFunction */ template<typename T> @@ -60,6 +60,17 @@ inline PyTypeObject* SbkType() return 0; } +/** + * This function template is used to copy a C++ object using the proper + * constructor, which could be the same type as used on the wrapped library + * or a C++ wrapper type provided by the binding. + */ +template<typename T> +inline T* SbkCopyCppObject(const T& cppobj) +{ + return new T(cppobj); +} + // Base Conversions ---------------------------------------------------------- template <typename T> struct Converter; @@ -68,17 +79,22 @@ struct ConverterBase { static PyObject* createWrapper(const T* cppobj) { - return Shiboken::SbkBaseWrapper_New(SbkType<T>(), cppobj);; + return Shiboken::SbkBaseWrapper_New(SbkType<T>(), cppobj); } - static T* copyCppObject(const T& cppobj) { return 0; } static bool isConvertible(PyObject* pyobj) { return pyobj == Py_None; } // Must be reimplemented. - static PyObject* toPython(const T& cppobj); + static PyObject* toPython(const T& cppobj) + { + return createWrapper(SbkCopyCppObject<T>(cppobj)); + } // Classes with implicit conversions are expected to reimplement // this to build T from its various implicit constructors. - static T toCpp(PyObject* pyobj) { return *Converter<T*>::toCpp(pyobj); } + static T toCpp(PyObject* pyobj) + { + return *Converter<T*>::toCpp(pyobj); + } }; // Specialization meant to be used by abstract classes and object-types @@ -105,12 +121,13 @@ struct ConverterBase<T*> : ConverterBase<T> ShiboTypeObject* shiboType = reinterpret_cast<ShiboTypeObject*>(pyobj->ob_type); if (shiboType->mi_specialcast) return (T*) shiboType->mi_specialcast(pyobj, reinterpret_cast<ShiboTypeObject*>(SbkType<T>())); - return (T*) ((Shiboken::SbkBaseWrapper*) pyobj)->cptr; + return (T*) SbkBaseWrapper_cptr(pyobj); } }; // Pointer Conversions template <typename T> struct Converter : ConverterBase<T> {}; + template <typename T> struct Converter<T*> : Converter<T> { @@ -128,9 +145,9 @@ struct Converter<T*> : Converter<T> static T* toCpp(PyObject* pyobj) { if (Shiboken_TypeCheck(pyobj, T)) - return (T*) ((Shiboken::SbkBaseWrapper*) pyobj)->cptr; + return (T*) SbkBaseWrapper_cptr(pyobj); else if (Converter<T>::isConvertible(pyobj)) - return Converter<T>::copyCppObject(Converter<T>::toCpp(pyobj)); + return SbkCopyCppObject<T>(Converter<T>::toCpp(pyobj)); return 0; } }; |