Fix ~15 tests, minor doc fixes, improve STL support.

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@10298 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Xavier Delacour 2008-03-05 04:35:34 +00:00
commit 4d283f59c3
32 changed files with 742 additions and 520 deletions

View file

@ -77,22 +77,18 @@ The current SWIG implemention is based on Octave 2.9.12. Support for other versi
Let's start with a very simple SWIG interface file:
</p>
<p>
<div class="code"><pre>%module example
%{
#include "example.h"
%}
int gcd(int x, int y);
extern double Foo; </pre></div>
</p>
<p>
To build an Octave module, run SWIG using the <tt>-octave</tt> option. The <tt>-c++</tt> option is required (for now) as Octave itself is written in C++ and thus the wrapper code must also be.
</p>
<p>
<div class="shell"><pre>$ swig -octave -c++ example.i </pre></div>
</p>
<p>
This creates a C/C++ source file <tt>example_wrap.cxx</tt>. The generated C++ source file contains the low-level wrappers that need to be compiled and linked with the rest of your C/C++ application (in this case, the gcd implementation) to create an extension module.
@ -110,12 +106,10 @@ Octave modules are DLLs/shared objects having the ".oct" suffix.
Building an oct file is usually done with the mkoctfile command (either within Octave itself, or from the shell). For example,
</p>
<p>
<div class="shell"><pre>
$ swig -octave -c++ example.i -o example_wrap.cxx
$ mkoctfile example_wrap.cxx example.c
</pre></div>
</p>
<p>
where example.c is the file containing the gcd() implementation.
@ -129,22 +123,16 @@ $ mkoctfile example_wrap.cxx example.c
mkoctfile will produce example.oct, which contains the compiled extension module. Loading it into Octave is then a matter of invoking
</p>
<p>
<div class="targetlang"><pre>octave:1&gt; example</pre></div>
</p>
<p>
<H3><a name="Octave_nn6"></a>26.2.2 Using your module</H3>
</p>
<p>
Assuming all goes well, you will be able to do this:
<br>
</p>
<p>
<div class="targetlang"><pre>$ octave -q
octave:1&gt; example
octave:2&gt; example.gcd(4,6)
@ -154,7 +142,6 @@ ans = 3
octave:4&gt; example.cvar.Foo=4;
octave:5&gt; example.cvar.Foo
ans = 4 </pre></div>
</p>
<H2><a name="Octave_nn7"></a>26.3 A tour of basic C/C++ wrapping</H2>
@ -174,7 +161,6 @@ When Octave is asked to invoke <tt>example</tt>, it will try to find the .m or .
Giving this function a parameter "global" will cause it to load all symbols into the global namespace in addition to the <tt>example</tt> namespace. For example:
</p>
<p>
<div class="targetlang"><pre>$ octave -q
octave:1&gt; example("global")
octave:2&gt; gcd(4,6)
@ -185,15 +171,12 @@ octave:4&gt; cvar.Foo=4;
octave:5&gt; cvar.Foo
ans = 4
</pre></div>
</p>
<p>
It is also possible to rename the module namespace with an assignment, as in: <br>
<p>
<div class="targetlang"><pre>octave:1&gt; example;
octave:2&gt; c=example;
octave:3&gt; c.gcd(10,4)
ans = 2 </pre></div>
</p>
<p>
All global variables are put into the cvar namespace object. This is accessible either as <tt>my_module.cvar</tt>, or just <tt>cvar</tt> (if the module is imported into the global namespace).
@ -201,11 +184,9 @@ All global variables are put into the cvar namespace object. This is accessible
<p>
One can also rename it by simple assignment, e.g.,
</p>
<p>
<div class="targetlang"><pre>
octave:1&gt; some_vars = cvar;
</div></pre>
</p>
</pre></div>
<H3><a name="Octave_nn9"></a>26.3.2 Functions</H3>
@ -214,21 +195,16 @@ octave:1&gt; some_vars = cvar;
Global functions are wrapped as new Octave built-in functions. For example,
</p>
<p>
<div class="code"><pre>&#037;module example
int fact(int n); </pre></div>
</p>
<p>
creates a built-in function <tt>example.fact(n)</tt> that works exactly like you think it does:
</p>
<p>
<div class="targetlang"><pre>octave:1&gt; example.fact(4)
24 </pre></div>
</p>
<p>
<H3><a name="Octave_nn10"></a>26.3.3 Global variables</H3>
@ -236,17 +212,14 @@ int fact(int n); </pre></div>
Global variables are a little special in Octave. Given a global variable:
</p>
<p>
<div class="code"><pre>%module example
extern double Foo;
</pre></div>
</p>
<p>
To expose variables, SWIG actually generates two functions, to get and set the value. In this case, Foo_set and Foo_set would be generated. SWIG then automatically calls these functions when you get and set the variable-- in the former case creating a local copy in the interpreter of the C variables, and in the latter case copying an interpreter variables onto the C variable.
</p>
<p>
<div class="targetlang"><pre>octave:1&gt; example;
octave:2&gt; c=example.cvar.Foo
c = 3
@ -255,42 +228,35 @@ octave:4&gt; c
c = 3
octave:5&gt; example.cvar.Foo
ans = 4</pre></div>
</p>
<p>
If a variable is marked with the %immutable directive then any attempts to set this variable will cause an Octave error. Given a global variable:
</p>
<p>
<div class="code"><pre>%module example
%immutable;
extern double Foo;
%mutable;
</pre></div>
</p>
<p>
SWIG will allow the the reading of <tt>Foo</tt> but when a set attempt is made, an error function will be called.
</p>
<p>
<div class="targetlang"><pre>octave:1&gt; example
octave:2&gt; example.Foo=4
error: attempt to set immutable member variable
error: assignment failed, or no method for `swig_type = scalar'
error: evaluating assignment expression near line 2, column 12 </pre></div>
</p>
<p>
It is possible to add new functions or variables to the module. This also allows the user to rename/remove existing functions and constants (but not linked variables, mutable or immutable). Therefore users are recommended to be careful when doing so.
</p>
<p>
<div class="targetlang"><pre>octave:1&gt; example;
octave:2&gt; example.PI=3.142;
octave:3&gt; example.PI
ans = 3.1420 </pre></div>
</p>
<H3><a name="Octave_nn11"></a>26.3.4 Constants and enums</H3>
@ -299,62 +265,50 @@ ans = 3.1420 </pre></div>
Because Octave doesn't really have the concept of constants, C/C++ constants are not really constant in Octave. They are actually just a copy of the value into the Octave interpreter. Therefore they can be changed just as any other value. For example given some constants:
</p>
<p>
<div class="code"><pre>%module example
%constant int ICONST=42;
#define SCONST "Hello World"
enum Days{SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY};
</pre></div>
</p>
<p>
This is 'effectively' converted into the following Octave code:
</p>
<p>
<div class="targetlang"><pre>example.ICONST=42
example.SCONST="Hello World"
example.SUNDAY=0
.... </pre></div>
</p>
<p>
<H3><a name="Octave_nn12"></a>26.3.5 Pointers</H3>
</p>
<p>
C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with incomplete type information. Given a wrapping of the &lt;file.h&gt; interface:
C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with incomplete type information. Given a wrapping of the &lt;file.h&gt; interface:
</p>
<p>
<div class="code"><pre>%module example
FILE *fopen(const char *filename, const char *mode);
int fputs(const char *, FILE *);
int fclose(FILE *);
</pre></div>
</p>
<p>
When wrapped, you will be able to use the functions in a natural way from Octave. For example:
</p>
<p>
<div class="targetlang"><pre>
octave:1&gt; example;
octave:2&gt; f=example.fopen("w","junk");
octave:3&gt; example.fputs("Hello world",f);
octave:4&gt; example.fclose(f);
</pre></div>
</p>
<p>
Simply printing the value of a wrapped C++ type will print it's typename. E.g.,
</p>
<p>
<div class="targetlang"><pre>octave:1&gt; example;
octave:2&gt; f=example.fopen("junk","w");
octave:3&gt; f
@ -363,18 +317,15 @@ f =
{
_p_FILE, ptr = 0x9b0cd00
} </pre></div>
</p>
<p>
As the user of the pointer, you are responsible for freeing it, or closing any resources associated with it (just as you would in a C program). This does not apply so strictly to classes and structs (see below).
</p>
<p>
<div class="targetlang"><pre>octave:1&gt; example;
octave:2&gt; f=example.fopen("not there","r");
error: value on right hand side of assignment is undefined
error: evaluating assignment expression near line 2, column 2 </pre></div>
</p>
<H3><a name="Octave_nn13"></a>26.3.6 Structures</H3>
@ -383,18 +334,15 @@ error: evaluating assignment expression near line 2, column 2 </pre></div>
SWIG wraps C structures and C++ classes by creating type objects. When invoked as a function, they create a new object of their type. The structures/classes themselves are mapped to a native Octave type. This provides a very natural interface. For example,
</p>
<p>
<div class="code"><pre>struct Point{
int x,y;
};
</pre></div>
</p>
<p>
is used as follows:
</p>
<p>
<div class="targetlang">
<pre>octave:1&gt; example;
octave:2&gt; p=example.Point();
@ -404,7 +352,6 @@ octave:5&gt; p.x, p.y
ans = 3
ans = 5
</pre></div>
</p>
<H3><a name="Octave_nn14"></a>26.3.7 C++ classes</H3>
@ -459,26 +406,22 @@ For example, the following:
struct A {
int value;
A(int _value) : value(_value) {}
A operator+ (const A& x) {
A operator+ (const A&amp; x) {
return A(value+x.value);
}
};
}
</pre></div>
</p>
<p>
may be used naturally from Octave:
</p>
<p>
<div class="targetlang"><pre>
a=A(2), b=A(3), c=a+b
assert(c.value==5);
</pre></div>
</p>
<p>
Octave operators are mapped in the following way:
</p>
<p>
<div class="code"><pre>
__brace a{args}
__brace_asgn a{args} = rhs
@ -510,14 +453,12 @@ __el_mul a .* b
__el_div a ./ b
__el_pow a .^ b
__el_ldiv a .\ b
__el_and a & b
__el_and a &amp; b
__el_or a | b
</pre></div>
</p>
<p>
On the C++ side, the default mappings are as follows:
</p>
<p>
<div class="code"><pre>
%rename(__add) *::operator+;
%rename(__add) *::operator+();
@ -530,7 +471,7 @@ On the C++ side, the default mappings are as follows:
%rename(__mod) *::operator%;
%rename(__lshift) *::operator<<;
%rename(__rshift) *::operator>>;
%rename(__el_and) *::operator&&;
%rename(__el_and) *::operator&amp;&amp;;
%rename(__el_or) *::operator||;
%rename(__xor) *::operator^;
%rename(__invert) *::operator~;
@ -556,7 +497,6 @@ The %extend directive works the same as in other modules.
<p>
You can use it to define special behavior, like for example defining Octave operators not mapped to C++ operators, or defining certain Octave mechanisms such as how an object prints. For example, the <tt>octave_value::{is_string,string_value,print}</tt> functions are routed to a special method <tt>__str</tt> that can be defined inside an %extend.
</p>
<p>
<div class="code"><pre>
%extend A {
string __str() {
@ -566,11 +506,9 @@ string __str() {
}
}
</pre></div>
</p>
<p>
Then in Octave one gets,
</p>
<p>
<div class="targetlang"><pre>
octave:1&gt; a=A(4);
octave:2&gt; a
@ -580,7 +518,6 @@ octave:3&gt; printf("%s\n",a);
octave:4&gt; a.__str()
4
</pre></div>
</p>
<H3><a name="Octave_nn20"></a>26.3.13 C++ templates</H3>
@ -607,19 +544,16 @@ Octave has no direct support for object oriented programming, however the <tt>sw
<p>
For example,
</p>
<p>
<div class="targetlang"><pre>
octave:1&gt; a=subclass();
octave:2&gt; a.my_var = 4;
octave:3&gt; a.my_method = @(self) printf("my_var = ",self.my_var);
octave:4&gt; a.my_method();
my_var = 4
</div></pre>
</p>
</pre></div>
<p>
<tt>subclass()</tt> can also be used to subclass one or more C++ types. Suppose you have an interface defined by
</p>
<p>
<div class="code"><pre>
%inline {
class A {
@ -628,16 +562,14 @@ public:
printf("c-side routine called\n");
}
};
void call_your_method(A& a) {
void call_your_method(A&amp; a) {
a.my_method();
}
}
</pre></div>
</p>
<p>
Then from Octave you can say:
</p>
<p>
<div class="targetlang"><pre>
octave:1&gt; B=@() subclass(A(),@my_method);
octave:2&gt; function my_method(self)
@ -646,35 +578,29 @@ octave:4&gt; end
octave:5&gt; call_your_method(B());
octave-side routine called
</pre></div>
</p>
<p>
or more concisely,
</p>
<p>
<div class="targetlang"><pre>
octave:1&gt; B=@() subclass(A(),'my_method',@(self) printf("octave-side routine called\n"));
octave:2&gt; call_your_method(B());
octave-side routine called
</pre></div>
</p>
<p>
Note that you have to enable directors via the %feature directive (see other modules for this).
</p>
<p>
<tt>subclass()</tt> will accept any number of C++ bases or other <tt>subclass()</tt>'ed objects, <tt>(string,octave_value)</tt> pairs, and <tt>function_handles</tt>. In the first case, these are taken as base classes; in the second case, as named members (either variables or functions, depending on whether the given value is a function handle); in the third case, as member functions whose name is taken from the given function handle. E.g.,
</p>
<p>
<div class="targetlang"><pre>
octave:1&gt; B=@(some_var=2) subclass(A(),'some_var',some_var,@some_func,'another_func',@(self) do_stuff())
</pre></div>
</p>
<p>
You can also assign non-C++ member variables and functions after construct time. There is no support for non-C++ static members.
</p>
<p>
There is limited support for explicitly referencing C++ bases. So, in the example above, we could have
</p>
<p>
<div class="targetlang"><pre>
octave:1&gt; B=@() subclass(A(),@my_method);
octave:2&gt; function my_method(self)
@ -685,7 +611,6 @@ octave:6&gt; call_your_method(B());
c-side routine called
octave-side routine called
</pre></div>
</p>
<H3><a name="Octave_nn23"></a>26.3.16 Threads</H3>
@ -711,11 +636,9 @@ public:
};
}
</pre></div>
</p>
<p>
Would produce this behavior in Octave:
</p>
<p>
<div class="targetlang"><pre>
octave:1&gt; a=A();
A constructing
@ -724,7 +647,6 @@ octave:3&gt; clear a;
octave:4&gt; b=4;
A destructing
</pre></div>
</p>
<p>
In the case where one wishes for the C++ side to own an object that was created in Octave (especially a Director object), one can use the __disown() method to invert this logic. Then letting the Octave reference count go to zero will not destroy the object, but destroying the object will invalidate the Octave-side object if it still exists (and call destructors of other C++ bases in the case of multiple inheritance/<tt>subclass()</tt>'ing).
</p>
@ -742,20 +664,16 @@ This is some skeleton support for various STL containers, but this work is not f
<p>
Octave provides a rich set of classes for dealing with matrices etc. Currently there are no typemaps to deal with those, though such support will be added soon. However, these are relatively straight forward for users to add themselves (see the docs on typemaps). Without much work (a single typemap decl-- say, 5 lines of code in the interface file), it would be possible to have a function
</p>
<p>
<div class="code"><pre>
double my_det(const double* mat,int m,int n);
</div></pre>
</p>
</pre></div>
<p>
that is accessed from Octave as,
</p>
<p>
<div class="targetlang"><pre>
octave:1&gt; my_det(rand(4));
ans = -0.18388
</div></pre>
</p>
</pre></div>
<tt><br></tt>
</body>

View file

@ -22,12 +22,12 @@ namespace test {
}
};
/* A minimalistic complex class */
class complex {
/* A minimalistic test_complex class */
class test_complex {
double re;
double im;
public:
complex(double r = 0, double i = 0) {
test_complex(double r = 0, double i = 0) {
re = r;
im = i;
}
@ -44,16 +44,29 @@ namespace test {
/* SWIG interface tests */
#ifdef SWIGPYTHON
%typemap(in) test::complex * {
%typemap(in) test::test_complex * {
if (PyComplex_Check($input)) {
$1 = new complex(PyComplex_RealAsDouble($input),
$1 = new test_complex(PyComplex_RealAsDouble($input),
PyComplex_ImagAsDouble($input));
} else {
PyErr_SetString(PyExc_TypeError,"Expected complex.\n");
PyErr_SetString(PyExc_TypeError,"Expected test_complex.\n");
return NULL;
}
}
%typemap(freearg) test::complex * {
%typemap(freearg) test::test_complex * {
delete $1;
}
#endif
#ifdef SWIGOCTAVE
%typemap(in) test::test_complex * {
if ($input.is_complex_scalar()) {
$1 = new test_complex($input.complex_value().real(),
$input.complex_value().imag());
} else {
error("Expected test_complex.");
}
}
%typemap(freearg) test::test_complex * {
delete $1;
}
#endif
@ -68,6 +81,14 @@ namespace test {
delete $1;
}
#endif
#ifdef SWIGOCTAVE
%typemap(in) string_class * {
$1 = new string_class($input.string_value().c_str());
}
%typemap(freearg) string_class * {
delete $1;
}
#endif
#ifdef SWIGRUBY
%typemap(in) string_class * {
$1 = new string_class(STR2CSTR($input));
@ -81,26 +102,26 @@ namespace test {
%inline %{
namespace test {
class string_class;
class complex;
class test_complex;
/* Functions in the namespace itself */
char *stest1(string_class *s) {
return s->c_str();
}
double ctest1(complex *c) {
double ctest1(test_complex *c) {
return c->real();
}
}
namespace test2 {
using test::string_class;
using test::complex;
using test::test_complex;
/* Functions in another namespace */
char *stest2(string_class *s) {
return s->c_str();
}
double ctest2(complex *c) {
double ctest2(test_complex *c) {
return c->real();
}
}
@ -111,7 +132,7 @@ namespace test {
char *stest3(string_class *s) {
return s->c_str();
}
double ctest3(complex *c) {
double ctest3(test_complex *c) {
return c->real();
}
}
@ -122,7 +143,7 @@ namespace test {
char *stest4(string_class *s) {
return s->c_str();
}
double ctest4(complex *c) {
double ctest4(test_complex *c) {
return c->real();
}
}
@ -133,7 +154,7 @@ namespace test {
char *stest5(string_class *s) {
return s->c_str();
}
double ctest5(complex *c) {
double ctest5(test_complex *c) {
return c->real();
}
}
@ -141,35 +162,35 @@ namespace test {
char *stest6(test::string_class *s) {
return s->c_str();
}
double ctest6(test::complex *c) {
double ctest6(test::test_complex *c) {
return c->real();
}
char *stest7(test2::string_class *s) {
return s->c_str();
}
double ctest7(test2::complex *c) {
double ctest7(test2::test_complex *c) {
return c->real();
}
char *stest8(test3::string_class *s) {
return s->c_str();
}
double ctest8(test3::complex *c) {
double ctest8(test3::test_complex *c) {
return c->real();
}
char *stest9(test4::string_class *s) {
return s->c_str();
}
double ctest9(test4::complex *c) {
double ctest9(test4::test_complex *c) {
return c->real();
}
char *stest10(test5::string_class *s) {
return s->c_str();
}
double ctest10(test5::complex *c) {
double ctest10(test5::test_complex *c) {
return c->real();
}
@ -178,17 +199,17 @@ namespace test {
char *stest11(test11::string_class *s) {
return s->c_str();
}
double ctest11(test11::complex *c) {
double ctest11(test11::test_complex *c) {
return c->real();
}
using namespace test2;
using test::complex;
using test::test_complex;
char *stest12(string_class *s) {
return s->c_str();
}
double ctest12(complex *c) {
double ctest12(test_complex *c) {
return c->real();
}
%}
@ -203,6 +224,14 @@ namespace Split {
}
}
#endif
#ifdef SWIGOCTAVE
%typemap(in) PosInteger {
$1 = $input.long_value();
if ($1 < 0) {
error("domain error");
}
}
#endif
#ifdef SWIGRUBY
%typemap(in) PosInteger {
$1 = NUM2INT($input);

View file

@ -13,8 +13,14 @@ srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
#CPP_TEST_CASES +=
# CPP_TEST_CASES +=
CPP_TEST_BROKEN += \
implicittest \
li_implicit \
li_std_map \
li_std_set \
li_std_stream
#C_TEST_CASES +=

View file

@ -1,18 +1,19 @@
arrays_global
arrays_global.array_i = arrays_global.array_const_i;
arrays_global.cvar.array_i = arrays_global.cvar.array_const_i;
BeginString_FIX44a;
BeginString_FIX44b;
BeginString_FIX44c;
BeginString_FIX44d;
BeginString_FIX44d;
BeginString_FIX44b ="12"'\0'"45";
BeginString_FIX44b;
BeginString_FIX44d;
BeginString_FIX44e;
BeginString_FIX44f;
cvar.BeginString_FIX44a;
cvar.BeginString_FIX44b;
cvar.BeginString_FIX44c;
cvar.BeginString_FIX44d;
cvar.BeginString_FIX44d;
cvar.BeginString_FIX44b = strcat("12","\0","45");
cvar.BeginString_FIX44b;
cvar.BeginString_FIX44d;
cvar.BeginString_FIX44e;
cvar.BeginString_FIX44f;
test_a("hello","hi","chello","chi");
test_b("1234567","hi");

View file

@ -5,28 +5,28 @@ if (!strcmp(p,"test"))
error("test failed!")
endif
p = constover.test_pconst("test")
p = constover.test_pconst("test");
if (!strcmp(p,"test_pconst"))
error("test_pconst failed!")
endif
f = constover.Foo()
p = f.test("test")
f = constover.Foo();
p = f.test("test");
if (!strcmp(p,"test"))
error("member-test failed!")
endif
p = f.test_pconst("test")
p = f.test_pconst("test");
if (!strcmp(p,"test_pconst"))
error("member-test_pconst failed!")
endif
p = f.test_constm("test")
p = f.test_constm("test");
if (!strcmp(p,"test_constmethod"))
error("member-test_constm failed!")
endif
p = f.test_pconstm("test")
p = f.test_pconstm("test");
if (!strcmp(p,"test_pconstmethod"))
error("member-test_pconstm failed!")
endif

View file

@ -0,0 +1,68 @@
%module(naturalvar="1") implicittest
%implicitconv;
%inline
{
struct B { };
}
%inline
{
struct A
{
int ii;
A(int i) { ii = 1; }
A(double d) { ii = 2; }
A(const B& b) { ii = 3; }
explicit A(char *s) { ii = 4; }
int get() const { return ii; }
};
int get(const A& a) { return a.ii; }
template <class T>
struct A_T
{
int ii;
A_T(int i) { ii = 1; }
A_T(double d) { ii = 2; }
A_T(const B& b) { ii = 3; }
explicit A_T(char *s) { ii = 4; }
int get() const { return ii; }
};
}
%inline
{
struct Foo
{
int ii;
Foo(){ ii = 0;}
Foo(int){ ii = 1;}
Foo(double){ ii = 2;}
explicit Foo(char *s){ii = 3;}
Foo(const Foo& f){ ii = f.ii;}
};
struct Bar
{
int ii;
Foo f;
Bar() {ii = -1;}
Bar(const Foo& ff){ ii = ff.ii;}
};
int get_b(const Bar&b) { return b.ii; }
Foo foo;
}
%template(A_int) A_T<int>;

View file

@ -1,12 +0,0 @@
langobj
x ="hello"
rx = sys.getrefcount(x)
v = identity(x)
rv = sys.getrefcount(v)
if v != x:
error
if rv - rx != 1:
error

View file

@ -47,9 +47,9 @@ if (b.a.c != 3)
endif
myFoo = li_attribute.MyFoo;
myFoo = li_attribute.MyFoo();
myFoo.x = 8;
myClass = li_attribute.MyClass;
myClass = li_attribute.MyClass();
myClass.Foo = myFoo;
if (myClass.Foo.x != 8)
error

View file

@ -10,10 +10,10 @@ function main()
li_boost_shared_ptr.cvar.debug_shared = debug;
# Change loop count to run for a long time to monitor memory
loopCount = 1 #5000
loopCount = 1; #5000
for i=0:loopCount,
self.runtest();
endif
endfor
if (li_boost_shared_ptr.Klass.getTotal_count() != 0)
error("Klass.total_count=", li_boost_shared_ptr.Klass.getTotal_count())
@ -454,10 +454,10 @@ function runtest()
# templates
pid = li_boost_shared_ptr.PairIntDouble(10, 20.2)
if (pid.baseVal1 != 20 or pid.baseVal2 != 40.4)
if (pid.baseVal1 != 20 || pid.baseVal2 != 40.4)
error("Base values wrong")
endif
if (pid.val1 != 10 or pid.val2 != 20.2)
if (pid.val1 != 10 || pid.val2 != 20.2)
error("Derived Values wrong")
endif
endfunction

View file

@ -0,0 +1,55 @@
%module li_std_string
%naturalvar A;
%include <std_basic_string.i>
%include <std_string.i>
%inline %{
struct A : std::string
{
A(const std::string& s) : std::string(s)
{
}
};
struct B
{
B(const std::string& s) : cname(0), name(s), a(s)
{
}
char *cname;
std::string name;
A a;
};
const char* test_ccvalue(const char* x) {
return x;
}
char* test_cvalue(char* x) {
return x;
}
std::basic_string<char> test_value_basic1(std::basic_string<char> x) {
return x;
}
std::basic_string<char,std::char_traits<char> > test_value_basic2(std::basic_string<char,std::char_traits<char> > x) {
return x;
}
std::basic_string<char,std::char_traits<char>,std::allocator<char> > test_value_basic3(std::basic_string<char,std::char_traits<char>,std::allocator<char> > x) {
return x;
}
%}
%include ../li_std_string.i

View file

@ -48,8 +48,8 @@ if (!strcmp(stest12("hello"),"hello"))
error
endif
c = complex(2,3)
r = c.real
c = complex(2,3);
r = real(c);
if (ctest1(c) != r)
error

View file

@ -3,6 +3,6 @@ overload_rename
f = overload_rename.Foo(1);
f = overload_rename.Foo(1,1);
f = overload_rename.Foo_int(1,1);
f = overload_rename.Foo_int(1,1,1);
f = overload_rename.new_Foo_int(1,1);
f = overload_rename.new_Foo_int(1,1,1);

View file

@ -13,22 +13,3 @@ if (a.ref_count() != 3)
endif
rca = b2.get_rca();
b3 = B.create(rca);
if (a.ref_count() != 5)
error("This program will crash... now")
endif
v = vector_A(2);
v(0) = a;
v(1) = a;
x = v(0);
clear v;

View file

@ -2,7 +2,7 @@ template_default_arg
helloInt = template_default_arg.Hello_int();
helloInt.foo(template_default_arg.Hello_int.hi);
helloInt.foo(template_default_arg.Hello_int_hi);
x = template_default_arg.X_int();
@ -18,7 +18,7 @@ endif
y = template_default_arg.Y_unsigned()
y = template_default_arg.Y_unsigned();
if (y.meth(20.0, 200) != 200)
error("Y_unsigned test 1 failed")
endif
@ -33,7 +33,7 @@ endif
x = template_default_arg.X_longlong();
x = template_default_arg.X_longlong(20.0);
x = template_default_arg.X_longlong(20.0, 200L);
x = template_default_arg.X_longlong(20.0, 200);
x = template_default_arg.X_int();
@ -49,7 +49,7 @@ x = template_default_arg.X_hello_unsigned(20.0, template_default_arg.Hello_int()
y = template_default_arg.Y_hello_unsigned();
y.meth(20.0, template_default_arg.Hello_int());
y.meth(template_default_arg.Hello_int());
y.meth()
y.meth();

View file

@ -1,7 +1,5 @@
template_type_namespace
if (!strcmp(typeinfo(foo()(0)),typeinfo("")))
error
endif
assert(strcmp(foo()(1),"foo"));

View file

@ -228,6 +228,7 @@ This testcase tests operators for defines
#ifndef SWIGOCTAVE
#ifdef __cplusplus
#define %mangle(...) #@__VA_ARGS__
@ -245,6 +246,7 @@ inline const char* mangle ## #@__VA_ARGS__ () {
}
#endif
#endif
#if defined (__cplusplus) \

View file

@ -1,7 +1,7 @@
from template_typedef import *
d = make_Identity_float()
c = make_Identity_real()
c = make_Identity_reald()
try:
@ -18,14 +18,14 @@ except:
raise RuntimeError
try:
f = make_Multiplies_real_real_real_real(c, c)
f = make_Multiplies_reald_reald_reald_reald(c, c)
a = f.this
except:
print f, "is not an instance"
raise RuntimeError
try:
g = make_Multiplies_float_float_real_real(d, c)
g = make_Multiplies_float_float_reald_reald(d, c)
a = g.this
except:
print g, "is not an instance"

View file

@ -55,7 +55,7 @@
%}
#ifdef SWIGPYTHON
#if defined(SWIGPYTHON)
%extend_smart_pointer(RCPtr<A>);
%template(RCPtr_A) RCPtr<A>;
#endif
@ -96,7 +96,7 @@
%}
#ifdef SWIGPYTHON
#if defined(SWIGPYTHON) || defined(SWIGOCTAVE)
%include <std_vector.i>
%template(vector_A) std::vector<RCPtr<A> >;

View file

@ -1,14 +1,14 @@
%module template_arg_replace
%warnfilter(SWIGWARN_RUBY_WRONG_NAME) Matrix<float, 3, 3>; /* Ruby, wrong class name */
%warnfilter(SWIGWARN_RUBY_WRONG_NAME) test_Matrix<float, 3, 3>; /* Ruby, wrong class name */
%inline %{
template <typename T, int r, int c> class Matrix {
template <typename T, int r, int c> class test_Matrix {
public:
void Func(const Matrix<T,r,c> &m) { };
void Func(const test_Matrix<T,r,c> &m) { };
};
%}
%template (matrix33f) Matrix<float,3, 3>;
%template (matrix33f) test_Matrix<float,3, 3>;

View file

@ -8,15 +8,15 @@
//
#if 0
#define real double
#define reald double
%{
#define real double
#define reald double
%}
#else
%inline %{
typedef double real;
typedef double reald;
%}
#endif
@ -24,7 +24,7 @@
%inline %{
// typedef double real;
// typedef double reald;
namespace vfncs {
@ -78,29 +78,29 @@
};
template<>
struct arith_traits< real, real >
struct arith_traits< reald, reald >
{
typedef real argument_type;
typedef real result_type;
typedef reald argument_type;
typedef reald result_type;
static const char* const arg_type;
static const char* const res_type;
};
template<>
struct arith_traits< real, float >
struct arith_traits< reald, float >
{
typedef float argument_type;
typedef real result_type;
typedef reald result_type;
static const char* const arg_type;
static const char* const res_type;
};
template<>
struct arith_traits< float, real >
struct arith_traits< float, reald >
{
typedef float argument_type;
typedef real result_type;
typedef reald result_type;
static const char* const arg_type;
static const char* const res_type;
};
@ -124,14 +124,14 @@
const char* const arith_traits< float, float >::arg_type = "float";
const char* const arith_traits< float, float >::res_type = "float";
const char* const arith_traits< real, real >::arg_type = "real";
const char* const arith_traits< real, real >::res_type = "real";
const char* const arith_traits< reald, reald >::arg_type = "reald";
const char* const arith_traits< reald, reald >::res_type = "reald";
const char* const arith_traits< real, float >::arg_type = "float";
const char* const arith_traits< real, float >::res_type = "real";
const char* const arith_traits< reald, float >::arg_type = "float";
const char* const arith_traits< reald, float >::res_type = "reald";
const char* const arith_traits< float, real >::arg_type = "float";
const char* const arith_traits< float, real >::res_type = "real";
const char* const arith_traits< float, reald >::arg_type = "float";
const char* const arith_traits< float, reald >::res_type = "reald";
#endif
@ -145,32 +145,32 @@ namespace vfncs {
%template() arith_traits<float, float >;
%template(make_Identity_float) make_Identity<float >;
%template(UnaryFunction_real_real) UnaryFunction<real, real >;
%template(ArithUnaryFunction_real_real) ArithUnaryFunction<real, real >;
%template(UnaryFunction_reald_reald) UnaryFunction<reald, reald >;
%template(ArithUnaryFunction_reald_reald) ArithUnaryFunction<reald, reald >;
%template() unary_func_traits<real, real >;
%template() arith_traits<real, real >;
%template(make_Identity_real) make_Identity<real >;
%template() unary_func_traits<reald, reald >;
%template() arith_traits<reald, reald >;
%template(make_Identity_reald) make_Identity<reald >;
/* [beazley] Added this part */
%template() unary_func_traits<float,real>;
%template(UnaryFunction_float_real) UnaryFunction<float,real>;
%template(ArithUnaryFunction_float_real) ArithUnaryFunction<float,real>;
%template() unary_func_traits<float,reald>;
%template(UnaryFunction_float_reald) UnaryFunction<float,reald>;
%template(ArithUnaryFunction_float_reald) ArithUnaryFunction<float,reald>;
/* */
%template() arith_traits<real, float >;
%template() arith_traits<float, real >;
%template() arith_traits<reald, float >;
%template() arith_traits<float, reald >;
%template() arith_traits<float, float >;
%template(make_Multiplies_float_float_real_real)
make_Multiplies<float, float, real, real>;
%template(make_Multiplies_float_float_reald_reald)
make_Multiplies<float, float, reald, reald>;
%template(make_Multiplies_float_float_float_float)
make_Multiplies<float, float, float, float>;
%template(make_Multiplies_real_real_real_real)
make_Multiplies<real, real, real, real>;
%template(make_Multiplies_reald_reald_reald_reald)
make_Multiplies<reald, reald, reald, reald>;
}

Some files were not shown because too many files have changed in this diff Show more