diff --git a/CHANGES.current b/CHANGES.current index 417bca656..d54db5ba8 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -7,6 +7,15 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/ Version 4.2.0 (in progress) =========================== +2022-12-02: wsfulton + #624 #1021 Improved template template parameters support. Previously, specifying more + than one simple template template parameter resulted in a parse error. Now + multiple template template parameters are working including instantiation with + %template. Example: + + template class, class> class Op, template class X, class Y> + class C { ... }; + 2022-11-29: bero Fix mismatch between #pragma GCC diagnostic push and pop statements diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index cd634081c..3a5e7f678 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -497,6 +497,7 @@ CPP_TEST_CASES += \ template_static \ template_tbase_template \ template_template_parameters \ + template_template_template_parameters \ template_typedef \ template_typedef_class_template \ template_typedef_cplx \ diff --git a/Examples/test-suite/cpp11_type_aliasing.i b/Examples/test-suite/cpp11_type_aliasing.i index ea4048408..8bef71247 100644 --- a/Examples/test-suite/cpp11_type_aliasing.i +++ b/Examples/test-suite/cpp11_type_aliasing.i @@ -112,3 +112,39 @@ using callback_t = int(*)(int); callback_t get_callback() { return mult2; } int call(callback_t funk, int param) { return funk(param); } %} + + +// Template template parameters - from #1021 +%inline %{ +#include + +class Node {}; +struct AnyVal { typedef AnyVal Super; }; + +template class C, typename T, typename Super, typename Root, typename O> + using DeriveToBase = typename std::conditional::value, Root, C >::type; + +template + using ImmediateBase = typename std::conditional::value, Root, RParent >::type; + +template class Expression { + typedef _Super Super; +}; + +void TestInstantiationsPart4() { + Expression express; + DeriveToBase derive_to_base = AnyVal(); +} +%} + +#if 0 +// TODO define and instantiate std::conditional and std::is_same +%template(ExpressionInstantiation) Expression; +%template(AnyTypeInstantiation) DeriveToBase; + +%inline %{ +AnyVal takeAnyVal(DeriveToBase av) { + return av; +} +%} +#endif diff --git a/Examples/test-suite/java/template_template_parameters_runme.java b/Examples/test-suite/java/template_template_parameters_runme.java index 613f9087c..244e12985 100644 --- a/Examples/test-suite/java/template_template_parameters_runme.java +++ b/Examples/test-suite/java/template_template_parameters_runme.java @@ -14,7 +14,7 @@ public class template_template_parameters_runme { } public static void main(String argv[]) { - // Test first part + // Test part 1 ListFastBool listBool = new ListFastBool(); listBool.setItem(true); boolean x_boolean = listBool.getAllotype(); @@ -27,7 +27,7 @@ public class template_template_parameters_runme { if (listDouble.getItem() != 10.2) throw new RuntimeException("Failed"); - // Test second part + // Test part 2 FloatTestStruct floatTestStruct = new FloatTestStruct(); FloatContainer2 floatContainer2 = floatTestStruct.getX(); floatContainer2.setX(8.1f); @@ -41,6 +41,10 @@ public class template_template_parameters_runme { IntTestStruct intTestStructReturned = template_template_parameters.TestStructContainer1Method(intTestStruct); if (intTestStructReturned.getX().getX() != 101) throw new RuntimeException("Failed"); + + // Test part 3 + MyFootInt99 mfi99 = new MyFootInt99(); + mfi99.OperatorPlusEquals(mfi99); } } diff --git a/Examples/test-suite/java/template_template_template_parameters_runme.java b/Examples/test-suite/java/template_template_template_parameters_runme.java new file mode 100644 index 000000000..519a9e068 --- /dev/null +++ b/Examples/test-suite/java/template_template_template_parameters_runme.java @@ -0,0 +1,36 @@ + + +import template_template_template_parameters.*; + +public class template_template_template_parameters_runme { + + static { + try { + System.loadLibrary("template_template_template_parameters"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) { + CustomAttrs custom_attrs = new CustomAttrs(); + AC ac = new AC(); + BAC bac = new BAC(); + CBAC cbac = new CBAC(); + DBAC dbac = new DBAC(); + + custom_attrs = ac.getAttributes(); + custom_attrs = bac.getAttributes(); + custom_attrs = cbac.getAttributes(); + custom_attrs = dbac.getAttributes(); + + bac.BMethod(custom_attrs, ac); + cbac.BMethod(custom_attrs, ac); + dbac.BMethod(custom_attrs, ac); + + cbac.CMethod(custom_attrs, bac); + dbac.DMethod(custom_attrs, bac); + } +} + diff --git a/Examples/test-suite/python/template_template_parameters_runme.py b/Examples/test-suite/python/template_template_parameters_runme.py index 4b0e27d9c..312935970 100644 --- a/Examples/test-suite/python/template_template_parameters_runme.py +++ b/Examples/test-suite/python/template_template_parameters_runme.py @@ -1,6 +1,6 @@ from template_template_parameters import * -# Test first part +# Test part 1 listBool = ListFastBool() listBool.item = True x_boolean = listBool.allotype @@ -13,7 +13,7 @@ x_double = listDouble.allotype if listDouble.item != 10.2: raise RuntimeError("Failed") -# Test second part +# Test part 2 floatTestStruct = FloatTestStruct() floatContainer2 = floatTestStruct.x floatContainer2.x = 8.1 @@ -28,3 +28,6 @@ intTestStructReturned = TestStructContainer1Method(intTestStruct) if intTestStructReturned.x.x != 101: raise RuntimeError("Failed") +# Test part 3 +mfi99 = MyFootInt99() +mfi99 += mfi99 # __iadd__ diff --git a/Examples/test-suite/template_template_parameters.i b/Examples/test-suite/template_template_parameters.i index 53b18b0b0..68c26bebe 100644 --- a/Examples/test-suite/template_template_parameters.i +++ b/Examples/test-suite/template_template_parameters.i @@ -1,9 +1,8 @@ %module template_template_parameters - %inline %{ -/* part 1 */ +// part 1 namespace pfc { template class t_alloc> class array_t {}; @@ -33,7 +32,7 @@ void TestInstantiations() { (void) myListImplInt; } -/* part 2 */ +// part 2 template struct Container1 { @@ -52,10 +51,10 @@ TestStruct TestStructContainer1Method(TestStruct >; %template(ListFastBool) list_tt; @@ -65,9 +64,31 @@ TestStruct TestStructContainer1Method(TestStruct; %template(DoubleAllocFast) pfc::alloc_fast; -/* part 2 */ +// part 2 %template(IntContainer1) Container1; %template(FloatContainer2) Container2; %template(IntTestStruct) TestStruct; %template(FloatTestStruct) TestStruct; + +// part 3 - from #624 + +%rename("") operator+=; // For Ruby and Octave that ignore operator+= + +%inline %{ +template struct Foot { + template