template templated static methods support

Fix compilation errors in generated code when instantiating a templated
static method within a template (non-static methods and constructors were
always okay). For example:

  template <typename T> class X {
    template <class InputIterator>
      static void fn(InputIterator first, InputIterator last) { ... }
  };
  class SimpleIterator { ... };

  %extend X<int> {
    %template(fn) fn<SimpleIterator>;
  }

The problem being fixed here is an extended method was generated when it
should not have been as for other %template instantiations within a
template - the template can be called directly.

Test includes variadic static method templates in a template, including
method overloading..
This commit is contained in:
William S Fulton 2024-02-28 22:32:04 +00:00
parent 5eac7bdaa8
commit feaabb0d2a
4 changed files with 72 additions and 6 deletions

View File

@ -7,3 +7,17 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.3.0 (in progress)
===========================
2024-02-28: wsfulton
Fix compilation errors in generated code when instantiating a templated
static method within a template (non-static methods and constructors were
always okay). For example:
template <typename T> class X {
template <class InputIterator>
static void fn(InputIterator first, InputIterator last) { ... }
};
class SimpleIterator { ... };
%extend X<int> {
%template(fn) fn<SimpleIterator>;
}

View File

@ -52,6 +52,18 @@ public:
collection_.push_back(val);
}
// Static templated method in template
template <class InputIterator>
static collection_type container_from_iterators( InputIterator first, InputIterator last)
{
size_type n = static_cast<size_type>(std::distance(first, last));
InputIterator value = first;
std::advance(value, n);
collection_type c;
c.assign(first, value);
return c;
}
// Variadic templated method in template
template<typename ... Args>
void emplace_back( Args&& ... args )
@ -66,10 +78,17 @@ public:
collection_.emplace_back(args ...);
}
ResourceLimitedVector()
// Variadic static templated method in template
template<typename ... Args>
static collection_type make_collection( Args&& ... args )
{
ResourceLimitedVector rlv(std::forward<Args>(args)...);
collection_type ct = rlv.collection_;
return ct;
}
ResourceLimitedVector() = default;
collection_type& getCollection() { return collection_; }
private:
@ -126,6 +145,7 @@ struct SimpleContainer {
%extend eprosima::fastrtps::ResourceLimitedVector<eprosima::fastrtps::rtps::octet> {
%template(assign) assign<SimpleIterator>;
%template(assign_and_append) assign_and_append<SimpleIterator>;
%template(container_from_iterators) container_from_iterators<SimpleIterator>;
// emplace_back template parameters need to match those in the octet constructor
%template(emplace_back) emplace_back<>;
%template(emplace_back) emplace_back<int>;
@ -133,4 +153,8 @@ struct SimpleContainer {
// Variadic templated constructor in template
%template(ResourceLimitedVector) ResourceLimitedVector<int>;
%template(ResourceLimitedVector) ResourceLimitedVector<eprosima::fastrtps::rtps::octet>;
// Variadic static templated method in template
%template(make_collection) make_collection<>;
%template(make_collection) make_collection<int>;
%template(make_collection) make_collection<eprosima::fastrtps::rtps::octet>;
}

View File

@ -47,6 +47,19 @@ public class cpp11_template_templated_methods_runme {
if (oo.getNum() != 333)
throw new RuntimeException("wrong finalval");
}
// container_from_iterators test
{
OctetVector ov = new OctetVector();
octet o = new octet(987);
ov.add(o);
SimpleContainer sc = new SimpleContainer(ov);
OctetVector collection = OctetResourceLimitedVector.container_from_iterators(sc.begin(), sc.end());
if (collection.size() != 1)
throw new RuntimeException("wrong collection size");
octet oo = collection.get(0);
if (oo.getNum() != 987)
throw new RuntimeException("wrong collection val");
}
// emplace_back test
{
OctetVector ov = new OctetVector();
@ -77,5 +90,22 @@ public class cpp11_template_templated_methods_runme {
octet o = new octet(888);
OctetResourceLimitedVector orlv2 = new OctetResourceLimitedVector(o);
}
// Variadic static templated method in template
{
OctetVector collection = OctetResourceLimitedVector.make_collection();
if (collection.size() != 0)
throw new RuntimeException("wrong make value 1111");
collection = OctetResourceLimitedVector.make_collection(1111);
octet oo = collection.get(0);
if (oo.getNum() != 1111)
throw new RuntimeException("wrong make value 1111");
octet o = new octet(2222);
collection = OctetResourceLimitedVector.make_collection(o);
oo = collection.get(0);
if (oo.getNum() != 2222)
throw new RuntimeException("wrong make value 2222");
}
}
}

View File

@ -1328,9 +1328,10 @@ int Language::staticmemberfunctionHandler(Node *n) {
SwigType *type = Getattr(n, "type");
ParmList *parms = Getattr(n, "parms");
String *cb = GetFlagAttr(n, "feature:callback");
String *cname, *mrename;
String *cname;
String *mrename = Swig_name_member(NSpace, ClassPrefix, symname);
if (!Extend) {
if (!(Extend && GetFlag(n, "isextendmember"))) {
Node *sb = Getattr(n, "cplus:staticbase");
String *sname = Getattr(sb, "name");
if (isNonVirtualProtectedAccess(n))
@ -1343,10 +1344,7 @@ int Language::staticmemberfunctionHandler(Node *n) {
cname = Swig_name_member(NSpace, mname, name);
Delete(mname);
Delete(classname_str);
}
mrename = Swig_name_member(NSpace, ClassPrefix, symname);
if (Extend) {
String *code = Getattr(n, "code");
String *defaultargs = Getattr(n, "defaultargs");
String *mangled = Swig_name_mangle_string(mrename);