aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cppgenerator.cpp13
-rw-r--r--headergenerator.cpp39
-rw-r--r--libshiboken/conversions.h61
-rw-r--r--shibokengenerator.cpp78
-rw-r--r--tests/samplebinding/complex_conversions.h4
-rw-r--r--tests/samplebinding/list_conversions.h5
-rw-r--r--tests/samplebinding/map_conversions.h5
-rw-r--r--tests/samplebinding/oddbool_conversions.h5
-rw-r--r--tests/samplebinding/pair_conversions.h4
9 files changed, 139 insertions, 75 deletions
diff --git a/cppgenerator.cpp b/cppgenerator.cpp
index 4f4731e2b..64e603c2d 100644
--- a/cppgenerator.cpp
+++ b/cppgenerator.cpp
@@ -330,7 +330,9 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s, const AbstractMetaFu
&& !m_formatUnits.contains(arg->type()->typeEntry()->name()));
s << INDENT;
if (convert) {
- QString typeName = translateType(arg->type(), func->ownerClass());
+ QString typeName = translateType(arg->type(), func->ownerClass(), ExcludeReference | ExcludeConst);
+ if (typeName.endsWith(" const"))
+ typeName = typeName.right(typeName.count()-5);
if ((arg->type()->isQObject() || arg->type()->isObject())
&& typeName.startsWith("const "))
typeName.remove(0, 6);
@@ -1558,12 +1560,13 @@ void CppGenerator::writeFlagsBinaryOperator(QTextStream& s, const AbstractMetaEn
Q_ASSERT(flagsEntry);
QString cppName = cppEnum->typeEntry()->name();
QString cpythonName = cpythonEnumName(cppEnum);
+ QString checkFunction = cpythonCheckFunction(cppEnum->typeEntry());
s << "PyObject*" << endl;
s << cpythonName << "___" << pyOpName << "__(PyObject* self, PyObject* arg)" << endl;
s << '{' << endl;
s << INDENT << "PyObject* py_result = 0;" << endl;
- s << INDENT << "if (" << cpythonName << "_Check(arg)) {" << endl;
+ s << INDENT << "if (" << checkFunction << "(arg)) {" << endl;
{
Indentation indent(INDENT);
s << INDENT << "py_result = Shiboken::Converter< ";
@@ -1598,12 +1601,13 @@ void CppGenerator::writeFlagsInplaceOperator(QTextStream& s, const AbstractMetaE
Q_ASSERT(flagsEntry);
QString cppName = cppEnum->typeEntry()->name();
QString cpythonName = cpythonEnumName(cppEnum);
+ QString checkFunction = cpythonCheckFunction(cppEnum->typeEntry());
s << "PyObject*" << endl;
s << cpythonName << "___" << pyOpName << "__(PyObject* self, PyObject* arg)" << endl;
s << '{' << endl;
s << INDENT << "PyObject* py_result = 0;" << endl;
- s << INDENT << "if (" << cpythonName << "_Check(arg)) {" << endl;
+ s << INDENT << "if (" << checkFunction << "(arg)) {" << endl;
{
Indentation indent(INDENT);
s << INDENT << "((" << flagsEntry->originalName() << ") ((PyEnumObject*)self)->ob_ival) " << cppOpName << endl;
@@ -1637,12 +1641,13 @@ void CppGenerator::writeFlagsUnaryOperator(QTextStream& s, const AbstractMetaEnu
Q_ASSERT(flagsEntry);
QString cppName = cppEnum->typeEntry()->name();
QString cpythonName = cpythonEnumName(cppEnum);
+ QString checkFunction = cpythonCheckFunction(cppEnum->typeEntry());
s << "PyObject*" << endl;
s << cpythonName << "___" << pyOpName << "__(PyObject* self, PyObject* arg)" << endl;
s << '{' << endl;
s << INDENT << "PyObject* py_result = 0;" << endl;
- s << INDENT << "if (" << cpythonName << "_Check(arg)) {" << endl;
+ s << INDENT << "if (" << checkFunction << "(arg)) {" << endl;
{
Indentation indent(INDENT);
s << INDENT << "py_result = Shiboken::Converter< ";
diff --git a/headergenerator.cpp b/headergenerator.cpp
index 9ee63f749..fea228fd3 100644
--- a/headergenerator.cpp
+++ b/headergenerator.cpp
@@ -171,12 +171,7 @@ void HeaderGenerator::writeVirtualDispatcher(QTextStream& s, const AbstractMetaF
void HeaderGenerator::writeTypeCheckMacro(QTextStream& s, const TypeEntry* type)
{
QString pyTypeName = cpythonTypeName(type);
- QString checkFunction = cpythonCheckFunction(type);
s << "PyAPI_DATA(PyTypeObject) " << pyTypeName << ';' << endl;
- s << "#define " << checkFunction << "(op) PyObject_TypeCheck(op, &";
- s << pyTypeName << ')' << endl;
- s << "#define " << checkFunction << "Exact(op) ((op)->ob_type == &";
- s << pyTypeName << ')' << endl;
}
void HeaderGenerator::writeTypeConverterDecl(QTextStream& s, const TypeEntry* type)
@@ -188,11 +183,9 @@ void HeaderGenerator::writeTypeConverterDecl(QTextStream& s, const TypeEntry* ty
s << "template<>" << endl;
s << "struct Converter< " << cppName << " >" << endl << '{' << endl;
- s << INDENT << "static PyObject* toPython(";
- if (type->isObject())
- s << "const ";
- s << cppName << " cppobj);" << endl;
- s << INDENT << "static " << cppName << " toCpp(PyObject* pyobj);" << endl;
+ s << INDENT << "static bool isConvertible(const PyObject* pyObj);\n";
+ s << INDENT << "static PyObject* toPython(const " << cppName << " cppobj);\n";
+ s << INDENT << "static " << cppName << " toCpp(PyObject* pyobj);\n";
s << "};" << endl;
}
@@ -205,10 +198,14 @@ void HeaderGenerator::writeTypeConverterImpl(QTextStream& s, const TypeEntry* ty
if (type->isObject())
cppName.append('*');
- s << "inline PyObject* Converter< " << cppName << " >::toPython(";
- if (type->isObject())
- s << "const ";
- s << cppName << " cppobj)" << endl;
+ // write isConvertible function
+ s << "inline bool Converter<" << cppName << " >::isConvertible(const PyObject* pyObj)\n";
+ s << "{\n";
+ s << INDENT << "return PyObject_TypeCheck(pyObj, &" << pyTypeName << ");\n";
+ s << "}\n";
+
+ // write toPython function
+ s << "inline PyObject* Converter<" << cppName << " >::toPython(const " << cppName << " cppobj)\n";
s << '{' << endl;
s << INDENT << "PyObject* pyobj;" << endl;
@@ -245,7 +242,8 @@ void HeaderGenerator::writeTypeConverterImpl(QTextStream& s, const TypeEntry* ty
s << INDENT << "return pyobj;" << endl;
s << '}' << endl << endl;
- s << "inline " << cppName << " Converter< " << cppName << " >::toCpp(PyObject* pyobj)" << endl;
+ // write toCpp function
+ s << "inline " << cppName << " Converter<" << cppName << " >::toCpp(PyObject* pyobj)" << endl;
s << '{' << endl;
if (type->isValue()) {
@@ -269,8 +267,9 @@ void HeaderGenerator::writeTypeConverterImpl(QTextStream& s, const TypeEntry* ty
s << "if (" << cpythonCheckFunction(argType) << "(pyobj))" << endl;
{
Indentation indent(INDENT);
- s << INDENT << "return " << cppName;
- s << "(Converter< " << argType->cppSignature() << " >::toCpp(pyobj));" << endl;
+ s << INDENT << "return " << cppName << '(';
+ writeBaseConversion(s, argType, 0);
+ s << "toCpp(pyobj));\n";
}
}
}
@@ -424,6 +423,9 @@ void HeaderGenerator::finishGeneration()
s << "namespace Shiboken" << endl << '{' << endl << endl;
+ s << "// Generated converters declarations ----------------------------------" << endl << endl;
+ s << convertersDecl << endl;
+
s << "// User defined converters --------------------------------------------" << endl;
foreach (TypeEntry* typeEntry, TypeDatabase::instance()->entries()) {
if (typeEntry->hasConversionRule()) {
@@ -432,8 +434,7 @@ void HeaderGenerator::finishGeneration()
}
}
- s << "// Generated converters -----------------------------------------------" << endl << endl;
- s << convertersDecl << endl;
+ s << "// Generated converters implementations -------------------------------" << endl << endl;
s << convertersImpl << endl;
s << "} // namespace Shiboken" << endl << endl;
diff --git a/libshiboken/conversions.h b/libshiboken/conversions.h
index ae6ab5e88..6c24780c1 100644
--- a/libshiboken/conversions.h
+++ b/libshiboken/conversions.h
@@ -45,20 +45,19 @@ namespace Shiboken
template <typename T>
struct Converter
{
- static PyObject* toPython(T cppobj);
- static T toCpp(PyObject* pyobj);
+ static bool isConvertible(const PyObject* pyObj);
+ static PyObject* toPython(const T cppObj);
+ static T toCpp(PyObject* pyObj);
};
-template <typename T>
-struct Converter<T &> : Converter<T> {};
-
-template <typename T>
-struct Converter<const T &> : Converter<T> {};
-
// Object Types ---------------------------------------------------------------
template <>
struct Converter<void*>
{
+ static bool isConvertible(const PyObject* pyObj)
+ {
+ return pyObj != 0;
+ }
static PyObject* toPython(void* cppobj)
{
PyObject* obj = BindingManager::instance().retrieveWrapper(cppobj);
@@ -75,9 +74,13 @@ struct Converter<void*>
template <>
struct Converter<bool>
{
- static PyObject* toPython(bool holder)
+ static bool isConvertible(const PyObject* pyObj)
+ {
+ return PyBool_Check(pyObj);
+ }
+ static PyObject* toPython(const bool cppObj)
{
- return PyBool_FromLong(holder);
+ return PyBool_FromLong(cppObj);
}
static bool toCpp(PyObject* pyobj)
{
@@ -88,9 +91,13 @@ struct Converter<bool>
template <typename PyIntEquiv>
struct Converter_PyInt
{
- static PyObject* toPython(PyIntEquiv holder)
+ static bool isConvertible(const PyObject* pyObj)
+ {
+ return PyInt_Check(pyObj);
+ }
+ static PyObject* toPython(const PyIntEquiv cppObj)
{
- return PyInt_FromLong((long) holder);
+ return PyInt_FromLong((long) cppObj);
}
static PyIntEquiv toCpp(PyObject* pyobj)
{
@@ -111,7 +118,11 @@ template <> struct Converter<long> : Converter_PyInt<long> {};
template <>
struct Converter<unsigned long>
{
- static PyObject* toPython(unsigned long holder)
+ static bool isConvertible(const PyObject* pyObj)
+ {
+ return PyLong_Check(pyObj);
+ }
+ static PyObject* toPython(const unsigned long holder)
{
return PyLong_FromUnsignedLong(holder);
}
@@ -124,7 +135,11 @@ struct Converter<unsigned long>
template <>
struct Converter<PY_LONG_LONG>
{
- static PyObject* toPython(PY_LONG_LONG holder)
+ static bool isConvertible(const PyObject* pyObj)
+ {
+ return PyLong_Check(pyObj);
+ }
+ static PyObject* toPython(const PY_LONG_LONG holder)
{
return PyLong_FromLongLong(holder);
}
@@ -137,7 +152,11 @@ struct Converter<PY_LONG_LONG>
template <>
struct Converter<unsigned PY_LONG_LONG>
{
- static PyObject* toPython(unsigned PY_LONG_LONG holder)
+ static bool isConvertible(const PyObject* pyObj)
+ {
+ return PyLong_Check(pyObj);
+ }
+ static PyObject* toPython(const unsigned PY_LONG_LONG holder)
{
return PyLong_FromUnsignedLongLong(holder);
}
@@ -150,7 +169,11 @@ struct Converter<unsigned PY_LONG_LONG>
template <typename PyFloatEquiv>
struct Converter_PyFloat
{
- static PyObject* toPython(PyFloatEquiv holder)
+ static bool isConvertible(const PyObject* pyObj)
+ {
+ return PyFloat_Check(pyObj);
+ }
+ static PyObject* toPython(const PyFloatEquiv holder)
{
return PyFloat_FromDouble((double) holder);
}
@@ -170,7 +193,11 @@ template <> struct Converter<double> : Converter_PyFloat<double> {};
template <typename CString>
struct Converter_CString
{
- static PyObject* toPython(CString holder)
+ static bool isConvertible(const PyObject* pyObj)
+ {
+ return PyString_Check(pyObj);
+ }
+ static PyObject* toPython(const CString holder)
{
return PyString_FromString(holder);
}
diff --git a/shibokengenerator.cpp b/shibokengenerator.cpp
index a25186de2..6f42bca72 100644
--- a/shibokengenerator.cpp
+++ b/shibokengenerator.cpp
@@ -59,30 +59,30 @@ void ShibokenGenerator::initPrimitiveTypesCorrespondences()
m_pythonPrimitiveTypeName.clear();
// PyBool
- m_pythonPrimitiveTypeName["bool"] = "PyBool";
+ m_pythonPrimitiveTypeName["bool"] = "bool";
// PyInt
- m_pythonPrimitiveTypeName["char"] = "PyInt";
- m_pythonPrimitiveTypeName["unsigned char"] = "PyInt";
- m_pythonPrimitiveTypeName["int"] = "PyInt";
- m_pythonPrimitiveTypeName["uint"] = "PyInt";
- m_pythonPrimitiveTypeName["unsigned int"] = "PyInt";
- m_pythonPrimitiveTypeName["short"] = "PyInt";
- m_pythonPrimitiveTypeName["ushort"] = "PyInt";
- m_pythonPrimitiveTypeName["unsigned short"] = "PyInt";
- m_pythonPrimitiveTypeName["long"] = "PyInt";
+ m_pythonPrimitiveTypeName["char"] = "char";
+ m_pythonPrimitiveTypeName["unsigned char"] = "unsigned char";
+ m_pythonPrimitiveTypeName["int"] = "int";
+ m_pythonPrimitiveTypeName["uint"] = "unsigned int";
+ m_pythonPrimitiveTypeName["unsigned int"] = "unsigned int";
+ m_pythonPrimitiveTypeName["short"] = "short";
+ m_pythonPrimitiveTypeName["ushort"] = "unsigned short";
+ m_pythonPrimitiveTypeName["unsigned short"] = "unsigned short";
+ m_pythonPrimitiveTypeName["long"] = "long";
// PyFloat
- m_pythonPrimitiveTypeName["double"] = "PyFloat";
- m_pythonPrimitiveTypeName["float"] = "PyFloat";
+ m_pythonPrimitiveTypeName["double"] = "float";
+ m_pythonPrimitiveTypeName["float"] = "double";
// PyLong
- m_pythonPrimitiveTypeName["unsigned long"] = "PyLong";
- m_pythonPrimitiveTypeName["ulong"] = "PyLong";
- m_pythonPrimitiveTypeName["long long"] = "PyLong";
- m_pythonPrimitiveTypeName["__int64"] = "PyLong";
- m_pythonPrimitiveTypeName["unsigned long long"] = "PyLong";
- m_pythonPrimitiveTypeName["unsigned __int64"] = "PyLong";
+ m_pythonPrimitiveTypeName["unsigned long"] = "unsigned long";
+ m_pythonPrimitiveTypeName["ulong"] = "unsigned long";
+ m_pythonPrimitiveTypeName["long long"] = "PY_LONG_LONG";
+ m_pythonPrimitiveTypeName["__int64"] = "PY_LONG_LONG";
+ m_pythonPrimitiveTypeName["unsigned long long"] = "PY_LONG_LONG";
+ m_pythonPrimitiveTypeName["unsigned __int64"] = "unsigned PY_LONG_LONG";
// Python operators
m_pythonOperators.clear();
@@ -261,15 +261,17 @@ QString ShibokenGenerator::writeBaseConversion(QTextStream& s, const AbstractMet
typeName.remove(0, 6);
QString conversion = typeName;
- if (type->isValuePointer()) {
- // If the type is a pointer to a Value Type,
- // remove the pointer symbol ('*')
+ // If the type is a pointer to a Value Type,
+ // remove the pointer symbol ('*')
+ if (type->isValuePointer())
conversion.chop(1);
- // And the constness, if any
- if (conversion.startsWith("const "))
- conversion.remove(0, 6);
- }
- s << "Shiboken::Converter< " << conversion << " >::";
+
+ // And the constness, if any
+ if (conversion.startsWith("const ") && type->name() != "char")
+ conversion.remove(0, 6);
+ if (conversion.endsWith("&"))
+ conversion.chop(1);
+ s << "Shiboken::Converter<" << conversion << " >::";
return typeName;
}
@@ -489,21 +491,27 @@ bool ShibokenGenerator::isReverseOperator(const AbstractMetaFunction* func)
args[1]->type()->typeEntry() == cppClass->typeEntry();
}
-static QString checkFunctionName(QString baseName, bool genericNumberType)
-{
- if (genericNumberType && ShibokenGenerator::isNumber(baseName))
- baseName = "PyNumber";
- return baseName + "_Check";
-}
-
QString ShibokenGenerator::cpythonCheckFunction(const AbstractMetaType* type, bool genericNumberType)
{
- return checkFunctionName(cpythonBaseName(type), genericNumberType);
+ if (genericNumberType && ShibokenGenerator::isNumber(cpythonBaseName(type)))
+ return "PyNumber_Check";
+
+ QString baseName;
+ QTextStream s(&baseName);
+ writeBaseConversion(s, type, 0);
+ s << "isConvertible";
+ s.flush();
+ return baseName;
}
QString ShibokenGenerator::cpythonCheckFunction(const TypeEntry* type, bool genericNumberType)
{
- return checkFunctionName(cpythonBaseName(type), genericNumberType);
+ if (genericNumberType && ShibokenGenerator::isNumber(cpythonBaseName(type)))
+ return "PyNumber_Check";
+ else {
+ QString typeName;
+ return "Converter<" + type->qualifiedCppName() + " >::isConvertible";
+ }
}
QString ShibokenGenerator::argumentString(const AbstractMetaFunction *func,
diff --git a/tests/samplebinding/complex_conversions.h b/tests/samplebinding/complex_conversions.h
index 375c2f63e..bd1f2cd2a 100644
--- a/tests/samplebinding/complex_conversions.h
+++ b/tests/samplebinding/complex_conversions.h
@@ -1,6 +1,10 @@
template<>
struct Converter<Complex>
{
+ static bool isConvertible(const PyObject* pyObj)
+ {
+ return PyComplex_Check(pyObj);
+ }
static PyObject* toPython(Complex cpx)
{
/*
diff --git a/tests/samplebinding/list_conversions.h b/tests/samplebinding/list_conversions.h
index 024f24b6e..97c7912c7 100644
--- a/tests/samplebinding/list_conversions.h
+++ b/tests/samplebinding/list_conversions.h
@@ -1,6 +1,11 @@
template <typename StdList>
struct Converter_std_list
{
+ static bool isConvertible(const PyObject* pyObj)
+ {
+ return PySequence_Check(const_cast<PyObject*>(pyObj));
+ }
+
static PyObject* toPython(StdList holder)
{
PyObject* result = PyList_New((int) holder.size());
diff --git a/tests/samplebinding/map_conversions.h b/tests/samplebinding/map_conversions.h
index a85aa909e..bd1b80f14 100644
--- a/tests/samplebinding/map_conversions.h
+++ b/tests/samplebinding/map_conversions.h
@@ -1,6 +1,11 @@
template <typename StdMap>
struct Converter_std_map
{
+ static bool isConvertible(const PyObject* pyObj)
+ {
+ return PyDict_Check(const_cast<PyObject*>(pyObj));
+ }
+
static PyObject* toPython(StdMap holder)
{
PyObject* result = PyDict_New();
diff --git a/tests/samplebinding/oddbool_conversions.h b/tests/samplebinding/oddbool_conversions.h
index 2e3f26414..7507cb52b 100644
--- a/tests/samplebinding/oddbool_conversions.h
+++ b/tests/samplebinding/oddbool_conversions.h
@@ -1,6 +1,11 @@
template <>
struct Converter<OddBool>
{
+ static bool isConvertible(const PyObject* pyObj)
+ {
+ return PyBool_Check(pyObj);
+ }
+
static PyObject* toPython(OddBool holder)
{
return PyBool_FromLong(holder.value());
diff --git a/tests/samplebinding/pair_conversions.h b/tests/samplebinding/pair_conversions.h
index d5f1431ca..aae68d061 100644
--- a/tests/samplebinding/pair_conversions.h
+++ b/tests/samplebinding/pair_conversions.h
@@ -1,6 +1,10 @@
template <typename StdPair>
struct Converter_std_pair
{
+ static bool isConvertible(const PyObject* pyObj)
+ {
+ return PySequence_Check(const_cast<PyObject*>(pyObj));
+ }
static PyObject* toPython(StdPair holder)
{
typename StdPair::first_type first(holder.first);