From 2e0e6ae9860c6b9351e0b170cb57d8e450edeb69 Mon Sep 17 00:00:00 2001 From: Aaron Jomy Date: Fri, 8 Nov 2024 13:21:36 +0100 Subject: [PATCH 1/2] Add longest inheritance path interface --- clingwrapper/src/clingwrapper.cxx | 51 +++++++++++++++++++++++++++++++ clingwrapper/src/cpp_cppyy.h | 2 ++ 2 files changed, 53 insertions(+) diff --git a/clingwrapper/src/clingwrapper.cxx b/clingwrapper/src/clingwrapper.cxx index 4a880c2f..7c6e682a 100644 --- a/clingwrapper/src/clingwrapper.cxx +++ b/clingwrapper/src/clingwrapper.cxx @@ -1211,6 +1211,57 @@ Cppyy::TCppIndex_t Cppyy::GetNumBases(TCppScope_t klass) return Cpp::GetNumBases(klass); } +//////////////////////////////////////////////////////////////////////////////// +/// \fn Cppyy::TCppIndex_t Cppyy::GetNumBasesLongestBranch(TCppScope_t klass) +/// \brief Retrieve number of base classes in the longest branch of the +/// inheritance tree of the input class. +/// \param[in] klass The class to start the retrieval process from. +/// +/// This is a helper function for Cppyy::GetNumBasesLongestBranch. +/// Given an inheritance tree, the function assigns weight 1 to each class that +/// has at least one base. Starting from the input class, the function is +/// called recursively on all the bases. For each base the return value is one +/// (the weight of the base itself) plus the maximum value retrieved for their +/// bases in turn. For example, given the following inheritance tree: +/// +/// ~~~{.cpp} +/// class A {}; class B: public A {}; +/// class X {}; class Y: public X {}; class Z: public Y {}; +/// class C: public B, Z {}; +/// ~~~ +/// +/// calling this function on an instance of `C` will return 3, the steps +/// required to go from C to X. +Cppyy::TCppIndex_t Cppyy::GetNumBasesLongestBranch(TCppScope_t klass) { + std::vector directbases; + for (TCppIndex_t ibase = 0; ibase < GetNumBases(klass); ++ibase) + directbases.push_back(GetScope(GetBaseName(klass, ibase))); + return directbases.size(); +// if (directbases.empty()) { +// // This is a leaf with no bases +// return 0; +// } + +// else { +// // If there is at least one direct base +// std::vector nbases_branches; +// nbases_branches.reserve(ndirectbases); +// // Traverse all direct bases of the current class and call the function +// // recursively +// for (auto baseclass : TRangeDynCast(directbases)) { +// if (!baseclass) +// continue; +// if (auto baseclass_tclass = baseclass->GetClassPointer()) { +// nbases_branches.emplace_back(GetLongestInheritancePath(baseclass_tclass)); +// } +// } +// // Get longest path among the direct bases of the current class +// auto longestbranch = std::max_element(std::begin(nbases_branches), std::end(nbases_branches)); +// // Add 1 to include the current class in the count +// return 1 + *longestbranch; +// } +} + std::string Cppyy::GetBaseName(TCppType_t klass, TCppIndex_t ibase) { return Cpp::GetName(Cpp::GetBaseClass(klass, ibase)); diff --git a/clingwrapper/src/cpp_cppyy.h b/clingwrapper/src/cpp_cppyy.h index 49a96b5c..911e6a63 100644 --- a/clingwrapper/src/cpp_cppyy.h +++ b/clingwrapper/src/cpp_cppyy.h @@ -232,6 +232,8 @@ namespace Cppyy { RPY_EXPORTED TCppIndex_t GetNumBases(TCppScope_t klass); RPY_EXPORTED + TCppIndex_t GetNumBasesLongestBranch(TCppScope_t klass); + RPY_EXPORTED std::string GetBaseName(TCppScope_t klass, TCppIndex_t ibase); RPY_EXPORTED TCppScope_t GetBaseScope(TCppScope_t klass, TCppIndex_t ibase); From 7d044207fba8a51ae606efe39288e519bfa50397 Mon Sep 17 00:00:00 2001 From: Aaron Jomy Date: Fri, 8 Nov 2024 13:22:55 +0100 Subject: [PATCH 2/2] Add ArgMatchScore interface for numba extension --- clingwrapper/src/clingwrapper.cxx | 29 +++++++++++++++++++++++++++++ clingwrapper/src/cpp_cppyy.h | 2 ++ 2 files changed, 31 insertions(+) diff --git a/clingwrapper/src/clingwrapper.cxx b/clingwrapper/src/clingwrapper.cxx index 7c6e682a..893f03dd 100644 --- a/clingwrapper/src/clingwrapper.cxx +++ b/clingwrapper/src/clingwrapper.cxx @@ -1461,6 +1461,35 @@ std::string Cppyy::GetMethodArgDefault(TCppMethod_t method, TCppIndex_t iarg) return Cpp::GetFunctionArgDefault(method, iarg); } +Cppyy::TCppIndex_t Cppyy::CompareMethodArgType(TCppMethod_t method, TCppIndex_t iarg, const std::string &req_type) +{ + // if (method) { + // TFunction* f = m2f(method); + // TMethodArg* arg = (TMethodArg *)f->GetListOfMethodArgs()->At((int)iarg); + // void *argqtp = gInterpreter->TypeInfo_QualTypePtr(arg->GetTypeInfo()); + + // TypeInfo_t *reqti = gInterpreter->TypeInfo_Factory(req_type.c_str()); + // void *reqqtp = gInterpreter->TypeInfo_QualTypePtr(reqti); + + // if (ArgSimilarityScore(argqtp, reqqtp) < 10) { + // return ArgSimilarityScore(argqtp, reqqtp); + // } + // else { // Match using underlying types + // if(gInterpreter->IsPointerType(argqtp)) + // argqtp = gInterpreter->TypeInfo_QualTypePtr(gInterpreter->GetPointerType(argqtp)); + + // // Handles reference types and strips qualifiers + // TypeInfo_t *arg_ul = gInterpreter->GetNonReferenceType(argqtp); + // TypeInfo_t *req_ul = gInterpreter->GetNonReferenceType(reqqtp); + // argqtp = gInterpreter->TypeInfo_QualTypePtr(gInterpreter->GetUnqualifiedType(gInterpreter->TypeInfo_QualTypePtr(arg_ul))); + // reqqtp = gInterpreter->TypeInfo_QualTypePtr(gInterpreter->GetUnqualifiedType(gInterpreter->TypeInfo_QualTypePtr(req_ul))); + + // return ArgSimilarityScore(argqtp, reqqtp); + // } + // } + return 0; // Method is not valid +} + std::string Cppyy::GetMethodSignature(TCppMethod_t method, bool show_formal_args, TCppIndex_t max_args) { std::ostringstream sig; diff --git a/clingwrapper/src/cpp_cppyy.h b/clingwrapper/src/cpp_cppyy.h index 911e6a63..1dad4cac 100644 --- a/clingwrapper/src/cpp_cppyy.h +++ b/clingwrapper/src/cpp_cppyy.h @@ -284,6 +284,8 @@ namespace Cppyy { RPY_EXPORTED TCppType_t GetMethodArgType(TCppMethod_t, TCppIndex_t iarg); RPY_EXPORTED + TCppIndex_t CompareMethodArgType(TCppMethod_t, TCppIndex_t iarg, const std::string &req_type); + RPY_EXPORTED std::string GetMethodArgTypeAsString(TCppMethod_t method, TCppIndex_t iarg); RPY_EXPORTED std::string GetMethodArgCanonTypeAsString(TCppMethod_t method, TCppIndex_t iarg);