From 8be363eae3aafcd8f4aa9d12ff673cb959fc4d3c Mon Sep 17 00:00:00 2001 From: "romin.tomasetti" Date: Sat, 22 Jan 2022 15:05:23 +0000 Subject: [PATCH] parser(C++11) : explicit template function support, see https://github.com/swig/swig/issues/2131 --- Examples/test-suite/cpp11_template_explicit.i | 25 +++++++++++++++++++ .../python/cpp11_template_explicit_runme.py | 11 ++++++++ Source/CParse/parser.y | 17 ++++++++++--- 3 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 Examples/test-suite/python/cpp11_template_explicit_runme.py diff --git a/Examples/test-suite/cpp11_template_explicit.i b/Examples/test-suite/cpp11_template_explicit.i index 71752f822..0a76b93d8 100644 --- a/Examples/test-suite/cpp11_template_explicit.i +++ b/Examples/test-suite/cpp11_template_explicit.i @@ -4,6 +4,7 @@ */ %module cpp11_template_explicit +/* Explicitely silence SWIG warning related to explicit templates */ #pragma SWIG nowarn=SWIGWARN_PARSE_EXPLICIT_TEMPLATE %inline %{ @@ -33,6 +34,30 @@ extern template class Temper; template class Temper; extern template class Temper; + +/* Templated function to check support for extern template functions */ +template +T my_templated_function(int a, double b) +{ + return T(); +} + +/* Explicit extern function template instantiation with simple type */ +extern template int my_templated_function(int, double); +template int my_templated_function(int, double); + +/* Explicit extern function template instantiation with more complex types */ +extern template A my_templated_function(int, double); +template A my_templated_function(int, double); + +extern template Temper my_templated_function>(int, double); +template Temper my_templated_function>(int, double); + %} %template(TemperInt) Temper; + +/* Enable several versions of the templated function */ +%template(my_templated_function_int ) my_templated_function; +%template(my_templated_function_A ) my_templated_function; +%template(my_templated_function_TemperInt) my_templated_function>; diff --git a/Examples/test-suite/python/cpp11_template_explicit_runme.py b/Examples/test-suite/python/cpp11_template_explicit_runme.py new file mode 100644 index 000000000..e713ad0d9 --- /dev/null +++ b/Examples/test-suite/python/cpp11_template_explicit_runme.py @@ -0,0 +1,11 @@ +import cpp11_template_explicit + +# Call variants of the same templated function +t1 = cpp11_template_explicit.my_templated_function_int (1,1.0) +t2 = cpp11_template_explicit.my_templated_function_A (2,2.0) +t3 = cpp11_template_explicit.my_templated_function_TemperInt(3,3.0) + +# Check return types +assert isinstance(t1,int) +assert isinstance(t2,cpp11_template_explicit.A) +assert isinstance(t3,cpp11_template_explicit.TemperInt) diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index c48d3a6f2..a21d029e0 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -4361,12 +4361,23 @@ cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN { $$ = 0; } - /* Explicit template instantiation without the translation unit */ + /* Explicit function template instantiation */ + | TEMPLATE cpp_alternate_rettype idcolon LPAREN parms RPAREN { + Swig_warning(WARN_PARSE_EXPLICIT_TEMPLATE, cparse_file, cparse_line, "Explicit function template instantiation ignored.\n"); + $$ = 0; + } + + /* Explicit class template instantiation without the translation unit */ | EXTERN TEMPLATE cpptype idcolon { - Swig_warning(WARN_PARSE_EXPLICIT_TEMPLATE, cparse_file, cparse_line, "Explicit template instantiation ignored.\n"); + Swig_warning(WARN_PARSE_EXPLICIT_TEMPLATE, cparse_file, cparse_line, "Explicit (extern) class template instantiation ignored.\n"); $$ = 0; } - ; + /* Explicit function template instantiation without the translation unit */ + | EXTERN TEMPLATE cpp_alternate_rettype idcolon LPAREN parms RPAREN { + Swig_warning(WARN_PARSE_EXPLICIT_TEMPLATE, cparse_file, cparse_line, "Explicit (extern) function template instantiation ignored.\n"); + $$ = 0; + } + ; cpp_template_possible: c_decl { $$ = $1;