aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcelo Lira <marcelo.lira@openbossa.org>2009-12-09 16:11:58 -0300
committerMarcelo Lira <marcelo.lira@openbossa.org>2009-12-10 15:45:33 -0300
commit88dc53b65f0fa7d6dc918198d7800501861ea3ac (patch)
treefb31fb31c273816397a7786efc29b10ef67cb40c
parent23ade48975d7755c38219c86a141f0a910c3e00e (diff)
Converter<T>::copyCppObject method was replaced by a template function.
Added the template function T* SbkCopyCppObject(const T& cppobj); whose task is simply to copy a C++ object. If the binding has a C++ class wrapper for it, the function is specialized to use the copy constructor of the C++ wrapper class. This replaces the Converter<T>::copyCppObject method. Also moved implementation of Converter<T>::toPython from the generator to ConverterBase<T> in the conversions header, for it makes use of the SbkCopyCppObject. Reviewed by Lauro Neto <lauro.neto@openbossa.org>
-rw-r--r--cppgenerator.cpp37
-rw-r--r--cppgenerator.h2
-rw-r--r--headergenerator.cpp43
-rw-r--r--headergenerator.h5
-rw-r--r--libshiboken/conversions.h33
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(&copyCppObjectImpl);
+
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;
}
};