TemplateProxy.cxx

Go to the documentation of this file.
00001 // Author: Wim Lavrijsen, Jan 2005
00002 
00003 // Bindings
00004 #include "PyROOT.h"
00005 #include "TemplateProxy.h"
00006 #include "Utility.h"
00007 
00008 
00009 namespace PyROOT {
00010 
00011 namespace {
00012 
00013 //= PyROOT template proxy construction/destruction ===========================
00014    TemplateProxy* tpp_new( PyTypeObject*, PyObject*, PyObject* )
00015    {
00016       TemplateProxy* pytmpl = PyObject_GC_New( TemplateProxy, &TemplateProxy_Type );
00017       pytmpl->fPyName  = NULL;
00018       pytmpl->fPyClass = NULL;
00019       pytmpl->fSelf    = NULL;
00020 
00021       PyObject_GC_Track( pytmpl );
00022       return pytmpl;
00023    }
00024 
00025 //____________________________________________________________________________
00026    void tpp_dealloc( TemplateProxy* pytmpl )
00027    {
00028       PyObject_GC_UnTrack( pytmpl );
00029       PyObject_GC_Del( pytmpl );
00030    }
00031 
00032 //____________________________________________________________________________
00033    int tpp_traverse( TemplateProxy* pytmpl, visitproc visit, void* args )
00034    {
00035       if ( pytmpl->fPyName ) {
00036          int err = visit( (PyObject*)pytmpl->fPyName, args );
00037          if ( err )
00038             return err;
00039       }
00040 
00041       if ( pytmpl->fPyClass ) {
00042          int err = visit( (PyObject*)pytmpl->fPyClass, args );
00043          if ( err )
00044             return err;
00045       }
00046 
00047       if ( pytmpl->fSelf ) {
00048          int err = visit( (PyObject*)pytmpl->fSelf, args );
00049          if ( err )
00050             return err;
00051       }
00052 
00053       return 0;
00054    }
00055 
00056 //____________________________________________________________________________
00057    int tpp_clear( TemplateProxy* pytmpl )
00058    {
00059       Py_XDECREF( (PyObject*)pytmpl->fPyName );
00060       pytmpl->fPyName = NULL;
00061 
00062       Py_XDECREF( (PyObject*)pytmpl->fPyClass );
00063       pytmpl->fPyClass = NULL;
00064 
00065       Py_XDECREF( (PyObject*)pytmpl->fSelf );
00066       pytmpl->fSelf = NULL;
00067 
00068       return 0;
00069    }
00070 
00071 //= PyROOT template proxy callable behavior ==================================
00072    PyObject* tpp_call( TemplateProxy* pytmpl, PyObject* args, PyObject* kwds )
00073    {
00074    // dispatcher to the actual member method, args is self object + template arguments
00075    // (as in a function call); build full instantiation
00076       PyObject* pymeth = 0;
00077 
00078       Py_ssize_t nArgs = PyTuple_GET_SIZE( args );
00079       if ( 1 <= nArgs ) {
00080 
00081       // build "< type, type, ... >" part of method name
00082          Py_INCREF( pytmpl->fPyName );
00083          PyObject* pyname = pytmpl->fPyName;
00084          if ( Utility::BuildTemplateName( pyname, args, 0 ) ) {
00085          // lookup method on self (to make sure it propagates), which is readily callable
00086             pymeth = PyObject_GetAttr( pytmpl->fSelf, pyname );
00087          }
00088          Py_XDECREF( pyname );
00089 
00090       }
00091 
00092       if ( pymeth )
00093          return pymeth;       // templated, now called by the user
00094 
00095    // if the method lookup fails, try to locate the "generic" version of the template
00096       PyErr_Clear();
00097       pymeth = PyObject_GetAttrString( pytmpl->fSelf, const_cast< char* >(
00098          (std::string( "__generic_" ) + PyROOT_PyUnicode_AsString( pytmpl->fPyName )).c_str()) );
00099 
00100       if ( pymeth )
00101          return PyObject_Call( pymeth, args, kwds );   // non-templated, executed as-is
00102       
00103       return pymeth;
00104    }
00105 
00106 //____________________________________________________________________________
00107    TemplateProxy* tpp_descrget( TemplateProxy* pytmpl, PyObject* pyobj, PyObject* )
00108    {
00109    // create and use a new template proxy (language requirement)
00110       TemplateProxy* newPyTmpl = (TemplateProxy*)TemplateProxy_Type.tp_alloc( &TemplateProxy_Type, 0 );
00111 
00112    // copy name and class
00113       Py_INCREF( pytmpl->fPyName );
00114       newPyTmpl->fPyName = pytmpl->fPyName;
00115 
00116       Py_XINCREF( pytmpl->fPyClass );
00117       newPyTmpl->fPyClass = pytmpl->fPyClass;
00118 
00119    // new method is to be bound to current object (may be NULL)
00120       Py_XINCREF( pyobj );
00121       newPyTmpl->fSelf = pyobj;
00122 
00123       return newPyTmpl;
00124    }
00125 
00126 } // unnamed namespace
00127 
00128 
00129 //= PyROOT template proxy type ===============================================
00130 PyTypeObject TemplateProxy_Type = {
00131    PyVarObject_HEAD_INIT( &PyType_Type, 0 )
00132    (char*)"ROOT.TemplateProxy", // tp_name
00133    sizeof(TemplateProxy),     // tp_basicsize
00134    0,                         // tp_itemsize
00135    (destructor)tpp_dealloc,   // tp_dealloc
00136    0,                         // tp_print
00137    0,                         // tp_getattr
00138    0,                         // tp_setattr
00139    0,                         // tp_compare
00140    0,                         // tp_repr
00141    0,                         // tp_as_number
00142    0,                         // tp_as_sequence
00143    0,                         // tp_as_mapping
00144    0,                         // tp_hash
00145    (ternaryfunc)tpp_call,     // tp_call
00146    0,                         // tp_str
00147    0,                         // tp_getattro
00148    0,                         // tp_setattro
00149    0,                         // tp_as_buffer
00150    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,      // tp_flags
00151    (char*)"PyROOT template proxy (internal)",    // tp_doc
00152    (traverseproc)tpp_traverse,// tp_traverse
00153    (inquiry)tpp_clear,        // tp_clear
00154    0,                         // tp_richcompare
00155    0,                         // tp_weaklistoffset
00156    0,                         // tp_iter
00157    0,                         // tp_iternext
00158    0,                         // tp_methods
00159    0,                         // tp_members
00160    0,                         // tp_getset
00161    0,                         // tp_base
00162    0,                         // tp_dict
00163    (descrgetfunc)tpp_descrget,// tp_descr_get
00164    0,                         // tp_descr_set
00165    0,                         // tp_dictoffset
00166    0,                         // tp_init
00167    0,                         // tp_alloc
00168    (newfunc)tpp_new,          // tp_new
00169    0,                         // tp_free
00170    0,                         // tp_is_gc
00171    0,                         // tp_bases
00172    0,                         // tp_mro
00173    0,                         // tp_cache
00174    0,                         // tp_subclasses
00175    0                          // tp_weaklist
00176 #if PY_VERSION_HEX >= 0x02030000
00177    , 0                        // tp_del
00178 #endif
00179 #if PY_VERSION_HEX >= 0x02060000
00180    , 0                        // tp_version_tag
00181 #endif
00182 };
00183 
00184 } // namespace PyROOT

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