diff options
author | Renato Araujo Oliveira Filho <renato.filho@openbossa.org> | 2010-11-19 14:30:22 -0300 |
---|---|---|
committer | Hugo Parente Lima <hugo.pl@gmail.com> | 2012-03-08 16:08:59 -0300 |
commit | 00924f871f1ed0511078157b5c37072d15621b3a (patch) | |
tree | 33d46c782be341318691cff84a02afb91f2c0c15 | |
parent | 7e98252ba8e0d2fc72fc569b3ceb82662297ac9d (diff) |
Created private pointer for Shiboken Meta Type.
Renamed ObjectType to BaseType.
Reviewer: Luciano Wolf <luciano.wolf@openbossa.org>
Hugo Parente Lima <hugo.pl@gmail.com>
-rw-r--r-- | generator/cppgenerator.cpp | 128 | ||||
-rw-r--r-- | generator/headergenerator.cpp | 6 | ||||
-rw-r--r-- | libshiboken/basewrapper.cpp | 396 | ||||
-rw-r--r-- | libshiboken/basewrapper.h | 193 | ||||
-rw-r--r-- | libshiboken/basewrapper_p.h | 50 | ||||
-rw-r--r-- | libshiboken/bindingmanager.cpp | 43 | ||||
-rw-r--r-- | libshiboken/bindingmanager.h | 6 | ||||
-rw-r--r-- | libshiboken/conversions.h | 30 | ||||
-rw-r--r-- | libshiboken/typeresolver.h | 2 |
9 files changed, 515 insertions, 339 deletions
diff --git a/generator/cppgenerator.cpp b/generator/cppgenerator.cpp index 239bd753b..537c658fb 100644 --- a/generator/cppgenerator.cpp +++ b/generator/cppgenerator.cpp @@ -788,13 +788,13 @@ void CppGenerator::writeMetaObjectMethod(QTextStream& s, const AbstractMetaClass { Indentation indentation(INDENT); s << INDENT << "SbkObject* pySelf = BindingManager::instance().retrieveWrapper(this);\n" - << INDENT << "void* typeData = Shiboken::getTypeUserData(pySelf);" << endl + << INDENT << "void* typeData = Shiboken::Wrapper::getTypeUserData(pySelf);" << endl << INDENT << "if (!typeData) {" << endl; { Indentation indentation2(INDENT); s << INDENT << "m_metaObject = PySide::DynamicQMetaObject::createBasedOn((PyObject*)pySelf, pySelf->ob_type, &" << metaClass->qualifiedCppName() << "::staticMetaObject);" << endl - << INDENT << "Shiboken::setTypeUserData(pySelf, m_metaObject, &Shiboken::callCppDestructor<PySide::DynamicQMetaObject>);" << endl; + << INDENT << "Shiboken::Wrapper::setTypeUserData(pySelf, m_metaObject, PySide::deleteDynamicQMetaObject);" << endl; } s << INDENT << "} else {" << endl; { @@ -830,7 +830,7 @@ void CppGenerator::writeConstructorWrapper(QTextStream& s, const AbstractMetaFun // Check if the right constructor was called. if (!metaClass->hasPrivateDestructor()) { - s << INDENT << "if (Shiboken::isUserType(self) && !Shiboken::canCallConstructor(self->ob_type, Shiboken::SbkType<" << metaClass->qualifiedCppName() << " >()))" << endl; + s << INDENT << "if (Shiboken::Wrapper::isUserType(self) && !Shiboken::BaseType::canCallConstructor(self->ob_type, Shiboken::SbkType<" << metaClass->qualifiedCppName() << " >()))" << endl; Indentation indent(INDENT); s << INDENT << "return " << m_currentErrorCode << ';' << endl << endl; } @@ -866,8 +866,8 @@ void CppGenerator::writeConstructorWrapper(QTextStream& s, const AbstractMetaFun s << INDENT << "SbkObject* sbkSelf = reinterpret_cast<SbkObject*>(self);" << endl; if (metaClass->isAbstract() || metaClass->baseClassNames().size() > 1) { - s << INDENT << "SbkObjectType* type = reinterpret_cast<SbkObjectType*>(self->ob_type);" << endl; - s << INDENT << "SbkObjectType* myType = reinterpret_cast<SbkObjectType*>(" << cpythonTypeNameExt(metaClass->typeEntry()) << ");" << endl; + s << INDENT << "SbkBaseType* type = reinterpret_cast<SbkBaseType*>(self->ob_type);" << endl; + s << INDENT << "SbkBaseType* myType = reinterpret_cast<SbkBaseType*>(" << cpythonTypeNameExt(metaClass->typeEntry()) << ");" << endl; } if (metaClass->isAbstract()) { @@ -891,9 +891,7 @@ void CppGenerator::writeConstructorWrapper(QTextStream& s, const AbstractMetaFun } { Indentation indentation(INDENT); - s << INDENT << "type->mi_init = myType->mi_init;" << endl; - s << INDENT << "type->mi_offsets = myType->mi_offsets;" << endl; - s << INDENT << "type->mi_specialcast = myType->mi_specialcast;" << endl; + s << INDENT << "Shiboken::BaseType::copyMultimpleheritance(type, myType);" << endl; } if (!metaClass->isAbstract()) s << INDENT << '}' << endl << endl; @@ -1175,7 +1173,7 @@ void CppGenerator::writeMethodWrapper(QTextStream& s, const AbstractMetaFunction s << INDENT << "if (!isReverse" << endl; { Indentation indent(INDENT); - s << INDENT << "&& Shiboken::isShibokenType(arg)" << endl; + s << INDENT << "&& Shiboken::Wrapper::checkType(arg)" << endl; s << INDENT << "&& !PyObject_TypeCheck(arg, self->ob_type)" << endl; s << INDENT << "&& PyObject_HasAttrString(arg, const_cast<char*>(\"" << revOpName << "\"))) {" << endl; // This PyObject_CallMethod call will emit lots of warnings like @@ -2046,7 +2044,7 @@ void CppGenerator::writeMethodCall(QTextStream& s, const AbstractMetaFunction* f virtualCall = virtualCall.replace("%CLASS_NAME", func->ownerClass()->qualifiedCppName()); normalCall = normalCall.replace("::%CLASS_NAME::", ""); methodCall = ""; - mc << "(Shiboken::isUserType(self) ? " << virtualCall << ":" << normalCall << ")"; + mc << "(Shiboken::Wrapper::isUserType(self) ? " << virtualCall << ":" << normalCall << ")"; } } } @@ -2154,7 +2152,7 @@ void CppGenerator::writeMethodCall(QTextStream& s, const AbstractMetaFunction* f break; } - s << INDENT << "Shiboken::keepReference(reinterpret_cast<SbkObject*>(self), \""; + s << INDENT << "Shiboken::Wrapper::keepReference(reinterpret_cast<SbkObject*>(self), \""; QString varName = arg_mod.referenceCounts.first().varName; if (varName.isEmpty()) varName = func->minimalSignature() + QString().number(arg_mod.index); @@ -2226,12 +2224,12 @@ void CppGenerator::writeMultipleInheritanceInitializerFunction(QTextStream& s, c void CppGenerator::writeSpecialCastFunction(QTextStream& s, const AbstractMetaClass* metaClass) { QString className = metaClass->qualifiedCppName(); - s << "static void* " << cpythonSpecialCastFunctionName(metaClass) << "(void* obj, SbkObjectType* desiredType)\n"; + s << "static void* " << cpythonSpecialCastFunctionName(metaClass) << "(void* obj, SbkBaseType* desiredType)\n"; s << "{\n"; s << INDENT << className << "* me = reinterpret_cast<" << className << "*>(obj);\n"; bool firstClass = true; foreach (const AbstractMetaClass* baseClass, getAllAncestors(metaClass)) { - s << INDENT << (!firstClass ? "else " : "") << "if (desiredType == reinterpret_cast<SbkObjectType*>(" << cpythonTypeNameExt(baseClass->typeEntry()) << "))\n"; + s << INDENT << (!firstClass ? "else " : "") << "if (desiredType == reinterpret_cast<SbkBaseType*>(" << cpythonTypeNameExt(baseClass->typeEntry()) << "))\n"; Indentation indent(INDENT); s << INDENT << "return static_cast<" << baseClass->qualifiedCppName() << "*>(me);\n"; firstClass = false; @@ -2283,11 +2281,11 @@ void CppGenerator::writeExtendedToCppFunction(QTextStream& s, const TypeEntry* e void CppGenerator::writeExtendedConverterInitialization(QTextStream& s, const TypeEntry* externalType, const QList<const AbstractMetaClass*>& conversions) { s << INDENT << "// Extended implicit conversions for " << externalType->targetLangPackage() << '.' << externalType->name() << endl; - s << INDENT << "shiboType = reinterpret_cast<SbkObjectType*>("; + s << INDENT << "shiboType = reinterpret_cast<SbkBaseType*>("; s << cppApiVariableName(externalType->targetLangPackage()) << '['; s << getTypeIndexVariableName(externalType) << "]);" << endl; - s << INDENT << "shiboType->ext_isconvertible = " << extendedIsConvertibleFunctionName(externalType) << ';' << endl; - s << INDENT << "shiboType->ext_tocpp = " << extendedToCppFunctionName(externalType) << ';' << endl; + s << INDENT << "Shiboken::BaseType::setExternalIsConvertibleFunction(shiboType, " << extendedIsConvertibleFunctionName(externalType) << ");" << endl; + s << INDENT << "Shiboken::BaseType::setExternalCppConversionFunction(shiboType, " << extendedToCppFunctionName(externalType) << ");" << endl; } QString CppGenerator::multipleInheritanceInitializerFunctionName(const AbstractMetaClass* metaClass) @@ -2326,13 +2324,9 @@ void CppGenerator::writeClassDefinition(QTextStream& s, const AbstractMetaClass* QString tp_init; QString tp_new; QString tp_dealloc; - QString cpp_dtor('0'); QString tp_as_number('0'); QString tp_as_sequence('0'); QString tp_hash('0'); - QString mi_init('0'); - QString obj_copier('0'); - QString mi_specialcast('0'); QString cppClassName = metaClass->qualifiedCppName(); QString className = cpythonTypeName(metaClass).replace(QRegExp("_Type$"), ""); QString baseClassName('0'); @@ -2369,14 +2363,6 @@ void CppGenerator::writeClassDefinition(QTextStream& s, const AbstractMetaClass* else deallocClassName = cppClassName; tp_dealloc = "&SbkDeallocWrapper"; - - QString dtorClassName = metaClass->qualifiedCppName(); -#ifdef AVOID_PROTECTED_HACK - if (metaClass->hasProtectedDestructor()) - dtorClassName = wrapperName(metaClass); -#endif - cpp_dtor = "&Shiboken::callCppDestructor<" + dtorClassName + " >"; - tp_init = onlyPrivCtor ? "0" : cpythonFunctionName(ctors.first()); } @@ -2417,25 +2403,19 @@ void CppGenerator::writeClassDefinition(QTextStream& s, const AbstractMetaClass* // class or some ancestor has multiple inheritance const AbstractMetaClass* miClass = getMultipleInheritingClass(metaClass); if (miClass) { - if (metaClass == miClass) { - mi_init = multipleInheritanceInitializerFunctionName(miClass); + if (metaClass == miClass) writeMultipleInheritanceInitializerFunction(s, metaClass); - } - mi_specialcast = '&'+cpythonSpecialCastFunctionName(metaClass); writeSpecialCastFunction(s, metaClass); s << endl; } - if (metaClass->typeEntry()->isValue() && shouldGenerateCppWrapper(metaClass)) - obj_copier = '&' + cpythonBaseName(metaClass) + "_ObjCopierFunc"; - if (!metaClass->typeEntry()->hashFunction().isEmpty()) tp_hash = '&' + cpythonBaseName(metaClass) + "_HashFunc"; s << "// Class Definition -----------------------------------------------" << endl; s << "extern \"C\" {" << endl; - s << "static SbkObjectType " << className + "_Type" << " = { { {" << endl; - s << INDENT << "PyObject_HEAD_INIT(&SbkObjectType_Type)" << endl; + s << "static SbkBaseType " << className + "_Type" << " = { { {" << endl; + s << INDENT << "PyObject_HEAD_INIT(&SbkBaseType_Type)" << endl; s << INDENT << "/*ob_size*/ 0," << endl; s << INDENT << "/*tp_name*/ \"" << metaClass->fullName() << "\"," << endl; s << INDENT << "/*tp_basicsize*/ sizeof(SbkObject)," << endl; @@ -2482,22 +2462,11 @@ void CppGenerator::writeClassDefinition(QTextStream& s, const AbstractMetaClass* s << INDENT << "/*tp_subclasses*/ 0," << endl; s << INDENT << "/*tp_weaklist*/ 0" << endl; s << "}, }," << endl; - s << INDENT << "/*mi_offsets*/ 0," << endl; - s << INDENT << "/*mi_init*/ " << mi_init << ',' << endl; - s << INDENT << "/*mi_specialcast*/ " << mi_specialcast << ',' << endl; - s << INDENT << "/*type_discovery*/ 0," << endl; - s << INDENT << "/*obj_copier*/ " << obj_copier << ',' << endl; - s << INDENT << "/*ext_isconvertible*/ 0," << endl; - s << INDENT << "/*ext_tocpp*/ 0," << endl; - s << INDENT << "/*cpp_dtor*/ " << cpp_dtor << ',' << endl; - s << INDENT << "/*is_multicpp*/ 0," << endl; - s << INDENT << "/*is_user_type*/ 0," << endl; + s << INDENT << "/*priv_data*/ 0" << endl; + s << "};" << endl; QString suffix; if (metaClass->typeEntry()->isObject() || metaClass->typeEntry()->isQObject()) suffix = "*"; - s << INDENT << "/*original_name*/ \"" << metaClass->qualifiedCppName() << suffix << "\"," << endl; - s << INDENT << "/*user_data*/ 0" << endl; - s << "};" << endl; s << "} //extern" << endl; } @@ -2757,7 +2726,7 @@ void CppGenerator::writeSetterFunction(QTextStream& s, const AbstractMetaField* bool pythonWrapperRefCounting = metaField->type()->typeEntry()->isObject() || metaField->type()->isValuePointer(); if (pythonWrapperRefCounting) { - s << INDENT << "Shiboken::keepReference(reinterpret_cast<SbkObject*>(self), \""; + s << INDENT << "Shiboken::Wrapper::keepReference(reinterpret_cast<SbkObject*>(self), \""; s << metaField->name() << "\", value);" << endl; //s << INDENT << "Py_XDECREF(oldvalue);" << endl; s << endl; @@ -3232,6 +3201,9 @@ void CppGenerator::writeClassRegister(QTextStream& s, const AbstractMetaClass* m s << '{' << endl; s << INDENT << cpythonTypeNameExt(metaClass->typeEntry()) << " = reinterpret_cast<PyTypeObject*>(&" << cpythonTypeName(metaClass->typeEntry()) << ");" << endl << endl; + // alloc private data + s << INDENT << "Shiboken::BaseType::initPrivateData(&" << cpythonTypeName(metaClass->typeEntry()) << ");" << endl; + // class inject-code target/beginning if (!metaClass->typeEntry()->codeSnips().isEmpty()) { writeCodeSnips(s, metaClass->typeEntry()->codeSnips(), CodeSnip::Beginning, TypeSystem::TargetLangCode, 0, 0, metaClass); @@ -3240,6 +3212,7 @@ void CppGenerator::writeClassRegister(QTextStream& s, const AbstractMetaClass* m if (metaClass->baseClass()) s << INDENT << pyTypeName << ".super.ht_type.tp_base = " << cpythonTypeNameExt(metaClass->baseClass()->typeEntry()) << ';' << endl; + // Multiple inheritance const AbstractMetaClassList baseClasses = getBaseClasses(metaClass); if (metaClass->baseClassNames().size() > 1) { @@ -3253,28 +3226,55 @@ void CppGenerator::writeClassRegister(QTextStream& s, const AbstractMetaClass* m s << INDENT << bases.join(", ") << ");" << endl << endl; } - // Fill multiple inheritance init function, if needed. + // Fill multiple inheritance data, if needed. const AbstractMetaClass* miClass = getMultipleInheritingClass(metaClass); - if (miClass && miClass != metaClass) { - s << INDENT << cpythonTypeName(metaClass) << ".mi_init = "; - s << "reinterpret_cast<SbkObjectType*>(" + cpythonTypeNameExt(miClass->typeEntry()) + ")->mi_init;" << endl << endl; + if (miClass) { + s << INDENT << "MultipleInheritanceInitFunction func;" << endl; + + if (miClass == metaClass) + s << INDENT << "func = " << multipleInheritanceInitializerFunctionName(miClass) << ";" << endl; + else + s << INDENT << "func = Shiboken::BaseType::getMultipleIheritanceFunction(reinterpret_cast<SbkBaseType*>(" << cpythonTypeNameExt(miClass->typeEntry()) << "));" << endl; + + s << INDENT << "Shiboken::BaseType::setMultipleIheritanceFunction(&" << cpythonTypeName(metaClass) << ", func);" << endl; + s << INDENT << "Shiboken::BaseType::setCastFunction(&" << cpythonTypeName(metaClass) << ", &" << cpythonSpecialCastFunctionName(metaClass) << ");" << endl; } + // Fill destrutor + QString dtorClassName = metaClass->qualifiedCppName(); + if (!metaClass->isNamespace() && !metaClass->hasPrivateDestructor()) { +#ifdef AVOID_PROTECTED_HACK + if (metaClass->hasProtectedDestructor()) + dtorClassName = wrapperName(metaClass); +#endif + s << INDENT << "Shiboken::BaseType::setDestructorFunction(&" << cpythonTypeName(metaClass) << ", &Shiboken::callCppDestructor<" << dtorClassName << " >);" << endl; + } + + // Fill copy function + if (metaClass->typeEntry()->isValue() && shouldGenerateCppWrapper(metaClass)) + s << INDENT << "Shiboken::BaseType::setCopyFunction(&" << cpythonTypeName(metaClass) << ", &" << cpythonBaseName(metaClass) + "_ObjCopierFunc);" << endl; + + s << INDENT << "if (PyType_Ready((PyTypeObject*)&" << pyTypeName << ") < 0)" << endl; + s << INDENT << INDENT << "return;" << endl << endl; + // Set typediscovery struct or fill the struct of another one if (metaClass->isPolymorphic()) { s << INDENT << "// Fill type discovery information" << endl; if (metaClass->baseClass()) { - s << INDENT << cpythonTypeName(metaClass) << ".type_discovery = &" << cpythonBaseName(metaClass) << "_typeDiscovery;" << endl; + s << INDENT << "Shiboken::BaseType::setTypeDiscoveryFunction(&" << cpythonTypeName(metaClass) << ", &" << cpythonBaseName(metaClass) << "_typeDiscovery);" << endl; s << INDENT << "Shiboken::BindingManager& bm = Shiboken::BindingManager::instance();" << endl; foreach (const AbstractMetaClass* base, baseClasses) { - s << INDENT << "bm.addClassInheritance(reinterpret_cast<SbkObjectType*>(" << cpythonTypeNameExt(base->typeEntry()) << "), &" << cpythonTypeName(metaClass) << ");" << endl; + s << INDENT << "bm.addClassInheritance(reinterpret_cast<SbkBaseType*>(" << cpythonTypeNameExt(base->typeEntry()) << "), &" << cpythonTypeName(metaClass) << ");" << endl; } } s << endl; } - s << INDENT << "if (PyType_Ready((PyTypeObject*)&" << pyTypeName << ") < 0)" << endl; - s << INDENT << INDENT << "return;" << endl << endl; + // Set OriginalName + QByteArray suffix; + if (metaClass->typeEntry()->isObject() || metaClass->typeEntry()->isQObject()) + suffix = "*"; + s << INDENT << "Shiboken::BaseType::setOriginalName(&" << pyTypeName << ", \"" << metaClass->qualifiedCppName() << suffix << "\");" << endl; if (metaClass->enclosingClass() && (metaClass->enclosingClass()->typeEntry()->codeGeneration() != TypeEntry::GenerateForSubclass) ) { s << INDENT << "PyDict_SetItemString(module," @@ -3345,7 +3345,7 @@ void CppGenerator::writeTypeDiscoveryFunction(QTextStream& s, const AbstractMeta { QString polymorphicExpr = metaClass->typeEntry()->polymorphicIdValue(); - s << "static SbkObjectType* " << cpythonBaseName(metaClass) << "_typeDiscovery(void* cptr, SbkObjectType* instanceType)\n{" << endl; + s << "static SbkBaseType* " << cpythonBaseName(metaClass) << "_typeDiscovery(void* cptr, SbkBaseType* instanceType)\n{" << endl; if (!metaClass->baseClass()) { s << INDENT << "TypeResolver* typeResolver = TypeResolver::get(typeid(*reinterpret_cast<" @@ -3353,7 +3353,7 @@ void CppGenerator::writeTypeDiscoveryFunction(QTextStream& s, const AbstractMeta s << INDENT << "if (typeResolver)" << endl; { Indentation indent(INDENT); - s << INDENT << "return reinterpret_cast<SbkObjectType*>(typeResolver->pythonType());" << endl; + s << INDENT << "return reinterpret_cast<SbkBaseType*>(typeResolver->pythonType());" << endl; } } else if (!polymorphicExpr.isEmpty()) { polymorphicExpr = polymorphicExpr.replace("%1", " reinterpret_cast<"+metaClass->qualifiedCppName()+"*>(cptr)"); @@ -3368,7 +3368,7 @@ void CppGenerator::writeTypeDiscoveryFunction(QTextStream& s, const AbstractMeta if (ancestor->baseClass()) continue; if (ancestor->isPolymorphic()) { - s << INDENT << "if (instanceType == reinterpret_cast<SbkObjectType*>(Shiboken::SbkType<" + s << INDENT << "if (instanceType == reinterpret_cast<SbkBaseType*>(Shiboken::SbkType<" << ancestor->qualifiedCppName() << " >()) && dynamic_cast<" << metaClass->qualifiedCppName() << "*>(reinterpret_cast<"<< ancestor->qualifiedCppName() << "*>(cptr)))" << endl; Indentation indent(INDENT); @@ -3675,7 +3675,7 @@ void CppGenerator::finishGeneration() s << INDENT << "}" << endl << endl; } - s << INDENT << "Shiboken::initShiboken();" << endl; + s << INDENT << "Shiboken::init();" << endl; s << INDENT << "PyObject* module = Py_InitModule(\"" << moduleName() << "\", "; s << moduleName() << "_methods);" << endl << endl; @@ -3689,7 +3689,7 @@ void CppGenerator::finishGeneration() if (!extendedConverters.isEmpty()) { s << INDENT << "// Initialize extended Converters" << endl; - s << INDENT << "SbkObjectType* shiboType;" << endl << endl; + s << INDENT << "SbkBaseType* shiboType;" << endl << endl; } foreach (const TypeEntry* externalType, extendedConverters.keys()) { writeExtendedConverterInitialization(s, externalType, extendedConverters[externalType]); diff --git a/generator/headergenerator.cpp b/generator/headergenerator.cpp index d9560d2ab..590aea381 100644 --- a/generator/headergenerator.cpp +++ b/generator/headergenerator.cpp @@ -434,7 +434,7 @@ void HeaderGenerator::finishGeneration() s << INDENT << metaClass->qualifiedCppName() << "* value = const_cast<" << metaClass->qualifiedCppName() << "* >(cppobj);" << endl; s << INDENT << "if (!isExactType)" << endl; s << INDENT << INDENT << "typeName = typeid(*value).name();" << endl; - s << INDENT << "PyObject* pyObj = Shiboken::Wrapper::newObject(reinterpret_cast<SbkObjectType*>(SbkType<" << metaClass->qualifiedCppName() << " >())," + s << INDENT << "PyObject* pyObj = Shiboken::Wrapper::newObject(reinterpret_cast<SbkBaseType*>(SbkType<" << metaClass->qualifiedCppName() << " >())," << "value, hasOwnership, isExactType, typeName);" << endl; s << INDENT << "PySide::Signal::updateSourceObject(pyObj);" << endl; s << INDENT << "return pyObj;" << endl; @@ -531,7 +531,7 @@ void HeaderGenerator::writeTypeConverterImpl(QTextStream& s, const TypeEntry* ty } - s << INDENT << "SbkObjectType* shiboType = reinterpret_cast<SbkObjectType*>(SbkType<"; + s << INDENT << "SbkBaseType* shiboType = reinterpret_cast<SbkBaseType*>(SbkType<"; s << type->name() << " >());" << endl; s << INDENT << "return "; bool isFirst = true; @@ -550,7 +550,7 @@ void HeaderGenerator::writeTypeConverterImpl(QTextStream& s, const TypeEntry* ty s << endl; { Indentation indent(INDENT); - s << INDENT << " || (shiboType->ext_isconvertible && shiboType->ext_isconvertible(pyobj));" << endl; + s << INDENT << " || (BaseType::isExternalConvertible(shiboType, pyobj));" << endl; } s << '}' << endl << endl; diff --git a/libshiboken/basewrapper.cpp b/libshiboken/basewrapper.cpp index 37d1282a2..39c18c3e1 100644 --- a/libshiboken/basewrapper.cpp +++ b/libshiboken/basewrapper.cpp @@ -34,16 +34,16 @@ extern "C" { -static void SbkObjectTypeDealloc(PyObject* pyObj); -static PyObject* SbkObjectTypeTpNew(PyTypeObject* metatype, PyObject* args, PyObject* kwds); +static void SbkBaseTypeDealloc(PyObject* pyObj); +static PyObject* SbkBaseTypeTpNew(PyTypeObject* metatype, PyObject* args, PyObject* kwds); -PyTypeObject SbkObjectType_Type = { +PyTypeObject SbkBaseType_Type = { PyObject_HEAD_INIT(0) /*ob_size*/ 0, /*tp_name*/ "Shiboken.ObjectType", - /*tp_basicsize*/ sizeof(SbkObjectType), + /*tp_basicsize*/ sizeof(SbkBaseType), /*tp_itemsize*/ 0, - /*tp_dealloc*/ SbkObjectTypeDealloc, + /*tp_dealloc*/ SbkBaseTypeDealloc, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, @@ -76,7 +76,7 @@ PyTypeObject SbkObjectType_Type = { /*tp_dictoffset*/ 0, /*tp_init*/ 0, /*tp_alloc*/ 0, - /*tp_new*/ SbkObjectTypeTpNew, + /*tp_new*/ SbkBaseTypeTpNew, /*tp_free*/ 0, /*tp_is_gc*/ 0, /*tp_bases*/ 0, @@ -101,8 +101,8 @@ static PyGetSetDef SbkObjectGetSetList[] = { {0} // Sentinel }; -SbkObjectType SbkObject_Type = { { { - PyObject_HEAD_INIT(&SbkObjectType_Type) +SbkBaseType SbkObject_Type = { { { + PyObject_HEAD_INIT(&SbkBaseType_Type) /*ob_size*/ 0, /*tp_name*/ "Shiboken.Object", /*tp_basicsize*/ sizeof(SbkObject), @@ -149,12 +149,7 @@ SbkObjectType SbkObject_Type = { { { /*tp_subclasses*/ 0, /*tp_weaklist*/ 0 }, }, - /*mi_offsets*/ 0, - /*mi_init*/ 0, - /*mi_specialcast*/ 0, - /*type_name_func*/ 0, - /*ext_isconvertible*/ 0, - /*ext_tocpp*/ 0 + /*priv_data*/ 0 }; @@ -166,12 +161,12 @@ void SbkDeallocWrapper(PyObject* pyObj) // If I have ownership and is valid delete C++ pointer if (sbkObj->d->hasOwnership && sbkObj->d->validCppObject) { - SbkObjectType* sbkType = reinterpret_cast<SbkObjectType*>(pyObj->ob_type); - if (sbkType->is_multicpp) { + SbkBaseType* sbkType = reinterpret_cast<SbkBaseType*>(pyObj->ob_type); + if (sbkType->d->is_multicpp) { Shiboken::DtorCallerVisitor visitor(sbkObj); Shiboken::walkThroughClassHierarchy(pyObj->ob_type, &visitor); } else { - sbkType->cpp_dtor(sbkObj->d->cptr[0]); + sbkType->d->cpp_dtor(sbkObj->d->cptr[0]); } } @@ -188,54 +183,64 @@ void SbkDeallocWrapperWithPrivateDtor(PyObject* self) Shiboken::Wrapper::deallocData(sbkObj); } -void SbkObjectTypeDealloc(PyObject* pyObj) +void SbkBaseTypeDealloc(PyObject* pyObj) { - SbkObjectType *sbkType = reinterpret_cast<SbkObjectType*>(pyObj->ob_type); + SbkBaseType *sbkType = reinterpret_cast<SbkBaseType*>(pyObj->ob_type); + if (!sbkType->d) + return; - if(sbkType->user_data && sbkType->d_func) { - sbkType->d_func(sbkType->user_data); - sbkType->user_data = 0; + if(sbkType->d->user_data && sbkType->d->d_func) { + sbkType->d->d_func(sbkType->d->user_data); + sbkType->d->user_data = 0; } + free(sbkType->d->original_name); + sbkType->d->original_name = 0; + delete sbkType->d; + sbkType->d = 0; } -PyObject* SbkObjectTypeTpNew(PyTypeObject* metatype, PyObject* args, PyObject* kwds) +PyObject* SbkBaseTypeTpNew(PyTypeObject* metatype, PyObject* args, PyObject* kwds) { // The meta type creates a new type when the Python programmer extends a wrapped C++ class. - SbkObjectType* newType = reinterpret_cast<SbkObjectType*>(PyType_Type.tp_new(metatype, args, kwds)); + SbkBaseType* newType = reinterpret_cast<SbkBaseType*>(PyType_Type.tp_new(metatype, args, kwds)); if (!newType) return 0; - std::list<SbkObjectType*> bases = Shiboken::getCppBaseClasses(reinterpret_cast<PyTypeObject*>(newType)); + SbkBaseTypePrivate* d = new SbkBaseTypePrivate; + memset(d, 0, sizeof(SbkBaseTypePrivate)); + + std::list<SbkBaseType*> bases = Shiboken::getCppBaseClasses(reinterpret_cast<PyTypeObject*>(newType)); if (bases.size() == 1) { - SbkObjectType* parentType = bases.front(); - newType->mi_offsets = parentType->mi_offsets; - newType->mi_init = parentType->mi_init; - newType->mi_specialcast = parentType->mi_specialcast; - newType->ext_isconvertible = parentType->ext_isconvertible; - newType->ext_tocpp = parentType->ext_tocpp; - newType->type_discovery = parentType->type_discovery; - newType->obj_copier = parentType->obj_copier; - newType->cpp_dtor = parentType->cpp_dtor; - newType->is_multicpp = 0; + SbkBaseTypePrivate* parentType = bases.front()->d; + 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->obj_copier = parentType->obj_copier; + d->cpp_dtor = parentType->cpp_dtor; + d->is_multicpp = 0; } else { - newType->mi_offsets = 0; - newType->mi_init = 0; - newType->mi_specialcast = 0; - newType->ext_isconvertible = 0; - newType->ext_tocpp = 0; - newType->type_discovery = 0; - newType->obj_copier = 0; - newType->cpp_dtor = 0; - newType->is_multicpp = 1; + 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->obj_copier = 0; + d->cpp_dtor = 0; + d->is_multicpp = 1; } if (bases.size() == 1) - newType->original_name = bases.front()->original_name; + d->original_name = strdup(bases.front()->d->original_name); else - newType->original_name = "object"; - newType->user_data = 0; - newType->d_func = 0; - newType->is_user_type = 1; + d->original_name = strdup("object"); + d->user_data = 0; + d->d_func = 0; + d->is_user_type = 1; + newType->d = d; return reinterpret_cast<PyObject*>(newType); } @@ -244,8 +249,8 @@ PyObject* SbkObjectTpNew(PyTypeObject* subtype, PyObject*, PyObject*) SbkObject* self = reinterpret_cast<SbkObject*>(subtype->tp_alloc(subtype, 0)); self->d = new SbkObjectPrivate; - SbkObjectType* sbkType = reinterpret_cast<SbkObjectType*>(subtype); - int numBases = sbkType->is_multicpp ? Shiboken::getNumberOfCppBaseClasses(subtype) : 1; + SbkBaseType* sbkType = reinterpret_cast<SbkBaseType*>(subtype); + int numBases = ((sbkType->d && sbkType->d->is_multicpp) ? Shiboken::getNumberOfCppBaseClasses(subtype) : 1); self->d->cptr = new void*[numBases]; std::memset(self->d->cptr, 0, sizeof(void*)*numBases); self->d->hasOwnership = 1; @@ -274,11 +279,11 @@ void walkThroughClassHierarchy(PyTypeObject* currentType, HierarchyVisitor* visi for (int i = 0; i < numBases; ++i) { PyTypeObject* type = reinterpret_cast<PyTypeObject*>(PyTuple_GET_ITEM(bases, i)); - if (type->ob_type != &SbkObjectType_Type) { + if (type->ob_type != &SbkBaseType_Type) { continue; } else { - SbkObjectType* sbkType = reinterpret_cast<SbkObjectType*>(type); - if (sbkType->is_user_type) + SbkBaseType* sbkType = reinterpret_cast<SbkBaseType*>(type); + if (sbkType->d->is_user_type) walkThroughClassHierarchy(type, visitor); else visitor->visit(sbkType); @@ -288,61 +293,6 @@ void walkThroughClassHierarchy(PyTypeObject* currentType, HierarchyVisitor* visi } } -void setTypeUserData(SbkObject* wrapper, void *user_data, DeleteUserDataFunc d_func) -{ - SbkObjectType* ob_type = reinterpret_cast<SbkObjectType*>(wrapper->ob_type); - if (ob_type->user_data) - ob_type->d_func(ob_type->user_data); - - ob_type->d_func = d_func; - ob_type->user_data = user_data; -} - -void* getTypeUserData(SbkObject* wrapper) -{ - return reinterpret_cast<SbkObjectType*>(wrapper->ob_type)->user_data; -} - -void keepReference(SbkObject* self, const char* key, PyObject* referredObject, bool append) -{ - - bool isNone = (!referredObject || (referredObject == Py_None)); - - if (!self->d->referredObjects) - self->d->referredObjects = new Shiboken::RefCountMap; - - RefCountMap& refCountMap = *(self->d->referredObjects); - if (!isNone) - incRefPyObject(referredObject); - - RefCountMap::iterator iter = refCountMap.find(key); - if (!append && (iter != refCountMap.end())) { - decRefPyObjectList(iter->second); - refCountMap.erase(iter); - } - - if (!isNone) { - std::list<SbkObject*> values = splitPyObject(referredObject); - if (append && (iter != refCountMap.end())) - refCountMap[key].insert(refCountMap[key].end(), values.begin(), values.end()); - else - refCountMap[key] = values; - } -} - -void clearReferences(SbkObject* self) -{ - if (!self->d->referredObjects) - return; - - RefCountMap& refCountMap = *(self->d->referredObjects); - RefCountMap::iterator iter; - for (iter = refCountMap.begin(); iter != refCountMap.end(); ++iter) - decRefPyObjectList(iter->second); - delete self->d->referredObjects; - self->d->referredObjects = 0; -} - bool importModule(const char* moduleName, PyTypeObject*** cppApiPtr) { Shiboken::AutoDecRef module(PyImport_ImportModule(moduleName)); @@ -361,13 +311,13 @@ bool importModule(const char* moduleName, PyTypeObject*** cppApiPtr) // Wrapper metatype and base type ---------------------------------------------------------- -void DtorCallerVisitor::visit(SbkObjectType* node) +void DtorCallerVisitor::visit(SbkBaseType* node) { - node->cpp_dtor(m_pyObj->d->cptr[m_count]); + node->d->cpp_dtor(m_pyObj->d->cptr[m_count]); m_count++; } -void initShiboken() +void init() { static bool shibokenAlreadInitialised = false; if (shibokenAlreadInitialised) @@ -381,7 +331,7 @@ void initShiboken() if (PyType_Ready(&SbkEnumType_Type) < 0) Py_FatalError("[libshiboken] Failed to initialise Shiboken.SbkEnumType metatype."); - if (PyType_Ready(&SbkObjectType_Type) < 0) + if (PyType_Ready(&SbkBaseType_Type) < 0) Py_FatalError("[libshiboken] Failed to initialise Shiboken.BaseWrapperType metatype."); if (PyType_Ready((PyTypeObject *)&SbkObject_Type) < 0) @@ -435,7 +385,7 @@ class FindBaseTypeVisitor : public HierarchyVisitor { public: FindBaseTypeVisitor(PyTypeObject* typeToFind) : m_found(false), m_typeToFind(typeToFind) {} - virtual void visit(SbkObjectType* node) + virtual void visit(SbkBaseType* node) { if (reinterpret_cast<PyTypeObject*>(node) == m_typeToFind) { m_found = true; @@ -449,17 +399,6 @@ class FindBaseTypeVisitor : public HierarchyVisitor PyTypeObject* m_typeToFind; }; -bool canCallConstructor(PyTypeObject* myType, PyTypeObject* ctorType) -{ - FindBaseTypeVisitor visitor(ctorType); - walkThroughClassHierarchy(myType, &visitor); - if (!visitor.found()) { - PyErr_Format(PyExc_TypeError, "%s isn't a direct base class of %s", ctorType->tp_name, myType->tp_name); - return false; - } - return true; -} - std::list<SbkObject*> splitPyObject(PyObject* pyObj) { std::list<SbkObject*> result; @@ -468,7 +407,7 @@ std::list<SbkObject*> splitPyObject(PyObject* pyObj) if (!lst.isNull()) { for(int i = 0, i_max = PySequence_Fast_GET_SIZE(lst.object()); i < i_max; i++) { PyObject* item = PySequence_Fast_GET_ITEM(lst.object(), i); - if (isShibokenType(item)) + if (Wrapper::checkType(item)) result.push_back(reinterpret_cast<SbkObject*>(item)); } } @@ -498,9 +437,145 @@ static void decRefPyObjectList(const std::list<SbkObject*>& lst) } } +namespace BaseType +{ + +bool checkType(PyTypeObject* type) +{ + return type->ob_type == &SbkBaseType_Type; +} + +bool isUserType(PyTypeObject* type) +{ + return BaseType::checkType(type) && reinterpret_cast<SbkBaseType*>(type)->d->is_user_type; +} + +bool canCallConstructor(PyTypeObject* myType, PyTypeObject* ctorType) +{ + FindBaseTypeVisitor visitor(ctorType); + walkThroughClassHierarchy(myType, &visitor); + if (!visitor.found()) { + PyErr_Format(PyExc_TypeError, "%s isn't a direct base class of %s", ctorType->tp_name, myType->tp_name); + return false; + } + return true; +} + +void* copy(SbkBaseType* self, const void* obj) +{ + return self->d->obj_copier(obj); +} + +void setCopyFunction(SbkBaseType* self, ObjectCopierFunction func) +{ + self->d->obj_copier = func; +} + +bool hasExternalCppConversions(SbkBaseType* self) +{ + return self->d->ext_tocpp; +} + +void* callExternalCppConversion(SbkBaseType* self, PyObject* obj) +{ + return self->d->ext_tocpp(obj); +} + +void setExternalCppConversionFunction(SbkBaseType* self, ExtendedToCppFunc func) +{ + self->d->ext_tocpp = func; +} + +void setExternalIsConvertibleFunction(SbkBaseType* self, ExtendedIsConvertibleFunc func) +{ + self->d->ext_isconvertible = func; +} + +bool isExternalConvertible(SbkBaseType* self, PyObject* obj) +{ + return self->d->ext_isconvertible && self->d->ext_isconvertible(obj); +} + +bool hasCast(SbkBaseType* self) +{ + return self->d->mi_specialcast; +} + +void* cast(SbkBaseType* self, SbkObject* obj, PyTypeObject *target) +{ + return self->d->mi_specialcast(Wrapper::cppPointer(obj, target), reinterpret_cast<SbkBaseType*>(target)); +} + +void setCastFunction(SbkBaseType* self, SpecialCastFunction func) +{ + self->d->mi_specialcast = func; +} + +void setOriginalName(SbkBaseType* self, const char* name) +{ + if (self->d->original_name) + free(self->d->original_name); + self->d->original_name = strdup(name); +} + +const char* getOriginalName(SbkBaseType* self) +{ + return self->d->original_name; +} + +void setTypeDiscoveryFunction(SbkBaseType* self, TypeDiscoveryFunc func) +{ + self->d->type_discovery = func; +} + +TypeDiscoveryFunc getTypeDiscoveryFunction(SbkBaseType* self) +{ + return self->d->type_discovery; +} + +void copyMultimpleheritance(SbkBaseType* self, SbkBaseType* other) +{ + self->d->mi_init = other->d->mi_init; + self->d->mi_offsets = other->d->mi_offsets; + self->d->mi_specialcast = other->d->mi_specialcast; +} + +void setMultipleIheritanceFunction(SbkBaseType* self, MultipleInheritanceInitFunction function) +{ + self->d->mi_init = function; +} + +MultipleInheritanceInitFunction getMultipleIheritanceFunction(SbkBaseType* self) +{ + return self->d->mi_init; +} + +void setDestructorFunction(SbkBaseType* self, ObjectDestructor func) +{ + self->d->cpp_dtor = func; +} + +void initPrivateData(SbkBaseType* self) +{ + self->d = new SbkBaseTypePrivate; + memset(self->d, 0, sizeof(SbkBaseTypePrivate)); +} + +} // namespace BaseType + namespace Wrapper { +bool checkType(PyObject* pyObj) +{ + return BaseType::checkType(pyObj->ob_type); +} + +bool isUserType(PyObject* pyObj) +{ + return BaseType::isUserType(pyObj->ob_type); +} + static void setSequenceOwnership(PyObject* pyObj, bool owner) { if (PySequence_Check(pyObj)) { @@ -512,7 +587,7 @@ static void setSequenceOwnership(PyObject* pyObj, bool owner) else releaseOwnership(*it); } - } else if (isShibokenType(pyObj)) { + } else if (Wrapper::checkType(pyObj)) { if (owner) getOwnership(reinterpret_cast<SbkObject*>(pyObj)); else @@ -665,7 +740,7 @@ void* cppPointer(SbkObject* pyObj, PyTypeObject* desiredType) { PyTypeObject* type = pyObj->ob_type; int idx = 0; - if (reinterpret_cast<SbkObjectType*>(type)->is_multicpp) + if (reinterpret_cast<SbkBaseType*>(type)->d->is_multicpp) idx = getTypeIndexOnHierarchy(type, desiredType); return pyObj->d->cptr[idx]; } @@ -673,7 +748,7 @@ void* cppPointer(SbkObject* pyObj, PyTypeObject* desiredType) bool setCppPointer(SbkObject* sbkObj, PyTypeObject* desiredType, void* cptr) { int idx = 0; - if (reinterpret_cast<SbkObjectType*>(sbkObj->ob_type)->is_multicpp) + if (reinterpret_cast<SbkBaseType*>(sbkObj->ob_type)->d->is_multicpp) idx = getTypeIndexOnHierarchy(sbkObj->ob_type, desiredType); bool alreadyInitialized = sbkObj->d->cptr[idx]; @@ -688,7 +763,7 @@ bool setCppPointer(SbkObject* sbkObj, PyTypeObject* desiredType, void* cptr) bool isValid(PyObject* pyObj) { if (!pyObj || pyObj == Py_None - || pyObj->ob_type->ob_type != &SbkObjectType_Type + || pyObj->ob_type->ob_type != &SbkBaseType_Type || ((SbkObject*)pyObj)->d->validCppObject) { return true; } @@ -696,7 +771,7 @@ bool isValid(PyObject* pyObj) return false; } -PyObject* newObject(SbkObjectType* instanceType, +PyObject* newObject(SbkBaseType* instanceType, void* cptr, bool hasOwnership, bool isExactType, @@ -708,7 +783,7 @@ PyObject* newObject(SbkObjectType* instanceType, if (typeName) { tr = TypeResolver::get(typeName); if (tr) - instanceType = reinterpret_cast<SbkObjectType*>(tr->pythonType()); + instanceType = reinterpret_cast<SbkBaseType*>(tr->pythonType()); } if (!tr) instanceType = BindingManager::instance().resolveType(cptr, instanceType); @@ -802,7 +877,7 @@ void setParent(PyObject* parent, PyObject* child) * so if you pass this class to someone that takes the ownership, we CAN'T enter in this if, but hey! QString * follows the sequence protocol. */ - if (PySequence_Check(child) && !isShibokenType(child)) { + if (PySequence_Check(child) && !Wrapper::checkType(child)) { Shiboken::AutoDecRef seq(PySequence_Fast(child, 0)); for (int i = 0, max = PySequence_Size(seq); i < max; ++i) setParent(parent, PySequence_Fast_GET_ITEM(seq.object(), i)); @@ -874,6 +949,61 @@ void deallocData(SbkObject* self) Py_TYPE(self)->tp_free(self); } +void setTypeUserData(SbkObject* wrapper, void *user_data, DeleteUserDataFunc d_func) +{ + SbkBaseType* ob_type = reinterpret_cast<SbkBaseType*>(wrapper->ob_type); + if (ob_type->d->user_data) + ob_type->d->d_func(ob_type->d->user_data); + + ob_type->d->d_func = d_func; + ob_type->d->user_data = user_data; +} + +void* getTypeUserData(SbkObject* wrapper) +{ + return reinterpret_cast<SbkBaseType*>(wrapper->ob_type)->d->user_data; +} + +void keepReference(SbkObject* self, const char* key, PyObject* referredObject, bool append) +{ + + bool isNone = (!referredObject || (referredObject == Py_None)); + + if (!self->d->referredObjects) + self->d->referredObjects = new Shiboken::RefCountMap; + + RefCountMap& refCountMap = *(self->d->referredObjects); + if (!isNone) + incRefPyObject(referredObject); + + RefCountMap::iterator iter = refCountMap.find(key); + if (!append && (iter != refCountMap.end())) { + decRefPyObjectList(iter->second); + refCountMap.erase(iter); + } + + if (!isNone) { + std::list<SbkObject*> values = splitPyObject(referredObject); + if (append && (iter != refCountMap.end())) + refCountMap[key].insert(refCountMap[key].end(), values.begin(), values.end()); + else + refCountMap[key] = values; + } +} + +void clearReferences(SbkObject* self) +{ + if (!self->d->referredObjects) + return; + + RefCountMap& refCountMap = *(self->d->referredObjects); + RefCountMap::iterator iter; + for (iter = refCountMap.begin(); iter != refCountMap.end(); ++iter) + decRefPyObjectList(iter->second); + delete self->d->referredObjects; + self->d->referredObjects = 0; +} + } // namespace Wrapper } // namespace Shiboken diff --git a/libshiboken/basewrapper.h b/libshiboken/basewrapper.h index f723a7a9b..aa1301dff 100644 --- a/libshiboken/basewrapper.h +++ b/libshiboken/basewrapper.h @@ -51,7 +51,7 @@ struct LIBSHIBOKEN_API SbkObject LIBSHIBOKEN_API void SbkDeallocWrapper(PyObject* pyObj); LIBSHIBOKEN_API void SbkDeallocWrapperWithPrivateDtor(PyObject* self); -struct SbkObjectType; +struct SbkBaseType; /// Function signature for the multiple inheritance information initializers that should be provided by classes with multiple inheritance. typedef int* (*MultipleInheritanceInitFunction)(const void*); @@ -61,9 +61,9 @@ typedef int* (*MultipleInheritanceInitFunction)(const void*); * part of a multiple inheritance hierarchy. * The implementation of this function is auto generated by the generator and you don't need to care about it. */ -typedef void* (*SpecialCastFunction)(void*, SbkObjectType*); +typedef void* (*SpecialCastFunction)(void*, SbkBaseType*); typedef void* (*ObjectCopierFunction)(const void*); -typedef SbkObjectType* (*TypeDiscoveryFunc)(void*, SbkObjectType*); +typedef SbkBaseType* (*TypeDiscoveryFunc)(void*, SbkBaseType*); typedef void* (*ExtendedToCppFunc)(PyObject*); typedef bool (*ExtendedIsConvertibleFunc)(PyObject*); @@ -71,34 +71,18 @@ typedef bool (*ExtendedIsConvertibleFunc)(PyObject*); // Used in userdata dealloc function typedef void (*DeleteUserDataFunc)(void*); -extern LIBSHIBOKEN_API PyTypeObject SbkObjectType_Type; -extern LIBSHIBOKEN_API SbkObjectType SbkObject_Type; +typedef void (*ObjectDestructor)(void*); +extern LIBSHIBOKEN_API PyTypeObject SbkBaseType_Type; +extern LIBSHIBOKEN_API SbkBaseType SbkObject_Type; + + +struct SbkBaseTypePrivate; /// PyTypeObject extended with C++ multiple inheritance information. -struct LIBSHIBOKEN_API SbkObjectType +struct LIBSHIBOKEN_API SbkBaseType { PyHeapTypeObject super; - int* mi_offsets; - MultipleInheritanceInitFunction mi_init; - /// Special cast function, null if this class doesn't have multiple inheritance. - SpecialCastFunction mi_specialcast; - TypeDiscoveryFunc type_discovery; - ObjectCopierFunction obj_copier; - /// 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 deletetion of the C++ instance calling the proper destructor. - void (*cpp_dtor)(void*); - /// True if this type holds two or more C++ instances, e.g.: a Python class which inherits from two C++ classes. - int is_multicpp:1; - /// True if this type was definied by the user. - int is_user_type:1; - /// C++ name - const char* original_name; - /// Type user data - void *user_data; - DeleteUserDataFunc d_func; + SbkBaseTypePrivate* d; }; LIBSHIBOKEN_API PyObject* SbkObjectTpNew(PyTypeObject* subtype, PyObject*, PyObject*); @@ -111,94 +95,109 @@ namespace Shiboken /** * Init shiboken library. */ -LIBSHIBOKEN_API void initShiboken(); +LIBSHIBOKEN_API void init(); -/** -* Returns true if the object is an instance of a type created by the Shiboken generator. -*/ -inline bool isShibokenType(PyObject*& pyObj) + +/// Delete the class T allocated on \p cptr. +template<typename T> +void callCppDestructor(void* cptr) { - return pyObj->ob_type->ob_type == &SbkObjectType_Type; + delete reinterpret_cast<T*>(cptr); } +LIBSHIBOKEN_API bool importModule(const char* moduleName, PyTypeObject*** cppApiPtr); +LIBSHIBOKEN_API void setErrorAboutWrongArguments(PyObject* args, const char* funcName, const char** cppOverloads); + +namespace BaseType { + /** -* Returns true if this object is an instance of an user defined type derived from an Shiboken type. +* Returns true if the object is an instance of a type created by the Shiboken generator. */ -inline bool isUserType(PyObject*& pyObj) -{ - return isShibokenType(pyObj) && reinterpret_cast<SbkObjectType*>(pyObj->ob_type)->is_user_type; -} +LIBSHIBOKEN_API bool checkType(PyTypeObject* pyObj); /** - * Get/Set Userdata in type class - */ -LIBSHIBOKEN_API void setTypeUserData(SbkObject* wrapper, void* user_data, DeleteUserDataFunc d_func); -LIBSHIBOKEN_API void* getTypeUserData(SbkObject* wrapper); +* Returns true if this object is an instance of an user defined type derived from an Shiboken type. +*/ +LIBSHIBOKEN_API bool isUserType(PyTypeObject* pyObj); /** * Returns true if the constructor of \p ctorType can be called for a instance of type \p myType. * \note This function set a python error when returning false. */ -LIBSHIBOKEN_API bool canCallConstructor(PyTypeObject* myType, PyTypeObject* ctorType); +LIBSHIBOKEN_API bool canCallConstructor(PyTypeObject* myType, PyTypeObject* ctorType); /** - * Increments the reference count of the referred Python object. - * A previous Python object in the same position identified by the 'key' parameter - * will have its reference counter decremented automatically when replaced. - * All the kept references should be decremented when the Python wrapper indicated by - * 'self' dies. - * No checking is done for any of the passed arguments, since it is meant to be used - * by generated code it is supposed that the generator is correct. - * \param self the wrapper instance that keeps references to other objects. - * \param key a key that identifies the C++ method signature and argument where the referredObject came from. - * \parem referredObject the object whose reference is used by the self object. - */ -LIBSHIBOKEN_API void keepReference(SbkObject* self, const char* key, PyObject* referredObject, bool append=false); + * Call copy function for the object type + **/ +LIBSHIBOKEN_API void* copy(SbkBaseType* self, const void *obj); +LIBSHIBOKEN_API void setCopyFunction(SbkBaseType* self, ObjectCopierFunction func); -/// Delete the class T allocated on \p cptr. -template<typename T> -void callCppDestructor(void* cptr) -{ - delete reinterpret_cast<T*>(cptr); -} +LIBSHIBOKEN_API void setExternalCppConversionFunction(SbkBaseType* self, ExtendedToCppFunc func); +LIBSHIBOKEN_API void setExternalIsConvertibleFunction(SbkBaseType* self, ExtendedIsConvertibleFunc func); +LIBSHIBOKEN_API bool hasExternalCppConversions(SbkBaseType* self); +LIBSHIBOKEN_API bool isExternalConvertible(SbkBaseType* self, PyObject* obj); +LIBSHIBOKEN_API void* callExternalCppConversion(SbkBaseType* self, PyObject* obj); + +LIBSHIBOKEN_API bool hasCast(SbkBaseType* self); +LIBSHIBOKEN_API void* cast(SbkBaseType* self, SbkObject* obj, PyTypeObject* target); +LIBSHIBOKEN_API void setCastFunction(SbkBaseType* self, SpecialCastFunction func); + +LIBSHIBOKEN_API void setOriginalName(SbkBaseType* self, const char* name); +LIBSHIBOKEN_API const char* getOriginalName(SbkBaseType* self); + +LIBSHIBOKEN_API void setTypeDiscoveryFunction(SbkBaseType* self, TypeDiscoveryFunc func); +LIBSHIBOKEN_API TypeDiscoveryFunc getTypeDiscoveryFunction(SbkBaseType* self); + +LIBSHIBOKEN_API void copyMultimpleheritance(SbkBaseType* self, SbkBaseType* other); +LIBSHIBOKEN_API void setMultipleIheritanceFunction(SbkBaseType* self, MultipleInheritanceInitFunction func); +LIBSHIBOKEN_API MultipleInheritanceInitFunction getMultipleIheritanceFunction(SbkBaseType* self); -LIBSHIBOKEN_API bool importModule(const char* moduleName, PyTypeObject*** cppApiPtr); -LIBSHIBOKEN_API void setErrorAboutWrongArguments(PyObject* args, const char* funcName, const char** cppOverloads); +LIBSHIBOKEN_API void setDestructorFunction(SbkBaseType* self, ObjectDestructor func); + +LIBSHIBOKEN_API void initPrivateData(SbkBaseType* self); +} namespace Wrapper { -LIBSHIBOKEN_API PyObject* newObject(SbkObjectType* instanceType, - void* cptr, - bool hasOwnership = true, - bool isExactType = false, - const char* typeName = 0); +/** +* Returns true if the object is an instance of a type created by the Shiboken generator. +*/ +LIBSHIBOKEN_API bool checkType(PyObject* pyObj); +LIBSHIBOKEN_API bool isUserType(PyObject* pyObj); + -LIBSHIBOKEN_API void setValidCpp(SbkObject* pyObj, bool value); -LIBSHIBOKEN_API void setHasCppWrapper(SbkObject* pyObj, bool value); -LIBSHIBOKEN_API bool hasCppWrapper(SbkObject* pyObj); +LIBSHIBOKEN_API PyObject* newObject(SbkBaseType* instanceType, + void* cptr, + bool hasOwnership = true, + bool isExactType = false, + const char* typeName = 0); -LIBSHIBOKEN_API bool hasOwnership(SbkObject* pyObj); -LIBSHIBOKEN_API void getOwnership(PyObject* pyObj); -LIBSHIBOKEN_API void getOwnership(SbkObject* pyObj); -LIBSHIBOKEN_API void releaseOwnership(PyObject* pyObj); -LIBSHIBOKEN_API void releaseOwnership(SbkObject* pyObj); +LIBSHIBOKEN_API void setValidCpp(SbkObject* pyObj, bool value); +LIBSHIBOKEN_API void setHasCppWrapper(SbkObject* pyObj, bool value); +LIBSHIBOKEN_API bool hasCppWrapper(SbkObject* pyObj); -LIBSHIBOKEN_API bool hasParentInfo(SbkObject* pyObj); +LIBSHIBOKEN_API bool hasOwnership(SbkObject* pyObj); +LIBSHIBOKEN_API void getOwnership(PyObject* pyObj); +LIBSHIBOKEN_API void getOwnership(SbkObject* pyObj); +LIBSHIBOKEN_API void releaseOwnership(PyObject* pyObj); +LIBSHIBOKEN_API void releaseOwnership(SbkObject* pyObj); + +LIBSHIBOKEN_API bool hasParentInfo(SbkObject* pyObj); /** * Get the C++ pointer of type \p desiredType from a Python object. */ -LIBSHIBOKEN_API void* cppPointer(SbkObject* pyObj, PyTypeObject* desiredType); +LIBSHIBOKEN_API void* cppPointer(SbkObject* pyObj, PyTypeObject* desiredType); /** * Set the C++ pointer of type \p desiredType of a Python object. */ -LIBSHIBOKEN_API bool setCppPointer(SbkObject* sbkObj, PyTypeObject* desiredType, void* cptr); +LIBSHIBOKEN_API bool setCppPointer(SbkObject* sbkObj, PyTypeObject* desiredType, void* cptr); /** * Returns false and sets a Python RuntimeError if the Python wrapper is not marked as valid. */ -LIBSHIBOKEN_API bool isValid(PyObject* wrapper); +LIBSHIBOKEN_API bool isValid(PyObject* wrapper); /** * Set the parent of \p child to \p parent. @@ -206,39 +205,59 @@ LIBSHIBOKEN_API bool isValid(PyObject* wrapper); * \param parent the parent object, if null, the child will have no parents. * \param child the child. */ -LIBSHIBOKEN_API void setParent(PyObject* parent, PyObject* child); +LIBSHIBOKEN_API void setParent(PyObject* parent, PyObject* child); /** * Remove this child from their parent, if any. * \param child the child. */ -LIBSHIBOKEN_API void removeParent(SbkObject* child, bool giveOwnershipBack = true, bool keepReferenc = false); +LIBSHIBOKEN_API void removeParent(SbkObject* child, bool giveOwnershipBack = true, bool keepReferenc = false); /** * \internal This is an internal function called by SbkBaseWrapper_Dealloc, it's exported just for techinical reasons. * \note Do not call this function inside your bindings. */ -LIBSHIBOKEN_API void destroyParentInfo(SbkObject* obj, bool removeFromParent = true); +LIBSHIBOKEN_API void destroyParentInfo(SbkObject* obj, bool removeFromParent = true); /** * Mark the object as invalid */ -LIBSHIBOKEN_API void invalidate(SbkObject* self); +LIBSHIBOKEN_API void invalidate(SbkObject* self); /** * Help function can be used to invalida a sequence of object **/ -LIBSHIBOKEN_API void invalidate(PyObject* pyobj); +LIBSHIBOKEN_API void invalidate(PyObject* pyobj); /** * Make the object valid again */ -LIBSHIBOKEN_API void makeValid(SbkObject* self); +LIBSHIBOKEN_API void makeValid(SbkObject* self); /** * Destroy any data in Shiboken structure and c++ pointer if the pyboject has the ownership **/ -LIBSHIBOKEN_API void destroy(SbkObject* self); +LIBSHIBOKEN_API void destroy(SbkObject* self); + +/** + * Get/Set Userdata in type class + */ +LIBSHIBOKEN_API void setTypeUserData(SbkObject* wrapper, void* user_data, DeleteUserDataFunc d_func); +LIBSHIBOKEN_API void* getTypeUserData(SbkObject* wrapper); + +/** + * Increments the reference count of the referred Python object. + * A previous Python object in the same position identified by the 'key' parameter + * will have its reference counter decremented automatically when replaced. + * All the kept references should be decremented when the Python wrapper indicated by + * 'self' dies. + * No checking is done for any of the passed arguments, since it is meant to be used + * by generated code it is supposed that the generator is correct. + * \param self the wrapper instance that keeps references to other objects. + * \param key a key that identifies the C++ method signature and argument where the referredObject came from. + * \parem referredObject the object whose reference is used by the self object. + */ +LIBSHIBOKEN_API void keepReference(SbkObject* self, const char* key, PyObject* referredObject, bool append=false); } // namespace Wrapper diff --git a/libshiboken/basewrapper_p.h b/libshiboken/basewrapper_p.h index 748ce2dca..702fdbd07 100644 --- a/libshiboken/basewrapper_p.h +++ b/libshiboken/basewrapper_p.h @@ -28,7 +28,7 @@ #include <map> struct SbkObject; -struct SbkObjectType; +struct SbkBaseType; namespace Shiboken { @@ -80,6 +80,34 @@ struct SbkObjectPrivate Shiboken::RefCountMap* referredObjects; }; + +struct SbkBaseTypePrivate +{ + int* mi_offsets; + MultipleInheritanceInitFunction mi_init; + + /// Special cast function, null if this class doesn't have multiple inheritance. + SpecialCastFunction mi_specialcast; + TypeDiscoveryFunc type_discovery; + ObjectCopierFunction obj_copier; + /// 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 deletetion 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. + int is_multicpp:1; + /// True if this type was definied by the user. + int is_user_type:1; + /// C++ name + char* original_name; + /// Type user data + void *user_data; + DeleteUserDataFunc d_func; +}; + + } // extern "C" namespace Shiboken @@ -97,7 +125,7 @@ class HierarchyVisitor public: HierarchyVisitor() : m_wasFinished(false) {} virtual ~HierarchyVisitor() {} - virtual void visit(SbkObjectType* node) = 0; + virtual void visit(SbkBaseType* node) = 0; void finish() { m_wasFinished = true; }; bool wasFinished() const { return m_wasFinished; } private: @@ -109,7 +137,7 @@ class BaseCountVisitor : public HierarchyVisitor public: BaseCountVisitor() : m_count(0) {} - void visit(SbkObjectType*) + void visit(SbkBaseType*) { m_count++; } @@ -124,21 +152,21 @@ class BaseAccumulatorVisitor : public HierarchyVisitor public: BaseAccumulatorVisitor() {} - void visit(SbkObjectType* node) + void visit(SbkBaseType* node) { m_bases.push_back(node); } - std::list<SbkObjectType*> bases() const { return m_bases; } + std::list<SbkBaseType*> bases() const { return m_bases; } private: - std::list<SbkObjectType*> m_bases; + std::list<SbkBaseType*> m_bases; }; class GetIndexVisitor : public HierarchyVisitor { public: GetIndexVisitor(PyTypeObject* desiredType) : m_index(-1), m_desiredType(desiredType) {} - virtual void visit(SbkObjectType* node) + virtual void visit(SbkBaseType* node) { m_index++; if (PyType_IsSubtype(reinterpret_cast<PyTypeObject*>(node), m_desiredType)) @@ -155,7 +183,7 @@ class DtorCallerVisitor : public HierarchyVisitor { public: DtorCallerVisitor(SbkObject* pyObj) : m_count(0), m_pyObj(pyObj) {} - void visit(SbkObjectType* node); + void visit(SbkBaseType* node); private: int m_count; SbkObject* m_pyObj; @@ -183,21 +211,21 @@ inline int getNumberOfCppBaseClasses(PyTypeObject* baseType) return visitor.count(); } -inline std::list<SbkObjectType*> getCppBaseClasses(PyTypeObject* baseType) +inline std::list<SbkBaseType*> getCppBaseClasses(PyTypeObject* baseType) { BaseAccumulatorVisitor visitor; walkThroughClassHierarchy(baseType, &visitor); return visitor.bases(); } +namespace Wrapper +{ /** * Decrements the reference counters of every object referred by self. * \param self the wrapper instance that keeps references to other objects. */ void clearReferences(SbkObject* self); -namespace Wrapper -{ /** * Destroy internal data **/ diff --git a/libshiboken/bindingmanager.cpp b/libshiboken/bindingmanager.cpp index b56cceed4..3742f6fe7 100644 --- a/libshiboken/bindingmanager.cpp +++ b/libshiboken/bindingmanager.cpp @@ -37,8 +37,8 @@ typedef google::dense_hash_map<const void*, SbkObject*> WrapperMap; class Graph { public: - typedef std::list<SbkObjectType*> NodeList; - typedef google::dense_hash_map<SbkObjectType*, NodeList> Edges; + typedef std::list<SbkBaseType*> NodeList; + typedef google::dense_hash_map<SbkBaseType*, NodeList> Edges; Edges m_edges; @@ -47,7 +47,7 @@ public: m_edges.set_empty_key(0); } - void addEdge(SbkObjectType* from, SbkObjectType* to) + void addEdge(SbkBaseType* from, SbkBaseType* to) { m_edges[from].push_back(to); } @@ -61,7 +61,7 @@ public: Edges::const_iterator i = m_edges.begin(); for (; i != m_edges.end(); ++i) { - SbkObjectType* node1 = i->first; + SbkBaseType* node1 = i->first; const NodeList& nodeList = i->second; NodeList::const_iterator j = nodeList.begin(); for (; j != nodeList.end(); ++j) @@ -71,19 +71,19 @@ public: } #endif - SbkObjectType* identifyType(void* cptr, SbkObjectType* type, SbkObjectType* baseType) const + SbkBaseType* identifyType(void* cptr, SbkBaseType* type, SbkBaseType* baseType) const { Edges::const_iterator edgesIt = m_edges.find(type); if (edgesIt != m_edges.end()) { const NodeList& adjNodes = m_edges.find(type)->second; NodeList::const_iterator i = adjNodes.begin(); for (; i != adjNodes.end(); ++i) { - SbkObjectType* newType = identifyType(cptr, *i, baseType); + SbkBaseType* newType = identifyType(cptr, *i, baseType); if (newType) return newType; } } - return type->type_discovery ? type->type_discovery(cptr, baseType) : 0; + return ((type->d && type->d->type_discovery) ? type->d->type_discovery(cptr, baseType) : 0); } }; @@ -166,13 +166,17 @@ bool BindingManager::hasWrapper(const void* cptr) void BindingManager::registerWrapper(SbkObject* pyObj, void* cptr) { - SbkObjectType* instanceType = reinterpret_cast<SbkObjectType*>(pyObj->ob_type); + SbkBaseType* instanceType = reinterpret_cast<SbkBaseType*>(pyObj->ob_type); + SbkBaseTypePrivate* d = instanceType->d; - if (instanceType->mi_init && !instanceType->mi_offsets) - instanceType->mi_offsets = instanceType->mi_init(cptr); + if (!d) + return; + + if (d->mi_init && !d->mi_offsets) + d->mi_offsets = d->mi_init(cptr); m_d->assignWrapper(pyObj, cptr); - if (instanceType->mi_offsets) { - int* offset = instanceType->mi_offsets; + if (d->mi_offsets) { + int* offset = d->mi_offsets; while (*offset != -1) { if (*offset > 0) m_d->assignWrapper(pyObj, reinterpret_cast<void*>((std::size_t) cptr + (*offset))); @@ -183,15 +187,16 @@ void BindingManager::registerWrapper(SbkObject* pyObj, void* cptr) void BindingManager::releaseWrapper(SbkObject* sbkObj) { - SbkObjectType* sbkType = reinterpret_cast<SbkObjectType*>(sbkObj->ob_type); - int numBases = sbkType->is_multicpp ? getNumberOfCppBaseClasses(sbkObj->ob_type) : 1; + SbkBaseType* sbkType = reinterpret_cast<SbkBaseType*>(sbkObj->ob_type); + SbkBaseTypePrivate* d = sbkType->d; + int numBases = ((d && d->is_multicpp) ? getNumberOfCppBaseClasses(sbkObj->ob_type) : 1); void** cptrs = reinterpret_cast<SbkObject*>(sbkObj)->d->cptr; for (int i = 0; i < numBases; ++i) { void* cptr = cptrs[i]; m_d->releaseWrapper(cptr); - if (sbkType->mi_offsets) { - int* offset = sbkType->mi_offsets; + if (d && d->mi_offsets) { + int* offset = d->mi_offsets; while (*offset != -1) { if (*offset > 0) m_d->releaseWrapper((void*) ((std::size_t) cptr + (*offset))); @@ -250,14 +255,14 @@ PyObject* BindingManager::getOverride(const void* cptr, const char* methodName) return 0; } -void BindingManager::addClassInheritance(SbkObjectType* parent, SbkObjectType* child) +void BindingManager::addClassInheritance(SbkBaseType* parent, SbkBaseType* child) { m_d->classHierarchy.addEdge(parent, child); } -SbkObjectType* BindingManager::resolveType(void* cptr, SbkObjectType* type) +SbkBaseType* BindingManager::resolveType(void* cptr, SbkBaseType* type) { - SbkObjectType* identifiedType = m_d->classHierarchy.identifyType(cptr, type, type); + SbkBaseType* identifiedType = m_d->classHierarchy.identifyType(cptr, type, type); return identifiedType ? identifiedType : type; } diff --git a/libshiboken/bindingmanager.h b/libshiboken/bindingmanager.h index b6d4ac42b..2ead23510 100644 --- a/libshiboken/bindingmanager.h +++ b/libshiboken/bindingmanager.h @@ -28,7 +28,7 @@ #include "shibokenmacros.h" struct SbkObject; -struct SbkObjectType; +struct SbkBaseType; namespace Shiboken { @@ -46,8 +46,8 @@ public: SbkObject* retrieveWrapper(const void* cptr); PyObject* getOverride(const void* cptr, const char* methodName); - void addClassInheritance(SbkObjectType* parent, SbkObjectType* child); - SbkObjectType* resolveType(void* cptr, SbkObjectType* type); + void addClassInheritance(SbkBaseType* parent, SbkBaseType* child); + SbkBaseType* resolveType(void* cptr, SbkBaseType* type); std::set<SbkObject*> getAllPyObjects(); private: diff --git a/libshiboken/conversions.h b/libshiboken/conversions.h index 4d55ef0fe..d6a3dd5ee 100644 --- a/libshiboken/conversions.h +++ b/libshiboken/conversions.h @@ -99,7 +99,7 @@ struct CppObjectCopier<T, true> { static inline T* copy(const T& obj) { - return reinterpret_cast<T*>(reinterpret_cast<SbkObjectType*>(SbkType<T>())->obj_copier(&obj)); + return reinterpret_cast<T*>(BaseType::copy(reinterpret_cast<SbkBaseType*>(SbkType<T>()), &obj)); } }; @@ -113,7 +113,7 @@ inline PyObject* createWrapper(const T* cppobj, bool hasOwnership = false, bool const char* typeName = 0; if (!isExactType) typeName = typeid(*const_cast<T*>(cppobj)).name(); - return Wrapper::newObject(reinterpret_cast<SbkObjectType*>(SbkType<T>()), + return Wrapper::newObject(reinterpret_cast<SbkBaseType*>(SbkType<T>()), const_cast<T*>(cppobj), hasOwnership, isExactType, typeName); } @@ -213,10 +213,8 @@ struct ValueTypeConverter { if (PyObject_TypeCheck(pyobj, SbkType<T>())) return true; - SbkObjectType* shiboType = reinterpret_cast<SbkObjectType*>(SbkType<T>()); - if (shiboType->ext_isconvertible) - return shiboType->ext_isconvertible(pyobj); - return false; + SbkBaseType* shiboType = reinterpret_cast<SbkBaseType*>(SbkType<T>()); + return BaseType::isExternalConvertible(shiboType, pyobj); } static inline PyObject* toPython(void* cppobj) { return toPython(*reinterpret_cast<T*>(cppobj)); } static inline PyObject* toPython(const T& cppobj) @@ -233,9 +231,9 @@ struct ValueTypeConverter static inline T toCpp(PyObject* pyobj) { if (!PyObject_TypeCheck(pyobj, SbkType<T>())) { - SbkObjectType* shiboType = reinterpret_cast<SbkObjectType*>(SbkType<T>()); - if (shiboType->ext_tocpp && isConvertible(pyobj)) { - T* cptr = reinterpret_cast<T*>(shiboType->ext_tocpp(pyobj)); + SbkBaseType* shiboType = reinterpret_cast<SbkBaseType*>(SbkType<T>()); + if (BaseType::hasExternalCppConversions(shiboType) && isConvertible(pyobj)) { + T* cptr = reinterpret_cast<T*>(BaseType::callExternalCppConversion(shiboType, pyobj)); std::auto_ptr<T> cptr_auto_ptr(cptr); return *cptr; } @@ -273,11 +271,9 @@ struct ObjectTypeConverter { if (pyobj == Py_None) return 0; - SbkObjectType* shiboType = reinterpret_cast<SbkObjectType*>(pyobj->ob_type); - if (shiboType->mi_specialcast) - return (T*) shiboType->mi_specialcast( - Wrapper::cppPointer(reinterpret_cast<SbkObject*>(pyobj), SbkType<T>()), - reinterpret_cast<SbkObjectType*>(SbkType<T>())); + SbkBaseType* shiboType = reinterpret_cast<SbkBaseType*>(pyobj->ob_type); + if (BaseType::hasCast(shiboType)) + return reinterpret_cast<T*>(BaseType::cast(shiboType, reinterpret_cast<SbkObject*>(pyobj), SbkType<T>())); return (T*) Wrapper::cppPointer(reinterpret_cast<SbkObject*>(pyobj), SbkType<T>()); } }; @@ -564,7 +560,7 @@ struct StdListConverter // binded types implementing sequence protocol, otherwise this will // cause a mess like QBitArray being accepted by someone expecting a // QStringList. - if ((SbkType<StdList>() && isShibokenType(pyObj)) || !PySequence_Check(pyObj)) + if ((SbkType<StdList>() && Wrapper::checkType(pyObj)) || !PySequence_Check(pyObj)) return false; for (int i = 0, max = PySequence_Length(pyObj); i < max; ++i) { AutoDecRef item(PySequence_GetItem(pyObj, i)); @@ -610,7 +606,7 @@ struct StdPairConverter { if (PyObject_TypeCheck(pyObj, SbkType<StdPair>())) return true; - if ((SbkType<StdPair>() && isShibokenType(pyObj)) || !PySequence_Check(pyObj) || PySequence_Length(pyObj) != 2) + if ((SbkType<StdPair>() && Wrapper::checkType(pyObj)) || !PySequence_Check(pyObj) || PySequence_Length(pyObj) != 2) return false; AutoDecRef item1(PySequence_GetItem(pyObj, 0)); @@ -655,7 +651,7 @@ struct StdMapConverter { if (PyObject_TypeCheck(pyObj, SbkType<StdMap>())) return true; - if ((SbkType<StdMap>() && isShibokenType(pyObj)) || !PyDict_Check(pyObj)) + if ((SbkType<StdMap>() && Wrapper::checkType(pyObj)) || !PyDict_Check(pyObj)) return false; PyObject* key; diff --git a/libshiboken/typeresolver.h b/libshiboken/typeresolver.h index bec990909..f959010fd 100644 --- a/libshiboken/typeresolver.h +++ b/libshiboken/typeresolver.h @@ -26,8 +26,6 @@ #include "shibokenmacros.h" #include "conversions.h" -class SbkObjectType; - namespace Shiboken { |