@@ -462,6 +462,10 @@ bool Cppyy::IsClassType(TCppType_t type) {
462
462
// returns true if no new type was added.
463
463
bool Cppyy::AppendTypesSlow (const std::string &name,
464
464
std::vector<Cpp::TemplateArgInfo>& types) {
465
+
466
+ // Add no new type if string is empty
467
+ if (name.empty ()) return true ;
468
+
465
469
// Try going via Cppyy::GetType first.
466
470
if (Cppyy::TCppType_t type = GetType (name, /* enable_slow_lookup=*/ true )) {
467
471
types.push_back (type);
@@ -1308,9 +1312,9 @@ ptrdiff_t Cppyy::GetBaseOffset(TCppScope_t derived, TCppScope_t base,
1308
1312
// return (TCppIndex_t)0; // unknown class?
1309
1313
// }
1310
1314
1311
- std::vector<Cppyy::TCppMethod_t> Cppyy::GetClassMethods (TCppScope_t scope )
1315
+ void Cppyy::GetClassMethods (TCppScope_t scope, std::vector<Cppyy::TCppMethod_t> &methods )
1312
1316
{
1313
- return Cpp::GetClassMethods (scope);
1317
+ Cpp::GetClassMethods (scope, methods );
1314
1318
}
1315
1319
1316
1320
std::vector<Cppyy::TCppScope_t> Cppyy::GetMethodsFromName (
@@ -1400,7 +1404,8 @@ std::string Cppyy::GetMethodArgDefault(TCppMethod_t method, TCppIndex_t iarg)
1400
1404
1401
1405
std::string Cppyy::GetMethodSignature (TCppMethod_t method, bool show_formal_args, TCppIndex_t max_args)
1402
1406
{
1403
- return Cpp::GetFunctionSignature (method);
1407
+ // FIXME : Doesn't work for template functions as it does in cling
1408
+ return Cpp::GetFunctionSignature (method);
1404
1409
}
1405
1410
1406
1411
std::string Cppyy::GetMethodPrototype (TCppMethod_t method, bool show_formal_args)
@@ -1416,40 +1421,23 @@ bool Cppyy::IsConstMethod(TCppMethod_t method)
1416
1421
return Cpp::IsConstMethod (method);
1417
1422
}
1418
1423
1419
- // Cppyy::TCppIndex_t Cppyy::GetNumTemplatedMethods(TCppScope_t scope, bool accept_namespace)
1420
- // {
1421
- // if (!accept_namespace && IsNamespace(scope))
1422
- // return (TCppIndex_t)0; // enforce lazy
1423
- //
1424
- // if (scope == GLOBAL_HANDLE) {
1425
- // TCollection* coll = gROOT->GetListOfFunctionTemplates();
1426
- // if (coll) return (TCppIndex_t)coll->GetSize();
1427
- // } else {
1428
- // TClassRef& cr = type_from_handle(scope);
1429
- // if (cr.GetClass()) {
1430
- // TCollection* coll = cr->GetListOfFunctionTemplates(true);
1431
- // if (coll) return (TCppIndex_t)coll->GetSize();
1432
- // }
1433
- // }
1434
- //
1435
- // // failure ...
1436
- // return (TCppIndex_t)0;
1437
- // }
1438
- //
1439
- // std::string Cppyy::GetTemplatedMethodName(TCppScope_t scope, TCppIndex_t imeth)
1440
- // {
1441
- // if (scope == (TCppScope_t)GLOBAL_HANDLE)
1442
- // return ((THashList*)gROOT->GetListOfFunctionTemplates())->At((int)imeth)->GetName();
1443
- // else {
1444
- // TClassRef& cr = type_from_handle(scope);
1445
- // if (cr.GetClass())
1446
- // return cr->GetListOfFunctionTemplates(false)->At((int)imeth)->GetName();
1447
- // }
1448
- //
1449
- // // failure ...
1450
- // assert(!"should not be called unless GetNumTemplatedMethods() succeeded");
1451
- // return "";
1452
- // }
1424
+ Cppyy::TCppIndex_t Cppyy::GetNumTemplatedMethods (TCppScope_t scope, bool accept_namespace)
1425
+ {
1426
+ std::vector<Cppyy::TCppMethod_t> mc;
1427
+ Cpp::GetFunctionTemplatedDecls (scope, mc);
1428
+ return mc.size ();
1429
+ }
1430
+
1431
+ std::string Cppyy::GetTemplatedMethodName (TCppScope_t scope, TCppIndex_t imeth)
1432
+ {
1433
+ std::vector<Cppyy::TCppMethod_t> mc;
1434
+ Cpp::GetFunctionTemplatedDecls (scope, mc);
1435
+
1436
+ if (imeth < mc.size ()) return GetMethodName (mc[imeth]);
1437
+
1438
+ return " " ;
1439
+ }
1440
+
1453
1441
//
1454
1442
// bool Cppyy::IsTemplatedConstructor(TCppScope_t scope, TCppIndex_t imeth)
1455
1443
// {
@@ -1495,85 +1483,40 @@ bool Cppyy::IsTemplatedMethod(TCppMethod_t method)
1495
1483
Cppyy::TCppMethod_t Cppyy::GetMethodTemplate (
1496
1484
TCppScope_t scope, const std::string& name, const std::string& proto)
1497
1485
{
1498
- #ifdef PRINT_DEBUG
1499
- printf (" ========== GMT: %s; %s\n " , name.c_str (), proto.c_str ());
1500
- #endif
1501
- // // There is currently no clean way of extracting a templated method out of ROOT/meta
1502
- // // for a variety of reasons, none of them fundamental. The game played below is to
1503
- // // first get any pre-existing functions already managed by ROOT/meta, but if that fails,
1504
- // // to do an explicit lookup that ignores the prototype (i.e. the full name should be
1505
- // // enough), and finally to ignore the template arguments part of the name as this fails
1506
- // // in cling if there are default parameters.
1507
- // TFunction* func = nullptr; ClassInfo_t* cl = nullptr;
1508
- // if (scope == (cppyy_scope_t)GLOBAL_HANDLE) {
1509
- // func = gROOT->GetGlobalFunctionWithPrototype(name.c_str(), proto.c_str());
1510
- // if (func && name.back() == '>') {
1511
- // // make sure that all template parameters match (more are okay, e.g. defaults or
1512
- // // ones derived from the arguments or variadic templates)
1513
- // if (!template_compare(name, func->GetName()))
1514
- // func = nullptr; // happens if implicit conversion matches the overload
1515
- // }
1516
- // } else {
1517
- // TClassRef& cr = type_from_handle(scope);
1518
- // if (cr.GetClass()) {
1519
- // func = cr->GetMethodWithPrototype(name.c_str(), proto.c_str());
1520
- // if (!func) {
1521
- // cl = cr->GetClassInfo();
1522
- // // try base classes to cover a common 'using' case (TODO: this is stupid and misses
1523
- // // out on base classes; fix that with improved access to Cling)
1524
- // TCppIndex_t nbases = GetNumBases(scope);
1525
- // for (TCppIndex_t i = 0; i < nbases; ++i) {
1526
- // TClassRef& base = type_from_handle(GetScope(GetBaseName(scope, i)));
1527
- // if (base.GetClass()) {
1528
- // func = base->GetMethodWithPrototype(name.c_str(), proto.c_str());
1529
- // if (func) break;
1530
- // }
1531
- // }
1532
- // }
1533
- // }
1534
- // }
1535
- //
1536
- // if (!func && name.back() == '>' && (cl || scope == (cppyy_scope_t)GLOBAL_HANDLE)) {
1537
- // // try again, ignoring proto in case full name is complete template
1538
- // auto declid = gInterpreter->GetFunction(cl, name.c_str());
1539
- // if (declid) {
1540
- // auto existing = gMethodTemplates.find(declid);
1541
- // if (existing == gMethodTemplates.end()) {
1542
- // auto cw = new_CallWrapper(declid, name);
1543
- // existing = gMethodTemplates.insert(std::make_pair(declid, cw)).first;
1544
- // }
1545
- // return (TCppMethod_t)existing->second;
1546
- // }
1547
- // }
1548
- //
1549
- // if (func) {
1550
- // // make sure we didn't match a non-templated overload
1551
- // if (func->ExtraProperty() & kIsTemplateSpec)
1552
- // return (TCppMethod_t)new_CallWrapper(func);
1553
- //
1554
- // // disregard this non-templated method as it will be considered when appropriate
1555
- // return (TCppMethod_t)nullptr;
1556
- // }
1557
- //
1558
- // // try again with template arguments removed from name, if applicable
1559
- // if (name.back() == '>') {
1560
- // auto pos = name.find('<');
1561
- // if (pos != std::string::npos) {
1562
- // TCppMethod_t cppmeth = GetMethodTemplate(scope, name.substr(0, pos), proto);
1563
- // if (cppmeth) {
1564
- // // allow if requested template names match up to the result
1565
- // const std::string& alt = GetMethodFullName(cppmeth);
1566
- // if (name.size() < alt.size() && alt.find('<') == pos) {
1567
- // if (template_compare(name, alt))
1568
- // return cppmeth;
1569
- // }
1570
- // }
1571
- // }
1572
- // }
1486
+ std::string pureName;
1487
+ std::string explicit_params;
1488
+
1489
+ if (name.find (' <' ) != std::string::npos) {
1490
+ pureName = name.substr (0 , name.find (' <' ));
1491
+ size_t start = name.find (' <' );
1492
+ size_t end = name.find (' >' );
1493
+ explicit_params = name.substr (start + 1 , end - start - 1 );
1494
+ }
1495
+
1496
+ else pureName = name;
1497
+
1498
+ std::vector<Cppyy::TCppMethod_t> unresolved_candidate_methods;
1499
+ Cpp::GetClassTemplatedMethods (pureName, scope,
1500
+ unresolved_candidate_methods);
1501
+
1502
+ // CPyCppyy assumes that we attempt instantiation here
1503
+ std::vector<Cpp::TemplateArgInfo> arg_types;
1504
+ std::vector<Cpp::TemplateArgInfo> templ_params;
1505
+ Cppyy::AppendTypesSlow (proto, arg_types);
1506
+ Cppyy::AppendTypesSlow (explicit_params, templ_params);
1507
+
1508
+ Cppyy::TCppMethod_t cppmeth = Cpp::BestTemplateFunctionMatch (unresolved_candidate_methods, templ_params, arg_types);
1509
+
1510
+ if (!cppmeth){
1511
+ return nullptr ;
1512
+ }
1513
+
1514
+ return cppmeth;
1515
+
1516
+ // if it fails, use Sema to propogate info about why it failed (DeductionInfo)
1573
1517
1574
- // failure ...
1575
- return (TCppMethod_t)nullptr ;
1576
1518
}
1519
+
1577
1520
//
1578
1521
// static inline
1579
1522
// std::string type_remap(const std::string& n1, const std::string& n2)
0 commit comments