Skip to content

Commit c6bf645

Browse files
committed
Add handling methods with more template arguments
```cpp CPP2_UFCS_TEMPLATE(FUNCNAME,PARAM1,...) ``` is replaced by ```cpp CPP2_UFCS_TEMPLATE(FUNCNAME,TEMPARGS,PARAM1,...) ``` That means that calling ```cpp obj.fun<int, long, double>(1,2); ``` will be generated to: ```cpp CPP2_UFCS_TEMPLATE(fun, (<int,long, double>), obj, 1, 2); ```
1 parent 7941854 commit c6bf645

File tree

2 files changed

+17
-12
lines changed

2 files changed

+17
-12
lines changed

include/cpp2util.h

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -536,21 +536,23 @@ class out {
536536
} \
537537
}(PARAM1)
538538

539-
#define CPP2_UFCS_TEMPLATE(FUNCNAME,PARAM1,...) \
539+
#define CPP2_UFCS_REMPARENS(...) __VA_ARGS__
540+
541+
#define CPP2_UFCS_TEMPLATE(FUNCNAME,TEMPARGS,PARAM1,...) \
540542
[](auto&& obj, auto&& ...params) { \
541-
if constexpr (requires{ std::forward<decltype(obj)>(obj).template FUNCNAME(std::forward<decltype(params)>(params)...); }) { \
542-
return std::forward<decltype(obj)>(obj).template FUNCNAME(std::forward<decltype(params)>(params)...); \
543+
if constexpr (requires{ std::forward<decltype(obj)>(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (std::forward<decltype(params)>(params)...); }) { \
544+
return std::forward<decltype(obj)>(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (std::forward<decltype(params)>(params)...); \
543545
} else { \
544-
return FUNCNAME(std::forward<decltype(obj)>(obj), std::forward<decltype(params)>(params)...); \
546+
return FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (std::forward<decltype(obj)>(obj), std::forward<decltype(params)>(params)...); \
545547
} \
546548
}(PARAM1, __VA_ARGS__)
547549

548-
#define CPP2_UFCS_TEMPLATE_0(FUNCNAME,PARAM1) \
550+
#define CPP2_UFCS_TEMPLATE_0(FUNCNAME,TEMPARGS,PARAM1) \
549551
[](auto&& obj) { \
550-
if constexpr (requires{ std::forward<decltype(obj)>(obj).template FUNCNAME(); }) { \
551-
return std::forward<decltype(obj)>(obj).template FUNCNAME(); \
552+
if constexpr (requires{ std::forward<decltype(obj)>(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (); }) { \
553+
return std::forward<decltype(obj)>(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (); \
552554
} else { \
553-
return FUNCNAME(std::forward<decltype(obj)>(obj)); \
555+
return FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (std::forward<decltype(obj)>(obj)); \
554556
} \
555557
}(PARAM1)
556558
//--------------------------------------------------------------------

source/cppfront.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1789,10 +1789,7 @@ class cppfront
17891789
}
17901790
// Going backwards if we found Dot and there is args variable
17911791
// it means that it should be handled by UFCS
1792-
else if( i->op->type() == lexeme::Dot && args
1793-
// don't use UFCS for methods with more than one template argument
1794-
&& i->id_expr && i->id_expr->template_args_count() < 2
1795-
)
1792+
else if( i->op->type() == lexeme::Dot && args )
17961793
{
17971794
auto funcname = print_to_string(*i->id_expr);
17981795

@@ -1805,8 +1802,14 @@ class cppfront
18051802
//printer.print_cpp2("CPP2_UFCS(", n.position());
18061803

18071804
auto ufcs_string = std::string("CPP2_UFCS");
1805+
18081806
if (i->id_expr->template_args_count() > 0) {
18091807
ufcs_string += "_TEMPLATE";
1808+
// we need to replace "fun<int,long,double>" to "fun, (<int,long,double>)" to be able to generate
1809+
// from obj.fun<int, long, double>(1,2) this CPP2_UFCS_TEMPLATE(fun, (<int,long, double>), obj, 1, 2)
1810+
auto split = funcname.find('<'); assert(split != std::string::npos);
1811+
funcname.insert(split, ", (");
1812+
funcname += ')';
18101813
}
18111814
// If there are no additional arguments, use the _0 version
18121815
if (args.value().empty()) {

0 commit comments

Comments
 (0)