TSetItemHolder.cxx

Go to the documentation of this file.
00001 // Author: Wim Lavrijsen, Oct 2005
00002 
00003 // Bindings
00004 #include "PyROOT.h"
00005 #include "TSetItemHolder.h"
00006 #include "Executors.h"
00007 #include "Adapters.h"
00008 
00009 
00010 //- protected members --------------------------------------------------------
00011 template< class T, class M >
00012 Bool_t PyROOT::TSetItemHolder< T, M >::InitExecutor_( TExecutor*& executor )
00013 {
00014 // basic call will do
00015    if ( ! TMethodHolder< T, M >::InitExecutor_( executor ) )
00016       return kFALSE;
00017 
00018 // check to make sure we're dealing with a RefExecutor
00019    if ( ! dynamic_cast< TRefExecutor* >( executor ) ) {
00020       PyErr_Format( PyExc_NotImplementedError,
00021          "no __setitem__ handler for return type (%s)",
00022          this->GetMethod().TypeOf().ReturnType().Name( ROOT::Reflex::Q | ROOT::Reflex::S ).c_str() );
00023       return kFALSE;
00024    }
00025 
00026    return kTRUE;
00027 }
00028 
00029 
00030 //- constructor --------------------------------------------------------------
00031 template< class T, class M >
00032 PyROOT::TSetItemHolder< T, M >::TSetItemHolder( const T& klass, const M& method ) :
00033       TMethodHolder< T, M >( klass, method )
00034 {
00035 }
00036 
00037 
00038 //____________________________________________________________________________
00039 template< class T, class M >
00040 PyObject* PyROOT::TSetItemHolder< T, M >::FilterArgs(
00041       ObjectProxy*& self, PyObject* args, PyObject* kwds )
00042 {
00043 // Prepare executor with a buffer for the return value.
00044 
00045    int nArgs = PyTuple_GET_SIZE( args );
00046    if ( nArgs <= 1 ) {
00047       PyErr_SetString( PyExc_TypeError, "insufficient arguments to __setitem__" );
00048       return 0;
00049    }
00050 
00051 // strip the last element of args to be used on return
00052    ((TRefExecutor*)this->GetExecutor())->SetAssignable( PyTuple_GET_ITEM( args, nArgs - 1 ) );
00053    PyObject* subset = PyTuple_GetSlice( args, 0, nArgs - 1 );
00054 
00055 // see whether any of the arguments is a tuple itself
00056    Py_ssize_t realsize = 0;
00057    for ( int i = 0; i < nArgs - 1; ++i ) {
00058       PyObject* item = PyTuple_GetItem( subset, i );
00059       realsize += PyTuple_Check( item ) ? PyTuple_GET_SIZE( item ) : 1;
00060    }
00061 
00062 // unroll any tuples, if present in the arguments
00063    PyObject* unrolled = 0;
00064    if ( realsize != nArgs - 1 ) {
00065       unrolled = PyTuple_New( realsize );
00066 
00067       int current = 0;
00068       for ( int i = 0; i < nArgs - 1; ++i, ++current ) {
00069          PyObject* item = PyTuple_GetItem( subset, i );
00070          if ( PyTuple_Check( item ) ) {
00071             for ( int j = 0; j < PyTuple_GET_SIZE( item ); ++j, ++current ) {
00072                PyObject* subitem = PyTuple_GetItem( item, j );
00073                Py_INCREF( subitem );
00074                PyTuple_SetItem( unrolled, current, subitem );
00075             }
00076          } else {
00077             Py_INCREF( item );
00078             PyTuple_SetItem( unrolled, current, item );
00079          }
00080       }
00081    }
00082 
00083 // actual call into C++
00084    PyObject* result = TMethodHolder< T, M >::FilterArgs( self, unrolled ? unrolled : subset, kwds );
00085    Py_XDECREF( unrolled );
00086    Py_DECREF( subset );
00087    return result;
00088 }
00089 
00090 //____________________________________________________________________________
00091 template class PyROOT::TSetItemHolder< PyROOT::TScopeAdapter, PyROOT::TMemberAdapter >;
00092 #ifdef PYROOT_USE_REFLEX
00093 template class PyROOT::TSetItemHolder< ROOT::Reflex::Scope, ROOT::Reflex::Member >;
00094 #endif

Generated on Tue Jul 5 14:10:16 2011 for ROOT_528-00b_version by  doxygen 1.5.1