22 const char*
name =
nullptr;
26 case '?':
name =
"bool";
break;
27 case 'c':
name =
"char";
break;
28 case 'b':
name =
"char";
break;
29 case 'B':
name =
"unsigned char";
break;
30 case 'h':
name =
"short";
break;
31 case 'H':
name =
"unsigned short";
break;
32 case 'i':
name =
"int";
break;
33 case 'I':
name =
"unsigned int";
break;
34 case 'l':
name =
"long";
break;
35 case 'L':
name =
"unsigned long";
break;
36 case 'q':
name =
"long long";
break;
37 case 'Q':
name =
"unsigned long long";
break;
38 case 'f':
name =
"float";
break;
39 case 'd':
name =
"double";
break;
40 case 'g':
name =
"long double";
break;
43 default:
name = (allow_voidp ?
"void*" :
nullptr);
break;
54 fTemplated(nullptr), fLowPriority(nullptr), fDoc(nullptr)
70 for (
const auto&
c :
p.second) {
80 bool isGreedy =
false;
101 fTI->fTemplated->AdoptMethod(pc);
109 std::string
proto =
"";
111#if PY_VERSION_HEX >= 0x03080000
121 PyObject* tpArgs = PyTuple_New(argc);
125 bool bArgSet =
false;
132 PyTuple_SET_ITEM(tpArgs, i, pyptrname);
136 Py_DECREF(pytc); pytc =
nullptr;
143 if (!bArgSet && pytc) {
155 Py_XDECREF(pytc); pytc =
nullptr;
157 PyTuple_SET_ITEM(tpArgs, i, pyactname);
169 PyTuple_SET_ITEM(tpArgs, i, tp);
173#if PY_VERSION_HEX >= 0x03080000
174 PyObject* pyargs = PyTuple_New(argc);
178 PyTuple_SET_ITEM(pyargs, i, item);
184 const std::string& name_v1 = \
185 Utility::ConstructTemplateArgs(
nullptr, tpArgs, pyargs, pref, 0, pcnt);
190 proto = name_v1.substr(1, name_v1.size()-2);
212 if (resname.find(
"initializer_list") != std::string::npos) {
213 auto pos =
proto.find(
"initializer_list");
214 while (pos != std::string::npos) {
215 proto.replace(pos, 16,
"vector");
216 pos =
proto.find(
"initializer_list", pos + 6);
220 if (m2 && m2 != cppmeth) {
228 bool bExactMatch = fname == resname;
233 PyObject* pyol = PyObject_GetItem(dct, pycachename);
234 if (!pyol) PyErr_Clear();
240 Py_DECREF(pycachename);
249 exact = PyObject_GetItem(dct, pyresname);
250 if (!exact) PyErr_Clear();
254 bool bIsConstructor =
false, bNeedsRebind =
true;
259 bNeedsRebind =
false;
262 bNeedsRebind =
false;
264 bIsConstructor =
true;
273 if (bIsConstructor) {
280 PyType_Type.tp_setattro(
fTI->fPyClass, pycachename, pyol);
300 if (!exact && !bExactMatch) {
301 PyType_Type.tp_setattro(
fTI->fPyClass, pyresname, pyol);
305 Py_DECREF(pyresname);
306 Py_DECREF(pycachename);
315 PyErr_Format(PyExc_TypeError,
"Failed to instantiate \"%s(%s)\"", fname.c_str(),
proto.c_str());
325 pytmpl->
fSelf =
nullptr;
329 pytmpl->
fTI = std::make_shared<TemplateInfo>();
331 PyObject_GC_Track(pytmpl);
344 if (op == Py_EQ || op == Py_NE) {
354 Py_INCREF(Py_NotImplemented);
355 return Py_NotImplemented;
362 Py_CLEAR(pytmpl->
fSelf);
373 PyObject_ClearWeakRefs((
PyObject*)pytmpl);
374 PyObject_GC_UnTrack(pytmpl);
376 pytmpl->
fTI.~TP_TInfo_t();
377 PyObject_GC_Del(pytmpl);
384 Py_VISIT(pytmpl->
fSelf);
393 if (pytmpl->
fTI->fDoc) {
394 Py_INCREF(pytmpl->
fTI->fDoc);
395 return pytmpl->
fTI->fDoc;
400 if (pytmpl->
fTI->fNonTemplated->HasMethods())
401 doc = PyObject_GetAttrString((
PyObject*)pytmpl->
fTI->fNonTemplated,
"__doc__");
402 if (pytmpl->
fTI->fTemplated->HasMethods()) {
407 }
else if (!doc && doc2) {
411 if (pytmpl->
fTI->fLowPriority->HasMethods()) {
416 }
else if (!doc && doc2) {
429 Py_XDECREF(pytmpl->
fTI->fDoc);
431 pytmpl->
fTI->fDoc = val;
439#define TPPCALL_RETURN \
440{ if (!errors.empty()) \
441 std::for_each(errors.begin(), errors.end(), Utility::PyError_t::Clear);\
454 bool bInserted =
false;
455 auto&
v = pytmpl->
fTI->fDispatchMap[use_targs ?
targs2str(pytmpl) :
""];
459 if (
p.first == sighash) {
465 if (!bInserted)
v.push_back(std::make_pair(sighash, pymeth));
470 bool implicitOkay,
bool use_targs, uint64_t sighash, std::vector<Utility::PyError_t>& errors)
503 if (isNS && pytmpl->
fSelf && pytmpl->
fSelf != Py_None) {
519 Py_DECREF(pymeth); pymeth =
nullptr;
523#if PY_VERSION_HEX >= 0x03080000
525 TemplateProxy* pytmpl,
PyObject*
const *args,
size_t nargsf,
PyObject* kwds)
558#if PY_VERSION_HEX < 0x03080000
559 size_t nargsf = PyTuple_GET_SIZE(args);
571 auto&
v = pytmpl->
fTI->fDispatchMap[
""];
572 for (
const auto&
p :
v) {
573 if (
p.first == sighash) {
580 if (!pytmpl->
fSelf || pytmpl->
fSelf == Py_None) {
586 Py_DECREF(pymeth); pymeth =
nullptr;
594 std::vector<Utility::PyError_t> errors;
605 if (pytmpl->
fSelf && pytmpl->
fSelf != Py_None && !isNS)
606 pymeth = PyObject_GetAttr(pytmpl->
fSelf, pyfullname);
608 pymeth = PyType_Type.tp_getattro(pytmpl->
fTI->fPyClass, pyfullname);
615 Py_DECREF(pyfullname);
619 }
else if (pymeth && PyCallable_Check(pymeth)) {
624 Py_DECREF(pyfullname);
638 Py_DECREF(pyfullname);
647 Py_DECREF(pyfullname);
655 true ,
false , sighash, errors);
661 false ,
true , sighash, errors);
670 pymeth = pytmpl->
Instantiate(pytmpl->
fTI->fCppName, args, nargsf, pref, &pcnt);
682 false ,
false , sighash, errors);
687 if (!errors.empty()) {
691 PyErr_Format(PyExc_TypeError,
"cannot resolve method template call for \'%s\'",
692 pytmpl->
fTI->fCppName.c_str());
707 newPyTmpl->
fSelf = pyobj;
710 newPyTmpl->
fSelf = Py_None;
717 new (&newPyTmpl->
fTI) std::shared_ptr<TemplateInfo>{pytmpl->
fTI};
719#if PY_VERSION_HEX >= 0x03080000
720 newPyTmpl->fVectorCall = pytmpl->fVectorCall;
743 return PyInt_FromLong(0);
761 (
char*)
"unused",
nullptr},
762 {(
char*)
nullptr,
nullptr,
nullptr,
nullptr,
nullptr}
773 fTI->fCppName = cppname;
775 fTI->fPyClass = pyclass;
777 std::vector<PyCallable*> dummy;
782#if PY_VERSION_HEX >= 0x03080000
783 fVectorCall = (vectorcallfunc)tpp_vectorcall;
792 const char* sigarg =
nullptr;
800 if (PyArg_ParseTuple(args,
const_cast<char*
>(
"s|i:__overload__"), &sigarg, &want_const)) {
801 want_const = PyTuple_GET_SIZE(args) == 1 ? -1 : want_const;
804 PyObject* ol = pytmpl->
fTI->fNonTemplated->FindOverload(sigarg, want_const);
807 ol = pytmpl->
fTI->fTemplated->FindOverload(sigarg, want_const);
810 ol = pytmpl->
fTI->fLowPriority->FindOverload(sigarg, want_const);
815 scope = ((
CPPClass*)pytmpl->
fTI->fPyClass)->fCppType;
817 scope, pytmpl->
fTI->fCppName,
proto.substr(1,
proto.size()-2));
818 }
else if (PyArg_ParseTuple(args,
const_cast<char*
>(
"O|i:__overload__"), &sigarg_tuple, &want_const)) {
820 want_const = PyTuple_GET_SIZE(args) == 1 ? -1 : want_const;
823 PyObject* ol = pytmpl->
fTI->fNonTemplated->FindOverload(sigarg_tuple, want_const);
826 ol = pytmpl->
fTI->fTemplated->FindOverload(sigarg_tuple, want_const);
829 ol = pytmpl->
fTI->fLowPriority->FindOverload(sigarg_tuple, want_const);
833 proto.push_back(
'<');
835 for (
int i = 0; i <
n; i++) {
836 PyObject *pItem = PyTuple_GetItem(sigarg_tuple, i);
838 PyErr_Format(PyExc_LookupError,
"argument types should be in string format");
843 proto.push_back(
',');
845 proto.push_back(
'>');
847 scope = ((
CPPClass*)pytmpl->
fTI->fPyClass)->fCppType;
849 scope, pytmpl->
fTI->fCppName,
proto.substr(1,
proto.size()-2));
851 PyErr_Format(PyExc_TypeError,
"Unexpected arguments to __overload__");
856 PyObject* pytype = 0, *pyvalue = 0, *pytrace = 0;
857 PyErr_Fetch(&pytype, &pyvalue, &pytrace);
860 PyErr_Restore(pytype, pyvalue, pytrace);
883 {(
char*)
"__overload__", (PyCFunction)
tpp_overload, METH_VARARGS,
884 (
char*)
"select overload for dispatch" },
885 {(
char*)
nullptr,
nullptr, 0,
nullptr }
892 (
char*)
"cppyy.TemplateProxy",
896#
if PY_VERSION_HEX >= 0x03080000
909#
if PY_VERSION_HEX >= 0x03080000
910 (ternaryfunc)PyVectorcall_Call,
918 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC
919#
if PY_VERSION_HEX >= 0x03080000
920 | Py_TPFLAGS_HAVE_VECTORCALL | Py_TPFLAGS_METHOD_DESCRIPTOR
923 (
char*)
"cppyy template proxy (internal)",
948#if PY_VERSION_HEX >= 0x02030000
951#if PY_VERSION_HEX >= 0x02060000
954#if PY_VERSION_HEX >= 0x03040000
957#if PY_VERSION_HEX >= 0x03080000
960#if PY_VERSION_HEX >= 0x030c0000
#define CPyCppyy_PyText_InternFromString
#define CPyCppyy_PyText_Append
#define CPyCppyy_PyText_AsString
static Py_ssize_t CPyCppyy_PyArgs_GET_SIZE(CPyCppyy_PyArgs_t args, size_t)
PyObject * CPyCppyy_PyArgs_t
#define CPyCppyy_PyText_AppendAndDel
PyObject * CPyCppyy_PyObject_Call(PyObject *cb, PyObject *args, size_t, PyObject *kwds)
#define CPyCppyy_PyText_FromFormat
PyObject * CPyCppyy_tp_call(PyObject *cb, PyObject *args, size_t, PyObject *kwds)
#define CPyCppyy_PyText_FromString
static PyObject * CPyCppyy_PyArgs_GET_ITEM(CPyCppyy_PyArgs_t args, Py_ssize_t i)
#define CPyCppyy_PyText_Check
#define PyVarObject_HEAD_INIT(type, size)
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 result
void MergeOverload(CPPOverload *meth)
void AdoptMethod(PyCallable *pc)
MethodInfo_t * fMethodInfo
virtual PyCallable * Clone()=0
virtual bool IsGreedy()=0
CPPOverload * fLowPriority
TP_DispatchMap_t fDispatchMap
CPPOverload * fNonTemplated
PyObject * Instantiate(const std::string &fname, CPyCppyy_PyArgs_t tmplArgs, size_t nargsf, Utility::ArgPreference, int *pcnt=nullptr)
void Set(const std::string &cppname, const std::string &pyname, PyObject *pyclass)
PyObject_HEAD PyObject * fSelf
void AdoptTemplate(PyCallable *pc)
void AdoptMethod(PyCallable *pc)
void MergeOverload(CPPOverload *mp)
std::string ConstructTemplateArgs(PyObject *pyname, PyObject *tpArgs, PyObject *args=nullptr, ArgPreference=kNone, int argoff=0, int *pcnt=nullptr)
size_t FetchError(std::vector< PyError_t > &, bool is_cpp=false)
void SetDetailedException(std::vector< PyError_t > &errors, PyObject *topmsg, PyObject *defexc)
CPPOverload * CPPOverload_New(const std::string &name, std::vector< PyCallable * > &methods)
static PyObject * tpp_richcompare(TemplateProxy *self, PyObject *other, int op)
bool AdjustSelf(PyCallArgs &cargs)
static PyObject * tpp_doc(TemplateProxy *pytmpl, void *)
static PyMappingMethods tpp_as_mapping
bool CPPOverload_Check(T *object)
static int tpp_clear(TemplateProxy *pytmpl)
static PyObject * tpp_call(TemplateProxy *pytmpl, PyObject *args, PyObject *kwds)
static PyObject * tpp_getuseffi(CPPOverload *, void *)
bool TemplateProxy_CheckExact(T *object)
static void tpp_dealloc(TemplateProxy *pytmpl)
uint64_t HashSignature(CPyCppyy_PyArgs_t args, size_t nargsf)
static int tpp_traverse(TemplateProxy *pytmpl, visitproc visit, void *arg)
static PyObject * tpp_overload(TemplateProxy *pytmpl, PyObject *args)
static int tpp_setuseffi(CPPOverload *, PyObject *, void *)
static PyGetSetDef tpp_getset[]
PyTypeObject CPPOverload_Type
PyTypeObject TemplateProxy_Type
static PyObject * tpp_subscript(TemplateProxy *pytmpl, PyObject *args)
static PyObject * CallMethodImp(TemplateProxy *pytmpl, PyObject *&pymeth, CPyCppyy_PyArgs_t args, size_t nargsf, PyObject *kwds, bool impOK, uint64_t sighash)
static void UpdateDispatchMap(TemplateProxy *pytmpl, bool use_targs, uint64_t sighash, CPPOverload *pymeth)
static TemplateProxy * tpp_new(PyTypeObject *, PyObject *, PyObject *)
static PyMethodDef tpp_methods[]
static int tpp_doc_set(TemplateProxy *pytmpl, PyObject *val, void *)
static Py_hash_t tpp_hash(TemplateProxy *self)
static PyObject * SelectAndForward(TemplateProxy *pytmpl, CPPOverload *pymeth, CPyCppyy_PyArgs_t args, size_t nargsf, PyObject *kwds, bool implicitOkay, bool use_targs, uint64_t sighash, std::vector< Utility::PyError_t > &errors)
static std::string targs2str(TemplateProxy *pytmpl)
static TemplateProxy * tpp_descr_get(TemplateProxy *pytmpl, PyObject *pyobj, PyObject *)
bool TemplateProxy_Check(T *object)
std::shared_ptr< TemplateInfo > TP_TInfo_t
static PyObject * TC2CppName(PyObject *pytc, const char *cpd, bool allow_voidp)
RPY_EXPORTED TCppMethod_t GetMethodTemplate(TCppScope_t scope, const std::string &name, const std::string &proto)
RPY_EXPORTED bool IsConstructor(TCppMethod_t method)
RPY_EXPORTED bool IsNamespace(TCppScope_t scope)
RPY_EXPORTED bool IsStaticMethod(TCppMethod_t method)
RPY_EXPORTED std::string GetMethodFullName(TCppMethod_t)
CPPOverload::Methods_t fMethods