diff options
Diffstat (limited to 'libshiboken')
-rw-r--r-- | libshiboken/CMakeLists.txt | 2 | ||||
-rw-r--r-- | libshiboken/basewrapper.cpp | 42 | ||||
-rw-r--r-- | libshiboken/basewrapper.h | 21 | ||||
-rw-r--r-- | libshiboken/basewrapper_p.h | 6 | ||||
-rw-r--r-- | libshiboken/sbkconverter.cpp | 214 | ||||
-rw-r--r-- | libshiboken/sbkconverter.h | 205 | ||||
-rw-r--r-- | libshiboken/sbkconverter_p.h | 90 | ||||
-rw-r--r-- | libshiboken/shiboken.h | 1 |
8 files changed, 544 insertions, 37 deletions
diff --git a/libshiboken/CMakeLists.txt b/libshiboken/CMakeLists.txt index b57a814c..342151af 100644 --- a/libshiboken/CMakeLists.txt +++ b/libshiboken/CMakeLists.txt @@ -27,6 +27,7 @@ set(libshiboken_SRC basewrapper.cpp gilstate.cpp helper.cpp +sbkconverter.cpp sbkenum.cpp sbkmodule.cpp sbkstring.cpp @@ -54,6 +55,7 @@ install(FILES conversions.h gilstate.h helper.h + sbkconverter.h sbkenum.h sbkmodule.h python25compat.h diff --git a/libshiboken/basewrapper.cpp b/libshiboken/basewrapper.cpp index 2baa5b85..181b7025 100644 --- a/libshiboken/basewrapper.cpp +++ b/libshiboken/basewrapper.cpp @@ -22,6 +22,7 @@ #include "basewrapper.h" #include "basewrapper_p.h" +#include "sbkconverter.h" #include "sbkenum.h" #include "autodecref.h" #include "typeresolver.h" @@ -250,6 +251,8 @@ void SbkObjectTypeDealloc(PyObject* pyObj) } free(sbkType->d->original_name); sbkType->d->original_name = 0; + if (!Shiboken::ObjectType::isUserType(reinterpret_cast<PyTypeObject*>(sbkType))) + Shiboken::Conversions::deleteConverter(sbkType->d->converter); delete sbkType->d; sbkType->d = 0; } @@ -297,20 +300,18 @@ PyObject* SbkObjectTypeTpNew(PyTypeObject* metatype, PyObject* args, PyObject* k d->mi_offsets = parentType->mi_offsets; d->mi_init = parentType->mi_init; d->mi_specialcast = parentType->mi_specialcast; - d->ext_isconvertible = parentType->ext_isconvertible; - d->ext_tocpp = parentType->ext_tocpp; d->type_discovery = parentType->type_discovery; d->cpp_dtor = parentType->cpp_dtor; d->is_multicpp = 0; + d->converter = parentType->converter; } else { d->mi_offsets = 0; d->mi_init = 0; d->mi_specialcast = 0; - d->ext_isconvertible = 0; - d->ext_tocpp = 0; d->type_discovery = 0; d->cpp_dtor = 0; d->is_multicpp = 1; + d->converter = 0; } if (bases.size() == 1) d->original_name = strdup(bases.front()->d->original_name); @@ -596,30 +597,13 @@ bool canCallConstructor(PyTypeObject* myType, PyTypeObject* ctorType) return true; } -bool hasExternalCppConversions(SbkObjectType* self) -{ - return self->d->ext_tocpp; -} - -void* callExternalCppConversion(SbkObjectType* self, PyObject* obj) -{ - return self->d->ext_tocpp(obj); -} - -void setExternalCppConversionFunction(SbkObjectType* self, ExtendedToCppFunc func) -{ - self->d->ext_tocpp = func; -} -void setExternalIsConvertibleFunction(SbkObjectType* self, ExtendedIsConvertibleFunc func) -{ - self->d->ext_isconvertible = func; -} +bool hasExternalCppConversions(SbkObjectType*) { return false; } // DEPRECATED. +bool isExternalConvertible(SbkObjectType* self, PyObject* obj) { return false; } // DEPRECATED. +void setExternalCppConversionFunction(SbkObjectType*, ExtendedToCppFunc) {} // DEPRECATED. +void setExternalIsConvertibleFunction(SbkObjectType*, ExtendedIsConvertibleFunc) {} // DEPRECATED. +void* callExternalCppConversion(SbkObjectType*, PyObject*) { return 0; } // DEPRECATED. -bool isExternalConvertible(SbkObjectType* self, PyObject* obj) -{ - return self->d->ext_isconvertible && self->d->ext_isconvertible(obj); -} bool hasCast(SbkObjectType* type) { @@ -741,6 +725,12 @@ void setTypeUserData(SbkObjectType* self, void* userData, DeleteUserDataFunc d_f self->d->d_func = d_func; } + +SbkConverter* getTypeConverter(SbkObjectType* type) +{ + return type->d->converter; +} + } // namespace ObjectType diff --git a/libshiboken/basewrapper.h b/libshiboken/basewrapper.h index 1d4b9643..c2539027 100644 --- a/libshiboken/basewrapper.h +++ b/libshiboken/basewrapper.h @@ -33,6 +33,7 @@ extern "C" { +struct SbkConverter; struct SbkObjectPrivate; /// Base Python object for all the wrapped C++ classes. @@ -65,8 +66,8 @@ typedef void* (*SpecialCastFunction)(void*, SbkObjectType*); typedef SbkObjectType* (*TypeDiscoveryFunc)(void*, SbkObjectType*); typedef void* (*TypeDiscoveryFuncV2)(void*, SbkObjectType*); -typedef void* (*ExtendedToCppFunc)(PyObject*); -typedef bool (*ExtendedIsConvertibleFunc)(PyObject*); +typedef void* (*ExtendedToCppFunc)(PyObject*); // DEPRECATED. +typedef bool (*ExtendedIsConvertibleFunc)(PyObject*); // DEPRECATED. // Used in userdata dealloc function typedef void (*DeleteUserDataFunc)(void*); @@ -131,11 +132,13 @@ LIBSHIBOKEN_API bool isUserType(PyTypeObject* pyObj); */ LIBSHIBOKEN_API bool canCallConstructor(PyTypeObject* myType, PyTypeObject* ctorType); -LIBSHIBOKEN_API void setExternalCppConversionFunction(SbkObjectType* self, ExtendedToCppFunc func); -LIBSHIBOKEN_API void setExternalIsConvertibleFunction(SbkObjectType* self, ExtendedIsConvertibleFunc func); -LIBSHIBOKEN_API bool hasExternalCppConversions(SbkObjectType* self); -LIBSHIBOKEN_API bool isExternalConvertible(SbkObjectType* self, PyObject* obj); -LIBSHIBOKEN_API void* callExternalCppConversion(SbkObjectType* self, PyObject* obj); + +LIBSHIBOKEN_API bool hasExternalCppConversions(SbkObjectType*); // DEPRECATED. +LIBSHIBOKEN_API bool isExternalConvertible(SbkObjectType*, PyObject*); // DEPRECATED. +LIBSHIBOKEN_API void setExternalCppConversionFunction(SbkObjectType*, ExtendedToCppFunc); // DEPRECATED. +LIBSHIBOKEN_API void setExternalIsConvertibleFunction(SbkObjectType*, ExtendedIsConvertibleFunc); // DEPRECATED. +LIBSHIBOKEN_API void* callExternalCppConversion(SbkObjectType*, PyObject*); // DEPRECATED. + /** * Tells if the \p type represents an object of a class with multiple inheritance in C++. @@ -206,6 +209,10 @@ LIBSHIBOKEN_API void setSubTypeInitHook(SbkObjectType* self, SubTypeInitH */ LIBSHIBOKEN_API void* getTypeUserData(SbkObjectType* self); LIBSHIBOKEN_API void setTypeUserData(SbkObjectType* self, void* userData, DeleteUserDataFunc d_func); + +/// Returns the converter assigned to the wrapper \p type. +LIBSHIBOKEN_API SbkConverter* getTypeConverter(SbkObjectType* type); + } namespace Object { diff --git a/libshiboken/basewrapper_p.h b/libshiboken/basewrapper_p.h index 9f96ba75..c943a2a0 100644 --- a/libshiboken/basewrapper_p.h +++ b/libshiboken/basewrapper_p.h @@ -31,6 +31,7 @@ struct SbkObject; struct SbkObjectType; +struct SbkConverter; namespace Shiboken { @@ -106,10 +107,6 @@ struct SbkObjectTypePrivate /// Special cast function, null if this class doesn't have multiple inheritance. SpecialCastFunction mi_specialcast; TypeDiscoveryFuncV2 type_discovery; - /// Extended "isConvertible" function to be used when a conversion operator is defined in another module. - ExtendedIsConvertibleFunc ext_isconvertible; - /// Extended "toCpp" function to be used when a conversion operator is defined in another module. - ExtendedToCppFunc ext_tocpp; /// Pointer to a function responsible for deletion of the C++ instance calling the proper destructor. ObjectDestructor cpp_dtor; /// True if this type holds two or more C++ instances, e.g.: a Python class which inherits from two C++ classes. @@ -124,6 +121,7 @@ struct SbkObjectTypePrivate void* user_data; DeleteUserDataFunc d_func; void (*subtype_init)(SbkObjectType*, PyObject*, PyObject*); + SbkConverter* converter; }; diff --git a/libshiboken/sbkconverter.cpp b/libshiboken/sbkconverter.cpp new file mode 100644 index 00000000..b252e16c --- /dev/null +++ b/libshiboken/sbkconverter.cpp @@ -0,0 +1,214 @@ +/* + * This file is part of the Shiboken Python Bindings Generator project. + * + * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: PySide team <contact@pyside.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "sbkconverter.h" +#include "sbkconverter_p.h" +#include "basewrapper_p.h" + +#include "sbkdbg.h" + +namespace Shiboken { +namespace Conversions { + +static SbkConverter* createConverterObject(PyTypeObject* type, + PythonToCppFunc toCppPointerConvFunc, + IsConvertibleToCppFunc toCppPointerCheckFunc, + CppToPythonFunc pointerToPythonFunc, + CppToPythonFunc copyToPythonFunc) +{ + SbkConverter* converter = new SbkConverter; + converter->pythonType = type; + + converter->pointerToPython = pointerToPythonFunc; + converter->copyToPython = copyToPythonFunc; + + converter->toCppPointerConversion = std::make_pair(toCppPointerCheckFunc, toCppPointerConvFunc); + converter->toCppConversions.clear(); + + return converter; +} + +SbkConverter* createConverter(SbkObjectType* type, + PythonToCppFunc toCppPointerConvFunc, + IsConvertibleToCppFunc toCppPointerCheckFunc, + CppToPythonFunc pointerToPythonFunc, + CppToPythonFunc copyToPythonFunc) +{ + SbkConverter* converter = createConverterObject((PyTypeObject*)type, + toCppPointerConvFunc, toCppPointerCheckFunc, + pointerToPythonFunc, copyToPythonFunc); + type->d->converter = converter; + return converter; +} + +void deleteConverter(SbkConverter* converter) +{ + if (converter) { + converter->toCppConversions.clear(); + delete converter; + } +} + +void addPythonToCppValueConversion(SbkConverter* converter, + PythonToCppFunc pythonToCppFunc, + IsConvertibleToCppFunc isConvertibleToCppFunc) +{ + converter->toCppConversions.push_back(std::make_pair(isConvertibleToCppFunc, pythonToCppFunc)); +} +void addPythonToCppValueConversion(SbkObjectType* type, + PythonToCppFunc pythonToCppFunc, + IsConvertibleToCppFunc isConvertibleToCppFunc) +{ + addPythonToCppValueConversion(type->d->converter, pythonToCppFunc, isConvertibleToCppFunc); +} + +PyObject* pointerToPython(SbkObjectType* type, const void* cppIn) +{ + if (!cppIn) + Py_RETURN_NONE; + return type->d->converter->pointerToPython(cppIn); +} + +PyObject* referenceToPython(SbkObjectType* type, const void* cppIn) +{ + assert(cppIn); + + // If it is a Object Type, produce a wrapper for it. + if (!type->d->converter->copyToPython) + return type->d->converter->pointerToPython(cppIn); + + // If it is a Value Type, try to find an existing wrapper, otherwise copy it as value to Python. + PyObject* pyOut = (PyObject*)BindingManager::instance().retrieveWrapper(cppIn); + if (pyOut) { + Py_INCREF(pyOut); + return pyOut; + } + return type->d->converter->copyToPython(cppIn); +} + +static inline PyObject* CopyCppToPython(SbkConverter* converter, const void* cppIn) +{ + assert(cppIn); + return converter->copyToPython(cppIn); +} +PyObject* copyToPython(SbkObjectType* type, const void* cppIn) +{ + return CopyCppToPython(type->d->converter, cppIn); +} +PyObject* copyToPython(SbkConverter* converter, const void* cppIn) +{ + return CopyCppToPython(converter, cppIn); +} + +PythonToCppFunc isPythonToCppPointerConvertible(SbkObjectType* type, PyObject* pyIn) +{ + assert(pyIn); + return type->d->converter->toCppPointerConversion.first(pyIn); +} + +static inline PythonToCppFunc IsPythonToCppConvertible(SbkConverter* converter, PyObject* pyIn) +{ + assert(pyIn); + ToCppConversionList& convs = converter->toCppConversions; + for (ToCppConversionList::iterator conv = convs.begin(); conv != convs.end(); ++conv) { + PythonToCppFunc toCppFunc = 0; + if ((toCppFunc = (*conv).first(pyIn))) + return toCppFunc; + } + return 0; +} +PythonToCppFunc isPythonToCppValueConvertible(SbkObjectType* type, PyObject* pyIn) +{ + return IsPythonToCppConvertible(type->d->converter, pyIn); +} +PythonToCppFunc isPythonToCppConvertible(SbkConverter* converter, PyObject* pyIn) +{ + return IsPythonToCppConvertible(converter, pyIn); +} + +PythonToCppFunc isPythonToCppReferenceConvertible(SbkObjectType* type, PyObject* pyIn) +{ + if (pyIn != Py_None) { + PythonToCppFunc toCpp = isPythonToCppPointerConvertible(type, pyIn); + if (toCpp) + return toCpp; + } + return isPythonToCppValueConvertible(type, pyIn); +} + +void nonePythonToCppNullPtr(PyObject*, void* cppOut) +{ + assert(cppOut); + *((void**)cppOut) = 0; +} + +void* cppPointer(PyTypeObject* desiredType, SbkObject* pyIn) +{ + assert(pyIn); + SbkObjectType* inType = (SbkObjectType*)pyIn->ob_type; + if (ObjectType::hasCast(inType)) + return ObjectType::cast(inType, pyIn, desiredType); + return Object::cppPointer(pyIn, desiredType); +} + +void pythonToCppPointer(SbkObjectType* type, PyObject* pyIn, void* cppOut) +{ + assert(type); + assert(pyIn); + assert(cppOut); + *((void**)cppOut) = (pyIn == Py_None) ? 0 : cppPointer((PyTypeObject*)type, (SbkObject*)pyIn); +} + +void pythonToCppCopy(SbkObjectType* type, PyObject* pyIn, void* cppOut) +{ + assert(type); + assert(pyIn); + assert(cppOut); + PythonToCppFunc toCpp = IsPythonToCppConvertible(type->d->converter, pyIn); + if (toCpp) + toCpp(pyIn, cppOut); +} + +bool isImplicitConversion(SbkObjectType* type, PythonToCppFunc toCppFunc) +{ + // This is the Object Type or Value Type conversion that only + // retrieves the C++ pointer held in the Python wrapper. + if (toCppFunc == type->d->converter->toCppPointerConversion.second) + return false; + + // Object Types doesn't have any kind of value conversion, + // only C++ pointer retrieval. + if (type->d->converter->toCppConversions.empty()) + return false; + + // The first conversion of the non-pointer conversion list is + // a Value Type's copy to C++ function, which is not an implicit + // conversion. + // Otherwise it must be one of the implicit conversions. + // Note that we don't check if the Python to C++ conversion is in + // the list of the type's conversions, for it is expected that the + // caller knows what he's doing. + ToCppConversionList::iterator conv = type->d->converter->toCppConversions.begin(); + return toCppFunc != (*conv).second; +} + +} } // namespace Shiboken::Conversions diff --git a/libshiboken/sbkconverter.h b/libshiboken/sbkconverter.h new file mode 100644 index 00000000..d7be2577 --- /dev/null +++ b/libshiboken/sbkconverter.h @@ -0,0 +1,205 @@ +/* + * This file is part of the Shiboken Python Bindings Generator project. + * + * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: PySide team <contact@pyside.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef SBK_CONVERTER_H +#define SBK_CONVERTER_H + +#include <limits> +#include <Python.h> +#include "shibokenmacros.h" +#include "basewrapper.h" + +/** + * This is a convenience macro identical to Python's PyObject_TypeCheck, + * except that the arguments have swapped places, for the great convenience + * of generator. + */ +#define SbkObject_TypeCheck(tp, ob) \ + (Py_TYPE(ob) == (tp) || PyType_IsSubtype(Py_TYPE(ob), (tp))) + +extern "C" +{ + +/** + * SbkConverter is used to perform type conversions from C++ + * to Python and vice-versa;.and it is also used for type checking. + * SbkConverter is a private structure that must be accessed + * using the functions provided by the converter API. + */ +struct SbkConverter; + +/** + * Given a void pointer to a C++ object, this function must return + * the proper Python object. It may be either an existing wrapper + * for the C++ object, or a newly create one. Or even the Python + * equivalent of the C++ value passed in the argument. + * + * C++ -> Python + */ +typedef PyObject* (*CppToPythonFunc)(const void*); + +/** + * This function converts a Python object to a C++ value, it may be + * a pointer, value, class, container or primitive type, passed via + * a void pointer, that will be cast properly inside the function. + * This function is usually returned by an IsConvertibleToCppFunc + * function, or obtained knowing the type of the Python object input, + * thus it will not check the Python object type, and will expect + * the void pointer to be pointing to a proper variable. + * + * Python -> C++ + */ +typedef void (*PythonToCppFunc)(PyObject*,void*); + +/** + * Checks if the Python object passed in the argument is convertible to a + * C++ type defined inside the function, it returns the converter function + * that will transform a Python argument into a C++ value. + * It returns NULL if the Python object is not convertible to the C++ type + * that the function represents. + * + * Python -> C++ ? + */ +typedef PythonToCppFunc (*IsConvertibleToCppFunc)(PyObject*); + +} // extern "C" + + +namespace Shiboken { +namespace Conversions { + +/** + * Creates a converter for a wrapper type. + * \param type A Shiboken.ObjectType that will receive the new converter. + * \param toCppPointerConvFunc Function to retrieve the C++ pointer held by a Python wrapper. + * \param toCppPointerCheckFunc Check and return the retriever function of the C++ pointer held by a Python wrapper. + * \param pointerToPythonFunc Function to convert a C++ object to a Python \p type wrapper, keeping their identity. + * \param copyToPythonFunc Function to convert a C++ object to a Python \p type, copying the object. + * \returns The new converter referred by the wrapper \p type. + */ +LIBSHIBOKEN_API SbkConverter* createConverter(SbkObjectType* type, + PythonToCppFunc toCppPointerConvFunc, + IsConvertibleToCppFunc toCppPointerCheckFunc, + CppToPythonFunc pointerToPythonFunc, + CppToPythonFunc copyToPythonFunc = 0); + +LIBSHIBOKEN_API void deleteConverter(SbkConverter* converter); + +/** + * Adds a new conversion of a Python object to a C++ value. + * This is used in copy and implicit conversions. + */ +LIBSHIBOKEN_API void addPythonToCppValueConversion(SbkConverter* converter, + PythonToCppFunc pythonToCppFunc, + IsConvertibleToCppFunc isConvertibleToCppFunc); +LIBSHIBOKEN_API void addPythonToCppValueConversion(SbkObjectType* type, + PythonToCppFunc pythonToCppFunc, + IsConvertibleToCppFunc isConvertibleToCppFunc); + +// C++ -> Python --------------------------------------------------------------------------- + +/** + * Retrieves the Python wrapper object for the given \p cppIn C++ pointer object. + * This function is used only for Value and Object Types. + * Example usage: + * TYPE* var; + * PyObject* pyVar = pointerToPython(SBKTYPE, &var); + */ +LIBSHIBOKEN_API PyObject* pointerToPython(SbkObjectType* type, const void* cppIn); + +/** + * For the given \p cppIn C++ reference it returns the Python wrapper object, + * always for Object Types, and when they already exist for reference types; + * for when the latter doesn't have an existing wrapper type, the C++ object + * is copied to Python. + * Example usage: + * TYPE& var = SOMETHING; + * PyObject* pyVar = referenceToPython(SBKTYPE, &var); + */ +LIBSHIBOKEN_API PyObject* referenceToPython(SbkObjectType* type, const void* cppIn); + +/** + * Retrieves the Python wrapper object for the given C++ value pointed by \p cppIn. + * This function is used only for Value Types. + * Example usage: + * TYPE var; + * PyObject* pyVar = copyToPython(SBKTYPE, &var); + */ +LIBSHIBOKEN_API PyObject* copyToPython(SbkObjectType* type, const void* cppIn); +LIBSHIBOKEN_API PyObject* copyToPython(SbkConverter* converter, const void* cppIn); + +// Python -> C++ --------------------------------------------------------------------------- + +/** + * Returns a Python to C++ conversion function if the Python object is convertible to a C++ pointer. + * It returns NULL if the Python object is not convertible to \p type. + */ +LIBSHIBOKEN_API PythonToCppFunc isPythonToCppPointerConvertible(SbkObjectType* type, PyObject* pyIn); + +/** + * Returns a Python to C++ conversion function if the Python object is convertible to a C++ value. + * The resulting converter function will create a copy of the Python object in C++, or implicitly + * convert the object to the expected \p type. + * It returns NULL if the Python object is not convertible to \p type. + */ +LIBSHIBOKEN_API PythonToCppFunc isPythonToCppValueConvertible(SbkObjectType* type, PyObject* pyIn); + +/** + * Returns a Python to C++ conversion function if the Python object is convertible to a C++ reference. + * The resulting converter function will return the underlying C++ object held by the Python wrapper, + * or a new C++ value if it must be a implicit conversion. + * It returns NULL if the Python object is not convertible to \p type. + */ +LIBSHIBOKEN_API PythonToCppFunc isPythonToCppReferenceConvertible(SbkObjectType* type, PyObject* pyIn); + +/// This is the same as isPythonToCppValueConvertible function. +LIBSHIBOKEN_API PythonToCppFunc isPythonToCppConvertible(SbkConverter* converter, PyObject* pyIn); + +/** + * Returns the C++ pointer for the \p pyIn object cast to the type passed via \p desiredType. + * It differs from Shiboken::Object::cppPointer because it casts the pointer to a proper + * memory offset depending on the desired type. + */ +LIBSHIBOKEN_API void* cppPointer(PyTypeObject* desiredType, SbkObject* pyIn); + +/// Converts a Python object \p pyIn to C++ and stores the result in the C++ pointer passed in \p cppOut. +LIBSHIBOKEN_API void pythonToCppPointer(SbkObjectType* type, PyObject* pyIn, void* cppOut); + +/// Converts a Python object \p pyIn to C++ and copies the result in the C++ variable passed in \p cppOut. +LIBSHIBOKEN_API void pythonToCppCopy(SbkObjectType* type, PyObject* pyIn, void* cppOut); + +/** + * Helper function returned by generated convertible checking functions + * that returns a C++ NULL when the input Python object is None. + */ +LIBSHIBOKEN_API void nonePythonToCppNullPtr(PyObject*, void* cppOut); + +/** + * Returns true if the \p toCpp function passed is an implicit conversion of Python \p type. + * It is used when C++ expects a reference argument, so it may be the same object received + * from Python, or another created through implicit conversion. + */ +LIBSHIBOKEN_API bool isImplicitConversion(SbkObjectType* type, PythonToCppFunc toCpp); + +} } // namespace Shiboken::Conversions + +#endif // SBK_CONVERTER_H diff --git a/libshiboken/sbkconverter_p.h b/libshiboken/sbkconverter_p.h new file mode 100644 index 00000000..199538cc --- /dev/null +++ b/libshiboken/sbkconverter_p.h @@ -0,0 +1,90 @@ +/* + * This file is part of the Shiboken Python Bindings Generator project. + * + * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: PySide team <contact@pyside.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef SBK_CONVERTER_P_H +#define SBK_CONVERTER_P_H + +#include <Python.h> +#include <list> +#include "sbkconverter.h" + +extern "C" +{ + +typedef std::pair<IsConvertibleToCppFunc, PythonToCppFunc> ToCppConversion; +typedef std::list<ToCppConversion> ToCppConversionList; + +/** + * \internal + * Private structure of SbkConverter. + */ +struct SbkConverter +{ + /** + * TODO: it certainly will be empty in some cases, like with PyDate. + * TODO: probably a setPythonType(SbkConverter*, PyTypeObject*) function will be required. + * Python type associated with this converter. If the type is a Shiboken + * wrapper, then it must be a SbkObjectType; otherwise it will be the + * Python type to which the C++ value will be converted (note that the + * C++ type could be produced from various Python types). + */ + PyTypeObject* pythonType; + /** + * This function converts a C++ object to a Python object of the type + * indicated in pythonType. The identity of the C++ object is kept, + * because it looks for an already existing Python wrapper associated + * with the C++ instance. + * It is used to convert C++ pointers and references to Python objects. + */ + CppToPythonFunc pointerToPython; + /** + * This function converts a C++ object to a Python object of the type + * indicated in pythonType. The identity of the is not kept, because a + * new instance of the C++ object is created. + * It is used to convert objects passed by value, or reference, if said + * reference can't be traced to an object that already has a Python + * wrapper assigned for it. + */ + CppToPythonFunc copyToPython; + /** + * This is a special case of a Python to C++ conversion. It returns + * the underlying C++ pointer of a Python wrapper passed as parameter + * or NULL if the Python object is a None value. + * It comes separated from the other toCppConversions because if you + * have a Python object representing a Value Type the type checking + * for both ValueType and ValueType* would be the same, thus the first + * check would be true and the second would never be reached. + */ + ToCppConversion toCppPointerConversion; + /** + * This is a list of type checking functions that return the + * proper Python to C++ conversion function, for the given Python + * object. + * For Object Types, that never have implicit conversions, this + * list is always empty. + */ + ToCppConversionList toCppConversions; +}; + +} // extern "C" + +#endif // SBK_CONVERTER_P_H diff --git a/libshiboken/shiboken.h b/libshiboken/shiboken.h index 269f01c9..274c1ce1 100644 --- a/libshiboken/shiboken.h +++ b/libshiboken/shiboken.h @@ -31,6 +31,7 @@ #include "gilstate.h" #include "threadstatesaver.h" #include "helper.h" +#include "sbkconverter.h" #include "sbkenum.h" #include "sbkmodule.h" #include "sbkstring.h" |