Enhance %extend to extend a class with template methods
This commit is contained in:
parent
c923e3da77
commit
b538070016
7 changed files with 207 additions and 1 deletions
|
|
@ -7,6 +7,19 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
|
|||
Version 3.0.12 (in progress)
|
||||
============================
|
||||
|
||||
2017-01-22: wsfulton
|
||||
Issue #876 Enhance %extend to extend a class with template methods, eg:
|
||||
|
||||
struct Foo {
|
||||
%extend {
|
||||
template<typename T>
|
||||
void do_stuff(int a, T b) {
|
||||
...
|
||||
}
|
||||
}
|
||||
};
|
||||
%template(do_stuff_inst) Foo::do_stuff<double>;
|
||||
|
||||
2017-01-22: kwwette
|
||||
[Octave] add support for version 4.2
|
||||
- The Octave API now uses some C++11 features. It is recommended to use
|
||||
|
|
|
|||
|
|
@ -3635,6 +3635,43 @@ This will generate two overloaded wrapper methods, the first will take a single
|
|||
and the second will take two integer arguments.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
It is even possible to extend a class via <tt>%extend</tt> with template methods, for example:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%include <std_string.i>
|
||||
|
||||
%inline %{
|
||||
class ExtendMe {
|
||||
public:
|
||||
template <typename T>
|
||||
T do_stuff_impl(int a, T b, double d) {
|
||||
return b;
|
||||
}
|
||||
};
|
||||
%}
|
||||
|
||||
%extend ExtendMe {
|
||||
template<typename T>
|
||||
T do_overloaded_stuff(T b) {
|
||||
return $self->do_stuff_impl(0, b, 4.0);
|
||||
}
|
||||
}
|
||||
%template(do_overloaded_stuff) ExtendMe::do_overloaded_stuff<std::string>;
|
||||
%template(do_overloaded_stuff) ExtendMe::do_overloaded_stuff<double>;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The wrapped <tt>ExtendMe</tt> class will then have two (overloaded) methods called <tt>do_overloaded_stuff</tt>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Compatibility Note</b>: Extending a class with template methods was added in version 3.0.12
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Needless to say, SWIG's template support provides plenty of opportunities to
|
||||
break the universe. That said, an important final point is that <b>SWIG does
|
||||
|
|
|
|||
|
|
@ -227,6 +227,7 @@ CPP_TEST_CASES += \
|
|||
extend_placement \
|
||||
extend_special_variables \
|
||||
extend_template \
|
||||
extend_template_method \
|
||||
extend_template_ns \
|
||||
extend_typedef_class \
|
||||
extern_c \
|
||||
|
|
|
|||
62
Examples/test-suite/extend_template_method.i
Normal file
62
Examples/test-suite/extend_template_method.i
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
%module extend_template_method
|
||||
|
||||
%include <std_string.i>
|
||||
|
||||
%inline %{
|
||||
class ExtendMe {
|
||||
public:
|
||||
template <typename T>
|
||||
T do_stuff_impl(int a, T b, double d) {
|
||||
return b;
|
||||
}
|
||||
};
|
||||
%}
|
||||
|
||||
%extend ExtendMe {
|
||||
template<typename T>
|
||||
T do_stuff(int a, T b) {
|
||||
return $self->do_stuff_impl(a, b, 4.0);
|
||||
}
|
||||
template<typename T>
|
||||
T do_overloaded_stuff(T b) {
|
||||
return $self->do_stuff_impl(0, b, 4.0);
|
||||
}
|
||||
}
|
||||
%template(do_stuff_double) ExtendMe::do_stuff<double>;
|
||||
%template(do_stuff_string) ExtendMe::do_stuff<std::string>;
|
||||
|
||||
%template(do_overloaded_stuff) ExtendMe::do_overloaded_stuff<std::string>;
|
||||
%template(do_overloaded_stuff) ExtendMe::do_overloaded_stuff<double>;
|
||||
|
||||
|
||||
%inline %{
|
||||
template<typename X>
|
||||
class TemplateExtendMe {
|
||||
public:
|
||||
template <typename T>
|
||||
T template_stuff_impl(X a, T b, double d) {
|
||||
return b;
|
||||
}
|
||||
};
|
||||
%}
|
||||
|
||||
%extend TemplateExtendMe {
|
||||
template<typename T>
|
||||
T do_template_stuff(int a, T b) {
|
||||
return $self->template_stuff_impl(a, b, 4.0);
|
||||
}
|
||||
template<typename T>
|
||||
T do_template_overloaded_stuff(T b) {
|
||||
return $self->template_stuff_impl(0, b, 4.0);
|
||||
}
|
||||
|
||||
%template(do_template_stuff_double) do_template_stuff<double>;
|
||||
%template(do_template_stuff_string) do_template_stuff<std::string>;
|
||||
|
||||
%template(do_template_overloaded_stuff) do_template_overloaded_stuff<std::string>;
|
||||
%template(do_template_overloaded_stuff) do_template_overloaded_stuff<double>;
|
||||
|
||||
}
|
||||
|
||||
%template(TemplateExtend) TemplateExtendMe<int>;
|
||||
|
||||
57
Examples/test-suite/java/extend_template_method_runme.java
Normal file
57
Examples/test-suite/java/extend_template_method_runme.java
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
|
||||
import extend_template_method.*;
|
||||
|
||||
public class extend_template_method_runme {
|
||||
|
||||
static {
|
||||
try {
|
||||
System.loadLibrary("extend_template_method");
|
||||
} 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[]) {
|
||||
{
|
||||
ExtendMe em = new ExtendMe();
|
||||
|
||||
{
|
||||
double ret_double = em.do_stuff_double(1, 1.1);
|
||||
if (ret_double != 1.1)
|
||||
throw new RuntimeException("double failed " + ret_double);
|
||||
String ret_string = em.do_stuff_string(1, "hello there");
|
||||
if (!ret_string.equals("hello there"))
|
||||
throw new RuntimeException("string failed " + ret_string);
|
||||
}
|
||||
{
|
||||
double ret_double = em.do_overloaded_stuff(1.1);
|
||||
if (ret_double != 1.1)
|
||||
throw new RuntimeException("double failed " + ret_double);
|
||||
String ret_string = em.do_overloaded_stuff("hello there");
|
||||
if (!ret_string.equals("hello there"))
|
||||
throw new RuntimeException("string failed " + ret_string);
|
||||
}
|
||||
}
|
||||
{
|
||||
TemplateExtend em = new TemplateExtend();
|
||||
|
||||
{
|
||||
double ret_double = em.do_template_stuff_double(1, 1.1);
|
||||
if (ret_double != 1.1)
|
||||
throw new RuntimeException("double failed " + ret_double);
|
||||
String ret_string = em.do_template_stuff_string(1, "hello there");
|
||||
if (!ret_string.equals("hello there"))
|
||||
throw new RuntimeException("string failed " + ret_string);
|
||||
}
|
||||
{
|
||||
double ret_double = em.do_template_overloaded_stuff(1.1);
|
||||
if (ret_double != 1.1)
|
||||
throw new RuntimeException("double failed " + ret_double);
|
||||
String ret_string = em.do_template_overloaded_stuff("hello there");
|
||||
if (!ret_string.equals("hello there"))
|
||||
throw new RuntimeException("string failed " + ret_string);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
36
Examples/test-suite/python/extend_template_method_runme.py
Normal file
36
Examples/test-suite/python/extend_template_method_runme.py
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
from extend_template_method import *
|
||||
|
||||
|
||||
em = ExtendMe()
|
||||
|
||||
ret_double = em.do_stuff_double(1, 1.1)
|
||||
if ret_double != 1.1:
|
||||
raise RuntimeError("double failed " + ret_double)
|
||||
ret_string = em.do_stuff_string(1, "hello there")
|
||||
if ret_string != "hello there":
|
||||
raise RuntimeError("string failed " + ret_string)
|
||||
|
||||
ret_double = em.do_overloaded_stuff(1.1)
|
||||
if ret_double != 1.1:
|
||||
raise RuntimeError("double failed " + ret_double)
|
||||
ret_string = em.do_overloaded_stuff("hello there")
|
||||
if ret_string != "hello there":
|
||||
raise RuntimeError("string failed " + ret_string)
|
||||
|
||||
|
||||
em = TemplateExtend()
|
||||
|
||||
ret_double = em.do_template_stuff_double(1, 1.1)
|
||||
if ret_double != 1.1:
|
||||
raise RuntimeError("double failed " + ret_double)
|
||||
ret_string = em.do_template_stuff_string(1, "hello there")
|
||||
if ret_string != "hello there":
|
||||
raise RuntimeError("string failed " + ret_string)
|
||||
|
||||
|
||||
ret_double = em.do_template_overloaded_stuff(1.1)
|
||||
if ret_double != 1.1:
|
||||
raise RuntimeError("double failed " + ret_double)
|
||||
ret_string = em.do_template_overloaded_stuff("hello there")
|
||||
if ret_string != "hello there":
|
||||
raise RuntimeError("string failed " + ret_string)
|
||||
|
|
@ -1267,7 +1267,7 @@ int Language::memberfunctionHandler(Node *n) {
|
|||
if (GetFlag(n, "explicitcall"))
|
||||
DirectorExtraCall = CWRAP_DIRECTOR_ONE_CALL;
|
||||
|
||||
Swig_MethodToFunction(n, NSpace, ClassType, Getattr(n, "template") ? SmartPointer : Extend | SmartPointer | DirectorExtraCall, director_type,
|
||||
Swig_MethodToFunction(n, NSpace, ClassType, Getattr(n, "template") ? Extend | SmartPointer : Extend | SmartPointer | DirectorExtraCall, director_type,
|
||||
is_member_director(CurrentClass, n));
|
||||
Setattr(n, "sym:name", fname);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue