aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHugo Lima <hugo.lima@openbossa.org>2010-02-25 19:11:32 -0300
committerHugo Lima <hugo.lima@openbossa.org>2010-02-26 14:28:12 -0300
commite8483c6c8f28a8fda67443cdc4480ff4252c288d (patch)
tree5cc3aabfa46e68fdb5b038093e5e6d2fe2b2a1d5
parent29364cfe33c86f9a0cd884e99e0f63d44785abae (diff)
Fix bug #142 by eliminating the CppCopier::copy function and adding it to a field in SbkBaseWrapper_Type.
-rw-r--r--cppgenerator.cpp35
-rw-r--r--cppgenerator.h5
-rw-r--r--headergenerator.cpp5
-rw-r--r--libshiboken/basewrapper.h2
-rw-r--r--libshiboken/conversions.h35
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(&copyCppObjectImpl);
- 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_cast<const " << metaClass->qualifiedCppName() << "*>(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 <contact@pyside.org>
*
@@ -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 <contact@pyside.org>
*
@@ -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 <contact@pyside.org>
*
@@ -72,20 +72,41 @@ template<> inline PyTypeObject* SbkType<char>() { return &PyInt_Type; }
template<> inline PyTypeObject* SbkType<signed char>() { return &PyInt_Type; }
template<> inline PyTypeObject* SbkType<unsigned char>() { return &PyInt_Type; }
+template<typename T>
+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 <typename T>
+template <typename T, bool hasWrapper = SbkTypeInfo<T>::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<typename T>
+struct CppObjectCopier<T, false>
+{
+ static inline T* copy(const T& obj)
+ {
+ return new T(*reinterpret_cast<const T*>(&obj));
+ }
+};
+
+template<typename T>
+struct CppObjectCopier<T, true>
+{
+ static inline T* copy(const T& obj)
+ {
+ return reinterpret_cast<T*>(reinterpret_cast<SbkBaseWrapperType*>(SbkType<T>())->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<T>(CppObjectCopier<T>::copy(cppobj), true, true);
- SbkBaseWrapper_setContainsCppWrapper(obj, CppObjectCopier<T>::isCppWrapper);
+ SbkBaseWrapper_setContainsCppWrapper(obj, SbkTypeInfo<T>::isCppWrapper);
return obj;
}
// Classes with implicit conversions are expected to reimplement