From 24e7f2a974548c78a96403574fed35ecfc139e01 Mon Sep 17 00:00:00 2001 From: Wim Lavrijsen <WLavrijsen@lbl.gov> Date: Tue, 5 Nov 2013 17:34:50 -0800 Subject: [PATCH] boat load of workaround for std::vector iterators; to be fixed by using collection proxy --- bindings/pyroot/src/Converters.cxx | 22 ++++++++++++++++++++ bindings/pyroot/src/Converters.h | 8 ++++++++ bindings/pyroot/src/Executors.cxx | 2 +- bindings/pyroot/src/RootWrapper.cxx | 9 ++++++++ bindings/pyroot/src/Utility.cxx | 32 ++++++----------------------- 5 files changed, 46 insertions(+), 27 deletions(-) diff --git a/bindings/pyroot/src/Converters.cxx b/bindings/pyroot/src/Converters.cxx index fb0ad27822d..f3bda825424 100644 --- a/bindings/pyroot/src/Converters.cxx +++ b/bindings/pyroot/src/Converters.cxx @@ -918,6 +918,23 @@ Bool_t PyROOT::TRootObjectPtrConverter::ToMemory( PyObject* value, void* address return kFALSE; } +//____________________________________________________________________________ +// CLING WORKAROUND -- classes for STL iterators are completely undefined in that +// they come in a bazillion different guises, so just do whatever +Bool_t PyROOT::TSTLIteratorConverter::SetArg( + PyObject* pyobject, TParameter_t& para, CallFunc_t* func, Long_t user ) +{ + if ( ! ObjectProxy_Check( pyobject ) ) + return kFALSE; + +// just set the pointer value, no check + ObjectProxy* pyobj = (ObjectProxy*)pyobject; + para.fVoidp = pyobj->GetObject(); + if ( func ) gInterpreter->CallFunc_SetArg( func, para.fLong ); + return kTRUE; +} +// -- END CLING WORKAROUND + //____________________________________________________________________________ Bool_t PyROOT::TVoidPtrRefConverter::SetArg( PyObject* pyobject, TParameter_t& para, CallFunc_t* func, Long_t ) @@ -1048,6 +1065,11 @@ PyROOT::TConverter* PyROOT::CreateConverter( const std::string& fullType, Long_t // converters for known/ROOT classes and default (void*) TConverter* result = 0; if ( TClass* klass = TClass::GetClass( realType.c_str() ) ) { + // CLING WORKAROUND -- special case for STL iterators + if ( realType.find( "__gnu_cxx::__normal_iterator", 0 ) == 0 ) + result = new TSTLIteratorConverter(); + else + // -- CLING WORKAROUND if ( cpd == "**" || cpd == "*&" || cpd == "&*" ) result = new TRootObjectPtrConverter( klass, control ); else if ( cpd == "*" ) diff --git a/bindings/pyroot/src/Converters.h b/bindings/pyroot/src/Converters.h index 6f3ab83c63e..42b0d467f20 100644 --- a/bindings/pyroot/src/Converters.h +++ b/bindings/pyroot/src/Converters.h @@ -203,6 +203,14 @@ namespace PyROOT { virtual Bool_t ToMemory( PyObject* value, void* address ); }; +// CLING WORKAROUND -- classes for STL iterators are completely undefined in that +// they come in a bazillion different guises, so just do whatever + class TSTLIteratorConverter : public TConverter { + public: + virtual Bool_t SetArg( PyObject*, TParameter_t&, CallFunc_t* = 0, Long_t = 0 ); + }; +// -- END CLING WORKAROUND + class TVoidPtrRefConverter : public TConverter { public: virtual Bool_t SetArg( PyObject*, TParameter_t&, CallFunc_t* = 0, Long_t = 0 ); diff --git a/bindings/pyroot/src/Executors.cxx b/bindings/pyroot/src/Executors.cxx index 4036324e809..d22838b40f3 100644 --- a/bindings/pyroot/src/Executors.cxx +++ b/bindings/pyroot/src/Executors.cxx @@ -419,7 +419,7 @@ PyROOT::TExecutor* PyROOT::CreateExecutor( const std::string& fullType ) return (h->second)(); // resolve typedefs etc., and collect qualifiers - std::string resolvedType = TClassEdit::ResolveTypedef( fullType.c_str(), true ); + std::string resolvedType = Utility::ResolveTypedef( fullType ); // a full, qualified matching executor is preferred h = gExecFactories.find( resolvedType ); diff --git a/bindings/pyroot/src/RootWrapper.cxx b/bindings/pyroot/src/RootWrapper.cxx index 14282e33a61..958e417dcf6 100644 --- a/bindings/pyroot/src/RootWrapper.cxx +++ b/bindings/pyroot/src/RootWrapper.cxx @@ -38,6 +38,10 @@ #include <algorithm> #include <vector> +//- FOR CLING WORKAROUND +#include "TError.h" +// + //- data _______________________________________________________________________ R__EXTERN PyObject* gRootModule; @@ -763,7 +767,12 @@ PyObject* PyROOT::BindRootObject( void* address, TClass* klass, Bool_t isRef ) } // get actual class for recycling checking and/or downcasting +// CLING WORKAROUND -- silence: +// Error in <TStreamerInfo::Build>: __gnu_cxx::__normal_iterator<int*,vector<int> >, discarding: int* _M_current, no [dimension] + Int_t oldval = gErrorIgnoreLevel; + gErrorIgnoreLevel = 5000; TClass* clActual = isRef ? 0 : klass->GetActualClass( address ); + gErrorIgnoreLevel = oldval; // obtain pointer to TObject base class (if possible) for memory mgmt; this is // done before downcasting, as upcasting from the current class may be easier and diff --git a/bindings/pyroot/src/Utility.cxx b/bindings/pyroot/src/Utility.cxx index b217c1434ff..0a6a13cb5d8 100644 --- a/bindings/pyroot/src/Utility.cxx +++ b/bindings/pyroot/src/Utility.cxx @@ -22,6 +22,7 @@ #include "TCollection.h" #include "TDataType.h" #include "TFunction.h" +#include "TMethod.h" #include "TMethodArg.h" #include "TError.h" #include "TInterpreter.h" @@ -351,39 +352,18 @@ Bool_t PyROOT::Utility::AddBinaryOperator( PyObject* pyclass, const char* op, co //____________________________________________________________________________ static inline TFunction* FindAndAddOperator( const std::string& lcname, const std::string& rcname, - const char* op, TCollection* funcs = 0 ) { + const char* op, TClass* klass = 0 ) { // Helper to find a function with matching signature in 'funcs'. std::string opname = "operator"; opname += op; + std::string proto = lcname + ", " + rcname; // case of global namespace - if ( ! funcs ) { - std::string proto = lcname + ", " + rcname; + if ( ! klass ) return gROOT->GetGlobalFunctionWithPrototype( opname.c_str(), proto.c_str() ); - } // case of specific namespace - TIter ifunc( funcs ); - - TFunction* func = 0; - while ( (func = (TFunction*)ifunc.Next()) ) { - if ( func->GetListOfMethodArgs()->GetSize() != 2 ) - continue; - - if ( func->GetName() == opname ) { - if ( ( lcname == ResolveTypedef( TClassEdit::CleanType( - ((TMethodArg*)func->GetListOfMethodArgs()->At(0))->GetTypeNormalizedName().c_str(), 1 ).c_str() ) ) && - ( rcname == ResolveTypedef( TClassEdit::CleanType( - ((TMethodArg*)func->GetListOfMethodArgs()->At(1))->GetTypeNormalizedName().c_str(), 1 ).c_str() ) ) ) { - - // done; break out loop - return func; - } - - } - } - - return 0; + return klass->GetMethodWithPrototype( opname.c_str(), proto.c_str() ); } Bool_t PyROOT::Utility::AddBinaryOperator( PyObject* pyclass, const std::string& lcname, @@ -396,7 +376,7 @@ Bool_t PyROOT::Utility::AddBinaryOperator( PyObject* pyclass, const std::string& PyCallable* pyfunc = 0; if ( gnucxx.GetClass() ) { - TFunction* func = FindAndAddOperator( lcname, rcname, op, gnucxx->GetListOfMethods() ); + TFunction* func = FindAndAddOperator( lcname, rcname, op, gnucxx.GetClass() ); if ( func ) pyfunc = new TFunctionHolder( TScopeAdapter::ByName( "__gnu_cxx" ), func ); } -- GitLab