Merge branch 'templates-scope-enforcement'
* templates-scope-enforcement: Test a few %template errors Add using declarations to templates into typedef table. Fix type lookup in the presence of using directives and using declarations More docs on %template Testcase fix for nameclash in php %template scope enforcement and class definition fixes Template documentation tweaks More consistent formatting of examples in documentation More consistent formatting of examples in documentation Documentation corrections to use targetlang formatting More consistent formatting of examples in documentation More consistent formatting of examples in documentation More consistent formatting of examples in documentation Namespace documentation minor corrections Improve description of template_parameters_resolve Minor code optimisation in template_parameters_resolve Fix scope lookup for template parameters containing unary scope operators Typemap change for templates
This commit is contained in:
commit
32a454cfef
51 changed files with 1924 additions and 700 deletions
|
|
@ -677,7 +677,7 @@ As a result, we get the following method in the module class:
|
|||
<div class="code">
|
||||
<pre>
|
||||
public static void myArrayCopy(int[] sourceArray, int[] targetArray, int nitems) {
|
||||
examplePINVOKE.myArrayCopy(sourceArray, targetArray, nitems);
|
||||
examplePINVOKE.myArrayCopy(sourceArray, targetArray, nitems);
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -997,9 +997,9 @@ When the following C# code is executed:
|
|||
<div class="code">
|
||||
<pre>
|
||||
public class runme {
|
||||
static void Main() {
|
||||
example.positivesonly(-1);
|
||||
}
|
||||
static void Main() {
|
||||
example.positivesonly(-1);
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1846,12 +1846,12 @@ and the following usage from C# after running the code through SWIG:
|
|||
|
||||
<div class="code">
|
||||
<pre>
|
||||
Wheel wheel = new Bike(10).getWheel();
|
||||
Console.WriteLine("wheel size: " + wheel.size);
|
||||
// Simulate a garbage collection
|
||||
global::System.GC.Collect();
|
||||
global::System.GC.WaitForPendingFinalizers();
|
||||
global::System.Console.WriteLine("wheel size: " + wheel.size);
|
||||
Wheel wheel = new Bike(10).getWheel();
|
||||
Console.WriteLine("wheel size: " + wheel.size);
|
||||
// Simulate a garbage collection
|
||||
global::System.GC.Collect();
|
||||
global::System.GC.WaitForPendingFinalizers();
|
||||
global::System.Console.WriteLine("wheel size: " + wheel.size);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -1980,9 +1980,9 @@ and more or less equivalent usage from C#
|
|||
|
||||
<div class="code">
|
||||
<pre>
|
||||
Container container = new Container();
|
||||
Element element = new Element(20);
|
||||
container.setElement(element);
|
||||
Container container = new Container();
|
||||
Element element = new Element(20);
|
||||
container.setElement(element);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -1993,14 +1993,14 @@ In order to understand why, consider a garbage collection occuring...
|
|||
|
||||
<div class="code">
|
||||
<pre>
|
||||
Container container = new Container();
|
||||
Element element = new Element(20);
|
||||
container.setElement(element);
|
||||
Console.WriteLine("element.value: " + container.getElement().value);
|
||||
// Simulate a garbage collection
|
||||
global::System.GC.Collect();
|
||||
global::System.GC.WaitForPendingFinalizers();
|
||||
global::System.Console.WriteLine("element.value: " + container.getElement().value);
|
||||
Container container = new Container();
|
||||
Element element = new Element(20);
|
||||
container.setElement(element);
|
||||
Console.WriteLine("element.value: " + container.getElement().value);
|
||||
// Simulate a garbage collection
|
||||
global::System.GC.Collect();
|
||||
global::System.GC.WaitForPendingFinalizers();
|
||||
global::System.Console.WriteLine("element.value: " + container.getElement().value);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -246,6 +246,16 @@
|
|||
<li><a href="SWIGPlus.html#SWIGPlus_nn28">Wrapping overloaded operators</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_class_extension">Class extension</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_nn30">Templates</a>
|
||||
<ul>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_template_directive">The %template directive</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_template_functions">Function templates</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_template_classes">Default template arguments</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_template_class_inheritance">Template base classes</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_template_specialization">Template specialization</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_template_member">Member templates</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_template_scoping">Scoping and templates</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_template_more">More on templates</a>
|
||||
</ul>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_namespaces">Namespaces</a>
|
||||
<ul>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_nspace">The nspace feature for namespaces</a>
|
||||
|
|
|
|||
|
|
@ -516,7 +516,7 @@ The special variables are often used in situations where method calls are logged
|
|||
$action
|
||||
}
|
||||
catch (MemoryError) {
|
||||
croak("Out of memory in $decl");
|
||||
croak("Out of memory in $decl");
|
||||
}
|
||||
}
|
||||
void log(const char *message);
|
||||
|
|
|
|||
|
|
@ -2592,36 +2592,36 @@ command line options, simply use code similar to this:
|
|||
<pre>
|
||||
void Language::main(int argc, char *argv[]) {
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (argv[i]) {
|
||||
if (strcmp(argv[i], "-interface") == 0) {
|
||||
if (argv[i+1]) {
|
||||
interface = NewString(argv[i+1]);
|
||||
Swig_mark_arg(i);
|
||||
Swig_mark_arg(i+1);
|
||||
i++;
|
||||
} else {
|
||||
Swig_arg_error();
|
||||
}
|
||||
} else if (strcmp(argv[i], "-globals") == 0) {
|
||||
if (argv[i+1]) {
|
||||
global_name = NewString(argv[i+1]);
|
||||
Swig_mark_arg(i);
|
||||
Swig_mark_arg(i+1);
|
||||
i++;
|
||||
} else {
|
||||
Swig_arg_error();
|
||||
}
|
||||
} else if ((strcmp(argv[i], "-proxy") == 0)) {
|
||||
proxy_flag = 1;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-keyword") == 0) {
|
||||
use_kw = 1;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-help") == 0) {
|
||||
fputs(usage, stderr);
|
||||
}
|
||||
...
|
||||
if (argv[i]) {
|
||||
if (strcmp(argv[i], "-interface") == 0) {
|
||||
if (argv[i+1]) {
|
||||
interface = NewString(argv[i+1]);
|
||||
Swig_mark_arg(i);
|
||||
Swig_mark_arg(i+1);
|
||||
i++;
|
||||
} else {
|
||||
Swig_arg_error();
|
||||
}
|
||||
} else if (strcmp(argv[i], "-globals") == 0) {
|
||||
if (argv[i+1]) {
|
||||
global_name = NewString(argv[i+1]);
|
||||
Swig_mark_arg(i);
|
||||
Swig_mark_arg(i+1);
|
||||
i++;
|
||||
} else {
|
||||
Swig_arg_error();
|
||||
}
|
||||
} else if ((strcmp(argv[i], "-proxy") == 0)) {
|
||||
proxy_flag = 1;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-keyword") == 0) {
|
||||
use_kw = 1;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-help") == 0) {
|
||||
fputs(usage, stderr);
|
||||
}
|
||||
...
|
||||
}
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
|
|
|||
|
|
@ -639,12 +639,12 @@ public:
|
|||
virtual ~FooBarAbstract() {};
|
||||
|
||||
std::string FooBar() {
|
||||
return this->Foo() + ", " + this->Bar();
|
||||
return this->Foo() + ", " + this->Bar();
|
||||
};
|
||||
|
||||
protected:
|
||||
virtual std::string Foo() {
|
||||
return "Foo";
|
||||
return "Foo";
|
||||
};
|
||||
|
||||
virtual std::string Bar() = 0;
|
||||
|
|
|
|||
|
|
@ -3935,9 +3935,9 @@ where <tt>Swig::DirectorException::raise</tt> is a helper method in the Director
|
|||
|
||||
<div class="code">
|
||||
<pre>
|
||||
static void raise(JNIEnv *jenv, jthrowable throwable) {
|
||||
throw DirectorException(jenv, throwable);
|
||||
}
|
||||
static void raise(JNIEnv *jenv, jthrowable throwable) {
|
||||
throw DirectorException(jenv, throwable);
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -4335,16 +4335,16 @@ struct Vector {
|
|||
|
||||
%extend Vector {
|
||||
char *toString() {
|
||||
static char tmp[1024];
|
||||
sprintf(tmp, "Vector(%g, %g, %g)", $self->x, $self->y, $self->z);
|
||||
return tmp;
|
||||
static char tmp[1024];
|
||||
sprintf(tmp, "Vector(%g, %g, %g)", $self->x, $self->y, $self->z);
|
||||
return tmp;
|
||||
}
|
||||
Vector(double x, double y, double z) {
|
||||
Vector *v = (Vector *) malloc(sizeof(Vector));
|
||||
v->x = x;
|
||||
v->y = y;
|
||||
v->z = z;
|
||||
return v;
|
||||
Vector *v = (Vector *) malloc(sizeof(Vector));
|
||||
v->x = x;
|
||||
v->y = y;
|
||||
v->z = z;
|
||||
return v;
|
||||
}
|
||||
};
|
||||
</pre>
|
||||
|
|
@ -5278,7 +5278,7 @@ void * operator new(size_t t) {
|
|||
throw bad_alloc();
|
||||
pJalloc->ref = 0;
|
||||
return static_cast<void *>(
|
||||
static_cast<char *>(static_cast<void *>(pJalloc)) + sizeof(Jalloc));
|
||||
static_cast<char *>(static_cast<void *>(pJalloc)) + sizeof(Jalloc));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -7240,7 +7240,7 @@ public class runme {
|
|||
example.print_args(animals);
|
||||
String args[] = example.get_args();
|
||||
for (int i=0; i<args.length; i++)
|
||||
System.out.println(i + ":" + args[i]);
|
||||
System.out.println(i + ":" + args[i]);
|
||||
}
|
||||
}
|
||||
</pre></div>
|
||||
|
|
|
|||
|
|
@ -411,7 +411,7 @@ void print_array(double x[10]);
|
|||
Now, in a scripting language, you might write this:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
a = new_doubleArray(10) # Create an array
|
||||
for i in range(0, 10):
|
||||
|
|
@ -475,7 +475,7 @@ void print_array(double x[10]);
|
|||
Allows you to do this:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
import example
|
||||
c = example.doubleArray(10) # Create double[10]
|
||||
|
|
@ -801,7 +801,7 @@ target language. In other words, if you were using a language like Tcl,
|
|||
and you wrote this,
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
% foo Hello
|
||||
</pre>
|
||||
|
|
@ -852,7 +852,7 @@ size_t parity(char *str, size_t len, size_t initial);
|
|||
Now, in the target language, you can use binary string data like this:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
>>> s = "H\x00\x15eg\x09\x20"
|
||||
>>> parity(s, 0)
|
||||
|
|
|
|||
|
|
@ -1008,11 +1008,10 @@ The following operators cannot be overloaded (mainly because they are not suppor
|
|||
<p>
|
||||
SWIG also accepts the <tt>__str__()</tt> member function which converts an object to a string. This function should return a const char*, preferably to static memory. This will be used for the <tt>print()</tt> and <tt>tostring()</tt> functions in Lua. Assuming the complex class has a function
|
||||
</p>
|
||||
<div class="code"><pre>const char* __str__()
|
||||
{
|
||||
static char buffer[255];
|
||||
sprintf(buffer, "Complex(%g, %g)", this->re(), this->im());
|
||||
return buffer;
|
||||
<div class="code"><pre>const char* __str__() {
|
||||
static char buffer[255];
|
||||
sprintf(buffer, "Complex(%g, %g)", this->re(), this->im());
|
||||
return buffer;
|
||||
}
|
||||
</pre></div>
|
||||
<p>
|
||||
|
|
@ -1031,11 +1030,10 @@ Complex(10, 12)
|
|||
<p>
|
||||
It is also possible to overload the operator<tt>[]</tt>, but currently this cannot be automatically performed. To overload the operator<tt>[]</tt> you need to provide two functions, <tt>__getitem__()</tt> and <tt>__setitem__()</tt>
|
||||
</p>
|
||||
<div class="code"><pre>class Complex
|
||||
{
|
||||
//....
|
||||
double __getitem__(int i)const; // i is the index, returns the data
|
||||
void __setitem__(int i, double d); // i is the index, d is the data
|
||||
<div class="code"><pre>class Complex {
|
||||
//....
|
||||
double __getitem__(int i)const; // i is the index, returns the data
|
||||
void __setitem__(int i, double d); // i is the index, d is the data
|
||||
};
|
||||
</pre></div>
|
||||
<p>
|
||||
|
|
|
|||
|
|
@ -949,7 +949,7 @@ Foo *BarToFoo(Bar *b) {
|
|||
}
|
||||
|
||||
Foo *IncrFoo(Foo *f, int i) {
|
||||
return f+i;
|
||||
return f+i;
|
||||
}
|
||||
%}
|
||||
</pre>
|
||||
|
|
@ -1057,7 +1057,7 @@ produces a single accessor function like this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
int *Foo_x_get(Foo *self) {
|
||||
return self->x;
|
||||
return self->x;
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1092,11 +1092,11 @@ generates accessor functions such as this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
Foo *Bar_f_get(Bar *b) {
|
||||
return &b->f;
|
||||
return &b->f;
|
||||
}
|
||||
|
||||
void Bar_f_set(Bar *b, Foo *val) {
|
||||
b->f = *val;
|
||||
b->f = *val;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1633,9 +1633,8 @@ class DoubleArray {
|
|||
void setitem(int i, double val) {
|
||||
if ((i >= 0) && (i < n))
|
||||
ptr[i] = val;
|
||||
else {
|
||||
else
|
||||
throw RangeError();
|
||||
}
|
||||
}
|
||||
};
|
||||
</pre></div>
|
||||
|
|
@ -1888,9 +1887,9 @@ like this:
|
|||
<div class="targetlang">
|
||||
<pre>
|
||||
%typemap(out) int {
|
||||
$result = sv_newmortal();
|
||||
set_setiv($result, (IV) $1);
|
||||
argvi++;
|
||||
$result = sv_newmortal();
|
||||
set_setiv($result, (IV) $1);
|
||||
argvi++;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2313,8 +2312,8 @@ Consider the following data structure:
|
|||
<div class="code"><pre>
|
||||
#define SIZE 8
|
||||
typedef struct {
|
||||
int values[SIZE];
|
||||
...
|
||||
int values[SIZE];
|
||||
...
|
||||
} Foo;
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -2328,10 +2327,10 @@ To make the member writable, a "memberin" typemap can be used.
|
|||
|
||||
<div class="code"><pre>
|
||||
%typemap(memberin) int [SIZE] {
|
||||
int i;
|
||||
for (i = 0; i < SIZE; i++) {
|
||||
$1[i] = $input[i];
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < SIZE; i++) {
|
||||
$1[i] = $input[i];
|
||||
}
|
||||
}
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -2600,48 +2599,48 @@ package example::Vector;
|
|||
%BLESSEDMEMBERS = ();
|
||||
|
||||
sub new () {
|
||||
my $self = shift;
|
||||
my @args = @_;
|
||||
$self = vectorc::new_Vector(@args);
|
||||
return undef if (!defined($self));
|
||||
bless $self, "example::Vector";
|
||||
$OWNER{$self} = 1;
|
||||
my %retval;
|
||||
tie %retval, "example::Vector", $self;
|
||||
return bless \%retval, "Vector";
|
||||
my $self = shift;
|
||||
my @args = @_;
|
||||
$self = vectorc::new_Vector(@args);
|
||||
return undef if (!defined($self));
|
||||
bless $self, "example::Vector";
|
||||
$OWNER{$self} = 1;
|
||||
my %retval;
|
||||
tie %retval, "example::Vector", $self;
|
||||
return bless \%retval, "Vector";
|
||||
}
|
||||
|
||||
sub DESTROY {
|
||||
return unless $_[0]->isa('HASH');
|
||||
my $self = tied(%{$_[0]});
|
||||
delete $ITERATORS{$self};
|
||||
if (exists $OWNER{$self}) {
|
||||
examplec::delete_Vector($self));
|
||||
delete $OWNER{$self};
|
||||
}
|
||||
return unless $_[0]->isa('HASH');
|
||||
my $self = tied(%{$_[0]});
|
||||
delete $ITERATORS{$self};
|
||||
if (exists $OWNER{$self}) {
|
||||
examplec::delete_Vector($self));
|
||||
delete $OWNER{$self};
|
||||
}
|
||||
}
|
||||
|
||||
sub FETCH {
|
||||
my ($self, $field) = @_;
|
||||
my $member_func = "vectorc::Vector_${field}_get";
|
||||
my $val = &$member_func($self);
|
||||
if (exists $BLESSEDMEMBERS{$field}) {
|
||||
return undef if (!defined($val));
|
||||
my %retval;
|
||||
tie %retval, $BLESSEDMEMBERS{$field}, $val;
|
||||
return bless \%retval, $BLESSEDMEMBERS{$field};
|
||||
}
|
||||
return $val;
|
||||
my ($self, $field) = @_;
|
||||
my $member_func = "vectorc::Vector_${field}_get";
|
||||
my $val = &$member_func($self);
|
||||
if (exists $BLESSEDMEMBERS{$field}) {
|
||||
return undef if (!defined($val));
|
||||
my %retval;
|
||||
tie %retval, $BLESSEDMEMBERS{$field}, $val;
|
||||
return bless \%retval, $BLESSEDMEMBERS{$field};
|
||||
}
|
||||
return $val;
|
||||
}
|
||||
|
||||
sub STORE {
|
||||
my ($self, $field, $newval) = @_;
|
||||
my $member_func = "vectorc::Vector_${field}_set";
|
||||
if (exists $BLESSEDMEMBERS{$field}) {
|
||||
&$member_func($self, tied(%{$newval}));
|
||||
} else {
|
||||
&$member_func($self, $newval);
|
||||
}
|
||||
my ($self, $field, $newval) = @_;
|
||||
my $member_func = "vectorc::Vector_${field}_set";
|
||||
if (exists $BLESSEDMEMBERS{$field}) {
|
||||
&$member_func($self, tied(%{$newval}));
|
||||
} else {
|
||||
&$member_func($self, $newval);
|
||||
}
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -2842,11 +2841,11 @@ this:
|
|||
|
||||
<div class="targetlang"><pre>
|
||||
sub dot_product {
|
||||
my @args = @_;
|
||||
$args[0] = tied(%{$args[0]}); # Get the real pointer values
|
||||
$args[1] = tied(%{$args[1]});
|
||||
my $result = vectorc::dot_product(@args);
|
||||
return $result;
|
||||
my @args = @_;
|
||||
$args[0] = tied(%{$args[0]}); # Get the real pointer values
|
||||
$args[1] = tied(%{$args[1]});
|
||||
my $result = vectorc::dot_product(@args);
|
||||
return $result;
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -2985,7 +2984,7 @@ sub set_transform
|
|||
for (my $j = 0; $j < 4, $j++)
|
||||
{
|
||||
mat44_set($a, $i, $j, $x->[i][j])
|
||||
}
|
||||
}
|
||||
}
|
||||
example.set_transform($im, $a);
|
||||
free_mat44($a);
|
||||
|
|
@ -3104,14 +3103,14 @@ the methods one() and two() (but not three()):
|
|||
%feature("director") Foo;
|
||||
class Foo {
|
||||
public:
|
||||
Foo(int foo);
|
||||
virtual void one();
|
||||
virtual void two();
|
||||
Foo(int foo);
|
||||
virtual void one();
|
||||
virtual void two();
|
||||
};
|
||||
|
||||
class Bar: public Foo {
|
||||
public:
|
||||
virtual void three();
|
||||
virtual void three();
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3279,9 +3278,9 @@ suffice in most cases:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%feature("director:except") {
|
||||
if ($error != NULL) {
|
||||
throw Swig::DirectorMethodException();
|
||||
}
|
||||
if ($error != NULL) {
|
||||
throw Swig::DirectorMethodException();
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3305,8 +3304,8 @@ suitable exception handler:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%exception {
|
||||
try { $action }
|
||||
catch (Swig::DirectorException &e) { SWIG_fail; }
|
||||
try { $action }
|
||||
catch (Swig::DirectorException &e) { SWIG_fail; }
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -986,14 +986,14 @@ the methods one() and two() (but not three()):
|
|||
%feature("director") Foo;
|
||||
class Foo {
|
||||
public:
|
||||
Foo(int foo);
|
||||
virtual void one();
|
||||
virtual void two();
|
||||
Foo(int foo);
|
||||
virtual void one();
|
||||
virtual void two();
|
||||
};
|
||||
|
||||
class Bar: public Foo {
|
||||
public:
|
||||
virtual void three();
|
||||
virtual void three();
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1125,12 +1125,12 @@ Here is an example:
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
...
|
||||
...
|
||||
};
|
||||
class FooContainer {
|
||||
public:
|
||||
void addFoo(Foo *);
|
||||
...
|
||||
void addFoo(Foo *);
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1175,9 +1175,9 @@ should suffice in most cases:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%feature("director:except") {
|
||||
if ($error == FAILURE) {
|
||||
throw Swig::DirectorMethodException();
|
||||
}
|
||||
if ($error == FAILURE) {
|
||||
throw Swig::DirectorMethodException();
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1204,8 +1204,8 @@ suitable exception handler:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%exception {
|
||||
try { $action }
|
||||
catch (Swig::DirectorException &e) { SWIG_fail; }
|
||||
try { $action }
|
||||
catch (Swig::DirectorException &e) { SWIG_fail; }
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -230,8 +230,8 @@ For example, given this C++ class declaration:
|
|||
class Shape
|
||||
{
|
||||
public:
|
||||
static void print();
|
||||
static int nshapes;
|
||||
static void print();
|
||||
static int nshapes;
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
|
|
|
|||
|
|
@ -226,16 +226,15 @@ resulting C file should be built as a python extension, inserting the module
|
|||
#include "example.h"
|
||||
|
||||
int fact(int n) {
|
||||
if (n < 0){ /* This should probably return an error, but this is simpler */
|
||||
return 0;
|
||||
}
|
||||
if (n == 0) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
/* testing for overflow would be a good idea here */
|
||||
return n * fact(n-1);
|
||||
}
|
||||
if (n < 0) { /* This should probably return an error, but this is simpler */
|
||||
return 0;
|
||||
}
|
||||
if (n == 0) {
|
||||
return 1;
|
||||
} else {
|
||||
/* testing for overflow would be a good idea here */
|
||||
return n * fact(n-1);
|
||||
}
|
||||
}
|
||||
|
||||
</pre>
|
||||
|
|
@ -1276,7 +1275,7 @@ Foo *BarToFoo(Bar *b) {
|
|||
}
|
||||
|
||||
Foo *IncrFoo(Foo *f, int i) {
|
||||
return f+i;
|
||||
return f+i;
|
||||
}
|
||||
%}
|
||||
</pre>
|
||||
|
|
@ -1386,7 +1385,7 @@ example, consider this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
struct Bar {
|
||||
int x[16];
|
||||
int x[16];
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1716,9 +1715,9 @@ Similarly, if you have a class like this,
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
Foo();
|
||||
Foo(const Foo &);
|
||||
...
|
||||
Foo();
|
||||
Foo(const Foo &);
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1951,11 +1950,11 @@ For example:
|
|||
%rename(Bar_spam) Bar::spam;
|
||||
|
||||
namespace Foo {
|
||||
int spam();
|
||||
int spam();
|
||||
}
|
||||
|
||||
namespace Bar {
|
||||
int spam();
|
||||
int spam();
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2166,9 +2165,9 @@ have a class like this
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
int x;
|
||||
int spam(int);
|
||||
...
|
||||
int x;
|
||||
int spam(int);
|
||||
...
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -2179,19 +2178,19 @@ then SWIG transforms it into a set of low-level procedural wrappers. For example
|
|||
<div class="code">
|
||||
<pre>
|
||||
Foo *new_Foo() {
|
||||
return new Foo();
|
||||
return new Foo();
|
||||
}
|
||||
void delete_Foo(Foo *f) {
|
||||
delete f;
|
||||
delete f;
|
||||
}
|
||||
int Foo_x_get(Foo *f) {
|
||||
return f->x;
|
||||
return f->x;
|
||||
}
|
||||
void Foo_x_set(Foo *f, int value) {
|
||||
f->x = value;
|
||||
f->x = value;
|
||||
}
|
||||
int Foo_spam(Foo *f, int arg1) {
|
||||
return f->spam(arg1);
|
||||
return f->spam(arg1);
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2310,10 +2309,10 @@ please refer to the python documentation:</p>
|
|||
<div class="code">
|
||||
<pre>
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyObject *dict;
|
||||
PyObject *args;
|
||||
PyObject *message;
|
||||
PyObject_HEAD
|
||||
PyObject *dict;
|
||||
PyObject *args;
|
||||
PyObject *message;
|
||||
} PyBaseExceptionObject;
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2323,12 +2322,12 @@ typedef struct {
|
|||
<div class="code">
|
||||
<pre>
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
void *ptr;
|
||||
swig_type_info *ty;
|
||||
int own;
|
||||
PyObject *next;
|
||||
PyObject *dict;
|
||||
PyObject_HEAD
|
||||
void *ptr;
|
||||
swig_type_info *ty;
|
||||
int own;
|
||||
PyObject *next;
|
||||
PyObject *dict;
|
||||
} SwigPyObject;
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2339,13 +2338,13 @@ typedef struct {
|
|||
<pre>
|
||||
class MyException {
|
||||
public:
|
||||
MyException (const char *msg_);
|
||||
~MyException ();
|
||||
MyException (const char *msg_);
|
||||
~MyException ();
|
||||
|
||||
const char *what () const;
|
||||
const char *what () const;
|
||||
|
||||
private:
|
||||
char *msg;
|
||||
char *msg;
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2372,9 +2371,9 @@ strings, you can define an <tt>'operator+ (const char*)'</tt> method :</p>
|
|||
<pre>
|
||||
class MyString {
|
||||
public:
|
||||
MyString (const char *init);
|
||||
MyString operator+ (const char *other) const;
|
||||
...
|
||||
MyString (const char *init);
|
||||
MyString operator+ (const char *other) const;
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2473,11 +2472,12 @@ slot entries. For example, suppose you have this class:
|
|||
<pre>
|
||||
class Twit {
|
||||
public:
|
||||
Twit operator+ (const Twit& twit) const;
|
||||
Twit operator+ (const Twit& twit) const;
|
||||
|
||||
// Forward to operator+
|
||||
Twit add (const Twit& twit) const
|
||||
{ return *this + twit; }
|
||||
// Forward to operator+
|
||||
Twit add (const Twit& twit) const {
|
||||
return *this + twit;
|
||||
}
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2565,9 +2565,9 @@ the function callback in the tp_hash slot for the builtin type for <tt>MyClass</
|
|||
<div class="code">
|
||||
<pre>
|
||||
static PyHeapTypeObject SwigPyBuiltin__MyClass_type = {
|
||||
...
|
||||
(hashfunc) myHashFunc, /* tp_hash */
|
||||
...
|
||||
...
|
||||
(hashfunc) myHashFunc, /* tp_hash */
|
||||
...
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -2636,8 +2636,8 @@ ownership of the result. For example:
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
Foo();
|
||||
Foo bar();
|
||||
Foo();
|
||||
Foo bar();
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2666,9 +2666,9 @@ they came from. Therefore, the ownership is set to zero. For example:
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
...
|
||||
Foo *spam();
|
||||
...
|
||||
...
|
||||
Foo *spam();
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2707,8 +2707,8 @@ or global variable. For example, consider this interface:
|
|||
%module example
|
||||
|
||||
struct Foo {
|
||||
int value;
|
||||
Foo *next;
|
||||
int value;
|
||||
Foo *next;
|
||||
};
|
||||
|
||||
Foo *head = 0;
|
||||
|
|
@ -2939,15 +2939,15 @@ the methods one() and two() (but not three()):
|
|||
%feature("director") Foo;
|
||||
class Foo {
|
||||
public:
|
||||
Foo(int foo);
|
||||
virtual ~Foo();
|
||||
virtual void one();
|
||||
virtual void two();
|
||||
Foo(int foo);
|
||||
virtual ~Foo();
|
||||
virtual void one();
|
||||
virtual void two();
|
||||
};
|
||||
|
||||
class Bar: public Foo {
|
||||
public:
|
||||
virtual void three();
|
||||
virtual void three();
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3087,12 +3087,12 @@ references. Here is an example:
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
...
|
||||
...
|
||||
};
|
||||
class FooContainer {
|
||||
public:
|
||||
void addFoo(Foo *);
|
||||
...
|
||||
void addFoo(Foo *);
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3133,9 +3133,9 @@ suffice in most cases:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%feature("director:except") {
|
||||
if ($error != NULL) {
|
||||
throw Swig::DirectorMethodException();
|
||||
}
|
||||
if ($error != NULL) {
|
||||
throw Swig::DirectorMethodException();
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3162,8 +3162,8 @@ suitable exception handler:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%exception {
|
||||
try { $action }
|
||||
catch (Swig::DirectorException &e) { SWIG_fail; }
|
||||
try { $action }
|
||||
catch (Swig::DirectorException &e) { SWIG_fail; }
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3240,7 +3240,7 @@ references, such as
|
|||
<pre>
|
||||
class Foo {
|
||||
…
|
||||
virtual const int& bar();
|
||||
virtual const int& bar();
|
||||
…
|
||||
};
|
||||
</pre>
|
||||
|
|
@ -3258,7 +3258,7 @@ types, wherever possible, for example
|
|||
<pre>
|
||||
class Foo {
|
||||
…
|
||||
virtual int bar();
|
||||
virtual int bar();
|
||||
…
|
||||
};
|
||||
</pre>
|
||||
|
|
@ -3511,7 +3511,7 @@ def bar(*args):
|
|||
|
||||
class Foo {
|
||||
public:
|
||||
int bar(int x);
|
||||
int bar(int x);
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3548,7 +3548,7 @@ proxy, just before the return statement.
|
|||
|
||||
class Foo {
|
||||
public:
|
||||
int bar(int x);
|
||||
int bar(int x);
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3577,7 +3577,7 @@ SWIG version 1.3.28 you can use the directive forms
|
|||
|
||||
class Foo {
|
||||
public:
|
||||
int bar(int x);
|
||||
int bar(int x);
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3606,8 +3606,8 @@ as it will then get attached to all the overloaded C++ methods. For example:
|
|||
|
||||
class Foo {
|
||||
public:
|
||||
int bar(int x);
|
||||
int bar();
|
||||
int bar(int x);
|
||||
int bar();
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -4142,11 +4142,11 @@ Sometimes a C function expects an array to be passed as a pointer. For example,
|
|||
<div class="code">
|
||||
<pre>
|
||||
int sumitems(int *first, int nitems) {
|
||||
int i, sum = 0;
|
||||
for (i = 0; i < nitems; i++) {
|
||||
sum += first[i];
|
||||
}
|
||||
return sum;
|
||||
int i, sum = 0;
|
||||
for (i = 0; i < nitems; i++) {
|
||||
sum += first[i];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -6526,7 +6526,7 @@ string that cannot be completely decoded as UTF-8:
|
|||
%inline %{
|
||||
|
||||
const char* non_utf8_c_str(void) {
|
||||
return "h\xe9llo w\xc3\xb6rld";
|
||||
return "h\xe9llo w\xc3\xb6rld";
|
||||
}
|
||||
|
||||
%}
|
||||
|
|
|
|||
|
|
@ -389,7 +389,7 @@ For example
|
|||
/* bar not wrapped unless foo has been defined and
|
||||
the declaration of bar within foo has already been parsed */
|
||||
int foo::bar(int) {
|
||||
... whatever ...
|
||||
... whatever ...
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1043,14 +1043,14 @@ expect :</p>
|
|||
<div class="targetlang"><pre>
|
||||
# Copy a file
|
||||
def filecopy(source, target):
|
||||
f1 = fopen(source, "r")
|
||||
f2 = fopen(target, "w")
|
||||
buffer = malloc(8192)
|
||||
nbytes = fread(buffer, 8192, 1, f1)
|
||||
while (nbytes > 0):
|
||||
fwrite(buffer, 8192, 1, f2)
|
||||
nbytes = fread(buffer, 8192, 1, f1)
|
||||
free(buffer)
|
||||
f1 = fopen(source, "r")
|
||||
f2 = fopen(target, "w")
|
||||
buffer = malloc(8192)
|
||||
nbytes = fread(buffer, 8192, 1, f1)
|
||||
while (nbytes > 0):
|
||||
fwrite(buffer, 8192, 1, f2)
|
||||
nbytes = fread(buffer, 8192, 1, f1)
|
||||
free(buffer)
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
@ -1236,9 +1236,9 @@ creating a wrapper equivalent to the following:
|
|||
|
||||
<div class="code"><pre>
|
||||
double wrap_dot_product(Vector *a, Vector *b) {
|
||||
Vector x = *a;
|
||||
Vector y = *b;
|
||||
return dot_product(x, y);
|
||||
Vector x = *a;
|
||||
Vector y = *b;
|
||||
return dot_product(x, y);
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -1266,12 +1266,12 @@ pointers. As a result, SWIG creates a wrapper like this:
|
|||
|
||||
<div class="code"><pre>
|
||||
Vector *wrap_cross_product(Vector *v1, Vector *v2) {
|
||||
Vector x = *v1;
|
||||
Vector y = *v2;
|
||||
Vector *result;
|
||||
result = (Vector *) malloc(sizeof(Vector));
|
||||
*(result) = cross(x, y);
|
||||
return result;
|
||||
Vector x = *v1;
|
||||
Vector y = *v2;
|
||||
Vector *result;
|
||||
result = (Vector *) malloc(sizeof(Vector));
|
||||
*(result) = cross(x, y);
|
||||
return result;
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -1280,10 +1280,10 @@ or if SWIG was run with the <tt>-c++</tt> option:</p>
|
|||
|
||||
<div class="code"><pre>
|
||||
Vector *wrap_cross(Vector *v1, Vector *v2) {
|
||||
Vector x = *v1;
|
||||
Vector y = *v2;
|
||||
Vector *result = new Vector(cross(x, y)); // Uses default copy constructor
|
||||
return result;
|
||||
Vector x = *v1;
|
||||
Vector y = *v2;
|
||||
Vector *result = new Vector(cross(x, y)); // Uses default copy constructor
|
||||
return result;
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -2368,10 +2368,10 @@ defined in the interface. For example:
|
|||
|
||||
<div class="code"><pre>
|
||||
struct Vector *new_Vector() {
|
||||
return (Vector *) calloc(1, sizeof(struct Vector));
|
||||
return (Vector *) calloc(1, sizeof(struct Vector));
|
||||
}
|
||||
void delete_Vector(struct Vector *obj) {
|
||||
free(obj);
|
||||
free(obj);
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2602,10 +2602,10 @@ like this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
WORD Foo_w_get(Foo *f) {
|
||||
return f->w;
|
||||
return f->w;
|
||||
}
|
||||
void Foo_w_set(FOO *f, WORD value) {
|
||||
f->w = value;
|
||||
f->w = value;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2896,7 +2896,7 @@ instead of a method. To do this, you might write some code like this:
|
|||
<pre>
|
||||
// Add a new attribute to Vector
|
||||
%extend Vector {
|
||||
const double magnitude;
|
||||
const double magnitude;
|
||||
}
|
||||
// Now supply the implementation of the Vector_magnitude_get function
|
||||
%{
|
||||
|
|
|
|||
|
|
@ -49,6 +49,16 @@
|
|||
<li><a href="#SWIGPlus_nn28">Wrapping overloaded operators</a>
|
||||
<li><a href="#SWIGPlus_class_extension">Class extension</a>
|
||||
<li><a href="#SWIGPlus_nn30">Templates</a>
|
||||
<ul>
|
||||
<li><a href="#SWIGPlus_template_directive">The %template directive</a>
|
||||
<li><a href="#SWIGPlus_template_functions">Function templates</a>
|
||||
<li><a href="#SWIGPlus_template_classes">Default template arguments</a>
|
||||
<li><a href="#SWIGPlus_template_class_inheritance">Template base classes</a>
|
||||
<li><a href="#SWIGPlus_template_specialization">Template specialization</a>
|
||||
<li><a href="#SWIGPlus_template_member">Member templates</a>
|
||||
<li><a href="#SWIGPlus_template_scoping">Scoping and templates</a>
|
||||
<li><a href="#SWIGPlus_template_more">More on templates</a>
|
||||
</ul>
|
||||
<li><a href="#SWIGPlus_namespaces">Namespaces</a>
|
||||
<ul>
|
||||
<li><a href="#SWIGPlus_nspace">The nspace feature for namespaces</a>
|
||||
|
|
@ -346,8 +356,8 @@ public:
|
|||
|
||||
class Spam {
|
||||
public:
|
||||
Foo *value;
|
||||
...
|
||||
Foo *value;
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -706,7 +716,7 @@ class Foo {
|
|||
protected:
|
||||
Foo(); // Not wrapped.
|
||||
public:
|
||||
...
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -726,7 +736,7 @@ public:
|
|||
|
||||
class Grok : public Bar {
|
||||
public:
|
||||
Grok(); // Not wrapped. No implementation of abstract spam().
|
||||
Grok(); // Not wrapped. No implementation of abstract spam().
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -777,9 +787,9 @@ the normal constructor function. For example, if you have this:
|
|||
<pre>
|
||||
class List {
|
||||
public:
|
||||
List();
|
||||
List(const List &); // Copy constructor
|
||||
...
|
||||
List();
|
||||
List(const List &); // Copy constructor
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -803,7 +813,7 @@ through a special function like this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
List *copy_List(List *f) {
|
||||
return new List(*f);
|
||||
return new List(*f);
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -832,7 +842,7 @@ However, copy constructor wrappers can be generated if using the <tt>copyctor</t
|
|||
|
||||
class List {
|
||||
public:
|
||||
List();
|
||||
List();
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -851,9 +861,9 @@ could be wrapped, but they had to be renamed. For example:
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
Foo();
|
||||
Foo();
|
||||
%name(CopyFoo) Foo(const Foo &);
|
||||
...
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -969,8 +979,8 @@ not primitive types, such as classes. For instance, if you had another class lik
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
List items;
|
||||
...
|
||||
List items;
|
||||
...
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -982,10 +992,10 @@ For example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
List *Foo_items_get(Foo *self) {
|
||||
return &self->items;
|
||||
return &self->items;
|
||||
}
|
||||
void Foo_items_set(Foo *self, List *value) {
|
||||
self->items = *value;
|
||||
self->items = *value;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1007,10 +1017,10 @@ It is the naturalvar feature and can be used to effectively change the way acces
|
|||
<div class="code">
|
||||
<pre>
|
||||
const List &Foo_items_get(Foo *self) {
|
||||
return self->items;
|
||||
return self->items;
|
||||
}
|
||||
void Foo_items_set(Foo *self, const List &value) {
|
||||
self->items = value;
|
||||
self->items = value;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1105,7 +1115,7 @@ SWIG will wrap all types of functions that have default arguments. For example m
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
void bar(int x, int y = 3, int z = 4);
|
||||
void bar(int x, int y = 3, int z = 4);
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1120,9 +1130,9 @@ Thus for the example above, it is as if we had instead given the following to SW
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
void bar(int x, int y, int z);
|
||||
void bar(int x, int y);
|
||||
void bar(int x);
|
||||
void bar(int x, int y, int z);
|
||||
void bar(int x, int y);
|
||||
void bar(int x);
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1158,7 +1168,7 @@ can be re-activated by using the <tt>compactdefaultargs</tt>
|
|||
%feature("compactdefaultargs") Foo::bar;
|
||||
class Foo {
|
||||
public:
|
||||
void bar(int x, int y = 3, int z = 4);
|
||||
void bar(int x, int y = 3, int z = 4);
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1278,7 +1288,7 @@ equivalent to one generated for the following declaration
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
...
|
||||
...
|
||||
};
|
||||
|
||||
void blah(Foo *f);
|
||||
|
|
@ -1485,8 +1495,8 @@ class A;
|
|||
|
||||
%feature("valuewrapper") B;
|
||||
struct B {
|
||||
B();
|
||||
// ....
|
||||
B();
|
||||
// ....
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -2936,63 +2946,76 @@ as <tt>vector<int></tt>. The wrapper for <tt>foo()</tt> will
|
|||
accept either variant.
|
||||
</p>
|
||||
|
||||
<H3><a name="SWIGPlus_template_directive">6.18.1 The %template directive</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
Starting with SWIG-1.3.7, simple C++ template declarations can also be
|
||||
wrapped. SWIG-1.3.12 greatly expands upon the earlier implementation. Before discussing this any further, there are a few things
|
||||
you need to know about template wrapping. First, a bare C++ template
|
||||
There are a couple of important points about template wrapping.
|
||||
First, a bare C++ template
|
||||
does not define any sort of runnable object-code for which SWIG can
|
||||
normally create a wrapper. Therefore, in order to wrap a template,
|
||||
you need to give SWIG information about a particular template
|
||||
instantiation (e.g., <tt>vector<int></tt>,
|
||||
instantiation (e.g., <tt>vector<int></tt>,
|
||||
<tt>array<double></tt>, etc.). Second, an instantiation name
|
||||
such as <tt>vector<int></tt> is generally not a valid identifier
|
||||
name in most target languages. Thus, you will need to give the
|
||||
template instantiation a more suitable name such as <tt>intvector</tt>
|
||||
when creating a wrapper.
|
||||
template instantiation a more suitable name such as <tt>intvector</tt>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To illustrate, consider the following template definition:
|
||||
To illustrate, consider the following class template definition:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
template<class T> class List {
|
||||
private:
|
||||
T *data;
|
||||
int nitems;
|
||||
int maxitems;
|
||||
T *data;
|
||||
int nitems;
|
||||
int maxitems;
|
||||
public:
|
||||
List(int max) {
|
||||
data = new T [max];
|
||||
nitems = 0;
|
||||
maxitems = max;
|
||||
}
|
||||
~List() {
|
||||
delete [] data;
|
||||
};
|
||||
void append(T obj) {
|
||||
if (nitems < maxitems) {
|
||||
data[nitems++] = obj;
|
||||
}
|
||||
}
|
||||
int length() {
|
||||
return nitems;
|
||||
}
|
||||
T get(int n) {
|
||||
return data[n];
|
||||
List(int max) {
|
||||
data = new T [max];
|
||||
nitems = 0;
|
||||
maxitems = max;
|
||||
}
|
||||
~List() {
|
||||
delete [] data;
|
||||
};
|
||||
void append(T obj) {
|
||||
if (nitems < maxitems) {
|
||||
data[nitems++] = obj;
|
||||
}
|
||||
}
|
||||
int length() {
|
||||
return nitems;
|
||||
}
|
||||
T get(int n) {
|
||||
return data[n];
|
||||
}
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
By itself, this template declaration is useless--SWIG simply ignores it
|
||||
because it doesn't know how to generate any code until unless a definition of
|
||||
By itself, this class template is useless--SWIG simply ignores it
|
||||
because it doesn't know how to generate any code unless a definition of
|
||||
<tt>T</tt> is provided.
|
||||
The <tt>%template</tt> directive is required to instantiate the template for use in a target language.
|
||||
The directive requires an identifier name for use in the target language plus the template for instantiation.
|
||||
The example below instantiates <tt>List<int></tt> for use as a class named <tt>intList</tt>:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%template(intList) List<int>;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
One way to create wrappers for a specific template instantiation is to simply
|
||||
provide an expanded version of the class directly like this:
|
||||
The instantiation expands the template code as a C++ compiler would do and then makes it available
|
||||
under the given identifier name.
|
||||
Essentially it is the same as wrapping the following concept code where
|
||||
the class template definition has <tt>T</TT> expanded to <tt>int</tt>
|
||||
(note that this is not entirely valid syntax):
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
|
|
@ -3000,42 +3023,20 @@ provide an expanded version of the class directly like this:
|
|||
%rename(intList) List<int>; // Rename to a suitable identifier
|
||||
class List<int> {
|
||||
private:
|
||||
int *data;
|
||||
int nitems;
|
||||
int maxitems;
|
||||
int *data;
|
||||
int nitems;
|
||||
int maxitems;
|
||||
public:
|
||||
List(int max);
|
||||
~List();
|
||||
void append(int obj);
|
||||
int length();
|
||||
int get(int n);
|
||||
List(int max);
|
||||
~List();
|
||||
void append(int obj);
|
||||
int length();
|
||||
int get(int n);
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
||||
<p>
|
||||
The <tt>%rename</tt> directive is needed to give the template class an appropriate identifier
|
||||
name in the target language (most languages would not recognize C++ template syntax as a valid
|
||||
class name). The rest of the code is the same as what would appear in a normal
|
||||
class definition.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Since manual expansion of templates gets old in a hurry, the <tt>%template</tt> directive can
|
||||
be used to create instantiations of a template class. Semantically, <tt>%template</tt> is
|
||||
simply a shortcut---it expands template code in exactly the same way as shown above. Here
|
||||
are some examples:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
/* Instantiate a few different versions of the template */
|
||||
%template(intList) List<int>;
|
||||
%template(doubleList) List<double>;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The argument to <tt>%template()</tt> is the name of the instantiation
|
||||
in the target language. The name you choose should not conflict with
|
||||
|
|
@ -3053,7 +3054,81 @@ typedef List<int> intList; // OK
|
|||
</div>
|
||||
|
||||
<p>
|
||||
SWIG can also generate wrappers for function templates using a similar technique.
|
||||
The <tt>%template</tt> directive
|
||||
must always appear <em>after</em> the definition of the template to be expanded, so the following will work:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
template<class T> class List { ... };
|
||||
%template(intList) List<int>;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
but if %template is used before the template definition, such as:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%template(intList) List<int>;
|
||||
template<class T> class List { ... };
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
SWIG will generate an error:
|
||||
</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
example.i:3: Error: Template 'List' undefined.
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Since the type system knows how to handle <tt>typedef</tt>, it is
|
||||
generally not necessary to instantiate different versions of a template
|
||||
for typenames that are equivalent. For instance, consider this code:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%template(intList) List<int>;
|
||||
typedef int Integer;
|
||||
...
|
||||
void foo(List<Integer> *x);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
In this case, <tt>List<Integer></tt> is exactly the same type as
|
||||
<tt>List<int></tt>. Any use of <tt>List<Integer></tt> is mapped back to the
|
||||
instantiation of <tt>List<int></tt> created earlier. Therefore, it is
|
||||
not necessary to instantiate a new class for the type <tt>Integer</tt> (doing so is
|
||||
redundant and will simply result in code bloat).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The template provide to <tt>%template</tt> for instantiation must be the actual template and not a typedef to a template.
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
typedef List<int> ListOfInt;
|
||||
|
||||
%template(intList) List<int>; // ok
|
||||
%template(intList) ListOfInt; // illegal - Syntax error
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
||||
<H3><a name="SWIGPlus_template_functions">6.18.2 Function templates</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
SWIG can also generate wrappers for function templates using a similar technique
|
||||
to that shown above for class templates.
|
||||
For example:
|
||||
</p>
|
||||
|
||||
|
|
@ -3073,6 +3148,28 @@ In this case, <tt>maxint</tt> and <tt>maxdouble</tt> become unique names for spe
|
|||
instantiations of the function.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
SWIG even supports overloaded templated functions. As usual the <tt>%template</tt> directive
|
||||
is used to wrap templated functions. For example:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
template<class T> void foo(T x) { };
|
||||
template<class T> void foo(T x, T y) { };
|
||||
|
||||
%template(foo) foo<int>;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
This will generate two overloaded wrapper methods, the first will take a single integer as an argument
|
||||
and the second will take two integer arguments.
|
||||
</p>
|
||||
|
||||
<H3><a name="SWIGPlus_template_classes">6.18.3 Default template arguments</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
The number of arguments supplied to <tt>%template</tt> should match that in the
|
||||
original template definition. Template default arguments are supported. For example:
|
||||
|
|
@ -3110,28 +3207,8 @@ instantiation only once in order to reduce the potential for code
|
|||
bloat.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Since the type system knows how to handle <tt>typedef</tt>, it is
|
||||
generally not necessary to instantiate different versions of a template
|
||||
for typenames that are equivalent. For instance, consider this code:
|
||||
</p>
|
||||
<H3><a name="SWIGPlus_template_class_inheritance">6.18.4 Template base classes</a></H3>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%template(intList) vector<int>;
|
||||
typedef int Integer;
|
||||
...
|
||||
void foo(vector<Integer> *x);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
In this case, <tt>vector<Integer></tt> is exactly the same type as
|
||||
<tt>vector<int></tt>. Any use of <tt>Vector<Integer></tt> is mapped back to the
|
||||
instantiation of <tt>vector<int></tt> created earlier. Therefore, it is
|
||||
not necessary to instantiate a new class for the type <tt>Integer</tt> (doing so is
|
||||
redundant and will simply result in code bloat).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
When a template is instantiated using <tt>%template</tt>, information
|
||||
|
|
@ -3158,13 +3235,13 @@ nothing is known about <tt>List<int></tt>, you will get a warning message
|
|||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
example.h:42: Warning 401. Nothing known about class 'List<int >'. Ignored.
|
||||
example.h:42: Warning 401. Maybe you forgot to instantiate 'List<int >' using %template.
|
||||
example.h:42: Warning 401. Nothing known about class 'List< int >'. Ignored.
|
||||
example.h:42: Warning 401. Maybe you forgot to instantiate 'List< int >' using %template.
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
If a template class inherits from another template class, you need to
|
||||
If a class template inherits from another class template, you need to
|
||||
make sure that base classes are instantiated before derived classes.
|
||||
For example:
|
||||
</p>
|
||||
|
|
@ -3235,6 +3312,9 @@ TEMPLATE_WRAP(PairStringInt, std::pair<string, int>)
|
|||
Note the use of a vararg macro for the type T. If this wasn't used, the comma in the templated type in the last example would not be possible.
|
||||
</p>
|
||||
|
||||
<H3><a name="SWIGPlus_template_specialization">6.18.5 Template specialization</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
The SWIG template mechanism <em>does</em> support specialization. For instance, if you define
|
||||
a class like this,
|
||||
|
|
@ -3244,15 +3324,15 @@ a class like this,
|
|||
<pre>
|
||||
template<> class List<int> {
|
||||
private:
|
||||
int *data;
|
||||
int nitems;
|
||||
int maxitems;
|
||||
int *data;
|
||||
int nitems;
|
||||
int maxitems;
|
||||
public:
|
||||
List(int max);
|
||||
~List();
|
||||
void append(int obj);
|
||||
int length();
|
||||
int get(int n);
|
||||
List(int max);
|
||||
~List();
|
||||
void append(int obj);
|
||||
int length();
|
||||
int get(int n);
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3275,15 +3355,15 @@ code defines a template that is applied when the template argument is a pointer.
|
|||
<pre>
|
||||
template<class T> class List<T*> {
|
||||
private:
|
||||
T *data;
|
||||
int nitems;
|
||||
int maxitems;
|
||||
T *data;
|
||||
int nitems;
|
||||
int maxitems;
|
||||
public:
|
||||
List(int max);
|
||||
~List();
|
||||
void append(int obj);
|
||||
int length();
|
||||
T get(int n);
|
||||
List(int max);
|
||||
~List();
|
||||
void append(T obj);
|
||||
int length();
|
||||
T get(int n);
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3322,10 +3402,13 @@ SWIG implements template argument deduction so that the following partial specia
|
|||
</pre>
|
||||
</div>
|
||||
|
||||
<H3><a name="SWIGPlus_template_member">6.18.6 Member templates</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
Member function templates are supported. The underlying principle is the same
|
||||
Member templates are supported. The underlying principle is the same
|
||||
as for normal templates--SWIG can't create a wrapper unless you provide
|
||||
more information about types. For example, a class with a member template might
|
||||
more information about types. For example, a class with a member function template might
|
||||
look like this:
|
||||
</p>
|
||||
|
||||
|
|
@ -3399,11 +3482,6 @@ methods to the Foo class.
|
|||
</p>
|
||||
|
||||
|
||||
<p>
|
||||
Note: because of the way that templates are handled, the <tt>%template</tt> directive
|
||||
must always appear <em>after</em> the definition of the template to be expanded.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Now, if your target language supports overloading, you can even try
|
||||
</p>
|
||||
|
|
@ -3424,7 +3502,7 @@ depending on the argument type.
|
|||
|
||||
<p>
|
||||
When used with members, the <tt>%template</tt> directive may be placed in another
|
||||
template class. Here is a slightly perverse example:
|
||||
class template. Here is a slightly perverse example:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
|
|
@ -3475,7 +3553,7 @@ template<class T1, class T2> struct pair {
|
|||
<p>
|
||||
This declaration is perfectly acceptable to SWIG, but the constructor template will be ignored
|
||||
unless you explicitly expand it. To do that, you could expand a few versions of the constructor
|
||||
in the template class itself. For example:
|
||||
in the class template itself. For example:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
|
|
@ -3536,6 +3614,110 @@ constructor, that will dispatch the proper call depending on the argument
|
|||
type.
|
||||
</p>
|
||||
|
||||
<H3><a name="SWIGPlus_template_scoping">6.18.7 Scoping and templates</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
The <tt>%template</tt> directive for a class template is the equivalent to an explicit instantiation
|
||||
of a C++ class template. The scope for a valid <tt>%template</tt> instantiation is the same
|
||||
as the scope required for a valid explicit instantiation of a C++ template.
|
||||
A definition of the template for the explicit instantiation must be in scope
|
||||
where the instantiation is declared and must not be enclosed within a different namespace.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For example, a few <tt>%template</tt> instantiations and C++ explicit instantiations are shown below:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
namespace N {
|
||||
template<typename T> class C {};
|
||||
}
|
||||
|
||||
// valid
|
||||
%template(cin) N::C<int>;
|
||||
template class N::C<int>;
|
||||
|
||||
// valid
|
||||
namespace N {
|
||||
%template(cin) C<int>;
|
||||
template class C<int>;
|
||||
}
|
||||
|
||||
// valid
|
||||
using namespace N;
|
||||
%template(cin) C<int>;
|
||||
template class C<int>;
|
||||
|
||||
// valid
|
||||
using N::C;
|
||||
%template(cin) C<int>;
|
||||
template class C<int>;
|
||||
|
||||
// ill-formed
|
||||
namespace unrelated {
|
||||
using N::C;
|
||||
%template(cin) C<int>;
|
||||
template class C<int>;
|
||||
}
|
||||
|
||||
// ill-formed
|
||||
namespace unrelated {
|
||||
using namespace N;
|
||||
%template(cin) C<int>;
|
||||
template class C<int>;
|
||||
}
|
||||
|
||||
// ill-formed
|
||||
namespace unrelated {
|
||||
namespace N {
|
||||
%template(cin) C<int>;
|
||||
template class C<int>;
|
||||
}
|
||||
}
|
||||
|
||||
// ill-formed
|
||||
namespace unrelated {
|
||||
%template(cin) N::C<int>;
|
||||
template class N::C<int>;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
When the scope is incorrect, such as for the ill-formed examples above, an error occurs:
|
||||
</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
cpp_template_scope.i:34: Error: 'C' resolves to 'N::C' and was incorrectly instantiated
|
||||
in scope 'unrelated' instead of within scope 'N'.
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
A note for the C++ standard geeks out there; a valid instantiation is one which conforms to
|
||||
the C++03 standard as C++11 made a change to disallow using declarations and using directives to find a template.
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
// valid C++03, ill-formed C++11
|
||||
using N::C;
|
||||
template class C<int>;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
<b>Compatibility Note</b>: Versions prior to SWIG-4.0.0 did not error out with incorrectly scoped
|
||||
<tt>%template</tt> declarations, but this led to numerous subtle template scope problems.
|
||||
</p>
|
||||
|
||||
|
||||
<H3><a name="SWIGPlus_template_more">6.18.8 More on templates</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
If all of this isn't quite enough and you really want to make
|
||||
someone's head explode, SWIG directives such as
|
||||
|
|
@ -3568,7 +3750,7 @@ instantiation.
|
|||
</p>
|
||||
|
||||
<p>
|
||||
It is also possible to separate these declarations from the template class. For example:
|
||||
It is also possible to separate these declarations from the class template. For example:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
|
|
@ -3587,11 +3769,11 @@ It is also possible to separate these declarations from the template class. For
|
|||
|
||||
...
|
||||
template<class T> class List {
|
||||
...
|
||||
public:
|
||||
List() { }
|
||||
T get(int index);
|
||||
...
|
||||
...
|
||||
public:
|
||||
List() { }
|
||||
T get(int index);
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3609,32 +3791,13 @@ additional methods to a specific instantiation. For example:
|
|||
%template(intList) List<int>;
|
||||
|
||||
%extend List<int> {
|
||||
void blah() {
|
||||
printf("Hey, I'm an List<int>!\n");
|
||||
}
|
||||
void blah() {
|
||||
printf("Hey, I'm an List<int>!\n");
|
||||
}
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
SWIG even supports overloaded templated functions. As usual the <tt>%template</tt> directive
|
||||
is used to wrap templated functions. For example:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
template<class T> void foo(T x) { };
|
||||
template<class T> void foo(T x, T y) { };
|
||||
|
||||
%template(foo) foo<int>;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
This will generate two overloaded wrapper methods, the first will take a single integer as an argument
|
||||
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>
|
||||
|
|
@ -3694,20 +3857,20 @@ For example:
|
|||
<pre>
|
||||
template <class T> class OuterTemplateClass {};
|
||||
|
||||
// The nested class OuterClass::InnerClass inherits from the template class
|
||||
// The nested class OuterClass::InnerClass inherits from the class template
|
||||
// OuterTemplateClass<OuterClass::InnerStruct> and thus the template needs
|
||||
// to be expanded with %template before the OuterClass declaration.
|
||||
%template(OuterTemplateClass_OuterClass__InnerStruct)
|
||||
OuterTemplateClass<OuterClass::InnerStruct>
|
||||
OuterTemplateClass<OuterClass::InnerStruct>
|
||||
|
||||
|
||||
// Don't forget to use %feature("flatnested") for OuterClass::InnerStruct and
|
||||
// OuterClass::InnerClass if the target language doesn't support nested classes.
|
||||
class OuterClass {
|
||||
public:
|
||||
// Forward declarations:
|
||||
struct InnerStruct;
|
||||
class InnerClass;
|
||||
public:
|
||||
// Forward declarations:
|
||||
struct InnerStruct;
|
||||
class InnerClass;
|
||||
};
|
||||
|
||||
struct OuterClass::InnerStruct {};
|
||||
|
|
@ -3736,7 +3899,7 @@ introduced a new class name. This name could then be used with other directives
|
|||
<pre>
|
||||
%template(vectori) vector<int>;
|
||||
%extend vectori {
|
||||
void somemethod() { }
|
||||
void somemethod() { }
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3750,7 +3913,7 @@ as the class name. For example:
|
|||
<pre>
|
||||
%template(vectori) vector<int>;
|
||||
%extend vector<int> {
|
||||
void somemethod() { }
|
||||
void somemethod() { }
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3915,6 +4078,8 @@ then SWIG simply creates three wrapper functions <tt>bar()</tt>,
|
|||
<tt>spam()</tt>, and <tt>blah()</tt> in the target language. SWIG
|
||||
does not prepend the names with a namespace prefix nor are the
|
||||
functions packaged in any kind of nested scope.
|
||||
Note that the default handling of flattening all the namespace scopes in the target language
|
||||
can be changed via the <a href="#SWIGPlus_nspace">nspace feature</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
@ -4009,7 +4174,7 @@ in a different namespace. For example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
namespace foo {
|
||||
template<typename T> T max(T a, T b) { return a > b ? a : b; }
|
||||
template<typename T> T max(T a, T b) { return a > b ? a : b; }
|
||||
}
|
||||
|
||||
using foo::max;
|
||||
|
|
@ -4018,8 +4183,8 @@ using foo::max;
|
|||
%template(maxfloat) foo::max<float>; // Okay (qualified name).
|
||||
|
||||
namespace bar {
|
||||
using namespace foo;
|
||||
%template(maxdouble) max<double>; // Okay.
|
||||
using namespace foo;
|
||||
%template(maxdouble) max<double>; // Okay.
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -4040,7 +4205,7 @@ namespace foo {
|
|||
typedef int Integer;
|
||||
class bar {
|
||||
public:
|
||||
...
|
||||
...
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -4203,9 +4368,7 @@ namespace foo {
|
|||
<p>
|
||||
<b>Note:</b> The flattening of namespaces is only intended to serve as
|
||||
a basic namespace implementation.
|
||||
None of the target language modules are currently programmed
|
||||
with any namespace awareness. In the future, language modules may or may not provide
|
||||
more advanced namespace support.
|
||||
More advanced handling of namespaces is discussed next.
|
||||
</p>
|
||||
|
||||
<H3><a name="SWIGPlus_nspace">6.19.1 The nspace feature for namespaces</a></H3>
|
||||
|
|
@ -4301,9 +4464,9 @@ In the example below, the generic template type is used to rename to <tt>bbb</tt
|
|||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%rename(bbb) Space::ABC::aaa(T t); // will match but with lower precedence than ccc
|
||||
%rename(bbb) Space::ABC::aaa(T t); // will match but with lower precedence than ccc
|
||||
%rename(ccc) Space::ABC<Space::XYZ>::aaa(Space::XYZ t);// will match but with higher precedence
|
||||
// than bbb
|
||||
// than bbb
|
||||
|
||||
namespace Space {
|
||||
class XYZ {};
|
||||
|
|
@ -4381,9 +4544,9 @@ class Error { };
|
|||
|
||||
class Foo {
|
||||
public:
|
||||
...
|
||||
void blah() throw(Error);
|
||||
...
|
||||
...
|
||||
void blah() throw(Error);
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -4445,10 +4608,10 @@ struct Error4 : EBase { };
|
|||
|
||||
class Foo {
|
||||
public:
|
||||
...
|
||||
void bar();
|
||||
void blah() throw(Error1, Error2, Error3, Error4);
|
||||
...
|
||||
...
|
||||
void bar();
|
||||
void blah() throw(Error1, Error2, Error3, Error4);
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -4524,7 +4687,7 @@ for member pointers.
|
|||
<p>
|
||||
In some C++ programs, objects are often encapsulated by smart-pointers
|
||||
or proxy classes. This is sometimes done to implement automatic memory management (reference counting) or
|
||||
persistence. Typically a smart-pointer is defined by a template class where
|
||||
persistence. Typically a smart-pointer is defined by a class template where
|
||||
the <tt>-></tt> operator has been overloaded. This class is then wrapped
|
||||
around some other class. For example:
|
||||
</p>
|
||||
|
|
@ -4533,21 +4696,21 @@ around some other class. For example:
|
|||
<pre>
|
||||
// Smart-pointer class
|
||||
template<class T> class SmartPtr {
|
||||
T *pointee;
|
||||
T *pointee;
|
||||
public:
|
||||
SmartPtr(T *p) : pointee(p) { ... }
|
||||
T *operator->() {
|
||||
return pointee;
|
||||
}
|
||||
...
|
||||
SmartPtr(T *p) : pointee(p) { ... }
|
||||
T *operator->() {
|
||||
return pointee;
|
||||
}
|
||||
...
|
||||
};
|
||||
|
||||
// Ordinary class
|
||||
class Foo_Impl {
|
||||
public:
|
||||
int x;
|
||||
virtual void bar();
|
||||
...
|
||||
int x;
|
||||
virtual void bar();
|
||||
...
|
||||
};
|
||||
|
||||
// Smart-pointer wrapper
|
||||
|
|
@ -4555,13 +4718,13 @@ typedef SmartPtr<Foo_Impl> Foo;
|
|||
|
||||
// Create smart pointer Foo
|
||||
Foo make_Foo() {
|
||||
return SmartPtr<Foo_Impl>(new Foo_Impl());
|
||||
return SmartPtr<Foo_Impl>(new Foo_Impl());
|
||||
}
|
||||
|
||||
// Do something with smart pointer Foo
|
||||
void do_something(Foo f) {
|
||||
printf("x = %d\n", f->x);
|
||||
f->bar();
|
||||
printf("x = %d\n", f->x);
|
||||
f->bar();
|
||||
}
|
||||
|
||||
// Call the wrapped smart pointer proxy class in the target language 'Foo'
|
||||
|
|
@ -4660,13 +4823,13 @@ example, if you have this code</p>
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
int x;
|
||||
int x;
|
||||
};
|
||||
|
||||
class Bar {
|
||||
public:
|
||||
int x;
|
||||
Foo *operator->();
|
||||
int x;
|
||||
Foo *operator->();
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -4915,19 +5078,19 @@ base classes. For example:
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
int blah(int x);
|
||||
int blah(int x);
|
||||
};
|
||||
|
||||
class Bar {
|
||||
public:
|
||||
double blah(double x);
|
||||
double blah(double x);
|
||||
};
|
||||
|
||||
class FooBar : public Foo, public Bar {
|
||||
public:
|
||||
using Foo::blah;
|
||||
using Bar::blah;
|
||||
char *blah(const char *x);
|
||||
using Foo::blah;
|
||||
using Bar::blah;
|
||||
char *blah(const char *x);
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -4970,14 +5133,14 @@ you wrap this code in Python, the module works just like you would expect:
|
|||
<pre>
|
||||
class Foo {
|
||||
protected:
|
||||
int x;
|
||||
int blah(int x);
|
||||
int x;
|
||||
int blah(int x);
|
||||
};
|
||||
|
||||
class Bar : public Foo {
|
||||
public:
|
||||
using Foo::x; // Make x public
|
||||
using Foo::blah; // Make blah public
|
||||
using Foo::x; // Make x public
|
||||
using Foo::blah; // Make blah public
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -5008,14 +5171,14 @@ correctly, you can always change the interface to the following:
|
|||
class FooBar : public Foo, public Bar {
|
||||
public:
|
||||
#ifndef SWIG
|
||||
using Foo::blah;
|
||||
using Bar::blah;
|
||||
using Foo::blah;
|
||||
using Bar::blah;
|
||||
#else
|
||||
int blah(int x); // explicitly tell SWIG about other declarations
|
||||
double blah(double x);
|
||||
int blah(int x); // explicitly tell SWIG about other declarations
|
||||
double blah(double x);
|
||||
#endif
|
||||
|
||||
char *blah(const char *x);
|
||||
char *blah(const char *x);
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -121,15 +121,15 @@ In this example we bind from C a function and a global variable into Scilab. The
|
|||
double Foo = 3.0;
|
||||
|
||||
int fact(int n) {
|
||||
if (n < 0) {
|
||||
return 0;
|
||||
}
|
||||
else if (n == 0) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return n * fact(n-1);
|
||||
}
|
||||
if (n < 0) {
|
||||
return 0;
|
||||
}
|
||||
else if (n == 0) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return n * fact(n-1);
|
||||
}
|
||||
}
|
||||
%}
|
||||
</pre></div>
|
||||
|
|
@ -896,8 +896,8 @@ Let's see it on an example of a struct with two members:
|
|||
%inline %{
|
||||
|
||||
typedef struct {
|
||||
int x;
|
||||
int arr[4];
|
||||
int x;
|
||||
int arr[4];
|
||||
} Foo;
|
||||
|
||||
%}
|
||||
|
|
@ -1143,11 +1143,11 @@ As explained in <a href="SWIGPlus.html#SWIGPlus_overloaded_methods">6.15</a> SWI
|
|||
%module example
|
||||
|
||||
void magnify(Square *square, double factor) {
|
||||
square->size *= factor;
|
||||
square->size *= factor;
|
||||
};
|
||||
|
||||
void magnify(Circle *circle, double factor) {
|
||||
square->radius *= factor;
|
||||
square->radius *= factor;
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
|
|
|
|||
|
|
@ -958,7 +958,7 @@ Foo *BarToFoo(Bar *b) {
|
|||
}
|
||||
|
||||
Foo *IncrFoo(Foo *f, int i) {
|
||||
return f+i;
|
||||
return f+i;
|
||||
}
|
||||
%}
|
||||
</pre>
|
||||
|
|
@ -1054,7 +1054,7 @@ example, consider this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
struct Bar {
|
||||
int x[16];
|
||||
int x[16];
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1456,9 +1456,9 @@ Similarly, if you have a class like this,
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
Foo();
|
||||
Foo(const Foo &);
|
||||
...
|
||||
Foo();
|
||||
Foo(const Foo &);
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1693,11 +1693,11 @@ For example:
|
|||
%rename(Bar_spam) Bar::spam;
|
||||
|
||||
namespace Foo {
|
||||
int spam();
|
||||
int spam();
|
||||
}
|
||||
|
||||
namespace Bar {
|
||||
int spam();
|
||||
int spam();
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1886,19 +1886,19 @@ then SWIG transforms it into a set of low-level procedural wrappers. For example
|
|||
<div class="code">
|
||||
<pre>
|
||||
Foo *new_Foo() {
|
||||
return new Foo();
|
||||
return new Foo();
|
||||
}
|
||||
void delete_Foo(Foo *f) {
|
||||
delete f;
|
||||
delete f;
|
||||
}
|
||||
int Foo_x_get(Foo *f) {
|
||||
return f->x;
|
||||
return f->x;
|
||||
}
|
||||
void Foo_x_set(Foo *f, int value) {
|
||||
f->x = value;
|
||||
f->x = value;
|
||||
}
|
||||
int Foo_spam(Foo *f, int arg1) {
|
||||
return f->spam(arg1);
|
||||
return f->spam(arg1);
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1945,8 +1945,8 @@ ownership of the result. For example:
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
Foo();
|
||||
Foo bar();
|
||||
Foo();
|
||||
Foo bar();
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1975,9 +1975,9 @@ they came from. Therefore, the ownership is set to zero. For example:
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
...
|
||||
Foo *spam();
|
||||
...
|
||||
...
|
||||
Foo *spam();
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2011,8 +2011,8 @@ or global variable. For example, consider this interface:
|
|||
%module example
|
||||
|
||||
struct Foo {
|
||||
int value;
|
||||
Foo *next;
|
||||
int value;
|
||||
Foo *next;
|
||||
};
|
||||
|
||||
Foo *head = 0;
|
||||
|
|
@ -2465,9 +2465,9 @@ you might define a typemap like this:
|
|||
%module example
|
||||
|
||||
%typemap(in) int {
|
||||
if (Tcl_GetIntFromObj(interp, $input, &$1) == TCL_ERROR)
|
||||
return TCL_ERROR;
|
||||
printf("Received an integer : %d\n", $1);
|
||||
if (Tcl_GetIntFromObj(interp, $input, &$1) == TCL_ERROR)
|
||||
return TCL_ERROR;
|
||||
printf("Received an integer : %d\n", $1);
|
||||
}
|
||||
%inline %{
|
||||
extern int fact(int n);
|
||||
|
|
@ -2585,7 +2585,7 @@ like this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%typemap(out) int {
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj($1));
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj($1));
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3215,28 +3215,28 @@ helper functions to access arrays :
|
|||
|
||||
%inline %{
|
||||
double *new_double(int size) {
|
||||
return (double *) malloc(size*sizeof(double));
|
||||
return (double *) malloc(size*sizeof(double));
|
||||
}
|
||||
void delete_double(double *a) {
|
||||
free(a);
|
||||
free(a);
|
||||
}
|
||||
double get_double(double *a, int index) {
|
||||
return a[index];
|
||||
return a[index];
|
||||
}
|
||||
void set_double(double *a, int index, double val) {
|
||||
a[index] = val;
|
||||
a[index] = val;
|
||||
}
|
||||
int *new_int(int size) {
|
||||
return (int *) malloc(size*sizeof(int));
|
||||
return (int *) malloc(size*sizeof(int));
|
||||
}
|
||||
void delete_int(int *a) {
|
||||
free(a);
|
||||
free(a);
|
||||
}
|
||||
int get_int(int *a, int index) {
|
||||
return a[index];
|
||||
return a[index];
|
||||
}
|
||||
int set_int(int *a, int index, int val) {
|
||||
a[index] = val;
|
||||
a[index] = val;
|
||||
}
|
||||
%}
|
||||
|
||||
|
|
|
|||
|
|
@ -423,8 +423,8 @@ Variable length arguments may be used in typemap specifications. For example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%typemap(in) (...) {
|
||||
// Get variable length arguments (somehow)
|
||||
...
|
||||
// Get variable length arguments (somehow)
|
||||
...
|
||||
}
|
||||
|
||||
%typemap(in) (const char *fmt, ...) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue