Add support for friend templates, including operator overloading.
Closes #196.
This commit is contained in:
parent
e044dc4405
commit
428b6176df
10 changed files with 146 additions and 3 deletions
|
|
@ -234,6 +234,7 @@ CPP_TEST_CASES += \
|
|||
features \
|
||||
fragments \
|
||||
friends \
|
||||
friends_template \
|
||||
funcptr_cpp \
|
||||
fvirtual \
|
||||
global_namespace \
|
||||
|
|
|
|||
26
Examples/test-suite/errors/cpp_template_friend.i
Normal file
26
Examples/test-suite/errors/cpp_template_friend.i
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
%module cpp_template_friend
|
||||
|
||||
template<typename T> T template_friend1(T);
|
||||
template<typename T> T template_friend1(T);
|
||||
struct MyTemplate1 {
|
||||
template<typename T> friend T template_friend1(T);
|
||||
};
|
||||
|
||||
template<typename T> T template_friend2(T);
|
||||
struct MyTemplate2 {
|
||||
template<typename T> friend T template_friend2(T);
|
||||
};
|
||||
template<typename T> T template_friend2(T);
|
||||
|
||||
|
||||
int normal_friend1(int);
|
||||
int normal_friend1(int);
|
||||
struct MyClass1 {
|
||||
friend int normal_friend1(int);
|
||||
};
|
||||
|
||||
int normal_friend2(int);
|
||||
struct MyClass2 {
|
||||
friend int normal_friend2(int);
|
||||
};
|
||||
int normal_friend2(int);
|
||||
8
Examples/test-suite/errors/cpp_template_friend.stderr
Normal file
8
Examples/test-suite/errors/cpp_template_friend.stderr
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
cpp_template_friend.i:4: Warning 302: Identifier 'template_friend1' redefined (ignored),
|
||||
cpp_template_friend.i:3: Warning 302: previous definition of 'template_friend1'.
|
||||
cpp_template_friend.i:13: Warning 302: Identifier 'template_friend2' redefined (ignored),
|
||||
cpp_template_friend.i:9: Warning 302: previous definition of 'template_friend2'.
|
||||
cpp_template_friend.i:17: Warning 322: Redundant redeclaration of 'normal_friend1',
|
||||
cpp_template_friend.i:16: Warning 322: previous declaration of 'normal_friend1'.
|
||||
cpp_template_friend.i:26: Warning 322: Redundant redeclaration of 'normal_friend2',
|
||||
cpp_template_friend.i:22: Warning 322: previous declaration of 'normal_friend2'.
|
||||
46
Examples/test-suite/friends_template.i
Normal file
46
Examples/test-suite/friends_template.i
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
%module friends_template
|
||||
|
||||
%{
|
||||
template <typename Type> class MyClass;
|
||||
|
||||
template <typename Type> int operator<<(double un, const MyClass <Type> & x) { return 0; }
|
||||
template <typename Type> int funk_hidden(double is, MyClass <Type> & x) { return 2; }
|
||||
|
||||
template <typename T> T template_friend_hidden(T t) { return t + 1; }
|
||||
%}
|
||||
|
||||
%inline %{
|
||||
template <typename Type> int operator>>(double is, MyClass <Type> & x) { return 1; }
|
||||
template <typename Type> int funk_seen(double is, MyClass <Type> & x) { return 2; }
|
||||
template <typename T> T template_friend_seen(T t1, T t2) { return t1 + t2; }
|
||||
int friend_plain_seen(int i) { return i; }
|
||||
|
||||
template <class Type> class MyClass
|
||||
{
|
||||
friend int operator<< <Type>(double un, const MyClass <Type> & x);
|
||||
friend int operator>> <Type>(double is, MyClass <Type> & x);
|
||||
friend int funk_hidden <Type>(double is, MyClass <Type> & x);
|
||||
friend int funk_seen <Type>(double is, MyClass <Type> & x);
|
||||
};
|
||||
|
||||
struct MyTemplate {
|
||||
template <typename T> friend T template_friend_hidden(T);
|
||||
template <typename T> friend T template_friend_seen(T, T);
|
||||
friend int friend_plain_seen(int i);
|
||||
};
|
||||
|
||||
MyClass<int> makeMyClassInt() { return MyClass<int>(); }
|
||||
%}
|
||||
|
||||
// Although the friends in MyClass are automatically instantiated via %template(MyClassDouble) MyClass<int>,
|
||||
// the operator friends are not valid and hence %rename is needed.
|
||||
%rename(OperatorInputDouble) operator>> <double>;
|
||||
%rename(OperatorOutputDouble) operator<< <double>;
|
||||
%template(MyClassDouble) MyClass<double>;
|
||||
|
||||
%template(TemplateFriendHiddenInt) template_friend_hidden<int>;
|
||||
%template(TemplateFriendSeenInt) template_friend_seen<int>;
|
||||
|
||||
// These have no %template(XX) MyClass<int> to instantiate, but they can be instantiated separately...
|
||||
%template(OperatorInputInt) operator>> <int>;
|
||||
%template(OperatorFunkSeenInt) funk_seen <int>;
|
||||
28
Examples/test-suite/java/friends_template_runme.java
Normal file
28
Examples/test-suite/java/friends_template_runme.java
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
|
||||
import friends_template.*;
|
||||
|
||||
public class friends_template_runme {
|
||||
|
||||
static {
|
||||
try {
|
||||
System.loadLibrary("friends_template");
|
||||
} 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[]) {
|
||||
friends_template.OperatorOutputDouble(1.1, new MyClassDouble());
|
||||
friends_template.OperatorInputDouble(1.1, new MyClassDouble());
|
||||
friends_template.funk_hidden(1.1, new MyClassDouble());
|
||||
friends_template.funk_seen(1.1, new MyClassDouble());
|
||||
|
||||
friends_template.TemplateFriendHiddenInt(0);
|
||||
friends_template.TemplateFriendSeenInt(0, 0);
|
||||
|
||||
SWIGTYPE_p_MyClassT_int_t myClassInt = friends_template.makeMyClassInt();
|
||||
friends_template.OperatorInputInt(1, myClassInt);
|
||||
friends_template.OperatorFunkSeenInt(1.1, myClassInt);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue