1 #ifndef AWFUL_PYTHON_METHOD_H
2 #define AWFUL_PYTHON_METHOD_H
4 namespace awful
{ namespace PythonImpl
6 template< class C
, typename obj_category
, typename PointerT
> struct CallContext
8 CallContext( PyObject
* pPyObj_
, PyObject
* pArgs_
) :
20 // Fucking macros and their hidden synctactic nature. Is it a bunch of statements? A sub-scope?
21 // Some random fragment of code only valid in a very specific context? Apparently here it is just
22 // a naked group of statements so I need to add braces that serve no apparent purpose but
23 // do change the meaning of the code.
25 // If only the C standard provided a way to define functions that are expanded at their call site
26 // that could be used instead of those shitty macros...
27 // Wait, who am I kidding? Python's developers discovered "const" in 2007.
28 Py_DECREF( m_pResult
);
34 return PyTuple_GET_SIZE( m_pArgs
);
37 void numExpectedParams( int Num_
) const
39 // Check if we have the proper number of parameters
40 int numargs
= numParams();
42 throw Error::NotEnoughParams( numargs
, Num_
);
48 typedef TypeConverter
< obj_category
, PointerT
> tc
;
49 tc::ConvertFromPython( m_pPyObj
, Ptr
);
53 template< typename category
, typename T
> bool getParam( const char* pName_
, T
& Dest_
)
55 typedef TypeConverter
< category
, T
> tc
;
56 PyObject
* pParam
= PyTuple_GET_ITEM( m_pArgs
, m_paramindex
);
58 if( !tc::CheckType_nothrow( pParam
) )
64 tc::ConvertFromPython_nocheck( pParam
, Dest_
);
69 template< typename category
, typename T
> void setReturnValue( const T
& Value_
)
71 typedef TypeConverter
< category
, T
> tc
;
72 m_pResult
= tc::ConvertToPython( Value_
);
75 // Cheapo ownership transfer
76 // This way the call context destructor knows that it should do a decref
77 // on the result object if it happens to be non-null.
80 PyObject
* pRes
= m_pResult
;
93 template< class C
, class CC
> struct CtorWrapper
95 static PyObject
* PyFunc( PyTypeObject
* pSubType
, PyObject
* pArgs_
, PyObject
* )
97 PyObject
* pPyObj
= pSubType
->tp_alloc( pSubType
, 0 ); // Retarded C-style fake method call
101 CC
context( pPyObj
, pArgs_
);
102 if( !method_traits
< C
, typename class_traits
< C
>::ctor_tag
>::
103 template CallWrapper
< CC
>::Call( context
) )
104 throw Error::NoOverloadFound();
108 catch( const Error::Base
& error
)
110 error
.ConvertToPython();
117 template< class C
, typename MtdTag
, class CC
> struct MethodWrapper
119 static PyObject
* PyFunc( PyObject
* pPyObj_
, PyObject
* pArgs_
)
123 CC
context( pPyObj_
, pArgs_
);
124 if( !method_traits
< C
, MtdTag
>::template CallWrapper
< CC
>::Call( context
) )
125 throw Error::NoOverloadFound();
127 PyObject
* pRes
= context
.getResult();
133 catch( const Error::Base
& error
)
135 error
.ConvertToPython();