From e8483c6c8f28a8fda67443cdc4480ff4252c288d Mon Sep 17 00:00:00 2001 From: Hugo Lima Date: Thu, 25 Feb 2010 19:11:32 -0300 Subject: Fix bug #142 by eliminating the CppCopier::copy function and adding it to a field in SbkBaseWrapper_Type. --- cppgenerator.cpp | 35 ++++++++++++++++++----------------- cppgenerator.h | 5 ++--- headergenerator.cpp | 5 ++--- libshiboken/basewrapper.h | 2 ++ libshiboken/conversions.h | 35 ++++++++++++++++++++++++++++------- 5 files changed, 52 insertions(+), 30 deletions(-) diff --git a/cppgenerator.cpp b/cppgenerator.cpp index 948ee3bfa..2cc1a05b1 100644 --- a/cppgenerator.cpp +++ b/cppgenerator.cpp @@ -154,11 +154,6 @@ void CppGenerator::generateClass(QTextStream &s, const AbstractMetaClass *metaCl QString copyCppObjectImpl; QTextStream copyImpl(©CppObjectImpl); - if (!metaClass->isNamespace()) { - Indentation indentation(INDENT); - writeSbkCopyCppObjectFunction(copyImpl, metaClass); - } - QString headerfile = fileNameForClass(metaClass); headerfile.replace("cpp", "h"); s << "#include \"" << headerfile << '"' << endl; @@ -329,6 +324,7 @@ void CppGenerator::generateClass(QTextStream &s, const AbstractMetaClass *metaCl s << "extern \"C\"" << endl << '{' << endl << endl; if (!metaClass->typeEntry()->hashFunction().isEmpty()) writeHashFunction(s, metaClass); + writeObjCopierFunction(s, metaClass); writeClassDefinition(s, metaClass); s << endl; @@ -1702,6 +1698,7 @@ void CppGenerator::writeClassDefinition(QTextStream& s, const AbstractMetaClass* QString tp_as_sequence('0'); QString tp_hash('0'); QString mi_init('0'); + QString obj_copier('0'); QString type_name_func('0'); QString mi_specialcast('0'); QString cppClassName = metaClass->qualifiedCppName(); @@ -1778,6 +1775,9 @@ void CppGenerator::writeClassDefinition(QTextStream& s, const AbstractMetaClass* s << endl; } + if (metaClass->typeEntry()->isValue() && shouldGenerateCppWrapper(metaClass)) + obj_copier = '&' + cpythonBaseName(metaClass) + "_ObjCopierFunc"; + if (!metaClass->typeEntry()->hashFunction().isEmpty()) tp_hash = '&' + cpythonBaseName(metaClass) + "_HashFunc"; @@ -1834,7 +1834,8 @@ void CppGenerator::writeClassDefinition(QTextStream& s, const AbstractMetaClass* s << INDENT << "/*mi_offsets*/ 0," << endl; s << INDENT << "/*mi_init*/ " << mi_init << ',' << endl; s << INDENT << "/*mi_specialcast*/ " << mi_specialcast << ',' << endl; - s << INDENT << "/*type_name_func*/ " << type_name_func << endl; + s << INDENT << "/*type_name_func*/ " << type_name_func << ',' << endl; + s << INDENT << "/*obj_copier*/ " << obj_copier << endl; s << "};" << endl; } @@ -2643,17 +2644,6 @@ void CppGenerator::writeTypeNameFunction(QTextStream& s, const AbstractMetaClass s << "}\n\n"; } -void CppGenerator::writeSbkCopyCppObjectFunction(QTextStream& s, const AbstractMetaClass* metaClass) -{ - if (!metaClass->typeEntry()->isValue() || !shouldGenerateCppWrapper(metaClass)) - return; - QString className = metaClass->qualifiedCppName(); - s << className << "* CppObjectCopier<" << className << " >::copy(const " << className << "& cppobj)" << endl; - s << '{' << endl; - s << INDENT << "return new " << wrapperName(metaClass) << "(cppobj);" << endl; - s << '}' << endl; -} - void CppGenerator::writeGetattroFunction(QTextStream& s, const AbstractMetaClass* metaClass) { s << "static PyObject* " << cpythonGetattroFunctionName(metaClass) << "(PyObject* self, PyObject* name)" << endl; @@ -2957,3 +2947,14 @@ void CppGenerator::writeHashFunction(QTextStream& s, const AbstractMetaClass* me s << ");" << endl; s << '}' << endl << endl; } + +void CppGenerator::writeObjCopierFunction(QTextStream& s, const AbstractMetaClass* metaClass) +{ + if (!(metaClass->typeEntry()->isValue() && shouldGenerateCppWrapper(metaClass))) + return; + s << "static void* " << cpythonBaseName(metaClass) << "_ObjCopierFunc(const void* ptr)"; + s << '{' << endl; + s << INDENT << "return new " << wrapperName(metaClass) << "(*reinterpret_castqualifiedCppName() << "*>(ptr));\n"; + s << '}' << endl << endl; + +} diff --git a/cppgenerator.h b/cppgenerator.h index 046d0c33a..2230d6ba2 100644 --- a/cppgenerator.h +++ b/cppgenerator.h @@ -1,7 +1,7 @@ /* * This file is part of the Shiboken Python Bindings Generator project. * - * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * Copyright (C) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). * * Contact: PySide team * @@ -70,8 +70,6 @@ private: void writeTypeNameFunction(QTextStream& s, const AbstractMetaClass* metaClass); - void writeSbkCopyCppObjectFunction(QTextStream& s, const AbstractMetaClass* metaClass); - void writeGetattroFunction(QTextStream& s, const AbstractMetaClass* metaClass); /** @@ -170,6 +168,7 @@ private: /// Returns true if generator should produce getters and setters for the given class. bool shouldGenerateGetSetList(const AbstractMetaClass* metaClass); void writeHashFunction(QTextStream& s, const AbstractMetaClass* metaClass); + void writeObjCopierFunction(QTextStream& s, const AbstractMetaClass* metaClass); // Maps special function names to function parameters and return types // used by CPython API in the sequence protocol. diff --git a/headergenerator.cpp b/headergenerator.cpp index 4c5971967..2d5bbf52e 100644 --- a/headergenerator.cpp +++ b/headergenerator.cpp @@ -1,7 +1,7 @@ /* * This file is part of the Shiboken Python Bindings Generator project. * - * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * Copyright (C) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). * * Contact: PySide team * @@ -438,10 +438,9 @@ void HeaderGenerator::writeSbkCopyCppObjectFunction(QTextStream& s, const Abstra return; QString className = metaClass->qualifiedCppName(); s << "template <>" << endl; - s << "struct CppObjectCopier<" << className << " >" << endl; + s << "struct SbkTypeInfo<" << className << " >" << endl; s << '{' << endl; s << INDENT << "static const bool isCppWrapper = true;" << endl; - s << INDENT << "static " << className << "* copy(const " << className << "& cppobj);" << endl; s << "};" << endl; } diff --git a/libshiboken/basewrapper.h b/libshiboken/basewrapper.h index a235b361d..ca876fccc 100644 --- a/libshiboken/basewrapper.h +++ b/libshiboken/basewrapper.h @@ -77,6 +77,7 @@ struct SbkBaseWrapperType; */ typedef void* (*SpecialCastFunction)(PyObject*, SbkBaseWrapperType*); typedef const char* (*TypeNameFunction)(const void*); +typedef void* (*ObjectCopierFunction)(const void*); LIBSHIBOKEN_API PyAPI_DATA(PyTypeObject) SbkBaseWrapperType_Type; LIBSHIBOKEN_API PyAPI_DATA(SbkBaseWrapperType) SbkBaseWrapper_Type; @@ -90,6 +91,7 @@ struct LIBSHIBOKEN_API SbkBaseWrapperType /// Special cast function, null if this class doesn't have multiple inheritance. SpecialCastFunction mi_specialcast; TypeNameFunction type_name_func; + ObjectCopierFunction obj_copier; }; /// Base Python object for all the wrapped C++ classes. diff --git a/libshiboken/conversions.h b/libshiboken/conversions.h index c78e65e13..f596ea6c8 100644 --- a/libshiboken/conversions.h +++ b/libshiboken/conversions.h @@ -1,7 +1,7 @@ /* * This file is part of the Shiboken Python Bindings Generator project. * - * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * Copyright (C) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). * * Contact: PySide team * @@ -72,20 +72,41 @@ template<> inline PyTypeObject* SbkType() { return &PyInt_Type; } template<> inline PyTypeObject* SbkType() { return &PyInt_Type; } template<> inline PyTypeObject* SbkType() { return &PyInt_Type; } +template +struct SbkTypeInfo { + static const bool isCppWrapper = false; +}; + /** * This struct 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. - * The "isCppWrapper" constant must be set to 'true' when CppObjectCopier - * is reimplemented by the Shiboken generator. */ -template +template ::isCppWrapper> struct CppObjectCopier { - static const bool isCppWrapper = false; - static inline T* copy(const T& cppobj) { return new T(cppobj); } + static inline T* copy(const T& obj); }; +template +struct CppObjectCopier +{ + static inline T* copy(const T& obj) + { + return new T(*reinterpret_cast(&obj)); + } +}; + +template +struct CppObjectCopier +{ + static inline T* copy(const T& obj) + { + return reinterpret_cast(reinterpret_cast(SbkType())->obj_copier(&obj)); + } +}; + + /** * Convenience template to create wrappers using the proper Python type for a given C++ class instance. */ @@ -107,7 +128,7 @@ struct ConverterBase static inline PyObject* toPython(const T& cppobj) { PyObject* obj = SbkCreateWrapper(CppObjectCopier::copy(cppobj), true, true); - SbkBaseWrapper_setContainsCppWrapper(obj, CppObjectCopier::isCppWrapper); + SbkBaseWrapper_setContainsCppWrapper(obj, SbkTypeInfo::isCppWrapper); return obj; } // Classes with implicit conversions are expected to reimplement -- cgit v1.2.3