Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
Executors.cxx
Go to the documentation of this file.
1// Bindings
2#include "CPyCppyy.h"
3#include "DeclareExecutors.h"
4#include "CPPInstance.h"
5#include "LowLevelViews.h"
6#include "ProxyWrappers.h"
7#include "PyStrings.h"
8#include "TypeManip.h"
9#include "Utility.h"
10
11// Standard
12#include <cstring>
13#include <map>
14#include <new>
15#include <sstream>
16#include <utility>
17#include <sys/types.h>
18#include <complex>
19
20
21//- data _____________________________________________________________________
22namespace CPyCppyy {
23 typedef std::map<std::string, ef_t> ExecFactories_t;
25
27
28 extern std::set<std::string> gIteratorTypes;
29}
30
31
32//- helpers ------------------------------------------------------------------
33namespace {
34
35#ifdef WITH_THREAD
36 class GILControl {
37 public:
38 GILControl() : fSave(PyEval_SaveThread()) { }
39 ~GILControl() {
41 }
42 private:
43 PyThreadState* fSave;
44 };
45#endif
46
47} // unnamed namespace
48
49#ifdef WITH_THREAD
50#define CPPYY_IMPL_GILCALL(rtype, tcode) \
51static inline rtype GILCall##tcode( \
52 Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, CPyCppyy::CallContext* ctxt)\
53{ \
54 if (!ReleasesGIL(ctxt)) \
55 return Cppyy::Call##tcode(method, self, ctxt->GetEncodedSize(), ctxt->GetArgs());\
56 GILControl gc{}; \
57 return Cppyy::Call##tcode(method, self, ctxt->GetEncodedSize(), ctxt->GetArgs());\
58}
59#else
60#define CPPYY_IMPL_GILCALL(rtype, tcode) \
61static inline rtype GILCall##tcode( \
62 Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, CPyCppyy::CallContext* ctxt)\
63{ \
64 return Cppyy::Call##tcode(method, self, ctxt->GetEncodedSize(), ctxt->GetArgs());\
65}
66#endif
67
69CPPYY_IMPL_GILCALL(unsigned char, B)
79
80static inline Cppyy::TCppObject_t GILCallO(Cppyy::TCppMethod_t method,
81 Cppyy::TCppObject_t self, CPyCppyy::CallContext* ctxt, Cppyy::TCppType_t klass)
82{
83#ifdef WITH_THREAD
84 if (!ReleasesGIL(ctxt))
85#endif
86 return Cppyy::CallO(method, self, ctxt->GetEncodedSize(), ctxt->GetArgs(), klass);
87#ifdef WITH_THREAD
88 GILControl gc{};
89 return Cppyy::CallO(method, self, ctxt->GetEncodedSize(), ctxt->GetArgs(), klass);
90#endif
91}
92
95{
96#ifdef WITH_THREAD
97 if (!ReleasesGIL(ctxt))
98#endif
99 return Cppyy::CallConstructor(method, klass, ctxt->GetEncodedSize(), ctxt->GetArgs());
100#ifdef WITH_THREAD
101 GILControl gc{};
102 return Cppyy::CallConstructor(method, klass, ctxt->GetEncodedSize(), ctxt->GetArgs());
103#endif
104}
105
106static inline PyObject* CPyCppyy_PyText_FromLong(long cl)
107{
108// python chars are range(256)
109 if (cl < -256 || cl > 255) {
110 PyErr_SetString(PyExc_ValueError, "char conversion out of range");
111 return nullptr;
112 }
113 int c = (int)cl;
114 if (c < 0) return CPyCppyy_PyText_FromFormat("%c", 256 - std::abs(c));
115 return CPyCppyy_PyText_FromFormat("%c", c);
116}
117
118static inline PyObject* CPyCppyy_PyText_FromULong(unsigned long uc)
119{
120// TODO: range check here?
121 if (255 < uc) {
122 PyErr_SetString(PyExc_ValueError, "char conversion out of range");
123 return nullptr;
124 }
125 int c = (int)uc;
126 return CPyCppyy_PyText_FromFormat("%c", c);
127}
128
130{
133 return result;
134}
135
136
137//- base executor implementation ---------------------------------------------
139{
140 /* empty */
141}
142
143//- executors for built-ins --------------------------------------------------
144PyObject* CPyCppyy::BoolExecutor::Execute(
146{
147// execute <method> with argument <self, ctxt>, construct python bool return value
148 bool retval = GILCallB(method, self, ctxt);
151 return result;
152}
153
154//----------------------------------------------------------------------------
155PyObject* CPyCppyy::BoolConstRefExecutor::Execute(
157{
158// execute <method> with argument <self, ctxt>, construct python bool return value
159 return CPyCppyy_PyBool_FromLong(*((bool*)GILCallR(method, self, ctxt)));
160}
161
162//----------------------------------------------------------------------------
163PyObject* CPyCppyy::CharExecutor::Execute(
165{
166// execute <method with argument <self, ctxt>, construct python string return value
167// with the single char
169}
170
171//----------------------------------------------------------------------------
172PyObject* CPyCppyy::CharConstRefExecutor::Execute(
174{
175// execute <method> with argument <self, ctxt>, construct python string return value
176// with the single char
177 return CPyCppyy_PyText_FromLong(*((char*)GILCallR(method, self, ctxt)));
178}
179
180//----------------------------------------------------------------------------
181PyObject* CPyCppyy::UCharExecutor::Execute(
183{
184// execute <method> with argument <self, args>, construct python string return value
185// with the single char
186 return CPyCppyy_PyText_FromLong((unsigned char)GILCallB(method, self, ctxt));
187}
188
189//----------------------------------------------------------------------------
190PyObject* CPyCppyy::UCharConstRefExecutor::Execute(
192{
193// execute <method> with argument <self, ctxt>, construct python string return value
194// with the single char from the pointer return
195 return CPyCppyy_PyText_FromLong(*((unsigned char*)GILCallR(method, self, ctxt)));
196}
197
198//----------------------------------------------------------------------------
199PyObject* CPyCppyy::WCharExecutor::Execute(
201{
202// execute <method> with argument <self, args>, construct python string return value
203// with the single wide char
204 wchar_t res = (wchar_t)GILCallL(method, self, ctxt);
205 return PyUnicode_FromWideChar(&res, 1);
206}
207
208//----------------------------------------------------------------------------
209PyObject* CPyCppyy::Char16Executor::Execute(
211{
212// execute <method> with argument <self, args>, construct python string return value
213// with the single char16
214 char16_t res = (char16_t)GILCallL(method, self, ctxt);
215 return PyUnicode_DecodeUTF16((const char*)&res, sizeof(char16_t), nullptr, nullptr);
216}
217
218//----------------------------------------------------------------------------
219PyObject* CPyCppyy::Char32Executor::Execute(
221{
222// execute <method> with argument <self, args>, construct python string return value
223// with the single char32
224 char32_t res = (char32_t)GILCallL(method, self, ctxt);
225 return PyUnicode_DecodeUTF32((const char*)&res, sizeof(char32_t), nullptr, nullptr);
226}
227
228//----------------------------------------------------------------------------
229PyObject* CPyCppyy::IntExecutor::Execute(
231{
232// execute <method> with argument <self, ctxt>, construct python int return value
233 return PyInt_FromLong((int)GILCallI(method, self, ctxt));
234}
235
236//----------------------------------------------------------------------------
237PyObject* CPyCppyy::Int8Executor::Execute(
239{
240// execute <method> with argument <self, ctxt>, construct python int return value
241 return PyInt_FromLong((int8_t)GILCallC(method, self, ctxt));
242}
243
244//----------------------------------------------------------------------------
245PyObject* CPyCppyy::UInt8Executor::Execute(
247{
248// execute <method> with argument <self, ctxt>, construct python int return value
249 return PyInt_FromLong((uint8_t)GILCallB(method, self, ctxt));
250}
251
252//----------------------------------------------------------------------------
253PyObject* CPyCppyy::ShortExecutor::Execute(
255{
256// execute <method> with argument <self, ctxt>, construct python int return value
257 return PyInt_FromLong((short)GILCallH(method, self, ctxt));
258}
259
260//----------------------------------------------------------------------------
261PyObject* CPyCppyy::LongExecutor::Execute(
263{
264// execute <method> with argument <self, ctxt>, construct python long return value
265 return PyLong_FromLong((long)GILCallL(method, self, ctxt));
266}
267
268//----------------------------------------------------------------------------
269PyObject* CPyCppyy::ULongExecutor::Execute(
271{
272// execute <method> with argument <self, ctxt>, construct python unsigned long return value
273 return PyLong_FromUnsignedLong((unsigned long)GILCallLL(method, self, ctxt));
274}
275
276//----------------------------------------------------------------------------
277PyObject* CPyCppyy::LongLongExecutor::Execute(
279{
280// execute <method> with argument <self, ctxt>, construct python long long return value
283}
284
285//----------------------------------------------------------------------------
286PyObject* CPyCppyy::ULongLongExecutor::Execute(
288{
289// execute <method> with argument <self, ctxt>, construct python unsigned long long return value
292}
293
294//----------------------------------------------------------------------------
295PyObject* CPyCppyy::FloatExecutor::Execute(
297{
298// execute <method> with argument <self, ctxt>, construct python float return value
299 return PyFloat_FromDouble((double)GILCallF(method, self, ctxt));
300}
301
302//----------------------------------------------------------------------------
303PyObject* CPyCppyy::DoubleExecutor::Execute(
305{
306// execute <method> with argument <self, ctxt>, construct python float return value
307 return PyFloat_FromDouble((double)GILCallD(method, self, ctxt));
308}
309
310//----------------------------------------------------------------------------
311PyObject* CPyCppyy::LongDoubleExecutor::Execute(
313{
314// execute <method> with argument <self, ctxt>, construct python float return value
315 return PyFloat_FromDouble((double)GILCallLD(method, self, ctxt));
316}
317
318//----------------------------------------------------------------------------
320{
321// prepare "buffer" for by-ref returns, used with __setitem__
322 if (pyobject) {
324 fAssignable = pyobject;
325 return true;
326 }
327
328 fAssignable = nullptr;
329 return false;
330}
331
332//----------------------------------------------------------------------------
333#define CPPYY_IMPL_REFEXEC(name, type, stype, F1, F2) \
334PyObject* CPyCppyy::name##RefExecutor::Execute( \
335 Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, CallContext* ctxt) \
336{ \
337 type* ref = (type*)GILCallR(method, self, ctxt); \
338 if (!ref) { /* can happen if wrapper compilation fails */ \
339 PyErr_SetString(PyExc_ReferenceError, "attempt to access a null-pointer");\
340 return nullptr; \
341 } \
342 if (!fAssignable) \
343 return F1((stype)*ref); \
344 else { \
345 *ref = (type)F2(fAssignable); \
346 Py_DECREF(fAssignable); \
347 fAssignable = nullptr; \
348 if (*ref == (type)-1 && PyErr_Occurred()) \
349 return nullptr; \
350 Py_INCREF(Py_None); \
351 return Py_None; \
352 } \
353}
354
357CPPYY_IMPL_REFEXEC(UChar, unsigned char, unsigned long, CPyCppyy_PyText_FromULong, PyLongOrInt_AsULong)
361CPPYY_IMPL_REFEXEC(UShort, unsigned short, unsigned long, PyInt_FromLong, PyLongOrInt_AsULong)
363CPPYY_IMPL_REFEXEC(UInt, unsigned int, unsigned long, PyLong_FromUnsignedLong, PyLongOrInt_AsULong)
365CPPYY_IMPL_REFEXEC(ULong, unsigned long, unsigned long, PyLong_FromUnsignedLong, PyLongOrInt_AsULong)
371
372template<typename T>
373static inline PyObject* PyComplex_FromComplex(const std::complex<T>& c) {
374 return PyComplex_FromDoubles(c.real(), c.imag());
375}
376
377template<typename T>
378static inline std::complex<T> PyComplex_AsComplex(PyObject* pycplx) {
380 return std::complex<T>(cplx.real, cplx.imag);
381}
382
383CPPYY_IMPL_REFEXEC(ComplexD, std::complex<double>,
385
386
387//----------------------------------------------------------------------------
388PyObject* CPyCppyy::STLStringRefExecutor::Execute(
390{
391// execute <method> with argument <self, ctxt>, return python string return value
392 std::string* result = (std::string*)GILCallR(method, self, ctxt);
393 if (!fAssignable) {
394 return CPyCppyy_PyText_FromStringAndSize(result->c_str(), result->size());
395 }
396
397 *result = std::string(
398 CPyCppyy_PyText_AsString(fAssignable), CPyCppyy_PyText_GET_SIZE(fAssignable));
399
400 Py_DECREF(fAssignable);
401 fAssignable = nullptr;
402
404}
405
406//----------------------------------------------------------------------------
407PyObject* CPyCppyy::VoidExecutor::Execute(
409{
410// execute <method> with argument <self, ctxt>, return None
412 if (PyErr_Occurred()) return nullptr;
414}
415
416//----------------------------------------------------------------------------
417PyObject* CPyCppyy::CStringExecutor::Execute(
419{
420// execute <method> with argument <self, ctxt>, construct python string return value
421 char* result = (char*)GILCallR(method, self, ctxt);
422 if (!result) {
425 }
426
428}
429
430//----------------------------------------------------------------------------
431PyObject* CPyCppyy::CStringRefExecutor::Execute(
433{
434// execute <method> with argument <self, ctxt>, construct python string return value
435 char** result = (char**)GILCallR(method, self, ctxt);
436 if (!result || !*result) {
439 }
440
442}
443
444//----------------------------------------------------------------------------
445PyObject* CPyCppyy::WCStringExecutor::Execute(
447{
448// execute <method> with argument <self, ctxt>, construct python unicode return value
449 wchar_t* result = (wchar_t*)GILCallR(method, self, ctxt);
450 if (!result) {
451 wchar_t w = L'\0';
452 return PyUnicode_FromWideChar(&w, 0);
453 }
454
456}
457
458//----------------------------------------------------------------------------
459PyObject* CPyCppyy::CString16Executor::Execute(
461{
462// execute <method> with argument <self, ctxt>, construct python unicode return value
463 char16_t* result = (char16_t*)GILCallR(method, self, ctxt);
464 if (!result) {
465 char16_t w = u'\0';
466 return PyUnicode_DecodeUTF16((const char*)&w, 0, nullptr, nullptr);
467 }
468
469 return PyUnicode_DecodeUTF16((const char*)result,
470 std::char_traits<char16_t>::length(result)*sizeof(char16_t), nullptr, nullptr);
471}
472
473//----------------------------------------------------------------------------
474PyObject* CPyCppyy::CString32Executor::Execute(
476{
477// execute <method> with argument <self, ctxt>, construct python unicode return value
478 char32_t* result = (char32_t*)GILCallR(method, self, ctxt);
479 if (!result) {
480 char32_t w = U'\0';
481 return PyUnicode_DecodeUTF32((const char*)&w, 0, nullptr, nullptr);
482 }
483
484 return PyUnicode_DecodeUTF32((const char*)result,
485 std::char_traits<char32_t>::length(result)*sizeof(char32_t), nullptr, nullptr);
486}
487
488
489//- pointer/array executors --------------------------------------------------
490PyObject* CPyCppyy::VoidArrayExecutor::Execute(
492{
493// execute <method> with argument <self, ctxt>, construct python long return value
494 intptr_t* result = (intptr_t*)GILCallR(method, self, ctxt);
495 if (!result) {
497 return gNullPtrObject;
498 }
500}
501
502//----------------------------------------------------------------------------
503#define CPPYY_IMPL_ARRAY_EXEC(name, type, suffix) \
504PyObject* CPyCppyy::name##ArrayExecutor::Execute( \
505 Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, CallContext* ctxt) \
506{ \
507 return CreateLowLevelView##suffix((type*)GILCallR(method, self, ctxt), fShape); \
508}
509
510CPPYY_IMPL_ARRAY_EXEC(Bool, bool, )
511CPPYY_IMPL_ARRAY_EXEC(SChar, signed char, )
512CPPYY_IMPL_ARRAY_EXEC(UChar, unsigned char, )
513CPPYY_IMPL_ARRAY_EXEC(Byte, std::byte, )
516CPPYY_IMPL_ARRAY_EXEC(Short, short, )
517CPPYY_IMPL_ARRAY_EXEC(UShort, unsigned short, )
518CPPYY_IMPL_ARRAY_EXEC(Int, int, )
519CPPYY_IMPL_ARRAY_EXEC(UInt, unsigned int, )
520CPPYY_IMPL_ARRAY_EXEC(Long, long, )
521CPPYY_IMPL_ARRAY_EXEC(ULong, unsigned long, )
522CPPYY_IMPL_ARRAY_EXEC(LLong, long long, )
523CPPYY_IMPL_ARRAY_EXEC(ULLong, unsigned long long, )
524CPPYY_IMPL_ARRAY_EXEC(Float, float, )
525CPPYY_IMPL_ARRAY_EXEC(Double, double, )
526CPPYY_IMPL_ARRAY_EXEC(LDouble, long double, )
527CPPYY_IMPL_ARRAY_EXEC(ComplexF, std::complex<float>, )
528CPPYY_IMPL_ARRAY_EXEC(ComplexD, std::complex<double>, )
529CPPYY_IMPL_ARRAY_EXEC(ComplexI, std::complex<int>, )
530CPPYY_IMPL_ARRAY_EXEC(ComplexL, std::complex<long>, )
531
532
533//- special cases ------------------------------------------------------------
534#define CPPYY_COMPLEX_EXEC(code, type) \
535PyObject* CPyCppyy::Complex##code##Executor::Execute( \
536 Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, CallContext* ctxt) \
537{ \
538 static Cppyy::TCppScope_t scopeid = Cppyy::GetScope("std::complex<"#type">");\
539 std::complex<type>* result = \
540 (std::complex<type>*)GILCallO(method, self, ctxt, scopeid); \
541 if (!result) { \
542 PyErr_SetString(PyExc_ValueError, "NULL result where temporary expected");\
543 return nullptr; \
544 } \
545 \
546 PyObject* pyres = PyComplex_FromDoubles(result->real(), result->imag()); \
547 ::operator delete(result); /* Cppyy::CallO calls ::operator new */ \
548 return pyres; \
549}
550
551CPPYY_COMPLEX_EXEC(D, double)
552
553//----------------------------------------------------------------------------
554PyObject* CPyCppyy::STLStringExecutor::Execute(
556{
557// execute <method> with argument <self, ctxt>, construct python string return value
558
559// TODO: make use of GILLCallS (?!)
560 static Cppyy::TCppScope_t sSTLStringScope = Cppyy::GetScope("std::string");
561 std::string* result = (std::string*)GILCallO(method, self, ctxt, sSTLStringScope);
562 if (!result) {
565 }
566
569 delete result; // Cppyy::CallO allocates and constructs a string, so it must be properly destroyed
570
571 return pyresult;
572}
573
574//----------------------------------------------------------------------------
575PyObject* CPyCppyy::STLWStringExecutor::Execute(
577{
578// execute <method> with argument <self, ctxt>, construct python string return value
579 static Cppyy::TCppScope_t sSTLWStringScope = Cppyy::GetScope("std::wstring");
580 std::wstring* result = (std::wstring*)GILCallO(method, self, ctxt, sSTLWStringScope);
581 if (!result) {
582 wchar_t w = L'\0';
583 return PyUnicode_FromWideChar(&w, 0);
584 }
585
587 delete result; // Cppyy::CallO allocates and constructs a string, so it must be properly destroyed
588
589 return pyresult;
590}
591
592//----------------------------------------------------------------------------
593PyObject* CPyCppyy::InstancePtrExecutor::Execute(
595{
596// execute <method> with argument <self, ctxt>, construct python proxy object return value
597 return BindCppObject((void*)GILCallR(method, self, ctxt), fClass);
598}
599
600//----------------------------------------------------------------------------
601CPyCppyy::InstanceExecutor::InstanceExecutor(Cppyy::TCppType_t klass) :
602 fClass(klass), fFlags(CPPInstance::kIsValue | CPPInstance::kIsOwner)
603{
604 /* empty */
605}
606
607//----------------------------------------------------------------------------
608PyObject* CPyCppyy::InstanceExecutor::Execute(
610{
611// execution will bring a temporary in existence
613
614 if (!value) {
615 if (!PyErr_Occurred()) // callee may have set a python error itself
616 PyErr_SetString(PyExc_ValueError, "nullptr result where temporary expected");
617 return nullptr;
618 }
619
620// the result can then be bound
622 if (!pyobj)
623 return nullptr;
624
625// python ref counting will now control this object's life span; it will be
626// deleted b/c it is marked as a by-value object owned by python (from fFlags)
627 return pyobj;
628}
629
630
631//----------------------------------------------------------------------------
632CPyCppyy::IteratorExecutor::IteratorExecutor(Cppyy::TCppType_t klass) :
633 InstanceExecutor(klass)
634{
635 fFlags |= CPPInstance::kNoMemReg | CPPInstance::kNoWrapConv; // adds to flags from base class
636}
637
638
639//----------------------------------------------------------------------------
640PyObject* CPyCppyy::InstanceRefExecutor::Execute(
642{
643// executor binds the result to the left-hand side, overwriting if an old object
645 if (!result || !fAssignable)
646 return result;
647 else {
648 // this generic code is quite slow compared to its C++ equivalent ...
650 if (!assign) {
651 PyErr_Clear();
654 PyErr_Format(PyExc_TypeError, "cannot assign to return object (%s)",
656 } else {
657 PyErr_SetString(PyExc_TypeError, "cannot assign to result");
658 }
661 Py_DECREF(fAssignable); fAssignable = nullptr;
662 return nullptr;
663 }
664
665 PyObject* res2 = PyObject_CallFunction(assign, const_cast<char*>("O"), fAssignable);
666
667 Py_DECREF(assign);
669 Py_DECREF(fAssignable); fAssignable = nullptr;
670
671 if (res2) {
672 Py_DECREF(res2); // typically, *this from operator=()
674 }
675
676 return nullptr;
677 }
678}
679
680//----------------------------------------------------------------------------
683 if (pystr) {
685 "C++ object expected, got %s", CPyCppyy_PyText_AsString(pystr));
687 } else
688 PyErr_SetString(PyExc_TypeError, "C++ object expected");
689 return nullptr;
690}
691
692PyObject* CPyCppyy::InstancePtrPtrExecutor::Execute(
694{
695// execute <method> with argument <self, ctxt>, construct python C++ proxy object
696// return ptr value
697 if (fAssignable && !CPPInstance_Check(fAssignable))
698 return SetInstanceCheckError(fAssignable);
699
700 void** result = (void**)GILCallR(method, self, ctxt);
701 if (!fAssignable)
702 return BindCppObject((void*)result, fClass,
704
705 CPPInstance* cppinst = (CPPInstance*)fAssignable;
706 *result = cppinst->GetObject();
707
708 Py_DECREF(fAssignable);
709 fAssignable = nullptr;
710
712}
713
714//----------------------------------------------------------------------------
715PyObject* CPyCppyy::InstancePtrRefExecutor::Execute(
717{
718// execute <method> with argument <self, ctxt>, construct python C++ proxy object
719// ignoring ref) return ptr value
720 if (fAssignable && !CPPInstance_Check(fAssignable))
721 return SetInstanceCheckError(fAssignable);
722
723 void** result = (void**)GILCallR(method, self, ctxt);
724 if (!fAssignable)
725 return BindCppObject(*result, fClass);
726
727 CPPInstance* cppinst = (CPPInstance*)fAssignable;
728 *result = cppinst->GetObject();
729
730 Py_DECREF(fAssignable);
731 fAssignable = nullptr;
732
734}
735
736
737//----------------------------------------------------------------------------
738PyObject* CPyCppyy::InstanceArrayExecutor::Execute(
740{
741// execute <method> with argument <self, ctxt>, construct TupleOfInstances from
742// return value
743 return BindCppObjectArray((void*)GILCallR(method, self, ctxt), fClass, {fSize});
744}
745
746//----------------------------------------------------------------------------
747PyObject* CPyCppyy::ConstructorExecutor::Execute(
749{
750// package return address in PyObject* for caller to handle appropriately (see
751// CPPConstructor for the actual build of the PyObject)
753}
754
755//----------------------------------------------------------------------------
756PyObject* CPyCppyy::PyObjectExecutor::Execute(
758{
759// execute <method> with argument <self, ctxt>, return python object
760 return (PyObject*)GILCallR(method, self, ctxt);
761}
762
763//----------------------------------------------------------------------------
764PyObject* CPyCppyy::FunctionPointerExecutor::Execute(
766{
767// execute <method> with argument <self, ctxt>, return std::function from func ptr
768
769// A function pointer in clang is represented by a Type, not a FunctionDecl and it's
770// not possible to get the latter from the former: the backend will need to support
771// both. Since that is far in the future, we'll use a std::function instead.
772 void* address = (void*)GILCallR(method, self, ctxt);
773 if (address)
775
776// There's currently now way to return a typed function nullptr, but given that
777// this is a return value (thus can not be set) and overloading function based
778// on function pointer return type is likely uncommon ...
780 return gNullPtrObject;
781}
782
783//- factories ----------------------------------------------------------------
785{
786// The matching of the fulltype to an executor factory goes through up to 4 levels:
787// 1) full, qualified match
788// 2) drop '&' as by ref/full type is often pretty much the same python-wise
789// 3) C++ classes, either by ref/ptr or by value
790// 4) additional special case for enums
791//
792// If all fails, void is used, which will cause the return type to be ignored on use
793
794// an exactly matching executor is best
795 ExecFactories_t::iterator h = gExecFactories.find(fullType);
796 if (h != gExecFactories.end())
797 return (h->second)(dims);
798
799// resolve typedefs etc.
800 const std::string& resolvedType = Cppyy::ResolveName(fullType);
801
802// a full, qualified matching executor is preferred
803 if (resolvedType != fullType) {
805 if (h != gExecFactories.end())
806 return (h->second)(dims);
807 }
808
809//-- nothing? ok, collect information about the type and possible qualifiers/decorators
810 bool isConst = strncmp(resolvedType.c_str(), "const", 5) == 0;
811 const std::string& cpd = TypeManip::compound(resolvedType);
812 std::string realType = TypeManip::clean_type(resolvedType, false);
813
814// accept unqualified type (as python does not know about qualifiers)
815 h = gExecFactories.find(realType + cpd);
816 if (h != gExecFactories.end())
817 return (h->second)(dims);
818
819// drop const, as that is mostly meaningless to python (with the exception
820// of c-strings, but those are specialized in the converter map)
821 if (isConst) {
823 h = gExecFactories.find(realType + cpd);
824 if (h != gExecFactories.end())
825 return (h->second)(dims);
826 }
827
828// simple array types
829 if (!cpd.empty() && (std::string::size_type)std::count(cpd.begin(), cpd.end(), '*') == cpd.size()) {
830 h = gExecFactories.find(realType + " ptr");
831 if (h != gExecFactories.end())
832 return (h->second)((!dims || dims.ndim() < (dim_t)cpd.size()) ? dims_t(cpd.size()) : dims);
833 }
834
835//-- still nothing? try pointer instead of array (for builtins)
836 if (cpd == "[]") {
837 h = gExecFactories.find(realType + "*");
838 if (h != gExecFactories.end())
839 return (h->second)(dims);
840 }
841
842// C++ classes and special cases
843 Executor* result = 0;
846 if (cpd == "")
847 return new IteratorExecutor(klass);
848 }
849
850 if (cpd == "")
851 result = new InstanceExecutor(klass);
852 else if (cpd == "&")
853 result = new InstanceRefExecutor(klass);
854 else if (cpd == "**" || cpd == "*[]" || cpd == "&*")
855 result = new InstancePtrPtrExecutor(klass);
856 else if (cpd == "*&")
857 result = new InstancePtrRefExecutor(klass);
858 else if (cpd == "[]") {
860 if (0 < asize)
861 result = new InstanceArrayExecutor(klass, asize);
862 else
863 result = new InstancePtrRefExecutor(klass);
864 } else
865 result = new InstancePtrExecutor(klass);
866 } else if (resolvedType.find("(*)") != std::string::npos ||
867 (resolvedType.find("::*)") != std::string::npos)) {
868 // this is a function pointer
869 // TODO: find better way of finding the type
870 auto pos1 = resolvedType.find('(');
871 auto pos2 = resolvedType.find("*)");
872 auto pos3 = resolvedType.rfind(')');
873 result = new FunctionPointerExecutor(
874 resolvedType.substr(0, pos1), resolvedType.substr(pos2+2, pos3-pos2-1));
875 } else {
876 // unknown: void* may work ("user knows best"), void will fail on use of return value
877 h = (cpd == "") ? gExecFactories.find("void") : gExecFactories.find("void ptr");
878 }
879
880 if (!result && h != gExecFactories.end())
881 // executor factory available, use it to create executor
882 result = (h->second)(dims);
883
884 return result; // may still be null
885}
886
887//----------------------------------------------------------------------------
890{
891 if (p && p->HasState())
892 delete p; // state-less executors are always shared
893}
894
895//----------------------------------------------------------------------------
897bool CPyCppyy::RegisterExecutor(const std::string& name, ef_t fac)
898{
899// register a custom executor
900 auto f = gExecFactories.find(name);
901 if (f != gExecFactories.end())
902 return false;
903
905 return true;
906}
907
908//----------------------------------------------------------------------------
910bool CPyCppyy::RegisterExecutorAlias(const std::string& name, const std::string& target)
911{
912// register a custom executor that is a reference to an existing converter
913 auto f = gExecFactories.find(name);
914 if (f != gExecFactories.end())
915 return false;
916
917 auto t = gExecFactories.find(target);
918 if (t == gExecFactories.end())
919 return false;
920
921 gExecFactories[name] = t->second;
922 return true;
923}
924
925//----------------------------------------------------------------------------
927bool CPyCppyy::UnregisterExecutor(const std::string& name)
928{
929// remove a custom executor
930 auto f = gExecFactories.find(name);
931 if (f != gExecFactories.end()) {
932 gExecFactories.erase(f);
933 return true;
934 }
935 return false;
936}
937
938//----------------------------------------------------------------------------
944
945
946//----------------------------------------------------------------------------
947namespace {
948
949using namespace CPyCppyy;
950
951#define WSTRING1 "std::basic_string<wchar_t>"
952#define WSTRING2 "std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>"
953
954//-- aliasing special case: C complex (is binary compatible with C++ std::complex)
955#ifndef _WIN32
956#define CCOMPLEX_D "_Complex double"
957#define CCOMPLEX_F "_Complex float"
958#else
959#define CCOMPLEX_D "_C_double_complex"
960#define CCOMPLEX_F "_C_float_complex"
961#endif
962
963struct InitExecFactories_t {
964public:
965 InitExecFactories_t() {
966 // load all executor factories in the global map 'gExecFactories'
968
969 // factories for built-ins
970 gf["bool"] = (ef_t)+[](cdims_t) { static BoolExecutor e{}; return &e; };
971 gf["bool&"] = (ef_t)+[](cdims_t) { return new BoolRefExecutor{}; };
972 gf["const bool&"] = (ef_t)+[](cdims_t) { static BoolConstRefExecutor e{}; return &e; };
973 gf["char"] = (ef_t)+[](cdims_t) { static CharExecutor e{}; return &e; };
974 gf["signed char"] = gf["char"];
975 gf["unsigned char"] = (ef_t)+[](cdims_t) { static UCharExecutor e{}; return &e; };
976 gf["char&"] = (ef_t)+[](cdims_t) { return new CharRefExecutor{}; };
977 gf["signed char&"] = gf["char&"];
978 gf["unsigned char&"] = (ef_t)+[](cdims_t) { return new UCharRefExecutor{}; };
979 gf["const char&"] = (ef_t)+[](cdims_t) { static CharConstRefExecutor e{}; return &e; };
980 gf["const signed char&"] = gf["const char&"];
981 gf["const unsigned char&"] = (ef_t)+[](cdims_t) { static UCharConstRefExecutor e{}; return &e; };
982 gf["wchar_t"] = (ef_t)+[](cdims_t) { static WCharExecutor e{}; return &e; };
983 gf["char16_t"] = (ef_t)+[](cdims_t) { static Char16Executor e{}; return &e; };
984 gf["char32_t"] = (ef_t)+[](cdims_t) { static Char32Executor e{}; return &e; };
985 gf["int8_t"] = (ef_t)+[](cdims_t) { static Int8Executor e{}; return &e; };
986 gf["int8_t&"] = (ef_t)+[](cdims_t) { return new Int8RefExecutor{}; };
987 gf["const int8_t&"] = (ef_t)+[](cdims_t) { static Int8RefExecutor e{}; return &e; };
988 gf["uint8_t"] = (ef_t)+[](cdims_t) { static UInt8Executor e{}; return &e; };
989 gf["uint8_t&"] = (ef_t)+[](cdims_t) { return new UInt8RefExecutor{}; };
990 gf["const uint8_t&"] = (ef_t)+[](cdims_t) { static UInt8RefExecutor e{}; return &e; };
991 gf["short"] = (ef_t)+[](cdims_t) { static ShortExecutor e{}; return &e; };
992 gf["short&"] = (ef_t)+[](cdims_t) { return new ShortRefExecutor{}; };
993 gf["int"] = (ef_t)+[](cdims_t) { static IntExecutor e{}; return &e; };
994 gf["int&"] = (ef_t)+[](cdims_t) { return new IntRefExecutor{}; };
995 gf["unsigned short"] = gf["int"];
996 gf["unsigned short&"] = (ef_t)+[](cdims_t) { return new UShortRefExecutor{}; };
997 gf["unsigned long"] = (ef_t)+[](cdims_t) { static ULongExecutor e{}; return &e; };
998 gf["unsigned long&"] = (ef_t)+[](cdims_t) { return new ULongRefExecutor{}; };
999 gf["unsigned int"] = gf["unsigned long"];
1000 gf["unsigned int&"] = (ef_t)+[](cdims_t) { return new UIntRefExecutor{}; };
1001 gf["long"] = (ef_t)+[](cdims_t) { static LongExecutor e{}; return &e; };
1002 gf["long&"] = (ef_t)+[](cdims_t) { return new LongRefExecutor{}; };
1003 gf["unsigned long"] = (ef_t)+[](cdims_t) { static ULongExecutor e{}; return &e; };
1004 gf["unsigned long&"] = (ef_t)+[](cdims_t) { return new ULongRefExecutor{}; };
1005 gf["long long"] = (ef_t)+[](cdims_t) { static LongLongExecutor e{}; return &e; };
1006 gf["long long&"] = (ef_t)+[](cdims_t) { return new LongLongRefExecutor{}; };
1007 gf["unsigned long long"] = (ef_t)+[](cdims_t) { static ULongLongExecutor e{}; return &e; };
1008 gf["unsigned long long&"] = (ef_t)+[](cdims_t) { return new ULongLongRefExecutor{}; };
1009
1010 gf["float"] = (ef_t)+[](cdims_t) { static FloatExecutor e{}; return &e; };
1011 gf["float&"] = (ef_t)+[](cdims_t) { return new FloatRefExecutor{}; };
1012 gf["double"] = (ef_t)+[](cdims_t) { static DoubleExecutor e{}; return &e; };
1013 gf["double&"] = (ef_t)+[](cdims_t) { return new DoubleRefExecutor{}; };
1014 gf["long double"] = (ef_t)+[](cdims_t) { static LongDoubleExecutor e{}; return &e; }; // TODO: lost precision
1015 gf["long double&"] = (ef_t)+[](cdims_t) { return new LongDoubleRefExecutor{}; };
1016 gf["std::complex<double>"] = (ef_t)+[](cdims_t) { static ComplexDExecutor e{}; return &e; };
1017 gf["std::complex<double>&"] = (ef_t)+[](cdims_t) { return new ComplexDRefExecutor{}; };
1018 gf["void"] = (ef_t)+[](cdims_t) { static VoidExecutor e{}; return &e; };
1019
1020 // pointer/array factories
1021 gf["void ptr"] = (ef_t)+[](cdims_t d) { return new VoidArrayExecutor{d}; };
1022 gf["bool ptr"] = (ef_t)+[](cdims_t d) { return new BoolArrayExecutor{d}; };
1023 gf["unsigned char ptr"] = (ef_t)+[](cdims_t d) { return new UCharArrayExecutor{d}; };
1024 gf["const unsigned char ptr"] = gf["unsigned char ptr"];
1025 gf["std::byte ptr"] = (ef_t)+[](cdims_t d) { return new ByteArrayExecutor{d}; };
1026 gf["const std::byte ptr"] = gf["std::byte ptr"];
1027 gf["byte ptr"] = gf["std::byte ptr"];
1028 gf["const byte ptr"] = gf["std::byte ptr"];
1029 gf["int8_t ptr"] = (ef_t)+[](cdims_t d) { return new Int8ArrayExecutor{d}; };
1030 gf["uint8_t ptr"] = (ef_t)+[](cdims_t d) { return new UInt8ArrayExecutor{d}; };
1031 gf["short ptr"] = (ef_t)+[](cdims_t d) { return new ShortArrayExecutor{d}; };
1032 gf["unsigned short ptr"] = (ef_t)+[](cdims_t d) { return new UShortArrayExecutor{d}; };
1033 gf["int ptr"] = (ef_t)+[](cdims_t d) { return new IntArrayExecutor{d}; };
1034 gf["unsigned int ptr"] = (ef_t)+[](cdims_t d) { return new UIntArrayExecutor{d}; };
1035 gf["long ptr"] = (ef_t)+[](cdims_t d) { return new LongArrayExecutor{d}; };
1036 gf["unsigned long ptr"] = (ef_t)+[](cdims_t d) { return new ULongArrayExecutor{d}; };
1037 gf["long long ptr"] = (ef_t)+[](cdims_t d) { return new LLongArrayExecutor{d}; };
1038 gf["unsigned long long ptr"] = (ef_t)+[](cdims_t d) { return new ULLongArrayExecutor{d}; };
1039 gf["float ptr"] = (ef_t)+[](cdims_t d) { return new FloatArrayExecutor{d}; };
1040 gf["double ptr"] = (ef_t)+[](cdims_t d) { return new DoubleArrayExecutor{d}; };
1041 gf["long double ptr"] = (ef_t)+[](cdims_t d) { return new LDoubleArrayExecutor{d}; };
1042 gf["std::complex<float> ptr"] = (ef_t)+[](cdims_t d) { return new ComplexFArrayExecutor{d}; };
1043 gf["std::complex<double> ptr"] = (ef_t)+[](cdims_t d) { return new ComplexDArrayExecutor{d}; };
1044 gf["std::complex<int> ptr"] = (ef_t)+[](cdims_t d) { return new ComplexIArrayExecutor{d}; };
1045 gf["std::complex<long> ptr"] = (ef_t)+[](cdims_t d) { return new ComplexLArrayExecutor{d}; };
1046
1047 // aliases
1048 gf["internal_enum_type_t"] = gf["int"];
1049 gf["internal_enum_type_t&"] = gf["int&"];
1050 gf["internal_enum_type_t ptr"] = gf["int ptr"];
1051 gf["std::byte"] = gf["uint8_t"];
1052 gf["byte"] = gf["uint8_t"];
1053 gf["std::byte&"] = gf["uint8_t&"];
1054 gf["byte&"] = gf["uint8_t&"];
1055 gf["const std::byte&"] = gf["const uint8_t&"];
1056 gf["const byte&"] = gf["const uint8_t&"];
1057 gf["std::int8_t"] = gf["int8_t"];
1058 gf["std::int8_t&"] = gf["int8_t&"];
1059 gf["const std::int8_t&"] = gf["const int8_t&"];
1060 gf["std::int8_t ptr"] = gf["int8_t ptr"];
1061 gf["std::uint8_t"] = gf["uint8_t"];
1062 gf["std::uint8_t&"] = gf["uint8_t&"];
1063 gf["const std::uint8_t&"] = gf["const uint8_t&"];
1064 gf["std::uint8_t ptr"] = gf["uint8_t ptr"];
1065#ifdef _WIN32
1066 gf["__int64"] = gf["long long"];
1067 gf["__int64&"] = gf["long long&"];
1068 gf["__int64 ptr"] = gf["long long ptr"];
1069 gf["unsigned __int64"] = gf["unsigned long long"];
1070 gf["unsigned __int64&"] = gf["unsigned long long&"];
1071 gf["unsigned __int64 ptr"] = gf["unsigned long long ptr"];
1072#endif
1073 gf[CCOMPLEX_D] = gf["std::complex<double>"];
1074 gf[CCOMPLEX_D "&"] = gf["std::complex<double>&"];
1075 gf[CCOMPLEX_F " ptr"] = gf["std::complex<float> ptr"];
1076 gf[CCOMPLEX_D " ptr"] = gf["std::complex<double> ptr"];
1077
1078 // We always need these executors when cppyy is based on an unpatched
1079 // ROOT, because the "long long" types are always converted to Long64_t
1080 // and ULong64_t already at the ROOT Meta level.
1081 // See https://github.com/root-project/root/issues/15872#issuecomment-2174092763
1082 gf["Long64_t"] = gf["long long"];
1083 gf["Long64_t&"] = gf["long long&"];
1084 gf["Long64_t ptr"] = gf["long long ptr"];
1085 gf["ULong64_t"] = gf["unsigned long long"];
1086 gf["ULong64_t&"] = gf["unsigned long long&"];
1087 gf["ULong64_t ptr"] = gf["unsigned long long ptr"];
1088
1089 // factories for special cases
1090 gf["const char*"] = (ef_t)+[](cdims_t) { static CStringExecutor e{}; return &e; };
1091 gf["char*"] = gf["const char*"];
1092 gf["const char*&"] = (ef_t)+[](cdims_t) { static CStringRefExecutor e{}; return &e; };
1093 gf["char*&"] = gf["const char*&"];
1094 gf["const signed char*"] = gf["const char*"];
1095 //gf["signed char*"] = gf["char*"];
1096 gf["signed char ptr"] = (ef_t)+[](cdims_t d) { return new SCharArrayExecutor{d}; };
1097 gf["wchar_t*"] = (ef_t)+[](cdims_t) { static WCStringExecutor e{}; return &e;};
1098 gf["char16_t*"] = (ef_t)+[](cdims_t) { static CString16Executor e{}; return &e;};
1099 gf["char32_t*"] = (ef_t)+[](cdims_t) { static CString32Executor e{}; return &e;};
1100 gf["std::string"] = (ef_t)+[](cdims_t) { static STLStringExecutor e{}; return &e; };
1101 gf["string"] = gf["std::string"];
1102 gf["std::string&"] = (ef_t)+[](cdims_t) { return new STLStringRefExecutor{}; };
1103 gf["string&"] = gf["std::string&"];
1104 gf["std::wstring"] = (ef_t)+[](cdims_t) { static STLWStringExecutor e{}; return &e; };
1105 gf[WSTRING1] = gf["std::wstring"];
1106 gf[WSTRING2] = gf["std::wstring"];
1107 gf["__init__"] = (ef_t)+[](cdims_t) { static ConstructorExecutor e{}; return &e; };
1108 gf["PyObject*"] = (ef_t)+[](cdims_t) { static PyObjectExecutor e{}; return &e; };
1109 gf["_object*"] = gf["PyObject*"];
1110 gf["FILE*"] = gf["void ptr"];
1111 }
1113
1114} // unnamed namespace
#define CPyCppyy_PyText_FromStringAndSize
Definition CPyCppyy.h:85
#define CPyCppyy_PyText_AsString
Definition CPyCppyy.h:76
#define CPyCppyy_PyText_GET_SIZE
Definition CPyCppyy.h:78
#define CPyCppyy_PyText_FromFormat
Definition CPyCppyy.h:80
#define Py_RETURN_NONE
Definition CPyCppyy.h:268
#define CPyCppyy_PyText_CheckExact
Definition CPyCppyy.h:75
#define CPyCppyy_PyText_FromString
Definition CPyCppyy.h:81
#define CCOMPLEX_D
#define CCOMPLEX_F
#define WSTRING1
#define WSTRING2
std::string fRetType
dims_t fShape
Cppyy::TCppType_t fClass
std::string fSignature
dim_t fSize
uint32_t fFlags
static PyObject * PyComplex_FromComplex(const std::complex< T > &c)
static char GILCallC(Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, CPyCppyy::CallContext *ctxt)
Definition Executors.cxx:70
static float GILCallF(Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, CPyCppyy::CallContext *ctxt)
Definition Executors.cxx:75
static PyObject * CPyCppyy_PyText_FromLong(long cl)
static PyObject * SetInstanceCheckError(PyObject *pyobj)
static std::complex< T > PyComplex_AsComplex(PyObject *pycplx)
static Cppyy::TCppObject_t GILCallO(Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, CPyCppyy::CallContext *ctxt, Cppyy::TCppType_t klass)
Definition Executors.cxx:80
static PY_LONG_DOUBLE GILCallLD(Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, CPyCppyy::CallContext *ctxt)
Definition Executors.cxx:77
#define CPPYY_IMPL_GILCALL(rtype, tcode)
Definition Executors.cxx:60
static Cppyy::TCppObject_t GILCallConstructor(Cppyy::TCppMethod_t method, Cppyy::TCppType_t klass, CPyCppyy::CallContext *ctxt)
Definition Executors.cxx:93
static long GILCallL(Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, CPyCppyy::CallContext *ctxt)
Definition Executors.cxx:73
#define CPPYY_COMPLEX_EXEC(code, type)
static short GILCallH(Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, CPyCppyy::CallContext *ctxt)
Definition Executors.cxx:71
static PyObject * CPyCppyy_PyText_FromULong(unsigned long uc)
static PyObject * CPyCppyy_PyBool_FromLong(long b)
static void GILCallV(Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, CPyCppyy::CallContext *ctxt)
Definition Executors.cxx:68
static PY_LONG_LONG GILCallLL(Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, CPyCppyy::CallContext *ctxt)
Definition Executors.cxx:74
#define CPPYY_IMPL_ARRAY_EXEC(name, type, suffix)
static void * GILCallR(Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, CPyCppyy::CallContext *ctxt)
Definition Executors.cxx:78
#define CPPYY_IMPL_REFEXEC(name, type, stype, F1, F2)
static unsigned char GILCallB(Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, CPyCppyy::CallContext *ctxt)
Definition Executors.cxx:69
static double GILCallD(Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, CPyCppyy::CallContext *ctxt)
Definition Executors.cxx:76
static int GILCallI(Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, CPyCppyy::CallContext *ctxt)
Definition Executors.cxx:72
_object PyObject
#define d(i)
Definition RSha256.hxx:102
#define b(i)
Definition RSha256.hxx:100
#define f(i)
Definition RSha256.hxx:104
#define c(i)
Definition RSha256.hxx:101
#define h(i)
Definition RSha256.hxx:106
#define e(i)
Definition RSha256.hxx:103
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t target
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void gc
char name[80]
Definition TGX11.cxx:145
#define CPYCPPYY_EXPORT
Definition CommonDefs.h:24
virtual bool SetAssignable(PyObject *)
const_iterator begin() const
const_iterator end() const
long double PY_LONG_DOUBLE
Definition cpp_cppyy.h:29
unsigned long long PY_ULONG_LONG
Definition cpp_cppyy.h:24
long long PY_LONG_LONG
Definition cpp_cppyy.h:16
#define I(x, y, z)
#define H(x, y, z)
PyObject * gAssign
Definition PyStrings.cxx:7
PyObject * gEmptyString
Definition PyStrings.cxx:21
std::string remove_const(const std::string &cppname)
Definition TypeManip.cxx:80
Py_ssize_t array_size(const std::string &name)
std::string clean_type(const std::string &cppname, bool template_strip=true, bool const_strip=true)
std::string compound(const std::string &name)
PyObject * FuncPtr2StdFunction(const std::string &retType, const std::string &signature, void *address)
Definition Utility.cxx:816
bool IsSTLIterator(const std::string &classname)
Definition Utility.cxx:1128
unsigned long PyLongOrInt_AsULong(PyObject *pyobject)
Definition Utility.cxx:132
CPYCPPYY_EXTERN bool UnregisterExecutor(const std::string &name)
Py_ssize_t dim_t
Definition API.h:89
CPYCPPYY_EXTERN bool RegisterExecutorAlias(const std::string &name, const std::string &target)
Dimensions dims_t
Definition API.h:102
PyObject * BindCppObjectNoCast(Cppyy::TCppObject_t object, Cppyy::TCppType_t klass, const unsigned flags=0)
CPYCPPYY_EXPORT void DestroyExecutor(Executor *p)
CPYCPPYY_EXTERN bool RegisterExecutor(const std::string &name, ExecutorFactory_t)
CPYCPPYY_EXTERN Executor * CreateExecutor(const std::string &name, cdims_t=0)
std::map< std::string, ef_t > ExecFactories_t
Definition Executors.cxx:23
PY_ULONG_LONG PyLongOrInt_AsULong64(PyObject *pyobject)
Definition Utility.cxx:159
bool CPPInstance_Check(T *object)
Executor *(* ef_t)(cdims_t)
Definition Executors.h:37
PyObject * BindCppObjectArray(Cppyy::TCppObject_t address, Cppyy::TCppType_t klass, cdims_t dims)
PyObject * CreatePointerView(void *ptr, cdims_t shape=0)
PyObject * gNullPtrObject
static ExecFactories_t gExecFactories
Definition Executors.cxx:24
std::set< std::string > gIteratorTypes
PyObject * BindCppObject(Cppyy::TCppObject_t object, Cppyy::TCppType_t klass, const unsigned flags=0)
CPYCPPYY_EXTERN void * CallVoidP(Cppyy::TCppMethod_t, Cppyy::TCppObject_t, CallContext *)
bool ReleasesGIL(CallContext *ctxt)
RPY_EXPORTED TCppObject_t CallO(TCppMethod_t method, TCppObject_t self, size_t nargs, void *args, TCppType_t result_type)
RPY_EXPORTED TCppObject_t CallConstructor(TCppMethod_t method, TCppType_t type, size_t nargs, void *args)
intptr_t TCppMethod_t
Definition cpp_cppyy.h:38
void * TCppObject_t
Definition cpp_cppyy.h:37
RPY_EXPORTED std::string ResolveName(const std::string &cppitem_name)
TCppScope_t TCppType_t
Definition cpp_cppyy.h:35
RPY_EXPORTED TCppScope_t GetScope(const std::string &scope_name)
size_t TCppScope_t
Definition cpp_cppyy.h:34
RooArgList L(Args_t &&... args)
Definition RooArgList.h:156