10#include "structmember.h"
26#ifndef CPPOverload_MAXFREELIST
27#define CPPOverload_MAXFREELIST 32
32class TPythonCallback :
public PyCallable {
37 if (!PyCallable_Check(callable)) {
38 PyErr_SetString(PyExc_TypeError,
"parameter must be callable");
45 ~TPythonCallback()
override {
50 PyObject* GetSignature(
bool =
true)
override {
51 return PyUnicode_FromString(
"*args, **kwargs");
53 PyObject* GetSignatureNames()
override {
return PyTuple_New(0); }
54 PyObject* GetSignatureTypes()
override {
return PyTuple_New(0); }
55 PyObject* GetPrototype(
bool =
true)
override {
56 return PyUnicode_FromString(
"<callback>");
59 if (PyObject_HasAttrString(fCallable,
"__doc__")) {
60 return PyObject_GetAttrString(fCallable,
"__doc__");
62 return GetPrototype();
66 int GetPriority()
override {
return 100; };
67 bool IsGreedy()
override {
return false; };
69 int GetMaxArgs()
override {
return 100; };
73 PyObject* GetArgDefault(
int ,
bool =
true)
override {
85 PyCallable* Clone()
override {
return new TPythonCallback(*
this); }
88 PyObject* kwds, CallContext* )
override {
91 if (nargsf & PY_VECTORCALL_ARGUMENTS_OFFSET) {
93 nargsf &= ~PY_VECTORCALL_ARGUMENTS_OFFSET;
96 Py_ssize_t nkwargs = kwds ? PyTuple_GET_SIZE(kwds) : 0;
97 Py_ssize_t totalargs = PyVectorcall_NARGS(nargsf) + nkwargs;
105 memcpy((
void*)&newArgs[1], args, totalargs *
sizeof(
PyObject*));
113 if (nargsf & PY_VECTORCALL_ARGUMENTS_OFFSET)
116 PyMem_Free((
void*)args);
123static inline bool IsPseudoFunc(CPPOverload* pymeth) {
128static int PriorityCmp(
const std::pair<int, PyCallable*>& left,
129 const std::pair<int, PyCallable*>& right) {
130 return left.first > right.first;
134static inline void ResetCallState(CPPInstance* descr_self,
135 CPPInstance*& im_self) {
137 if (descr_self != im_self) {
139 im_self = descr_self;
144static inline PyObject* HandleReturn(CPPOverload* pymeth, CPPInstance* im_self,
148 CPPInstance* cppres =
152 if (
IsCreator(pymeth->fMethodInfo->fFlags)) {
157 im_self->PythonOwns();
162 cppres->PythonOwns();
175 if (!(cppres->fFlags &
182 ptrdiff_t
offset = (ptrdiff_t)cppres->GetObject() -
183 (ptrdiff_t)im_self->GetObject();
193 pymeth->fMethodInfo->fFlags |=
201 pymeth->fMethodInfo->fFlags |=
208 ResetCallState(pymeth->fSelf, im_self);
214static PyObject* mp_name(CPPOverload* pymeth,
void*) {
215 return PyUnicode_FromString(pymeth->GetName().c_str());
219static PyObject* mp_module(CPPOverload* ,
void*) {
225static PyObject* mp_doc(CPPOverload* pymeth,
void*) {
226 if (pymeth->fMethodInfo->fDoc) {
227 Py_INCREF(pymeth->fMethodInfo->fDoc);
228 return pymeth->fMethodInfo->fDoc;
235 CPPOverload::Methods_t::size_type nMethods = methods.size();
238 PyObject* doc = methods[0]->GetDocString();
245 PyObject* separator = PyUnicode_FromString(
"\n");
246 for (CPPOverload::Methods_t::size_type i = 1; i < nMethods; ++i) {
247 PyUnicode_Append(&doc, separator);
248 PyUnicode_AppendAndDel(&doc, methods[i]->GetDocString());
250 Py_DECREF(separator);
255static int mp_doc_set(CPPOverload* pymeth,
PyObject* val,
void*) {
256 Py_XDECREF(pymeth->fMethodInfo->fDoc);
258 pymeth->fMethodInfo->fDoc = val;
272static PyObject* mp_func_overloads_names(CPPOverload* pymeth) {
276 PyObject* overloads_names_dict = PyDict_New();
278 for (PyCallable* method : methods) {
279 PyDict_SetItem(overloads_names_dict, method->GetPrototype(),
280 method->GetSignatureNames());
283 return overloads_names_dict;
300static PyObject* mp_func_overloads_types(CPPOverload* pymeth) {
304 PyObject* overloads_types_dict = PyDict_New();
306 for (PyCallable* method : methods) {
307 PyDict_SetItem(overloads_types_dict, method->GetPrototype(),
308 method->GetSignatureTypes());
311 return overloads_types_dict;
315static PyObject* mp_meth_func(CPPOverload* pymeth,
void*) {
317 CPPOverload* newPyMeth =
321 *pymeth->fMethodInfo->fRefCount += 1;
322 newPyMeth->fMethodInfo = pymeth->fMethodInfo;
332static PyObject* mp_meth_self(CPPOverload* pymeth,
void*) {
335 if (IsPseudoFunc(pymeth)) {
336 PyErr_Format(PyExc_AttributeError,
337 "function %s has no attribute \'im_self\'",
338 pymeth->fMethodInfo->fName.c_str());
340 }
else if (pymeth->fSelf != 0) {
341 Py_INCREF((
PyObject*)pymeth->fSelf);
349static PyObject* mp_meth_class(CPPOverload* pymeth,
void*) {
352 if (!IsPseudoFunc(pymeth) && pymeth->fMethodInfo->fMethods.size()) {
353 PyObject* pyclass = pymeth->fMethodInfo->fMethods[0]->GetScopeProxy();
355 PyErr_Format(PyExc_AttributeError,
356 "function %s has no attribute \'im_class\'",
357 pymeth->fMethodInfo->fName.c_str());
365static PyObject* mp_func_closure(CPPOverload* ,
void*) {
371static PyObject* mp_func_code(CPPOverload*,
void*) {
379static PyObject* mp_func_defaults(CPPOverload* pymeth,
void*) {
384 if (methods.size() != 1)
385 return PyTuple_New(0);
387 int maxarg = methods[0]->GetMaxArgs();
389 PyObject* defaults = PyTuple_New(maxarg);
392 for (
int iarg = 0; iarg < maxarg; ++iarg) {
393 PyObject* defvalue = methods[0]->GetArgDefault(iarg);
395 PyTuple_SET_ITEM(defaults, itup++, defvalue);
399 _PyTuple_Resize(&defaults, itup);
405static PyObject* mp_func_globals(CPPOverload* ,
void*) {
408 PyObject* pyglobal = PyModule_GetDict(PyImport_AddModule((
char*)
"cppjit"));
409 Py_XINCREF(pyglobal);
414static inline int set_flag(CPPOverload* pymeth,
PyObject*
value,
418 pymeth->fMethodInfo->fFlags &= ~flag;
422 long istrue = PyLong_AsLong(
value);
423 if (istrue == -1 && PyErr_Occurred()) {
424 PyErr_Format(PyExc_ValueError,
"a boolean 1 or 0 is required for %s",
name);
429 pymeth->fMethodInfo->fFlags |= flag;
431 pymeth->fMethodInfo->fFlags &= ~flag;
437static PyObject* mp_getcreates(CPPOverload* pymeth,
void*) {
439 return PyLong_FromLong((
long)
IsCreator(pymeth->fMethodInfo->fFlags));
443static int mp_setcreates(CPPOverload* pymeth,
PyObject*
value,
void*) {
448constexpr const char* mempolicy_error_message =
449 "The __mempolicy__ attribute can't be used, because in the past it was "
450 "reserved to manage the local memory policy. "
451 "If you want to do that now, please implement a pythonization for your "
452 "class that uses SetOwnership() to manage the "
453 "ownership of arguments according to your needs.";
456static PyObject* mp_getmempolicy(CPPOverload*,
void*) {
457 PyErr_SetString(PyExc_RuntimeError, mempolicy_error_message);
462static int mp_setmempolicy(CPPOverload*,
PyObject*,
void*) {
463 PyErr_SetString(PyExc_RuntimeError, mempolicy_error_message);
468#define CPPJIT_BOOLEAN_PROPERTY(name, flag, label) \
469 static PyObject* mp_get##name(CPPOverload* pymeth, void*) { \
470 if (pymeth->fMethodInfo->fFlags & flag) { \
476 static int mp_set##name(CPPOverload* pymeth, PyObject* value, void*) { \
477 return set_flag(pymeth, value, flag, label); \
487static
PyObject* mp_getcppname(CPPOverload* pymeth,
void*) {
489 return PyUnicode_FromString(
"CPPOverload_Type");
491 auto& methods = pymeth->fMethodInfo->fMethods;
493 return PyUnicode_FromString(
"void (*)()");
495 if (methods.size() == 1)
496 return methods[0]->GetTypeName();
498 return PyUnicode_FromString(
"void* (*)(...)");
502static PyGetSetDef mp_getset[] = {
503 {(
char*)
"__name__", (getter)mp_name,
nullptr,
nullptr,
nullptr},
504 {(
char*)
"__module__", (getter)mp_module,
nullptr,
nullptr,
nullptr},
505 {(
char*)
"__doc__", (getter)mp_doc, (setter)mp_doc_set,
nullptr,
nullptr},
510 {(
char*)
"im_func", (getter)mp_meth_func,
nullptr,
nullptr,
nullptr},
511 {(
char*)
"im_self", (getter)mp_meth_self,
nullptr,
nullptr,
nullptr},
512 {(
char*)
"im_class", (getter)mp_meth_class,
nullptr,
nullptr,
nullptr},
514 {(
char*)
"func_closure", (getter)mp_func_closure,
nullptr,
nullptr,
nullptr},
515 {(
char*)
"func_code", (getter)mp_func_code,
nullptr,
nullptr,
nullptr},
516 {(
char*)
"func_defaults", (getter)mp_func_defaults,
nullptr,
nullptr,
518 {(
char*)
"func_globals", (getter)mp_func_globals,
nullptr,
nullptr,
nullptr},
519 {(
char*)
"func_doc", (getter)mp_doc, (setter)mp_doc_set,
nullptr,
nullptr},
520 {(
char*)
"func_name", (getter)mp_name,
nullptr,
nullptr,
nullptr},
521 {(
char*)
"func_overloads_types", (getter)mp_func_overloads_types,
nullptr,
523 {(
char*)
"func_overloads_names", (getter)mp_func_overloads_names,
nullptr,
527 {(
char*)
"__creates__", (getter)mp_getcreates, (setter)mp_setcreates,
528 (
char*)
"For ownership rules of result: if true, objects are python-owned",
530 {(
char*)
"__mempolicy__", (getter)mp_getmempolicy, (setter)mp_setmempolicy,
531 (
char*)
"Unused",
nullptr},
532 {(
char*)
"__set_lifeline__", (getter)mp_getlifeline, (setter)mp_setlifeline,
533 (
char*)
"If true, set a lifeline from the return value onto self",
nullptr},
534 {(
char*)
"__release_gil__", (getter)mp_getthreaded, (setter)mp_setthreaded,
535 (
char*)
"If true, releases GIL on call into C++",
nullptr},
536 {(
char*)
"__useffi__", (getter)mp_getuseffi, (setter)mp_setuseffi,
537 (
char*)
"not implemented",
nullptr},
538 {(
char*)
"__sig2exc__", (getter)mp_getsig2exc, (setter)mp_setsig2exc,
539 (
char*)
"If true, turn signals into Python exceptions",
nullptr},
542 {(
char*)
"__cpp_name__", (getter)mp_getcppname,
nullptr,
nullptr,
nullptr},
544 {(
char*)
nullptr,
nullptr,
nullptr,
nullptr,
nullptr}};
554 CPPInstance* im_self = pymeth->fSelf;
557 auto& methods = pymeth->fMethodInfo->fMethods;
559 CPPOverload::Methods_t::size_type nMethods = methods.size();
562 const auto mflags = pymeth->fMethodInfo->fFlags;
569 ctxt.fPyContext = (
PyObject*)im_self;
578 PyObject*
result = methods[0]->Call(im_self, args, nargsf, kwds, &ctxt);
579 return HandleReturn(pymeth, im_self,
result);
586 auto& dispatchMap = pymeth->fMethodInfo->fDispatchMap;
587 PyCallable* memoized_pc =
nullptr;
588 for (
const auto&
p : dispatchMap) {
589 if (
p.first == sighash) {
590 memoized_pc =
p.second;
600 PyObject*
result = memoized_pc->Call(im_self, args, nargsf, kwds, &ctxt);
602 return HandleReturn(pymeth, im_self,
result);
608 ResetCallState(pymeth->fSelf, im_self);
616 std::vector<std::pair<int, PyCallable*>> pm;
617 pm.reserve(methods.size());
618 for (
auto ptr : methods)
619 pm.emplace_back(ptr->GetPriority(), ptr);
620 std::stable_sort(pm.begin(), pm.end(), PriorityCmp);
621 for (CPPOverload::Methods_t::size_type i = 0; i < methods.size(); ++i)
622 methods[i] = pm[i].second;
629 std::vector<Utility::PyError_t> errors;
630 std::vector<bool> implicit_possible(methods.size());
631 bool bHaveImplicit =
false;
632 for (
int stage = 0; stage < 3; ++stage) {
635 else if (stage == 2) {
636 ctxt.fFlags &= ~CallContext::kNoImplicit;
639 for (CPPOverload::Methods_t::size_type i = 0; i < nMethods; ++i) {
640 if (stage && !implicit_possible[i])
643 PyObject*
result = methods[i]->Call(im_self, args, nargsf, kwds, &ctxt);
647 dispatchMap.push_back(std::make_pair(sighash, methods[i]));
651 for (
auto&
p : dispatchMap) {
652 if (
p.first == sighash) {
653 p.second = methods[i];
659 return HandleReturn(pymeth, im_self,
result);
665 ResetCallState(pymeth->fSelf, im_self);
670 if (!PyErr_Occurred()) {
672 PyObject* sig = methods[i]->GetPrototype();
673 PyErr_Format(PyExc_SystemError,
"%s =>\n %s", PyUnicode_AsUTF8(sig),
674 (
char*)
"nullptr result without error in overload call");
685 bHaveImplicit =
true;
686 implicit_possible[i] =
true;
687 ctxt.fFlags &= ~CallContext::kHaveImplicit;
689 implicit_possible[i] =
false;
690 ResetCallState(pymeth->fSelf, im_self);
699 PyObject* topmsg = PyUnicode_FromFormat(
700 "none of the %d overloaded methods succeeded. Full details:",
710static PyObject* mp_str(CPPOverload* cppinst) {
712 std::ostringstream s;
713 s <<
"<C++ overload \"" << cppinst->fMethodInfo->fName <<
"\" at "
714 << (
void*)cppinst <<
">";
715 return PyUnicode_FromString(s.str().c_str());
719static CPPOverload* mp_descr_get(CPPOverload* pymeth, CPPInstance* pyobj,
737 bool gc_track =
false;
739 if (newPyMeth != NULL) {
740 free_list = (CPPOverload*)(newPyMeth->fSelf);
751 *pymeth->fMethodInfo->fRefCount += 1;
752 newPyMeth->fMethodInfo = pymeth->fMethodInfo;
754 newPyMeth->fVectorCall = pymeth->fVectorCall;
756 if (pyobj && (
PyObject*)pyobj != Py_None) {
758 newPyMeth->fSelf = pyobj;
761 newPyMeth->fSelf =
nullptr;
770 PyObject_GC_Track(newPyMeth);
779 pymeth->fSelf =
nullptr;
781 pymeth->fMethodInfo =
new CPPOverload::MethodInfo_t;
783 PyObject_GC_Track(pymeth);
788static void mp_dealloc(CPPOverload* pymeth) {
790 PyObject_GC_UnTrack(pymeth);
792 Py_CLEAR(pymeth->fSelf);
794 if (--(*pymeth->fMethodInfo->fRefCount) <= 0) {
795 delete pymeth->fMethodInfo;
803 PyObject_GC_Del(pymeth);
808static Py_ssize_t mp_hash(CPPOverload* pymeth) {
811#if PY_VERSION_HEX >= 0x030d0000
812 return Py_HashPointer(pymeth->fMethodInfo);
814 return _Py_HashPointer(pymeth->fMethodInfo);
819static int mp_traverse(CPPOverload* pymeth, visitproc visit,
void* args) {
822 return visit((
PyObject*)pymeth->fSelf, args);
828static int mp_clear(CPPOverload* pymeth) {
830 Py_CLEAR(pymeth->fSelf);
836static PyObject* mp_richcompare(CPPOverload* self, CPPOverload* other,
int op) {
843 if ((Py_TYPE(self) == Py_TYPE(other) &&
844 self->fMethodInfo == other->fMethodInfo) &&
845 ((IsPseudoFunc(self) && IsPseudoFunc(other)) ||
846 self->fSelf == other->fSelf)) {
855 const char* sigarg =
nullptr;
858 Py_ssize_t args_size = PyTuple_GET_SIZE(args);
859 if (args_size && PyArg_ParseTuple(args,
const_cast<char*
>(
"s|i:__overload__"),
860 &sigarg, &want_const)) {
861 want_const = args_size == 1 ? -1 : want_const;
862 return pymeth->FindOverload(sigarg ? sigarg :
"", want_const);
863 }
else if (args_size &&
864 PyArg_ParseTuple(args,
const_cast<char*
>(
"O|i:__overload__"),
865 &sigarg_tuple, &want_const)) {
867 want_const = args_size == 1 ? -1 : want_const;
868 return pymeth->FindOverload(sigarg_tuple, want_const);
870 PyErr_Format(PyExc_TypeError,
"Unexpected arguments to __overload__");
875static PyObject* mp_add_overload(CPPOverload* pymeth,
PyObject* new_overload) {
876 TPythonCallback* cb =
new TPythonCallback(new_overload);
877 pymeth->AdoptMethod(cb);
885 if (!PyArg_ParseTuple(args,
const_cast<char*
>(
"i|i:__cpp_reflex__"), &request,
889 return pymeth->fMethodInfo->fMethods[0]->Reflex(request,
format);
893static PyMethodDef mp_methods[] = {
894 {(
char*)
"__overload__", (PyCFunction)mp_overload, METH_VARARGS,
895 (
char*)
"select overload for dispatch"},
896 {(
char*)
"__add_overload__", (PyCFunction)mp_add_overload, METH_O,
897 (
char*)
"add a new overload"},
898 {(
char*)
"__cpp_reflex__", (PyCFunction)mp_reflex, METH_VARARGS,
899 (
char*)
"C++ overload reflection information"},
900 {(
char*)
nullptr,
nullptr, 0,
nullptr}};
906 PyVarObject_HEAD_INIT(&PyType_Type,
907 0)(
char*)
"cppjit.CPPOverload",
910 (destructor)mp_dealloc,
920 (ternaryfunc)PyVectorcall_Call,
926 Py_TPFLAGS_METHOD_DESCRIPTOR,
927 (
char*)
"cppjit method proxy (internal)",
928 (traverseproc)mp_traverse,
930 (richcmpfunc)mp_richcompare,
939 (descrgetfunc)mp_descr_get,
962 std::vector<PyCallable*>& methods) {
969 if (
name ==
"__init__")
977 std::string_view name_maybe_template =
name;
978 auto begin_template = name_maybe_template.find_first_of(
'<');
979 if (begin_template <= name_maybe_template.size()) {
980 name_maybe_template = name_maybe_template.substr(0, begin_template);
982 if (name_maybe_template.find(
"Clone") != std::string_view::npos) {
993 fMethodInfo->fMethods.push_back(pc);
1001 fMethodInfo->fMethods.insert(fMethodInfo->fMethods.end(),
1012 bool accept_any = signature ==
":any:";
1015 std::string sig1{
"("};
1017 sig1.append(signature);
1019 sig1.erase(std::remove(sig1.begin(), sig1.end(),
' '), std::end(sig1));
1023 for (
auto& meth : methods) {
1024 bool found = accept_any;
1026 PyObject* pysig2 = meth->GetSignature(
false);
1027 std::string sig2(PyUnicode_AsUTF8(pysig2));
1028 sig2.erase(std::remove(sig2.begin(), sig2.end(),
' '), std::end(sig2));
1034 pysig2 = meth->GetSignature(
true);
1035 std::string sig3(PyUnicode_AsUTF8(pysig2));
1036 sig3.erase(std::remove(sig3.begin(), sig3.end(),
' '), std::end(sig3));
1043 if (found && 0 <= want_const) {
1044 bool isconst = meth->IsConst();
1045 if (!((want_const && isconst) || (!want_const && !isconst)))
1051 newmeth = mp_new(
nullptr,
nullptr,
nullptr);
1053 vec.push_back(meth->Clone());
1054 newmeth->
Set(fMethodInfo->fName, vec);
1058 newmeth->
fSelf = fSelf;
1070 PyErr_Format(PyExc_LookupError,
"signature \"%s\" not found",
1078 Py_ssize_t
n = PyTuple_Size(args_tuple);
1084 Py_ssize_t min_score = INT_MAX;
1086 size_t best_method = 0, method_index = 0;
1088 for (
auto& meth : methods) {
1089 if (0 <= want_const) {
1090 bool isconst = meth->IsConst();
1091 if (!((want_const && isconst) || (!want_const && !isconst)))
1095 int score = meth->GetArgMatchScore(args_tuple);
1097 if (score < min_score) {
1100 best_method = method_index;
1107 std::string sigargs(
"(");
1109 for (
int i = 0; i <
n; i++) {
1110 PyObject* pItem = PyTuple_GetItem(args_tuple, i);
1111 if (!PyUnicode_Check(pItem)) {
1112 PyErr_Format(PyExc_LookupError,
1113 "argument types should be in string format");
1116 std::string arg_type(PyUnicode_AsUTF8(pItem));
1117 sigargs += arg_type +
", ";
1121 PyErr_Format(PyExc_LookupError,
"signature with arguments \"%s\" not found",
1126 CPPOverload* newmeth = mp_new(
nullptr,
nullptr,
nullptr);
1128 vec.push_back(methods[best_method]->Clone());
1129 newmeth->
Set(fMethodInfo->fName, vec);
1133 newmeth->
fSelf = fSelf;
1143 for (Methods_t::iterator it = fMethods.begin(); it != fMethods.end(); ++it) {
#define CPPOverload_MAXFREELIST
#define CPPJIT_BOOLEAN_PROPERTY(name, flag, label)
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 offset
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 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 Atom_t Time_t format
void AdoptMethod(PyCallable *pc)
void MergeOverload(CPPOverload *meth)
MethodInfo_t * fMethodInfo
std::vector< PyCallable * > Methods_t
PyObject * FindOverload(const std::string &signature, int want_const=-1)
vectorcallfunc fVectorCall
void Set(const std::string &name, std::vector< PyCallable * > &methods)
PyObject_HEAD CPPInstance * fSelf
PyObject *const * cpyrt_PyArgs_t
#define Py_TPFLAGS_HAVE_VECTORCALL
#define CPYRT_PYTYPE_TAIL
#define cpyrt_PyObject_Call
size_t FetchError(std::vector< PyError_t > &, bool is_cpp=false)
void SetDetailedException(std::vector< PyError_t > &&errors, PyObject *topmsg, PyObject *defexc)
bool IsConstructor(uint64_t flags)
bool IsSorted(uint64_t flags)
uint64_t HashSignature(cpyrt_PyArgs_t args, size_t nargsf)
static PyMethodObject * free_list
PyObject * GetScopeProxy(interop::TCppScope_t)
PyTypeObject CPPOverload_Type
bool IsCreator(uint64_t flags)
bool NoImplicit(CallContext *ctxt)
bool HaveImplicit(CallContext *ctxt)
bool CPPInstance_Check(T *object)
TCppFuncAddr_t GetFunctionAddress(TCppMethod_t method, bool check_enabled=true)
size_t SizeOf(TCppScope_t klass)
CPPOverload::DispatchMap_t fDispatchMap
CPPOverload::Methods_t fMethods
static uint32_t & GlobalPolicyFlags()