summaryrefslogtreecommitdiffstats
path: root/headergenerator.cpp
diff options
context:
space:
mode:
authorMarcelo Lira <marcelo.lira@openbossa.org>2009-11-01 15:20:49 -0300
committerMarcelo Lira <marcelo.lira@openbossa.org>2009-11-01 15:20:49 -0300
commit6dc8636c9f86fb83d970e736525e8b8252866bf6 (patch)
tree0bb2d8e08918011320d1d7b1e95db51fa078833e /headergenerator.cpp
parent76a79055e1d6c44e85f78f94c400725f1fbfbc3b (diff)
downloadshiboken-6dc8636c9f86fb83d970e736525e8b8252866bf6.tar.gz
shiboken-6dc8636c9f86fb83d970e736525e8b8252866bf6.tar.xz
shiboken-6dc8636c9f86fb83d970e736525e8b8252866bf6.zip
added "PyObject* createWrapper(const T* cppobj)" to the Converter structure
from libshiboken, other changes followed this improvement: * added a Converter<T*> specialization that inherits from Converter<T>; its toPython(const T* cppobj) method returns a existing Python wrapper and increments its refcount, or else it creates a new wrapper using the createWrapper method. Now createWrapper is the only method generated for Object Type conversions. * added a Converter<T&> specialization that inherits from Converter<T*> and just calls its parent's methods adapting them to C++ references. * added a base template class for C++ enums and flags conversions called Converter_CppEnum, it inherits from the base Conversion class. Now the HeaderGenerator need only to generate the Converter<ENUM>::createWrapper method. * all generated conversions now uses only the type name and no qualifiers (i.e. Object Type converters are declared Converter<TYPE> instead of Converter<TYPE*>
Diffstat (limited to 'headergenerator.cpp')
-rw-r--r--headergenerator.cpp153
1 files changed, 72 insertions, 81 deletions
diff --git a/headergenerator.cpp b/headergenerator.cpp
index af628a02..47d3d6fc 100644
--- a/headergenerator.cpp
+++ b/headergenerator.cpp
@@ -182,16 +182,24 @@ void HeaderGenerator::writeTypeCheckMacro(QTextStream& s, const TypeEntry* type)
void HeaderGenerator::writeTypeConverterDecl(QTextStream& s, const TypeEntry* type)
{
QString cppName = type->name();
- if (type->isObject())
- cppName.append('*');
s << "template<>" << endl;
- s << "struct Converter< " << cppName << " >" << endl << '{' << endl;
+ s << "struct Converter<" << cppName << " >";
+ if (type->isEnum() || type->isFlags())
+ s << " : Converter_CppEnum<" << cppName << " >";
+ s << endl << '{' << endl;
if (implicitConversions(type).size() > 0)
- s << INDENT << "static bool isConvertible(PyObject* pyObj);" << endl;
- s << INDENT << "static PyObject* toPython(const " << cppName << " cppobj);" << endl;
- s << INDENT << "static " << cppName << " toCpp(PyObject* pyobj);" << endl;
+ s << INDENT << "static bool isConvertible(PyObject* pyobj);" << endl;
+
+ s << INDENT << "static PyObject* createWrapper(const " << cppName;
+ s << (type->isObject() || type->isValue() ? '*' : '&');
+ s << " cppobj);" << endl;
+
+ if (type->isValue()) {
+ s << INDENT << "static PyObject* toPython(" << cppName << " cppobj);" << endl;
+ s << INDENT << "static " << cppName << " toCpp(PyObject* pyobj);" << endl;
+ }
s << "};" << endl;
}
@@ -201,13 +209,11 @@ void HeaderGenerator::writeTypeConverterImpl(QTextStream& s, const TypeEntry* ty
return;
QString pyTypeName = cpythonTypeName(type);
QString cppName = type->name();
- if (type->isObject())
- cppName.append('*');
- // write isConvertible function
+ // Write Converter<T>::isConvertible function
AbstractMetaFunctionList implicitConvs = implicitConversions(type);
if (implicitConvs.size() > 0) {
- s << "inline bool Converter<" << cppName << " >::isConvertible(PyObject* pyObj)" << endl;
+ s << "inline bool Converter<" << cppName << " >::isConvertible(PyObject* pyobj)" << endl;
s << '{' << endl;
s << INDENT << "return ";
bool isFirst = true;
@@ -218,94 +224,79 @@ void HeaderGenerator::writeTypeConverterImpl(QTextStream& s, const TypeEntry* ty
else
s << endl << INDENT << " || ";
s << cpythonCheckFunction(ctor->arguments().first()->type());
- s << "(pyObj)";
+ s << "(pyobj)";
}
s << ';' << endl;
s << '}' << endl;
}
- // write toPython function
- s << "inline PyObject* Converter<" << cppName << " >::toPython(const " << cppName << " cppobj)\n";
+ // Write Converter<T>::createWrapper function
+ s << "inline PyObject* Converter<" << cppName << " >::createWrapper(const " << cppName;
+ if (type->isObject() || type->isValue())
+ s << '*';
+ else
+ s << '&';
+ s << " cppobj)" << endl;
s << '{' << endl;
- s << INDENT << "PyObject* pyobj;" << endl;
-
- if (!(type->isEnum() || type->isFlags())) {
- s << INDENT << "void* holder = (void*) ";
- if (type->isValue())
- s << "new " << cppName << "(cppobj)";
- else
- s << "cppobj";
- s << ";" << endl;
- }
-
- s << INDENT << "pyobj = ";
-
- if (type->isEnum() || type->isFlags()) {
- s << "Shiboken::PyEnumObject_New(&" << pyTypeName << ',' << endl;
- s << INDENT << INDENT << "\"ReturnedValue\", (long) cppobj);" << endl;
+ s << INDENT << "return " << "Shiboken::";
+ if (type->isObject() || type->isValue()) {
+ s << "PyBaseWrapper_New(&" << pyTypeName << ", &" << pyTypeName << ',';
} else {
- QString newWrapper = QString("Shiboken::PyBaseWrapper_New(&")
- + pyTypeName + ", &" + pyTypeName
- + ", holder);";
- if (type->isValue()) {
- s << newWrapper << endl;
- } else {
- s << "Shiboken::Converter<void*>::toPython(holder);" << endl;
- s << INDENT << "if (!pyobj)" << endl;
- {
- Indentation indent(INDENT);
- s << INDENT << "pyobj = " << newWrapper << endl;
- }
+ // Type is enum or flag
+ s << "PyEnumObject_New(" << endl;
+ {
+ Indentation indent1(INDENT);
+ Indentation indent2(INDENT);
+ s << INDENT << '&' << pyTypeName << ',' << endl;
+ s << INDENT << "\"ReturnedValue\", (long)";
}
}
-
- s << INDENT << "return pyobj;" << endl;
+ s << " cppobj);" << endl;
s << '}' << endl << endl;
- // write toCpp function
+ // Write Converter<T>::toPython function
+ if (type->isValue()) {
+ s << "inline PyObject* Converter<" << cppName << " >::toPython(const ";
+ s << cppName << " cppobj)" << endl;
+ s << '{' << endl;
+ s << INDENT << "return Converter<" << cppName << " >::createWrapper(new ";
+ s << cppName << "(cppobj));" << endl;
+ s << '}' << endl << endl;
+ }
+
+ if (!type->isValue())
+ return;
+
+ // Write Converter<T>::toCpp function
s << "inline " << cppName << " Converter<" << cppName << " >::toCpp(PyObject* pyobj)" << endl;
s << '{' << endl;
- if (type->isValue()) {
- AbstractMetaFunctionList implicitConverters;
- if (type->isValue()) {
- const AbstractMetaClass* metaClass = classes().findClass(type->qualifiedCppName());
- if (metaClass)
- implicitConverters = metaClass->implicitConversions();
- }
- bool firstImplicitIf = true;
- foreach (const AbstractMetaFunction* ctor, implicitConverters) {
- if (ctor->isModifiedRemoved())
- continue;
-
- const AbstractMetaType* argType = ctor->arguments().first()->type();
- s << INDENT;
- if (firstImplicitIf)
- firstImplicitIf = false;
- else
- s << "else ";
- s << "if (" << cpythonCheckFunction(argType) << "(pyobj))" << endl;
- {
- Indentation indent(INDENT);
- s << INDENT << "return " << cppName << '(';
- writeBaseConversion(s, argType, 0);
- s << "toCpp(pyobj));\n";
- }
+ AbstractMetaFunctionList implicitConverters;
+ const AbstractMetaClass* metaClass = classes().findClass(type->qualifiedCppName());
+ if (metaClass)
+ implicitConverters = metaClass->implicitConversions();
+
+ bool firstImplicitIf = true;
+ foreach (const AbstractMetaFunction* ctor, implicitConverters) {
+ if (ctor->isModifiedRemoved())
+ continue;
+
+ const AbstractMetaType* argType = ctor->arguments().first()->type();
+ s << INDENT;
+ if (firstImplicitIf)
+ firstImplicitIf = false;
+ else
+ s << "else ";
+ s << "if (" << cpythonCheckFunction(argType) << "(pyobj))" << endl;
+ {
+ Indentation indent(INDENT);
+ s << INDENT << "return " << cppName << '(';
+ writeBaseConversion(s, argType, 0);
+ s << "toCpp(pyobj));\n";
}
}
- s << INDENT << "return ";
- if (type->isEnum() || type->isFlags()) {
- s << '(' << type->qualifiedCppName() << ") ((Shiboken::PyEnumObject*)pyobj)->ob_ival";
- } else {
- if (type->isValue())
- s << '*';
- s << "((" << cppName;
- if (type->isValue())
- s << '*';
- s << ") ((Shiboken::PyBaseWrapper*)pyobj)->cptr)";
- }
- s << ';' << endl;
+ s << INDENT << "return *Converter<" << cppName << "* >::toCpp(pyobj);" << endl;
s << '}' << endl << endl;
}