28
28
#include < string.h>
29
29
#include < typeinfo>
30
30
#include < iostream>
31
+ #include < vector>
31
32
32
33
33
34
// temp
@@ -163,6 +164,15 @@ void push_tokens_from_string(char *s, std::vector <const char*> &tokens) {
163
164
}
164
165
}
165
166
167
+ static inline
168
+ bool is_integral (std::string& s)
169
+ {
170
+ if (s == " false" ) { s = " 0" ; return true ; }
171
+ else if (s == " true" ) { s = " 1" ; return true ; }
172
+ return !s.empty () && std::find_if (s.begin (),
173
+ s.end (), [](unsigned char c) { return !std::isdigit (c); }) == s.end ();
174
+ }
175
+
166
176
class ApplicationStarter {
167
177
Cpp::TInterp_t Interp;
168
178
public:
@@ -473,19 +483,66 @@ bool Cppyy::IsFunctionPointerType(TCppType_t type) {
473
483
return Cpp::IsFunctionPointerType (type);
474
484
}
475
485
486
+ std::string trim (const std::string& line)
487
+ {
488
+ if (line.empty ()) return " " ;
489
+ const char * WhiteSpace = " \t\v\r\n " ;
490
+ std::size_t start = line.find_first_not_of (WhiteSpace);
491
+ std::size_t end = line.find_last_not_of (WhiteSpace);
492
+ return line.substr (start, end - start + 1 );
493
+ }
494
+
495
+ // returns false of angular brackets dont match, else true
496
+ bool split_comma_saparated_types (const std::string& name,
497
+ std::vector<std::string>& types) {
498
+ std::string trimed_name = trim (name);
499
+ size_t start_pos = 0 ;
500
+ size_t end_pos = 0 ;
501
+ size_t appended_count = 0 ;
502
+ int matching_angular_brackets = 0 ;
503
+ while (end_pos < trimed_name.size ()) {
504
+ switch (trimed_name[end_pos]) {
505
+ case ' ,' : {
506
+ if (!matching_angular_brackets) {
507
+ types.push_back (
508
+ trim (trimed_name.substr (start_pos, end_pos - start_pos)));
509
+ start_pos = end_pos + 1 ;
510
+ }
511
+ break ;
512
+ }
513
+ case ' <' : {
514
+ matching_angular_brackets++;
515
+ break ;
516
+ }
517
+ case ' >' : {
518
+ if (matching_angular_brackets == 1 ) {
519
+ types.push_back (
520
+ trim (trimed_name.substr (start_pos, end_pos - start_pos + 1 )));
521
+ start_pos = end_pos + 1 ;
522
+ } else if (matching_angular_brackets < 1 ) {
523
+ types.clear ();
524
+ return false ;
525
+ }
526
+ matching_angular_brackets--;
527
+ break ;
528
+ }
529
+ }
530
+ end_pos++;
531
+ }
532
+ if (start_pos < trimed_name.size ())
533
+ types.push_back (trim (trimed_name.substr (start_pos, end_pos - start_pos)));
534
+ return true ;
535
+ }
536
+
476
537
// returns true if no new type was added.
477
- bool Cppyy::AppendTypesSlow (const std::string & name,
538
+ bool Cppyy::AppendTypesSlow (const std::string& name,
478
539
std::vector<Cpp::TemplateArgInfo>& types) {
479
540
480
541
// Add no new type if string is empty
481
- if (name.empty ()) return true ;
542
+ if (name.empty ())
543
+ return true ;
482
544
483
- // Try going via Cppyy::GetType first.
484
- if (Cppyy::TCppType_t type = GetType (name, /* enable_slow_lookup=*/ true )) {
485
- types.push_back (type);
486
- return false ;
487
- }
488
- // Else, we might have an entire expression such as int, double.
545
+ // We might have an entire expression such as int, double.
489
546
static unsigned long long struct_count = 0 ;
490
547
std::string code = " template<typename ...T> struct __Cppyy_AppendTypesSlow {};\n " ;
491
548
if (!struct_count)
@@ -500,7 +557,29 @@ bool Cppyy::AppendTypesSlow(const std::string &name,
500
557
Cpp::GetClassTemplateInstantiationArgs (instance_class, types);
501
558
return oldSize == types.size ();
502
559
}
503
- return true ;
560
+
561
+ // We split each individual types based on , and resolve it
562
+ // FIXME: see discussion on should we support template instantiation with string:
563
+ // https://github.com/compiler-research/cppyy-backend/pull/137#discussion_r2079357491
564
+ // We should consider eliminating the `split_comma_saparated_types` and `is_integral`
565
+ // string parsing.
566
+ std::vector<std::string> individual_types;
567
+ if (!split_comma_saparated_types (name, individual_types))
568
+ return true ;
569
+
570
+ for (std::string& i : individual_types) {
571
+ // Try going via Cppyy::GetType first.
572
+ if (Cppyy::TCppType_t type = GetType (i, /* enable_slow_lookup=*/ true )) {
573
+ const char * integral_value = nullptr ;
574
+ if (is_integral (i))
575
+ integral_value = strdup (i.c_str ());
576
+ types.emplace_back (type, integral_value);
577
+ } else {
578
+ types.clear ();
579
+ return true ;
580
+ }
581
+ }
582
+ return false ;
504
583
}
505
584
506
585
Cppyy::TCppType_t Cppyy::GetType (const std::string &name, bool enable_slow_lookup /* = false */ ) {
0 commit comments