summaryrefslogtreecommitdiffstats
path: root/libshiboken
diff options
context:
space:
mode:
authorMarcelo Lira <marcelo.lira@openbossa.org>2011-08-08 03:29:21 -0300
committerMarcelo Lira <marcelo.lira@openbossa.org>2011-12-09 20:28:02 -0300
commita3f655eb36f0a3d7a854db9cb5721d30c7668ef0 (patch)
treebf98139bf3efc4cb3492f3916ce6b23a0e7ddc9d /libshiboken
parent443e74dc231c82c758121df87698495646b118b8 (diff)
downloadshiboken-a3f655eb36f0a3d7a854db9cb5721d30c7668ef0.tar.gz
shiboken-a3f655eb36f0a3d7a854db9cb5721d30c7668ef0.tar.xz
shiboken-a3f655eb36f0a3d7a854db9cb5721d30c7668ef0.zip
Implemented new type converters, but only for wrapper types.
Diffstat (limited to 'libshiboken')
-rw-r--r--libshiboken/CMakeLists.txt2
-rw-r--r--libshiboken/basewrapper.cpp42
-rw-r--r--libshiboken/basewrapper.h21
-rw-r--r--libshiboken/basewrapper_p.h6
-rw-r--r--libshiboken/sbkconverter.cpp214
-rw-r--r--libshiboken/sbkconverter.h205
-rw-r--r--libshiboken/sbkconverter_p.h90
-rw-r--r--libshiboken/shiboken.h1
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"