Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
CPPGetSetItem.cxx
Go to the documentation of this file.
1// Bindings
2#include "CPyCppyy.h"
3#include "CPPGetSetItem.h"
4#include "Executors.h"
5
6
7//- private helpers -----------------------------------------------------------
8static inline
9void unroll(CPyCppyy_PyArgs_t packed_args, CPyCppyy_PyArgs_t unrolled, Py_ssize_t nArgs)
10{
11// Unroll up to nArgs arguments from packed_args into unrolled.
12 for (int i = 0, iur = 0; i < nArgs; ++i, ++iur) {
13 PyObject* item = CPyCppyy_PyArgs_GET_ITEM(packed_args, i);
14 if (PyTuple_Check(item)) {
15 for (int j = 0; j < PyTuple_GET_SIZE(item); ++j, ++iur) {
16 PyObject* subitem = PyTuple_GET_ITEM(item, j);
17 Py_INCREF(subitem);
18 CPyCppyy_PyArgs_SET_ITEM(unrolled, iur, subitem);
19 }
20 } else {
21 Py_INCREF(item);
22 CPyCppyy_PyArgs_SET_ITEM(unrolled, iur, item);
23 }
24 }
25}
26
27//- protected members ---------------------------------------------------------
29{
30// basic call will do
31 if (!CPPMethod::InitExecutor_(executor))
32 return false;
33
34// check to make sure we're dealing with a RefExecutor
35 if (!dynamic_cast<RefExecutor*>(executor)) {
36 PyErr_Format(PyExc_NotImplementedError,
37 "no __setitem__ handler for return type (%s)",
38 this->GetReturnTypeName().c_str());
39 return false;
40 }
41
42 return true;
43}
44
45//-----------------------------------------------------------------------------
47{
48// Prepare executor with a buffer for the return value.
50 if (nArgs <= 1) {
51 PyErr_SetString(PyExc_TypeError, "insufficient arguments to __setitem__");
52 return false;
53 }
54
55// use the last element of args for assignment upon return, then slice it from
56// the (unrolled) actual arguments
57 ((RefExecutor*)this->GetExecutor())->SetAssignable(CPyCppyy_PyArgs_GET_ITEM(cargs.fArgs, nArgs-1));
58
59// see whether any of the arguments is a tuple to be unrolled
60 Py_ssize_t realsize = 0;
61 for (Py_ssize_t i = 0; i < nArgs-1; ++i) {
62 PyObject* item = CPyCppyy_PyArgs_GET_ITEM(cargs.fArgs, i);
63 realsize += PyTuple_Check(item) ? PyTuple_GET_SIZE(item) : 1;
64 }
65
66// unroll any tuples, if present in the arguments
67#if PY_VERSION_HEX >= 0x03080000
68 if (realsize != nArgs-1) {
69 CPyCppyy_PyArgs_t unrolled = (PyObject**)PyMem_Malloc(realsize * sizeof(PyObject*));
70 unroll(cargs.fArgs, unrolled, nArgs-1);
71 cargs.fArgs = unrolled;
72 cargs.fFlags |= PyCallArgs::kDoFree;
73 }
74#else
75 if (realsize != nArgs-1) {
76 CPyCppyy_PyArgs_t unrolled = PyTuple_New(realsize);
77 unroll(cargs.fArgs, unrolled, nArgs-1);
78 cargs.fArgs = unrolled;
79 } else
80 cargs.fArgs = PyTuple_GetSlice(cargs.fArgs, 0, nArgs-1);
82#endif
83 cargs.fNArgsf = realsize;
84
85// continue normal method processing
86 return CPPMethod::ProcessArgs(cargs);
87}
88
89
90//-----------------------------------------------------------------------------
92{
93// Unroll tuples for call, otherwise just like regular CPPMethod of __getitem__.
95
96// see whether any of the arguments is a tuple to be unrolled
97 Py_ssize_t realsize = 0;
98 for (Py_ssize_t i = 0; i < nArgs; ++i) {
99 PyObject* item = CPyCppyy_PyArgs_GET_ITEM(cargs.fArgs, i);
100 realsize += PyTuple_Check(item) ? PyTuple_GET_SIZE(item) : 1;
101 }
102
103// unroll any tuples, if present in the arguments
104 if (realsize != nArgs) {
105 CPyCppyy_PyArgs_t packed_args = cargs.fArgs;
106#if PY_VERSION_HEX >= 0x03080000
107 cargs.fArgs = (PyObject**)PyMem_Malloc(realsize * sizeof(PyObject*));
108 cargs.fFlags |= PyCallArgs::kDoFree;
109#else
110 cargs.fArgs = PyTuple_New(realsize);
112#endif
113 cargs.fNArgsf = realsize;
114 unroll(packed_args, cargs.fArgs, nArgs);
115 }
116
117// continue normal method processing
118 return CPPMethod::ProcessArgs(cargs);
119}
static void unroll(CPyCppyy_PyArgs_t packed_args, CPyCppyy_PyArgs_t unrolled, Py_ssize_t nArgs)
int Py_ssize_t
Definition CPyCppyy.h:215
static PyObject * CPyCppyy_PyArgs_SET_ITEM(CPyCppyy_PyArgs_t args, Py_ssize_t i, PyObject *item)
Definition CPyCppyy.h:334
static Py_ssize_t CPyCppyy_PyArgs_GET_SIZE(CPyCppyy_PyArgs_t args, size_t)
Definition CPyCppyy.h:337
PyObject * CPyCppyy_PyArgs_t
Definition CPyCppyy.h:330
static PyObject * CPyCppyy_PyArgs_GET_ITEM(CPyCppyy_PyArgs_t args, Py_ssize_t i)
Definition CPyCppyy.h:331
_object PyObject
virtual bool ProcessArgs(PyCallArgs &args)
std::string GetReturnTypeName()
virtual bool ProcessArgs(PyCallArgs &args)
virtual bool InitExecutor_(Executor *&, CallContext *ctxt=nullptr)
virtual bool InitExecutor_(Executor *&, CallContext *ctxt=nullptr)
virtual bool ProcessArgs(PyCallArgs &args)
CPyCppyy_PyArgs_t fArgs
Definition CPPMethod.h:39