1+ #include " dispatcher.hpp"
2+
3+ namespace c2py {
4+ template <typename Eraser, bool Constructors>
5+ PyObject *dispatcher_t <Eraser, Constructors>::call_impl(PyObject *self, PyObject *args, PyObject *kwargs) const {
6+
7+ for (auto const &ov : ov_list)
8+ if (ov->is_callable (self, args, kwargs)) return ov->operator ()(self, args, kwargs);
9+
10+ // The call has failed. We rerun, but raising the exception in each case, and report
11+ std::stringstream err;
12+ err << " [c2py] Can not call the function with the arguments\n " ;
13+ // if (self) err << " - " << PyUnicode_AsUTF8(pyref{PyObject_Str(self)}) << "\n";
14+ if (args) err << " " << PyUnicode_AsUTF8 (pyref{PyObject_Str (args)}) << " \n " ;
15+ if (kwargs) err << " " << PyUnicode_AsUTF8 (pyref{PyObject_Str (kwargs)}) << " \n " ;
16+ err << " The dispatch to C++ failed with the following error(s):\n " ;
17+ int c = 0 ;
18+ for (auto const &ov : ov_list) {
19+ ++c;
20+ ov->is_callable (self, args, kwargs, true );
21+ err << " [" << c << " ] " << ov->signature () << " \n -- " << c2py::get_python_error () << " \n\n " ;
22+ }
23+ PyErr_SetString (PyExc_TypeError, err.str ().c_str ());
24+ return nullptr ;
25+ }
26+
27+ // overload doc (string) in case only one overload ...
28+ // FIXME : to make generated code simpler in most cases.
29+ template <typename Eraser, bool Constructors>
30+ [[nodiscard]] std::string dispatcher_t <Eraser, Constructors>::doc(std::initializer_list<const char *> const &docs) const {
31+ assert (docs.size () == ov_list.size ()); // by construction for the automated tool
32+ std::stringstream fs;
33+ fs << " Dispatched C++ function\n " ;
34+ // should use itertools ?
35+ // for (auto &&[n, ov] : itertools::enumerate(ov_list)) { fs << "[" << n + 1 << "] " << ov->signature() << "\n"; }
36+ int n = 1 ;
37+ for (auto const &ov : ov_list) fs << " [" << n++ << " ] " << ov->signature () << " \n " ;
38+ fs << " \n " ;
39+ for (auto const &x : docs) { fs << x << " \n " ; }
40+ return fs.str ();
41+ }
42+
43+ template struct dispatcher_t <pycfun_kw, false >;
44+ template struct dispatcher_t <pycfun_kw, true >;
45+ template struct dispatcher_t <pycfun23, false >;
46+ template struct dispatcher_t <pycfun23, true >;
47+
48+ } // namespace c2py
0 commit comments