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);
333 Py_CLEAR(pytmpl->
fSelf);
344 PyObject_ClearWeakRefs((
PyObject*)pytmpl);
345 PyObject_GC_UnTrack(pytmpl);
347 pytmpl->
fTI.~TP_TInfo_t();
348 PyObject_GC_Del(pytmpl);
355 Py_VISIT(pytmpl->
fSelf);
366 if (pytmpl->
fTI->fNonTemplated->HasMethods())
367 doc = PyObject_GetAttrString((
PyObject*)pytmpl->
fTI->fNonTemplated,
"__doc__");
368 if (pytmpl->
fTI->fTemplated->HasMethods()) {
373 }
else if (!doc && doc2) {
377 if (pytmpl->
fTI->fLowPriority->HasMethods()) {
382 }
else if (!doc && doc2) {
398 return tpp_doc(pytmpl,
nullptr);
413 bool bInserted =
false;
414 auto&
v = pytmpl->
fTI->fDispatchMap[use_targs ?
targs2str(pytmpl) :
""];
418 if (p.first == sighash) {
424 if (!bInserted)
v.push_back(std::make_pair(sighash, pymeth));
435 if (isNS && pytmpl->
fSelf) {
438 PyObject* newArgs = PyTuple_New(sz+1);
439 for (
int i = 0; i < sz; ++i) {
440 PyObject* item = PyTuple_GET_ITEM(args, i);
442 PyTuple_SET_ITEM(newArgs, i+1, item);
456 Py_DECREF(pymeth); pymeth =
nullptr;
460#define TPPCALL_RETURN \
461{ if (!errors.empty()) \
462 std::for_each(errors.begin(), errors.end(), Utility::PyError_t::Clear);\
497 std::vector<Utility::PyError_t> errors;
499 PyObject* pymeth =
nullptr, *result =
nullptr;
508 for (
const auto& p :
v) {
509 if (p.first == sighash) {
516 if (!pytmpl->
fSelf) {
522 Py_DECREF(pymeth); pymeth =
nullptr;
531 if (!kwds) kwds = PyDict_New();
545 pymeth = PyObject_GetAttr((pytmpl->
fSelf && !isNS) ? pytmpl->
fSelf : pytmpl->
fTI->fPyClass, pyfullname);
550 result =
CallMethodImp(pytmpl, pymeth, args, kwds,
true, sighash);
552 Py_DECREF(pyfullname);
556 }
else if (pymeth && PyCallable_Check(pymeth)) {
558 result = PyObject_CallObject(pymeth, args);
561 Py_DECREF(pyfullname);
573 result =
CallMethodImp(pytmpl, pymeth, args, kwds,
true, sighash);
575 Py_DECREF(pyfullname);
583 Py_DECREF(pyfullname);
591 if (pytmpl->
fTI->fNonTemplated->HasMethods()) {
599 Py_DECREF(pymeth); pymeth =
nullptr;
608 if (pytmpl->
fTI->fTemplated->HasMethods()) {
615 Py_DECREF(pymeth); pymeth =
nullptr;
632 result =
CallMethodImp(pytmpl, pymeth, args, kwds,
false, sighash);
640 if (pytmpl->
fTI->fLowPriority->HasMethods()) {
647 Py_DECREF(pymeth); pymeth =
nullptr;
656 if (!errors.empty()) {
660 PyErr_Format(PyExc_TypeError,
"cannot resolve method template call for \'%s\'",
676 newPyTmpl->
fSelf = pyobj;
682 new (&newPyTmpl->
fTI) std::shared_ptr<TemplateInfo>{pytmpl->
fTI};
719 {(
char*)
"__doc__", (getter)
tpp_doc,
nullptr,
nullptr,
nullptr},
721 (
char*)
"unused",
nullptr},
722 {(
char*)
nullptr,
nullptr,
nullptr,
nullptr,
nullptr}
729 (
char*)
"cppyy.TemplateProxy",
747 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
748 (
char*)
"cppyy template proxy (internal)",
773#if PY_VERSION_HEX >= 0x02030000
776#if PY_VERSION_HEX >= 0x02060000
779#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)
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_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 *)
static void tpp_dealloc(TemplateProxy *pytmpl)
static int tpp_traverse(TemplateProxy *pytmpl, visitproc visit, void *arg)
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 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 bool IsConstructor(TCppMethod_t method)
RPY_EXPORTED TCppMethod_t GetMethodTemplate(TCppScope_t scope, const std::string &name, const std::string &proto)
RPY_EXPORTED bool IsStaticMethod(TCppMethod_t method)
RPY_EXPORTED std::string GetMethodFullName(TCppMethod_t)
RPY_EXPORTED bool IsNamespace(TCppScope_t scope)
CPPOverload::Methods_t fMethods