From f06ca60651e70768a1e29b48cbfbdfe88ee7b9d6 Mon Sep 17 00:00:00 2001 From: Wim Lavrijsen <WLavrijsen@lbl.gov> Date: Wed, 4 May 2011 22:55:51 +0000 Subject: [PATCH] enable the use of std::exception deriveds in python git-svn-id: http://root.cern.ch/svn/root/trunk@39104 27541ba8-7e3a-0410-8455-c3a389f83636 --- bindings/pyroot/ROOT.py | 13 ++++++-- bindings/pyroot/src/RootWrapper.cxx | 48 +++++++++++++++++++++-------- 2 files changed, 45 insertions(+), 16 deletions(-) diff --git a/bindings/pyroot/ROOT.py b/bindings/pyroot/ROOT.py index ada08dfbc80..e05edf8a11e 100755 --- a/bindings/pyroot/ROOT.py +++ b/bindings/pyroot/ROOT.py @@ -192,13 +192,20 @@ _root.Template = Template ### scope place holder for STL classes ------------------------------------------ -class std: - stlclasses = ( 'complex', 'exception', 'pair', \ +class _stdmeta( type ): + def __getattr__( cls, attr ): # for non-templated classes in std + klass = _root.MakeRootClass( attr, cls ) + setattr( cls, attr, klass ) + return klass + +class std( object ): + __metaclass__ = _stdmeta + + stlclasses = ( 'complex', 'pair', \ 'deque', 'list', 'queue', 'stack', 'vector', 'map', 'multimap', 'set', 'multiset' ) for name in stlclasses: locals()[ name ] = Template( "std::%s" % name ) -# exec '%(name)s = Template( "std::%(name)s" )' % { 'name' : name } string = _root.MakeRootClass( 'string' ) diff --git a/bindings/pyroot/src/RootWrapper.cxx b/bindings/pyroot/src/RootWrapper.cxx index 0e1c730f026..6a7cc44334c 100644 --- a/bindings/pyroot/src/RootWrapper.cxx +++ b/bindings/pyroot/src/RootWrapper.cxx @@ -125,19 +125,27 @@ namespace { PyROOT::BindRootObject( obj, klass ) ); } - std::set< std::string > gSTLTypes, gLoadedSTLTypes; + std::set< std::string > gSTLTypes, gSTLExceptions; struct InitSTLTypes_t { InitSTLTypes_t() { + std::string nss = "std::"; + const char* stlTypes[] = { "complex", "exception", "deque", "list", "queue", "stack", "vector", "map", "multimap", "set", "multiset" }; - std::string nss = "std::"; for ( int i = 0; i < int(sizeof(stlTypes)/sizeof(stlTypes[0])); ++i ) { gSTLTypes.insert( stlTypes[ i ] ); gSTLTypes.insert( nss + stlTypes[ i ] ); } - gLoadedSTLTypes.insert( "vector" ); + + const char* stlExceptions[] = { "logic_error", "domain_error", + "invalid_argument", "length_error", "out_of_range", "runtime_error", + "range_error", "overflow_error", "underflow_error" }; + for ( int i = 0; i < int(sizeof(stlExceptions)/sizeof(stlExceptions[0])); ++i ) { + gSTLExceptions.insert( stlExceptions[ i ] ); + gSTLExceptions.insert( nss + stlExceptions[ i ] ); + } } } initSTLTypes_; @@ -151,22 +159,36 @@ namespace { if ( klass != 0 ) TClass::RemoveClass( (TClass*)klass ); - // make sure to only load once - if ( gLoadedSTLTypes.find( sub ) == gLoadedSTLTypes.end() ) { + // strip std:: part as needed to form proper file name + if ( sub.substr( 0, 5 ) == "std::" ) + sub = sub.substr( 5, std::string::npos ); - // strip std:: part as needed to form proper file name - if ( sub.substr( 0, 5 ) == "std::" ) - sub = sub.substr( 5, std::string::npos ); + // tell CINT to go for it + gROOT->ProcessLine( (std::string( "#include <" ) + sub + ">").c_str() ); - // tell CINT to go for it - gROOT->ProcessLine( (std::string( "#include <" ) + sub + ">").c_str() ); + // prevent second attempt to load by erasing name + gSTLTypes.erase( gSTLTypes.find( sub ) ); + gSTLTypes.erase( gSTLTypes.find( "std::" + sub ) ); - // prevent second attempt to load by erasing name - gLoadedSTLTypes.insert( sub ); - gLoadedSTLTypes.insert( "std::" + sub ); + return kTRUE; + } else if ( gSTLExceptions.find( sub ) != gSTLExceptions.end() ) { + // removal is required or the dictionary can't be updated properly + if ( klass != 0 ) + TClass::RemoveClass( (TClass*)klass ); + + // load base class std::exception if not yet done so, and refresh + if ( gSTLTypes.find( "exception" ) != gSTLTypes.end() ) { + gROOT->ProcessLine( "#include <exception>" ); + TClass::RemoveClass( TClass::GetClass( "std::exception" ) ); + gSTLTypes.erase( gSTLTypes.find( "exception" ) ); + gSTLTypes.erase( gSTLTypes.find( "std::exception" ) ); } + // load stdexcept, which contains all std exceptions + gROOT->ProcessLine( "#include <stdexcept>" ); + gSTLExceptions.clear(); // completely done with std exceptions + return kTRUE; } -- GitLab