// @(#)root/pyroot:$Id$ // Author: Wim Lavrijsen, Jan 2005 #ifndef PYROOT_METHODPROXY_H #define PYROOT_METHODPROXY_H // ROOT #include "DllImport.h" // Bindings #include "PyCallable.h" // Standard #include #include #include namespace PyROOT { /** Method proxy object to hold ROOT methods @author WLAV @date 01/07/2005 @version 1.0 */ class MethodProxy { public: typedef std::map< Long_t, Int_t > DispatchMap_t; typedef std::vector< PyCallable* > Methods_t; struct MethodInfo_t { MethodInfo_t() : fFlags( kNone ) { fRefCount = new int(1); } ~MethodInfo_t(); enum EMethodInfoFlags { kNone = 0, kIsSorted = 1, // if method overload priority determined kIsCreator = 2, // if method creates python-owned objects kIsConstructor = 4, // if method is a C++ constructor kIsHeuristics = 8, // if method requires heuristics memory policy kIsStrict = 16, // if method requires strict memory policy kReleaseGIL = 32 // if method should release the GIL }; std::string fName; MethodProxy::DispatchMap_t fDispatchMap; MethodProxy::Methods_t fMethods; UInt_t fFlags; int* fRefCount; private: MethodInfo_t( const MethodInfo_t& ); MethodInfo_t& operator=( const MethodInfo_t& ); }; public: void Set( const std::string& name, std::vector< PyCallable* >& methods ); const std::string& GetName() const { return fMethodInfo->fName; } void AddMethod( PyCallable* pc ); void AddMethod( MethodProxy* meth ); public: // public, as the python C-API works with C structs PyObject_HEAD ObjectProxy* fSelf; // The instance it is bound to, or NULL MethodInfo_t* fMethodInfo; private: // private, as the python C-API will handle creation MethodProxy() {} }; //- method proxy type and type verification ---------------------------------- R__EXTERN PyTypeObject MethodProxy_Type; template< typename T > inline Bool_t MethodProxy_Check( T* object ) { return object && PyObject_TypeCheck( object, &MethodProxy_Type ); } template< typename T > inline Bool_t MethodProxy_CheckExact( T* object ) { return object && Py_TYPE(object) == &MethodProxy_Type; } //- creation ----------------------------------------------------------------- inline MethodProxy* MethodProxy_New( const std::string& name, std::vector< PyCallable* >& methods ) { // Create and initialize a new method proxy from the overloads. MethodProxy* pymeth = (MethodProxy*)MethodProxy_Type.tp_new( &MethodProxy_Type, 0, 0 ); pymeth->Set( name, methods ); return pymeth; } inline MethodProxy* MethodProxy_New( const std::string& name, PyCallable* method ) { // Create and initialize a new method proxy from the method. std::vector< PyCallable* > p; p.push_back( method ); return MethodProxy_New( name, p ); } } // namespace PyROOT #endif // !PYROOT_METHODPROXY_H