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;
41 default:
name = (allow_voidp ?
"void*" :
nullptr);
break;
52 fNonTemplated(nullptr), fTemplated(nullptr), fLowPriority(nullptr)
69 for (
const auto&
c :
p.second) {
85 fTI->fPyClass = pyclass;
87 std::vector<PyCallable*> dummy;
96 bool isGreedy =
false;
117 fTI->fTemplated->AdoptMethod(pc);
125 std::string
proto =
"";
129 PyObject* tpArgs = PyTuple_New(nArgs);
130 for (
int i = 0; i < nArgs; ++i) {
131 PyObject* itemi = PyTuple_GET_ITEM(args, i);
133 bool bArgSet =
false;
140 PyTuple_SET_ITEM(tpArgs, i, pyptrname);
144 Py_DECREF(pytc); pytc =
nullptr;
151 if (!bArgSet && pytc) {
163 Py_XDECREF(pytc); pytc =
nullptr;
165 PyTuple_SET_ITEM(tpArgs, i, pyactname);
177 PyTuple_SET_ITEM(tpArgs, i, tp);
184 proto = name_v1.substr(1, name_v1.size()-2);
206 if (resname.find(
"initializer_list") != std::string::npos) {
207 auto pos =
proto.find(
"initializer_list");
208 while (pos != std::string::npos) {
209 proto.replace(pos, 16,
"vector");
210 pos =
proto.find(
"initializer_list", pos + 6);
214 if (m2 && m2 != cppmeth) {
222 bool bExactMatch = fname == resname;
227 PyObject* pyol = PyObject_GetItem(dct, pycachename);
228 if (!pyol) PyErr_Clear();
234 Py_DECREF(pycachename);
243 exact = PyObject_GetItem(dct, pyresname);
244 if (!exact) PyErr_Clear();
248 bool bIsConstructor =
false, bNeedsRebind =
true;
253 bNeedsRebind =
false;
256 bNeedsRebind =
false;
258 bIsConstructor =
true;
267 if (bIsConstructor) {
274 PyType_Type.tp_setattro(
fTI->fPyClass, pycachename, pyol);
294 if (!exact && !bExactMatch) {
295 PyType_Type.tp_setattro(
fTI->fPyClass, pyresname, pyol);
299 Py_DECREF(pyresname);
300 Py_DECREF(pycachename);
309 PyErr_Format(PyExc_TypeError,
"Failed to instantiate \"%s(%s)\"", fname.c_str(),
proto.c_str());
319 pytmpl->
fSelf =
nullptr;
323 pytmpl->
fTI = std::make_shared<TemplateInfo>();
325 PyObject_GC_Track(pytmpl);
338 if (op == Py_EQ || op == Py_NE) {
348 Py_INCREF(Py_NotImplemented);
349 return Py_NotImplemented;
356 Py_CLEAR(pytmpl->
fSelf);
367 PyObject_ClearWeakRefs((
PyObject*)pytmpl);
368 PyObject_GC_UnTrack(pytmpl);
370 pytmpl->
fTI.~TP_TInfo_t();
371 PyObject_GC_Del(pytmpl);
378 Py_VISIT(pytmpl->
fSelf);
389 if (pytmpl->
fTI->fNonTemplated->HasMethods())
390 doc = PyObject_GetAttrString((
PyObject*)pytmpl->
fTI->fNonTemplated,
"__doc__");
391 if (pytmpl->
fTI->fTemplated->HasMethods()) {
396 }
else if (!doc && doc2) {
400 if (pytmpl->
fTI->fLowPriority->HasMethods()) {
405 }
else if (!doc && doc2) {
421 return tpp_doc(pytmpl,
nullptr);
436 bool bInserted =
false;
437 auto&
v = pytmpl->
fTI->fDispatchMap[use_targs ?
targs2str(pytmpl) :
""];
441 if (
p.first == sighash) {
447 if (!bInserted)
v.push_back(std::make_pair(sighash, pymeth));
458 if (isNS && pytmpl->
fSelf) {
461 PyObject* newArgs = PyTuple_New(sz+1);
462 for (
int i = 0; i < sz; ++i) {
463 PyObject* item = PyTuple_GET_ITEM(args, i);
465 PyTuple_SET_ITEM(newArgs, i+1, item);
479 Py_DECREF(pymeth); pymeth =
nullptr;
483#define TPPCALL_RETURN \
484{ if (!errors.empty()) \
485 std::for_each(errors.begin(), errors.end(), Utility::PyError_t::Clear);\
520 std::vector<Utility::PyError_t> errors;
531 for (
const auto&
p :
v) {
532 if (
p.first == sighash) {
539 if (!pytmpl->
fSelf) {
545 Py_DECREF(pymeth); pymeth =
nullptr;
554 if (!kwds) kwds = PyDict_New();
568 pymeth = PyObject_GetAttr((pytmpl->
fSelf && !isNS) ? pytmpl->
fSelf : pytmpl->
fTI->fPyClass, pyfullname);
575 Py_DECREF(pyfullname);
579 }
else if (pymeth && PyCallable_Check(pymeth)) {
581 result = PyObject_CallObject(pymeth, args);
584 Py_DECREF(pyfullname);
598 Py_DECREF(pyfullname);
606 Py_DECREF(pyfullname);
614 if (pytmpl->
fTI->fNonTemplated->HasMethods()) {
622 Py_DECREF(pymeth); pymeth =
nullptr;
631 if (pytmpl->
fTI->fTemplated->HasMethods()) {
638 Py_DECREF(pymeth); pymeth =
nullptr;
663 if (pytmpl->
fTI->fLowPriority->HasMethods()) {
670 Py_DECREF(pymeth); pymeth =
nullptr;
679 if (!errors.empty()) {
683 PyErr_Format(PyExc_TypeError,
"cannot resolve method template call for \'%s\'",
699 newPyTmpl->
fSelf = pyobj;
705 new (&newPyTmpl->
fTI) std::shared_ptr<TemplateInfo>{pytmpl->
fTI};
726 return PyInt_FromLong(0);
742 {(
char*)
"__doc__", (getter)
tpp_doc,
nullptr,
nullptr,
nullptr},
744 (
char*)
"unused",
nullptr},
745 {(
char*)
nullptr,
nullptr,
nullptr,
nullptr,
nullptr}
753 const char* sigarg =
nullptr;
759 if (PyArg_ParseTuple(args,
const_cast<char*
>(
"s|i:__overload__"), &sigarg, &want_const)) {
760 want_const = PyTuple_GET_SIZE(args) == 1 ? -1 : want_const;
763 PyObject* ol = pytmpl->
fTI->fNonTemplated->FindOverload(sigarg, want_const);
766 ol = pytmpl->
fTI->fTemplated->FindOverload(sigarg, want_const);
769 ol = pytmpl->
fTI->fLowPriority->FindOverload(sigarg, want_const);
773 }
else if (PyArg_ParseTuple(args,
const_cast<char*
>(
"O|i:__overload__"), &sigarg_tuple, &want_const)) {
775 want_const = PyTuple_GET_SIZE(args) == 1 ? -1 : want_const;
778 PyObject* ol = pytmpl->
fTI->fNonTemplated->FindOverload(sigarg_tuple, want_const);
781 ol = pytmpl->
fTI->fTemplated->FindOverload(sigarg_tuple, want_const);
784 ol = pytmpl->
fTI->fLowPriority->FindOverload(sigarg_tuple, want_const);
788 proto.push_back(
'<');
790 for (
int i = 0; i <
n; i++) {
791 PyObject *pItem = PyTuple_GetItem(sigarg_tuple, i);
793 PyErr_Format(PyExc_LookupError,
"argument types should be in string format");
798 proto.push_back(
',');
800 proto.push_back(
'>');
802 PyErr_Format(PyExc_TypeError,
"Unexpected arguments to __overload__");
807 PyObject* pytype = 0, *pyvalue = 0, *pytrace = 0;
808 PyErr_Fetch(&pytype, &pyvalue, &pytrace);
816 PyErr_Restore(pytype, pyvalue, pytrace);
839 {(
char*)
"__overload__", (PyCFunction)
tpp_overload, METH_VARARGS,
840 (
char*)
"select overload for dispatch" },
841 {(
char*)
nullptr,
nullptr, 0,
nullptr }
847 (
char*)
"cppyy.TemplateProxy",
865 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
866 (
char*)
"cppyy template proxy (internal)",
891#if PY_VERSION_HEX >= 0x02030000
894#if PY_VERSION_HEX >= 0x02060000
897#if PY_VERSION_HEX >= 0x03040000
#define CPyCppyy_PyText_InternFromString
#define CPyCppyy_PyText_Append
#define CPyCppyy_PyText_AsString
#define CPyCppyy_PyText_AppendAndDel
#define CPyCppyy_PyText_FromFormat
#define CPyCppyy_PyText_FromString
#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, PyObject *tmplArgs, 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)
size_t FetchError(std::vector< PyError_t > &)
std::string ConstructTemplateArgs(PyObject *pyname, PyObject *tpArgs, PyObject *args=nullptr, ArgPreference=kNone, int argoff=0, int *pcnt=nullptr)
void SetDetailedException(std::vector< PyError_t > &errors, PyObject *topmsg, PyObject *defexc)
Set of helper functions that are invoked from the pythonizors, on the Python side.
CPPOverload * CPPOverload_New(const std::string &name, std::vector< PyCallable * > &methods)
static PyObject * tpp_richcompare(TemplateProxy *self, PyObject *other, int op)
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_repr(TemplateProxy *pytmpl)
static PyObject * tpp_getuseffi(CPPOverload *, void *)
static TemplateProxy * tpp_descrget(TemplateProxy *pytmpl, PyObject *pyobj, PyObject *)
bool TemplateProxy_CheckExact(T *object)
static void tpp_dealloc(TemplateProxy *pytmpl)
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
uint64_t HashSignature(PyObject *args)
static PyObject * tpp_subscript(TemplateProxy *pytmpl, PyObject *args)
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 Py_hash_t tpp_hash(TemplateProxy *self)
static std::string targs2str(TemplateProxy *pytmpl)
bool TemplateProxy_Check(T *object)
std::shared_ptr< TemplateInfo > TP_TInfo_t
static PyObject * CallMethodImp(TemplateProxy *pytmpl, PyObject *&pymeth, PyObject *args, PyObject *kwds, bool impOK, uint64_t sighash)
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