diff --git a/Examples/test-suite/cpp11_template_parameters_decltype.i b/Examples/test-suite/cpp11_template_parameters_decltype.i index f61e48960..0d05bb886 100644 --- a/Examples/test-suite/cpp11_template_parameters_decltype.i +++ b/Examples/test-suite/cpp11_template_parameters_decltype.i @@ -1,9 +1,5 @@ %module cpp11_template_parameters_decltype -%include -%include -%include - %inline %{ // Github issue #1589 template @@ -13,33 +9,99 @@ void A() { } // %template(A) A<>; // not working %template(A) A; // workaround + +%include +%include +%include + #pragma SWIG nowarn=SWIGWARN_CPP11_DECLTYPE -// Non-template expression equivalent to template expression further down: -%inline %{ -#include -#include - void f(bool c = std::is_constructible>>().begin()->first)>::value) {} +%{ +// Simple implementation of helper functions required in test below +std::string array(std::vector::const_iterator begin, std::vector::const_iterator end) { + return "not implemented"; +} +std::string object(std::map::const_iterator begin, std::map::const_iterator end) { + return "not implemented"; +} %} %inline %{ +#include + // Github issue #1590 struct Converter { std::string to_json() const { return std::string(); } }; struct Json { - Json(std::string s) {} + int ctor; + Json(std::string s) : ctor(0) {} template < class T, class = decltype(&T::to_json) > - Json(const T & t) : Json(t.to_json()) {} + Json(const T & t) : Json(t.to_json()) { ctor = 1; } // Github issue #1589 // Implicit constructor: map-like objects (std::map, std::unordered_map, etc) template ().begin()->first)>::value, int>::type = 0> - Json(const M & m) : Json(object(m.begin(), m.end())) {} + Json(const M & m) : Json(object(m.begin(), m.end())) { ctor = 2; } + // Implicit constructor: vector-like objects (std::list, std::vector, std::set, etc) + template ().begin())>::value, + int>::type = 0> + Json(const V & v) : Json(array(v.begin(), v.end())) { ctor = 3; } + + // Same sort of thing as constructors above but for a member function + int mmm(std::string s) { return 100; } + template < class T, class = decltype(&T::to_json) > + int mmm(const T & t) { return 101; } + template ().begin()->first)>::value, + int>::type = 0> + int mmm(const M & m) { return 102; } + template ().begin())>::value, + int>::type = 0> + int mmm(const V & v) { return 103; } }; + +void tester(bool show) { + // Example usage from c++ + if (show) { + Json json0(std::string("hi")); + Converter converter; + std::cout << "json0 " << json0.ctor << std::endl; + Json json1 = Json(converter); + std::cout << "json1 " << json1.ctor << std::endl; + std::map myStringStringMap; + Json json2 = Json(myStringStringMap); + std::cout << "json2 " << json2.ctor << std::endl; + std::vector myVectorString; + Json json3 = Json(myVectorString); + std::cout << "json3 " << json3.ctor << std::endl; + + std::cout << "json0.mmm " << json0.mmm("bye") << std::endl; + std::cout << "json1.mmm " << json1.mmm(converter) << std::endl; + std::cout << "json2.mmm " << json2.mmm(myStringStringMap) << std::endl; + std::cout << "json3.mmm " << json3.mmm(myVectorString) << std::endl; + } +} %} +%template(VectorString) std::vector; +%template(MapStringString) std::map; + +// There is quite a bit of inconsistency about providing or not providing default +// template parameters that needs investigating. Below is a combination that works. + +// Note that instantiating the two Json constructors (or the two mmm methods) that +// use enable_if is ambiguous given the enable_if is not evaluated by SWIG. + // %template(Json) Json::Json; // not working %template(Json) Json::Json; // workaround +%template(Json) Json::Json, 0>; +%template(Json) Json::Json, 0>; + +%template(mmm) Json::mmm; +%template(mmm) Json::mmm, 0>; +%template(mmm) Json::mmm, 0>; diff --git a/Examples/test-suite/java/cpp11_template_parameters_decltype_runme.java b/Examples/test-suite/java/cpp11_template_parameters_decltype_runme.java new file mode 100644 index 000000000..dd5fc2d25 --- /dev/null +++ b/Examples/test-suite/java/cpp11_template_parameters_decltype_runme.java @@ -0,0 +1,45 @@ +import cpp11_template_parameters_decltype.*; + +public class cpp11_template_parameters_decltype_runme { + + static { + try { + System.loadLibrary("cpp11_template_parameters_decltype"); + } 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[]) { + boolean show = false; // for debugging + + cpp11_template_parameters_decltype.tester(show); + Json json0 = new Json("hi"); + if (json0.getCtor() != 0) + throw new RuntimeException("json0 failed"); + if (json0.mmm("bye") != 100) + throw new RuntimeException("json0.mmm failed"); + + Converter converter = new Converter(); + Json json1 = new Json(converter); + if (json1.getCtor() != 1) + throw new RuntimeException("json1 failed"); + if (json1.mmm(converter) != 101) + throw new RuntimeException("json1.mmm failed"); + + MapStringString myMapStringString = new MapStringString(); + Json json2 = new Json(myMapStringString); + if (json2.getCtor() != 2) + throw new RuntimeException("json2 failed"); + if (json2.mmm(myMapStringString) != 102) + throw new RuntimeException("json2.mmm failed"); + + VectorString myVectorString = new VectorString(); + Json json3 = new Json(myVectorString); + if (json3.getCtor() != 3) + throw new RuntimeException("json3 failed"); + if (json3.mmm(myVectorString) != 103) + throw new RuntimeException("json3.mmm failed"); + } +} diff --git a/Source/Swig/naming.c b/Source/Swig/naming.c index 4d7d89340..a825a5e89 100644 --- a/Source/Swig/naming.c +++ b/Source/Swig/naming.c @@ -972,8 +972,8 @@ static int nodes_are_equivalent(Node *a, Node *b, int a_inclass) { } } - if (Cmp(ta, "cdecl") == 0) { - /* both cdecl case */ + if (Equal(ta, "cdecl") || Equal(ta, "constructor")) { + /* both cdecl or constructor case */ /* typedef */ String *a_storage = Getattr(a, "storage"); String *b_storage = Getattr(b, "storage");