Convert to unix fileformat

This commit is contained in:
William S Fulton 2013-01-12 16:54:45 +00:00
commit 079165abe2
22 changed files with 2479 additions and 2479 deletions

View file

@ -1,18 +1,18 @@
TOP = ../..
SWIG = $(TOP)/../preinst-swig
SRCS = example.c
TARGET = example
INTERFACE = example.i
all::
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua
static::
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
TARGET='mylua' INTERFACE='$(INTERFACE)' lua_static
clean::
$(MAKE) -f $(TOP)/Makefile lua_clean
check: all
TOP = ../..
SWIG = $(TOP)/../preinst-swig
SRCS = example.c
TARGET = example
INTERFACE = example.i
all::
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua
static::
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
TARGET='mylua' INTERFACE='$(INTERFACE)' lua_static
clean::
$(MAKE) -f $(TOP)/Makefile lua_clean
check: all

View file

@ -1,25 +1,25 @@
/* File : example.c */
#include <stdlib.h>
/* we are using the qsort function, which needs a helper function to sort */
int compare_int(const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
void sort_int(int* arr, int len)
{
qsort(arr, len, sizeof(int), compare_int);
}
// ditto doubles
int compare_double(const void * a, const void * b)
{
return (int)( *(double*)a - *(double*)b );
}
void sort_double(double* arr, int len)
{
qsort(arr, len, sizeof(double), compare_double);
}
/* File : example.c */
#include <stdlib.h>
/* we are using the qsort function, which needs a helper function to sort */
int compare_int(const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
void sort_int(int* arr, int len)
{
qsort(arr, len, sizeof(int), compare_int);
}
// ditto doubles
int compare_double(const void * a, const void * b)
{
return (int)( *(double*)a - *(double*)b );
}
void sort_double(double* arr, int len)
{
qsort(arr, len, sizeof(double), compare_double);
}

View file

@ -1,42 +1,42 @@
/* File : example.i */
%module example
/* in this file there are two sorting functions
and three different ways to wrap them.
See the lua code for how they are called
*/
%include <carrays.i> // array helpers
// this declares a batch of function for manipulating C integer arrays
%array_functions(int,int)
// this adds some lua code directly into the module
// warning: you need the example. prefix if you want it added into the module
// addmittedly this code is a bit tedious, but its a one off effort
%luacode {
function example.sort_int2(t)
local len=table.maxn(t) -- the len
local arr=example.new_int(len)
for i=1,len do
example.int_setitem(arr,i-1,t[i]) -- note: C index is one less then lua indea
end
example.sort_int(arr,len) -- call the fn
-- copy back
for i=1,len do
t[i]=example.int_getitem(arr,i-1) -- note: C index is one less then lua indea
end
example.delete_int(arr) -- must delete it
end
}
// this way uses the SWIG-Lua typemaps to do the conversion for us
// the %apply command states to apply this wherever the argument signature matches
%include <typemaps.i>
%apply (double *INOUT,int) {(double* arr,int len)};
%inline %{
extern void sort_int(int* arr, int len);
extern void sort_double(double* arr, int len);
%}
/* File : example.i */
%module example
/* in this file there are two sorting functions
and three different ways to wrap them.
See the lua code for how they are called
*/
%include <carrays.i> // array helpers
// this declares a batch of function for manipulating C integer arrays
%array_functions(int,int)
// this adds some lua code directly into the module
// warning: you need the example. prefix if you want it added into the module
// addmittedly this code is a bit tedious, but its a one off effort
%luacode {
function example.sort_int2(t)
local len=table.maxn(t) -- the len
local arr=example.new_int(len)
for i=1,len do
example.int_setitem(arr,i-1,t[i]) -- note: C index is one less then lua indea
end
example.sort_int(arr,len) -- call the fn
-- copy back
for i=1,len do
t[i]=example.int_getitem(arr,i-1) -- note: C index is one less then lua indea
end
example.delete_int(arr) -- must delete it
end
}
// this way uses the SWIG-Lua typemaps to do the conversion for us
// the %apply command states to apply this wherever the argument signature matches
%include <typemaps.i>
%apply (double *INOUT,int) {(double* arr,int len)};
%inline %{
extern void sort_int(int* arr, int len);
extern void sort_double(double* arr, int len);
%}

View file

@ -1,74 +1,74 @@
---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
-- lua5.0 doesnt have a nice way to do this
lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
assert(lib)()
else
-- lua 5.1 does
require('example')
end
-- a helper to print a Lua table
function print_table(t)
print(table.concat(t,","))
end
-- a helper to print a C array
function print_array(arr,len)
for i=0,len-1 do
io.write(example.int_getitem(arr,i),",")
end
io.write("\n")
end
math.randomseed(0) -- init random
--[[ version 1: passing a C array to the code
lets test call sort_int()
this requires a C array, so is the hardest to use]]
ARRAY_SIZE=10
arr=example.new_int(ARRAY_SIZE)
for i=0,ARRAY_SIZE-1 do
example.int_setitem(arr,i,math.random(1000))
end
print "unsorted"
print_array(arr,ARRAY_SIZE)
example.sort_int(arr,ARRAY_SIZE)
print "sorted"
print_array(arr,ARRAY_SIZE)
example.delete_int(arr) -- must delete it
print ""
--[[ version 2: using %luacode to write a helper
a simpler way is to use a %luacode
which is a lua function added into the module
this can do the conversion for us
so we can just add a lua table directly
(what we do is move the lua code into the module instead)
]]
t={}
for i=1,ARRAY_SIZE do
t[i]=math.random(1000)
end
print "unsorted"
print_table(t)
example.sort_int2(t) -- calls lua helper which then calls C
print "sorted"
print_table(t)
print ""
--[[ version 3: use a typemap
this is the best way
it uses the SWIG-Lua typemaps to do the work
one item of note: the typemap creates a copy, rather than edit-in-place]]
t={}
for i=1,ARRAY_SIZE do
t[i]=math.random(1000)/10
end
print "unsorted"
print_table(t)
t=example.sort_double(t) -- replace t with the result
print "sorted"
print_table(t)
---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
-- lua5.0 doesnt have a nice way to do this
lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
assert(lib)()
else
-- lua 5.1 does
require('example')
end
-- a helper to print a Lua table
function print_table(t)
print(table.concat(t,","))
end
-- a helper to print a C array
function print_array(arr,len)
for i=0,len-1 do
io.write(example.int_getitem(arr,i),",")
end
io.write("\n")
end
math.randomseed(0) -- init random
--[[ version 1: passing a C array to the code
lets test call sort_int()
this requires a C array, so is the hardest to use]]
ARRAY_SIZE=10
arr=example.new_int(ARRAY_SIZE)
for i=0,ARRAY_SIZE-1 do
example.int_setitem(arr,i,math.random(1000))
end
print "unsorted"
print_array(arr,ARRAY_SIZE)
example.sort_int(arr,ARRAY_SIZE)
print "sorted"
print_array(arr,ARRAY_SIZE)
example.delete_int(arr) -- must delete it
print ""
--[[ version 2: using %luacode to write a helper
a simpler way is to use a %luacode
which is a lua function added into the module
this can do the conversion for us
so we can just add a lua table directly
(what we do is move the lua code into the module instead)
]]
t={}
for i=1,ARRAY_SIZE do
t[i]=math.random(1000)
end
print "unsorted"
print_table(t)
example.sort_int2(t) -- calls lua helper which then calls C
print "sorted"
print_table(t)
print ""
--[[ version 3: use a typemap
this is the best way
it uses the SWIG-Lua typemaps to do the work
one item of note: the typemap creates a copy, rather than edit-in-place]]
t={}
for i=1,ARRAY_SIZE do
t[i]=math.random(1000)/10
end
print "unsorted"
print_table(t)
t=example.sort_double(t) -- replace t with the result
print "sorted"
print_table(t)

View file

@ -1,85 +1,85 @@
/* embed.c a simple test for an embeded interpreter
The idea is that we wrapper a few simple function (example.c)
and write our own app to call it.
What it will do is load the wrappered lib, load runme.lua and then call some functions.
To make life easier, all the printf's have either [C] or [Lua] at the start
so you can see where they are coming from.
We will be using the luaL_dostring()/lua_dostring() function to call into lua
*/
#include <stdlib.h>
#include <stdio.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
/* the SWIG wrappered library */
extern int luaopen_example(lua_State*L);
/* a really simple way of calling lua from C
just give it a lua state & a string to execute
Unfortunately lua keeps changing its API's.
In lua 5.0.X its lua_dostring()
In lua 5.1.X its luaL_dostring()
so we have a few extra compiles
*/
int dostring(lua_State *L, char* str) {
int ok;
#if (defined(LUA_VERSION_NUM) && (LUA_VERSION_NUM>=501))
ok=luaL_dostring(L,str); /* looks like this is lua 5.1.X or later, good */
#else
ok=lua_dostring(L,str); /* might be lua 5.0.x, using lua_dostring */
#endif
if (ok!=0)
printf("[C] ERROR in dostring: %s\n",lua_tostring(L,-1));
return ok;
}
int main(int argc,char* argv[]) {
lua_State *L;
int ok;
printf("[C] Welcome to the simple embedded lua example\n");
printf("[C] We are in C\n");
printf("[C] opening a lua state & loading the libraries\n");
L=lua_open();
luaopen_base(L);
luaopen_string(L);
luaopen_math(L);
printf("[C] now loading the SWIG wrappered library\n");
luaopen_example(L);
printf("[C] all looks ok\n");
printf("\n");
printf("[C] lets load the file 'runme.lua'\n");
printf("[C] any lua code in this file will be executed\n");
if (luaL_loadfile(L, "runme.lua") || lua_pcall(L, 0, 0, 0)) {
printf("[C] ERROR: cannot run lua file: %s",lua_tostring(L, -1));
exit(3);
}
printf("[C] We are now back in C, all looks ok\n");
printf("\n");
printf("[C] lets call the function 'do_tests()'\n");
ok=dostring(L,"do_tests()");
printf("[C] We are back in C, the dostring() function returned %d\n",ok);
printf("\n");
printf("[C] Lets call lua again, but create an error\n");
ok=dostring(L,"no_such_function()");
printf("[C] We are back in C, the dostring() function returned %d\n",ok);
printf("[C] it should also have returned 1 and printed an error message\n");
printf("\n");
printf("[C] Lets call lua again, calling the greeting function\n");
ok=dostring(L,"call_greeting()");
printf("[C] This was C=>Lua=>C (getting a bit complex)\n");
printf("\n");
printf("[C] all finished, closing the lua state\n");
lua_close(L);
return 0;
}
/* embed.c a simple test for an embeded interpreter
The idea is that we wrapper a few simple function (example.c)
and write our own app to call it.
What it will do is load the wrappered lib, load runme.lua and then call some functions.
To make life easier, all the printf's have either [C] or [Lua] at the start
so you can see where they are coming from.
We will be using the luaL_dostring()/lua_dostring() function to call into lua
*/
#include <stdlib.h>
#include <stdio.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
/* the SWIG wrappered library */
extern int luaopen_example(lua_State*L);
/* a really simple way of calling lua from C
just give it a lua state & a string to execute
Unfortunately lua keeps changing its API's.
In lua 5.0.X its lua_dostring()
In lua 5.1.X its luaL_dostring()
so we have a few extra compiles
*/
int dostring(lua_State *L, char* str) {
int ok;
#if (defined(LUA_VERSION_NUM) && (LUA_VERSION_NUM>=501))
ok=luaL_dostring(L,str); /* looks like this is lua 5.1.X or later, good */
#else
ok=lua_dostring(L,str); /* might be lua 5.0.x, using lua_dostring */
#endif
if (ok!=0)
printf("[C] ERROR in dostring: %s\n",lua_tostring(L,-1));
return ok;
}
int main(int argc,char* argv[]) {
lua_State *L;
int ok;
printf("[C] Welcome to the simple embedded lua example\n");
printf("[C] We are in C\n");
printf("[C] opening a lua state & loading the libraries\n");
L=lua_open();
luaopen_base(L);
luaopen_string(L);
luaopen_math(L);
printf("[C] now loading the SWIG wrappered library\n");
luaopen_example(L);
printf("[C] all looks ok\n");
printf("\n");
printf("[C] lets load the file 'runme.lua'\n");
printf("[C] any lua code in this file will be executed\n");
if (luaL_loadfile(L, "runme.lua") || lua_pcall(L, 0, 0, 0)) {
printf("[C] ERROR: cannot run lua file: %s",lua_tostring(L, -1));
exit(3);
}
printf("[C] We are now back in C, all looks ok\n");
printf("\n");
printf("[C] lets call the function 'do_tests()'\n");
ok=dostring(L,"do_tests()");
printf("[C] We are back in C, the dostring() function returned %d\n",ok);
printf("\n");
printf("[C] Lets call lua again, but create an error\n");
ok=dostring(L,"no_such_function()");
printf("[C] We are back in C, the dostring() function returned %d\n",ok);
printf("[C] it should also have returned 1 and printed an error message\n");
printf("\n");
printf("[C] Lets call lua again, calling the greeting function\n");
ok=dostring(L,"call_greeting()");
printf("[C] This was C=>Lua=>C (getting a bit complex)\n");
printf("\n");
printf("[C] all finished, closing the lua state\n");
lua_close(L);
return 0;
}

View file

@ -1,22 +1,22 @@
/* File : example.c */
#include <stdio.h>
/* A global variable */
double Foo = 3.0;
/* Compute the greatest common divisor of positive integers */
int gcd(int x, int y) {
int g;
g = y;
while (x > 0) {
g = x;
x = y % x;
y = g;
}
return g;
}
void greeting() {
printf("Hello from the C function 'greeting'\n");
}
/* File : example.c */
#include <stdio.h>
/* A global variable */
double Foo = 3.0;
/* Compute the greatest common divisor of positive integers */
int gcd(int x, int y) {
int g;
g = y;
while (x > 0) {
g = x;
x = y % x;
y = g;
}
return g;
}
void greeting() {
printf("Hello from the C function 'greeting'\n");
}

View file

@ -1,233 +1,233 @@
/* embed2.c some more test for an embeded interpreter
This will go a bit further as it will pass values to and from the lua code.
It uses less of the SWIG code, and more of the raw lua API's
What it will do is load the wrappered lib, load runme.lua and then call some functions.
To make life easier, all the printf's have either [C] or [Lua] at the start
so you can see where they are coming from.
We will be using the luaL_dostring()/lua_dostring() function to call into lua
*/
/* Deal with Microsoft's attempt at deprecating C standard runtime functions */
#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
# define _CRT_SECURE_NO_DEPRECATE
#endif
/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */
#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE)
# define _SCL_SECURE_NO_DEPRECATE
#endif
#include <stdlib.h>
#include <stdio.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#include <stdarg.h>
#include <string.h>
/* the SWIG wrappered library */
extern int luaopen_example(lua_State*L);
/* This is an example of how to call the Lua function
int add(int,int)
its very tedious, but gives you an idea of the issues involded.
(look below for a better idea)
*/
int call_add(lua_State *L,int a,int b,int* res) {
int top;
/* ok, here we go:
push a, push b, call 'add' check & return res
*/
top=lua_gettop(L); /* for later */
lua_pushstring(L, "add"); /* function name */
lua_gettable(L, LUA_GLOBALSINDEX); /* function to be called */
if (!lua_isfunction(L,-1)) {
printf("[C] error: cannot find function 'add'\n");
lua_settop(L,top); // reset
return 0;
}
lua_pushnumber(L,a);
lua_pushnumber(L,b);
if (lua_pcall(L, 2, 1, 0) != 0) /* call function with 2 arguments and 1 result */
{
printf("[C] error running function `add': %s\n",lua_tostring(L, -1));
lua_settop(L,top); // reset
return 0;
}
// check results
if (!lua_isnumber(L,-1)) {
printf("[C] error: returned value is not a number\n");
lua_settop(L,top); // reset
return 0;
}
*res=(int)lua_tonumber(L,-1);
lua_settop(L,top); /* reset stack */
return 1; // ok
}
/* This is a variargs call function for calling from C into Lua.
Original Code from Programming in Lua (PIL) by Roberto Ierusalimschy
ISBN 85-903798-1-7
http://www.lua.org/pil/25.3.html
This has been modified slightly to make it compile, and its still a bit rough.
But it gives the idea of how to make it work.
*/
int call_va (lua_State *L,const char *func, const char *sig, ...) {
va_list vl;
int narg, nres; /* number of arguments and results */
int top;
top=lua_gettop(L); /* for later */
va_start(vl, sig);
lua_getglobal(L, func); /* get function */
/* push arguments */
narg = 0;
while (*sig) { /* push arguments */
switch (*sig++) {
case 'd': /* double argument */
lua_pushnumber(L, va_arg(vl, double));
break;
case 'i': /* int argument */
lua_pushnumber(L, va_arg(vl, int));
break;
case 's': /* string argument */
lua_pushstring(L, va_arg(vl, char *));
break;
case '>':
goto endwhile;
default:
printf("invalid option (%c)\n", *(sig - 1));
goto fail;
}
narg++;
/* do we need this?*/
/* luaL_checkstack(L, 1, "too many arguments"); */
}
endwhile:
/* do the call */
nres = (int)strlen(sig); /* number of expected results */
if (lua_pcall(L, narg, nres, 0) != 0) /* do the call */
{
printf("error running function `%s': %s\n",func, lua_tostring(L, -1));
goto fail;
}
/* retrieve results */
nres = -nres; /* stack index of first result */
while (*sig) { /* get results */
switch (*sig++) {
case 'd': /* double result */
if (!lua_isnumber(L, nres)) {
printf("wrong result type\n");
goto fail;
}
*va_arg(vl, double *) = lua_tonumber(L, nres);
break;
case 'i': /* int result */
if (!lua_isnumber(L, nres)) {
printf("wrong result type\n");
goto fail;
}
*va_arg(vl, int *) = (int)lua_tonumber(L, nres);
break;
case 's': /* string result */
if (!lua_isstring(L, nres)) {
printf("wrong result type\n");
goto fail;
}
strcpy(va_arg(vl, char *),lua_tostring(L, nres));/* WARNING possible buffer overflow */
break;
default: {
printf("invalid option (%c)", *(sig - 1));
goto fail;
}
}
nres++;
}
va_end(vl);
lua_settop(L,top); /* reset stack */
return 1; /* ok */
fail:
lua_settop(L,top); /* reset stack */
return 0; /* error */
}
int main(int argc,char* argv[]) {
lua_State *L;
int ok;
int res;
char str[80];
printf("[C] Welcome to the simple embedded Lua example v2\n");
printf("[C] We are in C\n");
printf("[C] opening a Lua state & loading the libraries\n");
L=lua_open();
luaopen_base(L);
luaopen_string(L);
luaopen_math(L);
printf("[C] now loading the SWIG wrappered library\n");
luaopen_example(L);
printf("[C] all looks ok\n");
printf("\n");
printf("[C] lets load the file 'runme.lua'\n");
printf("[C] any lua code in this file will be executed\n");
if (luaL_loadfile(L, "runme.lua") || lua_pcall(L, 0, 0, 0)) {
printf("[C] ERROR: cannot run lua file: %s",lua_tostring(L, -1));
exit(3);
}
printf("[C] We are now back in C, all looks ok\n");
printf("\n");
printf("[C] lets call the Lua function 'add(1,1)'\n");
printf("[C] using the C function 'call_add'\n");
ok=call_add(L,1,1,&res);
printf("[C] the function returned %d with value %d\n",ok,res);
printf("\n");
printf("[C] lets do this rather easier\n");
printf("[C] we will call the same Lua function using a generic C function 'call_va'\n");
ok=call_va(L,"add","ii>i",1,1,&res);
printf("[C] the function returned %d with value %d\n",ok,res);
printf("\n");
printf("[C] we will now use the same generic C function to call 'append(\"cat\",\"dog\")'\n");
ok=call_va(L,"append","ss>s","cat","dog",str);
printf("[C] the function returned %d with value %s\n",ok,str);
printf("\n");
printf("[C] we can also make some bad calls to ensure the code doesn't fail\n");
printf("[C] calling adds(1,2)\n");
ok=call_va(L,"adds","ii>i",1,2,&res);
printf("[C] the function returned %d with value %d\n",ok,res);
printf("[C] calling add(1,'fred')\n");
ok=call_va(L,"add","is>i",1,"fred",&res);
printf("[C] the function returned %d with value %d\n",ok,res);
printf("\n");
printf("[C] Note: no protection if you mess up the va-args, this is C\n");
printf("\n");
printf("[C] Finally we will call the wrappered gcd function gdc(6,9):\n");
printf("[C] This will pass the values to Lua, then call the wrappered function\n");
printf(" Which will get the values from Lua, call the C code \n");
printf(" and return the value to Lua and eventually back to C\n");
printf("[C] Certainly not the best way to do it :-)\n");
ok=call_va(L,"gcd","ii>i",6,9,&res);
printf("[C] the function returned %d with value %d\n",ok,res);
printf("\n");
printf("[C] all finished, closing the lua state\n");
lua_close(L);
return 0;
}
/* embed2.c some more test for an embeded interpreter
This will go a bit further as it will pass values to and from the lua code.
It uses less of the SWIG code, and more of the raw lua API's
What it will do is load the wrappered lib, load runme.lua and then call some functions.
To make life easier, all the printf's have either [C] or [Lua] at the start
so you can see where they are coming from.
We will be using the luaL_dostring()/lua_dostring() function to call into lua
*/
/* Deal with Microsoft's attempt at deprecating C standard runtime functions */
#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
# define _CRT_SECURE_NO_DEPRECATE
#endif
/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */
#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE)
# define _SCL_SECURE_NO_DEPRECATE
#endif
#include <stdlib.h>
#include <stdio.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#include <stdarg.h>
#include <string.h>
/* the SWIG wrappered library */
extern int luaopen_example(lua_State*L);
/* This is an example of how to call the Lua function
int add(int,int)
its very tedious, but gives you an idea of the issues involded.
(look below for a better idea)
*/
int call_add(lua_State *L,int a,int b,int* res) {
int top;
/* ok, here we go:
push a, push b, call 'add' check & return res
*/
top=lua_gettop(L); /* for later */
lua_pushstring(L, "add"); /* function name */
lua_gettable(L, LUA_GLOBALSINDEX); /* function to be called */
if (!lua_isfunction(L,-1)) {
printf("[C] error: cannot find function 'add'\n");
lua_settop(L,top); // reset
return 0;
}
lua_pushnumber(L,a);
lua_pushnumber(L,b);
if (lua_pcall(L, 2, 1, 0) != 0) /* call function with 2 arguments and 1 result */
{
printf("[C] error running function `add': %s\n",lua_tostring(L, -1));
lua_settop(L,top); // reset
return 0;
}
// check results
if (!lua_isnumber(L,-1)) {
printf("[C] error: returned value is not a number\n");
lua_settop(L,top); // reset
return 0;
}
*res=(int)lua_tonumber(L,-1);
lua_settop(L,top); /* reset stack */
return 1; // ok
}
/* This is a variargs call function for calling from C into Lua.
Original Code from Programming in Lua (PIL) by Roberto Ierusalimschy
ISBN 85-903798-1-7
http://www.lua.org/pil/25.3.html
This has been modified slightly to make it compile, and its still a bit rough.
But it gives the idea of how to make it work.
*/
int call_va (lua_State *L,const char *func, const char *sig, ...) {
va_list vl;
int narg, nres; /* number of arguments and results */
int top;
top=lua_gettop(L); /* for later */
va_start(vl, sig);
lua_getglobal(L, func); /* get function */
/* push arguments */
narg = 0;
while (*sig) { /* push arguments */
switch (*sig++) {
case 'd': /* double argument */
lua_pushnumber(L, va_arg(vl, double));
break;
case 'i': /* int argument */
lua_pushnumber(L, va_arg(vl, int));
break;
case 's': /* string argument */
lua_pushstring(L, va_arg(vl, char *));
break;
case '>':
goto endwhile;
default:
printf("invalid option (%c)\n", *(sig - 1));
goto fail;
}
narg++;
/* do we need this?*/
/* luaL_checkstack(L, 1, "too many arguments"); */
}
endwhile:
/* do the call */
nres = (int)strlen(sig); /* number of expected results */
if (lua_pcall(L, narg, nres, 0) != 0) /* do the call */
{
printf("error running function `%s': %s\n",func, lua_tostring(L, -1));
goto fail;
}
/* retrieve results */
nres = -nres; /* stack index of first result */
while (*sig) { /* get results */
switch (*sig++) {
case 'd': /* double result */
if (!lua_isnumber(L, nres)) {
printf("wrong result type\n");
goto fail;
}
*va_arg(vl, double *) = lua_tonumber(L, nres);
break;
case 'i': /* int result */
if (!lua_isnumber(L, nres)) {
printf("wrong result type\n");
goto fail;
}
*va_arg(vl, int *) = (int)lua_tonumber(L, nres);
break;
case 's': /* string result */
if (!lua_isstring(L, nres)) {
printf("wrong result type\n");
goto fail;
}
strcpy(va_arg(vl, char *),lua_tostring(L, nres));/* WARNING possible buffer overflow */
break;
default: {
printf("invalid option (%c)", *(sig - 1));
goto fail;
}
}
nres++;
}
va_end(vl);
lua_settop(L,top); /* reset stack */
return 1; /* ok */
fail:
lua_settop(L,top); /* reset stack */
return 0; /* error */
}
int main(int argc,char* argv[]) {
lua_State *L;
int ok;
int res;
char str[80];
printf("[C] Welcome to the simple embedded Lua example v2\n");
printf("[C] We are in C\n");
printf("[C] opening a Lua state & loading the libraries\n");
L=lua_open();
luaopen_base(L);
luaopen_string(L);
luaopen_math(L);
printf("[C] now loading the SWIG wrappered library\n");
luaopen_example(L);
printf("[C] all looks ok\n");
printf("\n");
printf("[C] lets load the file 'runme.lua'\n");
printf("[C] any lua code in this file will be executed\n");
if (luaL_loadfile(L, "runme.lua") || lua_pcall(L, 0, 0, 0)) {
printf("[C] ERROR: cannot run lua file: %s",lua_tostring(L, -1));
exit(3);
}
printf("[C] We are now back in C, all looks ok\n");
printf("\n");
printf("[C] lets call the Lua function 'add(1,1)'\n");
printf("[C] using the C function 'call_add'\n");
ok=call_add(L,1,1,&res);
printf("[C] the function returned %d with value %d\n",ok,res);
printf("\n");
printf("[C] lets do this rather easier\n");
printf("[C] we will call the same Lua function using a generic C function 'call_va'\n");
ok=call_va(L,"add","ii>i",1,1,&res);
printf("[C] the function returned %d with value %d\n",ok,res);
printf("\n");
printf("[C] we will now use the same generic C function to call 'append(\"cat\",\"dog\")'\n");
ok=call_va(L,"append","ss>s","cat","dog",str);
printf("[C] the function returned %d with value %s\n",ok,str);
printf("\n");
printf("[C] we can also make some bad calls to ensure the code doesn't fail\n");
printf("[C] calling adds(1,2)\n");
ok=call_va(L,"adds","ii>i",1,2,&res);
printf("[C] the function returned %d with value %d\n",ok,res);
printf("[C] calling add(1,'fred')\n");
ok=call_va(L,"add","is>i",1,"fred",&res);
printf("[C] the function returned %d with value %d\n",ok,res);
printf("\n");
printf("[C] Note: no protection if you mess up the va-args, this is C\n");
printf("\n");
printf("[C] Finally we will call the wrappered gcd function gdc(6,9):\n");
printf("[C] This will pass the values to Lua, then call the wrappered function\n");
printf(" Which will get the values from Lua, call the C code \n");
printf(" and return the value to Lua and eventually back to C\n");
printf("[C] Certainly not the best way to do it :-)\n");
ok=call_va(L,"gcd","ii>i",6,9,&res);
printf("[C] the function returned %d with value %d\n",ok,res);
printf("\n");
printf("[C] all finished, closing the lua state\n");
lua_close(L);
return 0;
}

View file

@ -1,22 +1,22 @@
/* File : example.c */
#include <stdio.h>
/* A global variable */
double Foo = 3.0;
/* Compute the greatest common divisor of positive integers */
int gcd(int x, int y) {
int g;
g = y;
while (x > 0) {
g = x;
x = y % x;
y = g;
}
return g;
}
void greeting() {
printf("Hello from the C function 'greeting'\n");
}
/* File : example.c */
#include <stdio.h>
/* A global variable */
double Foo = 3.0;
/* Compute the greatest common divisor of positive integers */
int gcd(int x, int y) {
int g;
g = y;
while (x > 0) {
g = x;
x = y % x;
y = g;
}
return g;
}
void greeting() {
printf("Hello from the C function 'greeting'\n");
}

View file

@ -1,8 +1,8 @@
/* File : example.i */
%module example
%{
#include "example.h"
%}
%include "example.h"
/* File : example.i */
%module example
%{
#include "example.h"
%}
%include "example.h"

View file

@ -1,19 +1,19 @@
TOP = ../..
SWIG = $(TOP)/../preinst-swig
CXXSRCS =
TARGET = example
INTERFACE = example.i
LIBS = -lm
all::
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua_cpp
static::
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
TARGET='mylua' INTERFACE='$(INTERFACE)' lua_cpp_static
clean::
$(MAKE) -f $(TOP)/Makefile lua_clean
check: all
TOP = ../..
SWIG = $(TOP)/../preinst-swig
CXXSRCS =
TARGET = example
INTERFACE = example.i
LIBS = -lm
all::
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua_cpp
static::
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
TARGET='mylua' INTERFACE='$(INTERFACE)' lua_cpp_static
clean::
$(MAKE) -f $(TOP)/Makefile lua_clean
check: all

View file

@ -1,53 +1,53 @@
/* File : example.h */
#include <string>
#ifndef SWIG
struct A {
};
#endif
class Exc {
public:
Exc(int c, const char *m) {
code = c;
strncpy(msg,m,256);
}
int code;
char msg[256];
};
#if defined(_MSC_VER)
#pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
#endif
class Test {
public:
int simple() throw(int&) {
throw(37);
return 1;
}
int message() throw(const char *) {
throw("I died.");
return 1;
}
int hosed() throw(Exc) {
throw(Exc(42,"Hosed"));
return 1;
}
int unknown() throw(A*) {
static A a;
throw &a;
return 1;
}
int multi(int x) throw(int, const char *, Exc) {
if (x == 1) throw(37);
if (x == 2) throw("Bleah!");
if (x == 3) throw(Exc(42,"No-go-diggy-die"));
return 1;
}
};
#if defined(_MSC_VER)
#pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
#endif
/* File : example.h */
#include <string>
#ifndef SWIG
struct A {
};
#endif
class Exc {
public:
Exc(int c, const char *m) {
code = c;
strncpy(msg,m,256);
}
int code;
char msg[256];
};
#if defined(_MSC_VER)
#pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
#endif
class Test {
public:
int simple() throw(int&) {
throw(37);
return 1;
}
int message() throw(const char *) {
throw("I died.");
return 1;
}
int hosed() throw(Exc) {
throw(Exc(42,"Hosed"));
return 1;
}
int unknown() throw(A*) {
static A a;
throw &a;
return 1;
}
int multi(int x) throw(int, const char *, Exc) {
if (x == 1) throw(37);
if (x == 2) throw("Bleah!");
if (x == 3) throw(Exc(42,"No-go-diggy-die"));
return 1;
}
};
#if defined(_MSC_VER)
#pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
#endif

View file

@ -1,17 +1,17 @@
/* File : example.i */
%module example
%{
#include "example.h"
%}
%include "std_string.i"
// we want to return Exc objects to the interpreter
// therefore we add this typemap
// note: only works if Exc is copyable
%apply SWIGTYPE EXCEPTION_BY_VAL {Exc};
/* Let's just grab the original header file here */
%include "example.h"
/* File : example.i */
%module example
%{
#include "example.h"
%}
%include "std_string.i"
// we want to return Exc objects to the interpreter
// therefore we add this typemap
// note: only works if Exc is copyable
%apply SWIGTYPE EXCEPTION_BY_VAL {Exc};
/* Let's just grab the original header file here */
%include "example.h"

View file

@ -1,96 +1,96 @@
-- file: example.lua
---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
-- lua5.0 doesnt have a nice way to do this
lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
assert(lib)()
else
-- lua 5.1 does
require('example')
end
-- throw a lot of exceptions:
-- you must catch exceptions using pcall and then checking the result
t = example.Test()
print "calling t:unknown()"
ok,res=pcall(function() t:unknown() end)
if ok then
print " that worked! Funny"
else
print(" call failed with error:",res)
end
print "calling t:simple()"
ok,res=pcall(function() t:simple() end)
if ok then
print " that worked! Funny"
else
print(" call failed with error:",res)
end
print "calling t:message()"
ok,res=pcall(function() t:message() end)
if ok then
print " that worked! Funny"
else
print(" call failed with error:",res)
end
print "calling t:hosed()"
ok,res=pcall(function() t:hosed() end)
if ok then
print " that worked! Funny"
else
print(" call failed with error:",res.code,res.msg)
end
-- this is a rather strange way to perform the multiple catch of exceptions
print "calling t:mutli()"
for i=1,3 do
ok,res=pcall(function() t:multi(i) end)
if ok then
print " that worked! Funny"
else
if swig_type(res)=="Exc *" then
print(" call failed with Exc exception:",res.code,res.msg)
else
print(" call failed with error:",res)
end
end
end
-- this is a bit crazy, but it shows obtaining of the stacktrace
function a()
b()
end
function b()
t:message()
end
print [[
Now lets call function a()
which calls b()
which calls into C++
which will throw an exception!]]
ok,res=pcall(a)
if ok then
print " that worked! Funny"
else
print(" call failed with error:",res)
end
print "Now lets do the same using xpcall(a,debug.traceback)"
ok,res=xpcall(a,debug.traceback)
if ok then
print " that worked! Funny"
else
print(" call failed with error:",res)
end
print "As you can see, the xpcall gives a nice stacktrace to work with"
ok,res=pcall(a)
print(ok,res)
ok,res=xpcall(a,debug.traceback)
print(ok,res)
-- file: example.lua
---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
-- lua5.0 doesnt have a nice way to do this
lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
assert(lib)()
else
-- lua 5.1 does
require('example')
end
-- throw a lot of exceptions:
-- you must catch exceptions using pcall and then checking the result
t = example.Test()
print "calling t:unknown()"
ok,res=pcall(function() t:unknown() end)
if ok then
print " that worked! Funny"
else
print(" call failed with error:",res)
end
print "calling t:simple()"
ok,res=pcall(function() t:simple() end)
if ok then
print " that worked! Funny"
else
print(" call failed with error:",res)
end
print "calling t:message()"
ok,res=pcall(function() t:message() end)
if ok then
print " that worked! Funny"
else
print(" call failed with error:",res)
end
print "calling t:hosed()"
ok,res=pcall(function() t:hosed() end)
if ok then
print " that worked! Funny"
else
print(" call failed with error:",res.code,res.msg)
end
-- this is a rather strange way to perform the multiple catch of exceptions
print "calling t:mutli()"
for i=1,3 do
ok,res=pcall(function() t:multi(i) end)
if ok then
print " that worked! Funny"
else
if swig_type(res)=="Exc *" then
print(" call failed with Exc exception:",res.code,res.msg)
else
print(" call failed with error:",res)
end
end
end
-- this is a bit crazy, but it shows obtaining of the stacktrace
function a()
b()
end
function b()
t:message()
end
print [[
Now lets call function a()
which calls b()
which calls into C++
which will throw an exception!]]
ok,res=pcall(a)
if ok then
print " that worked! Funny"
else
print(" call failed with error:",res)
end
print "Now lets do the same using xpcall(a,debug.traceback)"
ok,res=xpcall(a,debug.traceback)
if ok then
print " that worked! Funny"
else
print(" call failed with error:",res)
end
print "As you can see, the xpcall gives a nice stacktrace to work with"
ok,res=pcall(a)
print(ok,res)
ok,res=xpcall(a,debug.traceback)
print(ok,res)

View file

@ -1,19 +1,19 @@
TOP = ../..
SWIG = $(TOP)/../preinst-swig
CXXSRCS = example.cxx
TARGET = example
INTERFACE = example.i
LIBS = -lm
all::
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua_cpp
static::
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
TARGET='mylua' INTERFACE='$(INTERFACE)' lua_cpp_static
clean::
$(MAKE) -f $(TOP)/Makefile lua_clean
check: all
TOP = ../..
SWIG = $(TOP)/../preinst-swig
CXXSRCS = example.cxx
TARGET = example
INTERFACE = example.i
LIBS = -lm
all::
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua_cpp
static::
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
TARGET='mylua' INTERFACE='$(INTERFACE)' lua_cpp_static
clean::
$(MAKE) -f $(TOP)/Makefile lua_clean
check: all

View file

@ -1,69 +1,69 @@
/* File : example.c */
#include "example.h"
#include <stdio.h>
#define M_PI 3.14159265358979323846
/* Move the shape to a new location */
void Shape::move(double dx, double dy) {
x += dx;
y += dy;
}
int Shape::nshapes = 0;
double Circle::area(void) {
return M_PI*radius*radius;
}
double Circle::perimeter(void) {
return 2*M_PI*radius;
}
double Square::area(void) {
return width*width;
}
double Square::perimeter(void) {
return 4*width;
}
Circle* createCircle(double w)
{
return new Circle(w);
}
Square* createSquare(double w)
{
return new Square(w);
}
ShapeOwner::ShapeOwner() {printf(" ShapeOwner(%p)\n",this);}
ShapeOwner::~ShapeOwner()
{
printf(" ~ShapeOwner(%p)\n",this);
for(unsigned i=0;i<shapes.size();i++)
delete shapes[i];
}
void ShapeOwner::add(Shape* ptr) // this method takes ownership of the object
{
shapes.push_back(ptr);
}
Shape* ShapeOwner::get(int idx) // this pointer is still owned by the class (assessor)
{
if (idx < 0 || idx >= static_cast<int>(shapes.size()))
return NULL;
return shapes[idx];
}
Shape* ShapeOwner::remove(int idx) // this method returns memory which must be deleted
{
if (idx < 0 || idx >= static_cast<int>(shapes.size()))
return NULL;
Shape* ptr=shapes[idx];
shapes.erase(shapes.begin()+idx);
return ptr;
}
/* File : example.c */
#include "example.h"
#include <stdio.h>
#define M_PI 3.14159265358979323846
/* Move the shape to a new location */
void Shape::move(double dx, double dy) {
x += dx;
y += dy;
}
int Shape::nshapes = 0;
double Circle::area(void) {
return M_PI*radius*radius;
}
double Circle::perimeter(void) {
return 2*M_PI*radius;
}
double Square::area(void) {
return width*width;
}
double Square::perimeter(void) {
return 4*width;
}
Circle* createCircle(double w)
{
return new Circle(w);
}
Square* createSquare(double w)
{
return new Square(w);
}
ShapeOwner::ShapeOwner() {printf(" ShapeOwner(%p)\n",this);}
ShapeOwner::~ShapeOwner()
{
printf(" ~ShapeOwner(%p)\n",this);
for(unsigned i=0;i<shapes.size();i++)
delete shapes[i];
}
void ShapeOwner::add(Shape* ptr) // this method takes ownership of the object
{
shapes.push_back(ptr);
}
Shape* ShapeOwner::get(int idx) // this pointer is still owned by the class (assessor)
{
if (idx < 0 || idx >= static_cast<int>(shapes.size()))
return NULL;
return shapes[idx];
}
Shape* ShapeOwner::remove(int idx) // this method returns memory which must be deleted
{
if (idx < 0 || idx >= static_cast<int>(shapes.size()))
return NULL;
Shape* ptr=shapes[idx];
shapes.erase(shapes.begin()+idx);
return ptr;
}

View file

@ -1,54 +1,54 @@
/* File : example.h */
#include <vector>
class Shape {
public:
Shape() {
nshapes++;
}
virtual ~Shape() {
nshapes--;
};
double x, y;
void move(double dx, double dy);
virtual double area(void) = 0;
virtual double perimeter(void) = 0;
static int nshapes;
};
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) { };
virtual double area(void);
virtual double perimeter(void);
};
class Square : public Shape {
private:
double width;
public:
Square(double w) : width(w) { };
virtual double area(void);
virtual double perimeter(void);
};
Circle* createCircle(double w); // this method creates a new object
Square* createSquare(double w); // this method creates a new object
class ShapeOwner {
private:
std::vector<Shape*> shapes;
ShapeOwner(const ShapeOwner&); // no copying
ShapeOwner& operator=(const ShapeOwner&); // no copying
public:
ShapeOwner();
~ShapeOwner();
void add(Shape* ptr); // this method takes ownership of the object
Shape* get(int idx); // this pointer is still owned by the class (assessor)
Shape* remove(int idx); // this method returns memory which must be deleted
};
/* File : example.h */
#include <vector>
class Shape {
public:
Shape() {
nshapes++;
}
virtual ~Shape() {
nshapes--;
};
double x, y;
void move(double dx, double dy);
virtual double area(void) = 0;
virtual double perimeter(void) = 0;
static int nshapes;
};
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) { };
virtual double area(void);
virtual double perimeter(void);
};
class Square : public Shape {
private:
double width;
public:
Square(double w) : width(w) { };
virtual double area(void);
virtual double perimeter(void);
};
Circle* createCircle(double w); // this method creates a new object
Square* createSquare(double w); // this method creates a new object
class ShapeOwner {
private:
std::vector<Shape*> shapes;
ShapeOwner(const ShapeOwner&); // no copying
ShapeOwner& operator=(const ShapeOwner&); // no copying
public:
ShapeOwner();
~ShapeOwner();
void add(Shape* ptr); // this method takes ownership of the object
Shape* get(int idx); // this pointer is still owned by the class (assessor)
Shape* remove(int idx); // this method returns memory which must be deleted
};

View file

@ -1,32 +1,32 @@
/* File : example.i */
%module example
%{
#include "example.h"
%}
// before we grab the header file, we must warn SWIG about some of these functions.
// these functions create data, so must be managed
%newobject createCircle;
%newobject createSquare;
// this method returns as pointer which must be managed
%newobject ShapeOwner::remove;
// you cannot use %delobject on ShapeOwner::add()
// as this disowns the ShapeOwner, not the Shape (oops)
//%delobject ShapeOwner::add(Shape*); DO NOT USE
// either you can use a new function (such as this)
/*%delobject add_Shape;
%inline %{
void add_Shape(Shape* s,ShapeOwner* own){own->add(s);}
%}*/
// or a better solution is a typemap
%apply SWIGTYPE *DISOWN {Shape* ptr};
// now we can grab the header file
%include "example.h"
/* File : example.i */
%module example
%{
#include "example.h"
%}
// before we grab the header file, we must warn SWIG about some of these functions.
// these functions create data, so must be managed
%newobject createCircle;
%newobject createSquare;
// this method returns as pointer which must be managed
%newobject ShapeOwner::remove;
// you cannot use %delobject on ShapeOwner::add()
// as this disowns the ShapeOwner, not the Shape (oops)
//%delobject ShapeOwner::add(Shape*); DO NOT USE
// either you can use a new function (such as this)
/*%delobject add_Shape;
%inline %{
void add_Shape(Shape* s,ShapeOwner* own){own->add(s);}
%}*/
// or a better solution is a typemap
%apply SWIGTYPE *DISOWN {Shape* ptr};
// now we can grab the header file
%include "example.h"

View file

@ -1,104 +1,104 @@
-- Operator overloading example
---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
-- lua5.0 doesnt have a nice way to do this
lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
assert(lib)()
else
-- lua 5.1 does
require('example')
end
print "ok, lets test Lua's ownership of C++ objects"
print("Currently there are",example.Shape_nshapes,"shapes (there should be 0)")
print "\nLets make a couple"
a=example.Square(10)
b=example.Circle(1)
print("Currently there are",example.Shape_nshapes,"shapes (there should be 2)")
print "\nNote lets use the createX functions"
c=example.createCircle(5)
d=example.createSquare(3)
print("Currently there are",example.Shape_nshapes,"shapes (there should be 4)")
print "\nWe will run the garbage collector & see if they are till here"
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 4)")
print "\nLets get rid of them all, collect garbage & see if they are till here"
a,b,c,d=nil,nil,nil,nil
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 0)")
print "\nLets start putting stuff into the ShapeOwner"
print "The ShapeOwner now owns the shapes, but Lua still has pointers to them"
o=example.ShapeOwner()
a=example.Square(10)
b=example.Circle(1)
o:add(a)
o:add(b)
o:add(example.createSquare(5))
print("Currently there are",example.Shape_nshapes,"shapes (there should be 3)")
print "\nWe will nil our references,run the garbage collector & see if they are till here"
print "they should be, as the ShapeOwner owns them"
a,b=nil,nil
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 3)")
print "\nWe will access them and check that they are still valid"
a=o:get(0)
b=o:get(1)
print(" Area's are",a:area(),b:area(),o:get(2):area())
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 3)")
print "\nWe will remove one from the C++ owner & pass its ownership to Lua,"
print " then check that they are still unchanged"
a,b=nil,nil
a=o:remove(0) -- a now owns it
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 3)")
print "\nDelete the ShapeOwner (this should destroy two shapes),"
print " but we have one left in Lua"
o=nil
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 1)")
print "\nFinal tidy up "
a=nil
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 0)")
print "Final test, we will create some Shapes & pass them around like mad"
print "If there is any memory leak, you will see it in the memory usage"
io.flush()
sh={}
-- make some objects
for i=0,10 do
a=example.Circle(i)
b=example.Square(i)
sh[a]=true
sh[b]=true
end
o=example.ShapeOwner()
for i=0,10000 do
for k,_ in pairs(sh) do
o:add(k)
end
sh={} -- clear it
while true do
a=o:remove(0)
if a==nil then break end
sh[a]=true
end
if i%100==0 then collectgarbage() end
end
print "done"
o,sh=nil,nil
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 0)")
print "thats all folks!"
-- Operator overloading example
---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
-- lua5.0 doesnt have a nice way to do this
lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
assert(lib)()
else
-- lua 5.1 does
require('example')
end
print "ok, lets test Lua's ownership of C++ objects"
print("Currently there are",example.Shape_nshapes,"shapes (there should be 0)")
print "\nLets make a couple"
a=example.Square(10)
b=example.Circle(1)
print("Currently there are",example.Shape_nshapes,"shapes (there should be 2)")
print "\nNote lets use the createX functions"
c=example.createCircle(5)
d=example.createSquare(3)
print("Currently there are",example.Shape_nshapes,"shapes (there should be 4)")
print "\nWe will run the garbage collector & see if they are till here"
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 4)")
print "\nLets get rid of them all, collect garbage & see if they are till here"
a,b,c,d=nil,nil,nil,nil
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 0)")
print "\nLets start putting stuff into the ShapeOwner"
print "The ShapeOwner now owns the shapes, but Lua still has pointers to them"
o=example.ShapeOwner()
a=example.Square(10)
b=example.Circle(1)
o:add(a)
o:add(b)
o:add(example.createSquare(5))
print("Currently there are",example.Shape_nshapes,"shapes (there should be 3)")
print "\nWe will nil our references,run the garbage collector & see if they are till here"
print "they should be, as the ShapeOwner owns them"
a,b=nil,nil
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 3)")
print "\nWe will access them and check that they are still valid"
a=o:get(0)
b=o:get(1)
print(" Area's are",a:area(),b:area(),o:get(2):area())
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 3)")
print "\nWe will remove one from the C++ owner & pass its ownership to Lua,"
print " then check that they are still unchanged"
a,b=nil,nil
a=o:remove(0) -- a now owns it
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 3)")
print "\nDelete the ShapeOwner (this should destroy two shapes),"
print " but we have one left in Lua"
o=nil
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 1)")
print "\nFinal tidy up "
a=nil
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 0)")
print "Final test, we will create some Shapes & pass them around like mad"
print "If there is any memory leak, you will see it in the memory usage"
io.flush()
sh={}
-- make some objects
for i=0,10 do
a=example.Circle(i)
b=example.Square(i)
sh[a]=true
sh[b]=true
end
o=example.ShapeOwner()
for i=0,10000 do
for k,_ in pairs(sh) do
o:add(k)
end
sh={} -- clear it
while true do
a=o:remove(0)
if a==nil then break end
sh[a]=true
end
if i%100==0 then collectgarbage() end
end
print "done"
o,sh=nil,nil
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 0)")
print "thats all folks!"

View file

@ -1,246 +1,246 @@
/* -----------------------------------------------------------------------------
* li_std_map_runme.cs
*
* SWIG C# tester for std_map.i
* This class tests all the functionality of the std_map.i wrapper.
* Upon successful testing, the main function doesn't print out anything.
* If any error is found - it will be printed on the screen.
* ----------------------------------------------------------------------------- */
using System;
using System.Collections.Generic;
using li_std_mapNamespace;
public class li_std_map_runme {
private static readonly int collectionSize = 20;
private static readonly int midCollection = collectionSize / 2;
public static void Main()
{
// Set up an int int map
StringIntMap simap = new StringIntMap();
for (int i = 0; i < collectionSize; i++)
{
int val = i * 18;
simap.Add(i.ToString(), val);
}
// Count property test
if (simap.Count != collectionSize)
throw new Exception("Count test failed");
// IsReadOnly property test
if (simap.IsReadOnly)
throw new Exception("IsReadOnly test failed");
// Item indexing test
simap["0"] = 200;
if (simap["0"] != 200)
throw new Exception("Item property test failed");
simap["0"] = 0 * 18;
// ContainsKey() test
for (int i = 0; i < collectionSize; i++)
{
if (!simap.ContainsKey(i.ToString()))
throw new Exception("ContainsKey test " + i + " failed");
}
// ContainsKey() test
for (int i = 0; i < collectionSize; i++)
{
if (!simap.Contains(new KeyValuePair<string, int>(i.ToString(), i * 18)))
throw new Exception("Contains test " + i + " failed");
}
// TryGetValue() test
int value;
bool rc = simap.TryGetValue("3", out value);
if (rc != true || value != (3 * 18))
throw new Exception("TryGetValue test 1 failed");
rc = simap.TryGetValue("-1", out value);
if (rc != false)
throw new Exception("TryGetValue test 2 failed");
// Keys and Values test
{
IList<string> keys = new List<string>(simap.Keys);
IList<int> values = new List<int>(simap.Values);
Dictionary<string, int> check = new Dictionary<string, int>();
if (keys.Count != collectionSize)
throw new Exception("Keys count test failed");
if (values.Count != collectionSize)
throw new Exception("Values count test failed");
for (int i = 0; i < keys.Count; i++)
{
if (simap[keys[i]] != values[i])
throw new Exception("Keys and values test failed for index " + i);
check.Add(keys[i], values[i]);
}
for (int i = 0; i < collectionSize; i++)
{
if (!check.ContainsKey(i.ToString()))
throw new Exception("Keys and Values ContainsKey test " + i + " failed");
}
}
// Add and Remove test
for (int i = 100; i < 103; i++)
{
simap.Add(i.ToString(), i * 18);
if (!simap.ContainsKey(i.ToString()) || simap[i.ToString()] != (i * 18))
throw new Exception("Add test failed for index " + i);
simap.Remove(i.ToString());
if (simap.ContainsKey(i.ToString()))
throw new Exception("Remove test failed for index " + i);
}
for (int i = 200; i < 203; i++)
{
simap.Add(new KeyValuePair<string, int>(i.ToString(), i * 18));
if (!simap.ContainsKey(i.ToString()) || simap[i.ToString()] != (i * 18))
throw new Exception("Add explicit test failed for index " + i);
simap.Remove(new KeyValuePair<string, int>(i.ToString(), i * 18));
if (simap.ContainsKey(i.ToString()))
throw new Exception("Remove explicit test failed for index " + i);
}
// Duplicate key test
try
{
simap.Add("3", 0);
throw new Exception("Adding duplicate key test failed");
}
catch (ArgumentException)
{
}
// CopyTo() test
{
KeyValuePair<string, int>[] outputarray = new KeyValuePair<string, int>[collectionSize];
simap.CopyTo(outputarray);
foreach (KeyValuePair<string, int> val in outputarray)
{
if (simap[val.Key] != val.Value)
throw new Exception("CopyTo (1) test failed, index:" + val.Key);
}
}
{
KeyValuePair<string, int>[] outputarray = new KeyValuePair<string, int>[midCollection + collectionSize];
simap.CopyTo(outputarray, midCollection);
for (int i = midCollection; i < midCollection + collectionSize; i++)
{
KeyValuePair<string, int> val = outputarray[i];
if (simap[val.Key] != val.Value)
throw new Exception("CopyTo (2) test failed, index:" + val.Key);
}
}
{
KeyValuePair<string, int>[] outputarray = new KeyValuePair<string, int>[collectionSize - 1];
try
{
simap.CopyTo(outputarray);
throw new Exception("CopyTo (4) test failed");
}
catch (ArgumentException)
{
}
}
// Clear test
simap.Clear();
if (simap.Count != 0)
throw new Exception("Clear test failed");
// Test wrapped methods
for (int i = 1; i <= 5; i++)
{
simap[i.ToString()] = i;
}
double avg = li_std_map.valueAverage(simap);
if (avg != 3.0)
throw new Exception("Wrapped method valueAverage test failed. Got " + avg);
string keyStringified = li_std_map.stringifyKeys(simap);
if (keyStringified != " 1 2 3 4 5")
throw new Exception("Wrapped method stringifyKeys test failed. Got " + keyStringified);
// Test a map with a new complex type (Struct)
{
IntStructMap ismap = new IntStructMap();
for (int i = 0; i < 10; i++)
{
ismap.Add(i, new Struct(i * 10.1));
}
if (ismap.Count != 10)
throw new Exception("Count test on complex type map failed");
foreach (KeyValuePair<int, Struct> p in ismap)
{
if ((p.Key * 10.1) != p.Value.num)
throw new Exception("Iteration test on complex type map failed for index " + p.Key);
}
}
// Test a map of pointers
{
IntStructPtrMap ispmap = new IntStructPtrMap();
for (int i = 0; i < 10; i++)
{
ispmap.Add(i, new Struct(i * 10.1));
}
if (ispmap.Count != 10)
throw new Exception("Count test on complex type pointer map failed");
foreach (KeyValuePair<int, Struct> p in ispmap)
{
if ((p.Key * 10.1) != p.Value.num)
throw new Exception("Iteration test on complex type pointer map failed for index " + p.Key);
}
}
{
IntStructConstPtrMap iscpmap = new IntStructConstPtrMap();
for (int i = 0; i < 10; i++)
{
iscpmap.Add(i, new Struct(i * 10.1));
}
if (iscpmap.Count != 10)
throw new Exception("Count test on complex type const pointer map failed");
foreach (KeyValuePair<int, Struct> p in iscpmap)
{
if ((p.Key * 10.1) != p.Value.num)
throw new Exception("Iteration test on complex type const pointer map failed for index " + p.Key);
}
}
// Test complex type as key (Struct)
{
StructIntMap limap = new StructIntMap();
Struct s7 = new Struct(7);
Struct s8 = new Struct(8);
limap[s7] = 8;
if (limap[s7] != 8)
throw new Exception("Assignment test on complex key map failed");
if (!limap.ContainsKey(s7))
throw new Exception("Key test (1) on complex key map failed");
if (limap.ContainsKey(s8))
throw new Exception("Key test (2) on complex key map failed");
}
// All done
}
}
/* -----------------------------------------------------------------------------
* li_std_map_runme.cs
*
* SWIG C# tester for std_map.i
* This class tests all the functionality of the std_map.i wrapper.
* Upon successful testing, the main function doesn't print out anything.
* If any error is found - it will be printed on the screen.
* ----------------------------------------------------------------------------- */
using System;
using System.Collections.Generic;
using li_std_mapNamespace;
public class li_std_map_runme {
private static readonly int collectionSize = 20;
private static readonly int midCollection = collectionSize / 2;
public static void Main()
{
// Set up an int int map
StringIntMap simap = new StringIntMap();
for (int i = 0; i < collectionSize; i++)
{
int val = i * 18;
simap.Add(i.ToString(), val);
}
// Count property test
if (simap.Count != collectionSize)
throw new Exception("Count test failed");
// IsReadOnly property test
if (simap.IsReadOnly)
throw new Exception("IsReadOnly test failed");
// Item indexing test
simap["0"] = 200;
if (simap["0"] != 200)
throw new Exception("Item property test failed");
simap["0"] = 0 * 18;
// ContainsKey() test
for (int i = 0; i < collectionSize; i++)
{
if (!simap.ContainsKey(i.ToString()))
throw new Exception("ContainsKey test " + i + " failed");
}
// ContainsKey() test
for (int i = 0; i < collectionSize; i++)
{
if (!simap.Contains(new KeyValuePair<string, int>(i.ToString(), i * 18)))
throw new Exception("Contains test " + i + " failed");
}
// TryGetValue() test
int value;
bool rc = simap.TryGetValue("3", out value);
if (rc != true || value != (3 * 18))
throw new Exception("TryGetValue test 1 failed");
rc = simap.TryGetValue("-1", out value);
if (rc != false)
throw new Exception("TryGetValue test 2 failed");
// Keys and Values test
{
IList<string> keys = new List<string>(simap.Keys);
IList<int> values = new List<int>(simap.Values);
Dictionary<string, int> check = new Dictionary<string, int>();
if (keys.Count != collectionSize)
throw new Exception("Keys count test failed");
if (values.Count != collectionSize)
throw new Exception("Values count test failed");
for (int i = 0; i < keys.Count; i++)
{
if (simap[keys[i]] != values[i])
throw new Exception("Keys and values test failed for index " + i);
check.Add(keys[i], values[i]);
}
for (int i = 0; i < collectionSize; i++)
{
if (!check.ContainsKey(i.ToString()))
throw new Exception("Keys and Values ContainsKey test " + i + " failed");
}
}
// Add and Remove test
for (int i = 100; i < 103; i++)
{
simap.Add(i.ToString(), i * 18);
if (!simap.ContainsKey(i.ToString()) || simap[i.ToString()] != (i * 18))
throw new Exception("Add test failed for index " + i);
simap.Remove(i.ToString());
if (simap.ContainsKey(i.ToString()))
throw new Exception("Remove test failed for index " + i);
}
for (int i = 200; i < 203; i++)
{
simap.Add(new KeyValuePair<string, int>(i.ToString(), i * 18));
if (!simap.ContainsKey(i.ToString()) || simap[i.ToString()] != (i * 18))
throw new Exception("Add explicit test failed for index " + i);
simap.Remove(new KeyValuePair<string, int>(i.ToString(), i * 18));
if (simap.ContainsKey(i.ToString()))
throw new Exception("Remove explicit test failed for index " + i);
}
// Duplicate key test
try
{
simap.Add("3", 0);
throw new Exception("Adding duplicate key test failed");
}
catch (ArgumentException)
{
}
// CopyTo() test
{
KeyValuePair<string, int>[] outputarray = new KeyValuePair<string, int>[collectionSize];
simap.CopyTo(outputarray);
foreach (KeyValuePair<string, int> val in outputarray)
{
if (simap[val.Key] != val.Value)
throw new Exception("CopyTo (1) test failed, index:" + val.Key);
}
}
{
KeyValuePair<string, int>[] outputarray = new KeyValuePair<string, int>[midCollection + collectionSize];
simap.CopyTo(outputarray, midCollection);
for (int i = midCollection; i < midCollection + collectionSize; i++)
{
KeyValuePair<string, int> val = outputarray[i];
if (simap[val.Key] != val.Value)
throw new Exception("CopyTo (2) test failed, index:" + val.Key);
}
}
{
KeyValuePair<string, int>[] outputarray = new KeyValuePair<string, int>[collectionSize - 1];
try
{
simap.CopyTo(outputarray);
throw new Exception("CopyTo (4) test failed");
}
catch (ArgumentException)
{
}
}
// Clear test
simap.Clear();
if (simap.Count != 0)
throw new Exception("Clear test failed");
// Test wrapped methods
for (int i = 1; i <= 5; i++)
{
simap[i.ToString()] = i;
}
double avg = li_std_map.valueAverage(simap);
if (avg != 3.0)
throw new Exception("Wrapped method valueAverage test failed. Got " + avg);
string keyStringified = li_std_map.stringifyKeys(simap);
if (keyStringified != " 1 2 3 4 5")
throw new Exception("Wrapped method stringifyKeys test failed. Got " + keyStringified);
// Test a map with a new complex type (Struct)
{
IntStructMap ismap = new IntStructMap();
for (int i = 0; i < 10; i++)
{
ismap.Add(i, new Struct(i * 10.1));
}
if (ismap.Count != 10)
throw new Exception("Count test on complex type map failed");
foreach (KeyValuePair<int, Struct> p in ismap)
{
if ((p.Key * 10.1) != p.Value.num)
throw new Exception("Iteration test on complex type map failed for index " + p.Key);
}
}
// Test a map of pointers
{
IntStructPtrMap ispmap = new IntStructPtrMap();
for (int i = 0; i < 10; i++)
{
ispmap.Add(i, new Struct(i * 10.1));
}
if (ispmap.Count != 10)
throw new Exception("Count test on complex type pointer map failed");
foreach (KeyValuePair<int, Struct> p in ispmap)
{
if ((p.Key * 10.1) != p.Value.num)
throw new Exception("Iteration test on complex type pointer map failed for index " + p.Key);
}
}
{
IntStructConstPtrMap iscpmap = new IntStructConstPtrMap();
for (int i = 0; i < 10; i++)
{
iscpmap.Add(i, new Struct(i * 10.1));
}
if (iscpmap.Count != 10)
throw new Exception("Count test on complex type const pointer map failed");
foreach (KeyValuePair<int, Struct> p in iscpmap)
{
if ((p.Key * 10.1) != p.Value.num)
throw new Exception("Iteration test on complex type const pointer map failed for index " + p.Key);
}
}
// Test complex type as key (Struct)
{
StructIntMap limap = new StructIntMap();
Struct s7 = new Struct(7);
Struct s8 = new Struct(8);
limap[s7] = 8;
if (limap[s7] != 8)
throw new Exception("Assignment test on complex key map failed");
if (!limap.ContainsKey(s7))
throw new Exception("Key test (1) on complex key map failed");
if (limap.ContainsKey(s8))
throw new Exception("Key test (2) on complex key map failed");
}
// All done
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,498 +1,498 @@
// This tests intrusive_ptr is working okay. It also checks that there are no memory leaks in the
// class that intrusive_ptr is pointing via a counting mechanism in the constructors and destructor of Klass.
// In order to test that there are no leaks of the intrusive_ptr class itself (as it is created on the heap)
// the runtime tests can be run for a long time to monitor memory leaks using memory monitor tools
// like 'top'. There is a wrapper for intrusive_ptr in intrusive_ptr_wrapper.h which enables one to
// count the instances of intrusive_ptr. Uncomment the INTRUSIVE_PTR_WRAPPER macro to turn this on.
//
// Also note the debug_shared flag which can be set from the target language.
%module li_boost_intrusive_ptr
%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK);
%warnfilter(SWIGWARN_LANG_SMARTPTR_MISSING) KlassDerived;
%warnfilter(SWIGWARN_LANG_SMARTPTR_MISSING) KlassDerivedDerived;
%inline %{
#include "boost/shared_ptr.hpp"
#include "boost/intrusive_ptr.hpp"
#include <boost/detail/atomic_count.hpp>
// Uncomment macro below to turn on intrusive_ptr memory leak checking as described above
//#define INTRUSIVE_PTR_WRAPPER
#ifdef INTRUSIVE_PTR_WRAPPER
# include "intrusive_ptr_wrapper.h"
# include "shared_ptr_wrapper.h"
#endif
%}
%{
#ifndef INTRUSIVE_PTR_WRAPPER
# define SwigBoost boost
#endif
%}
%include "std_string.i"
#ifndef INTRUSIVE_PTR_WRAPPER
# define SWIG_INTRUSIVE_PTR_NAMESPACE SwigBoost
# define SWIG_SHARED_PTR_NAMESPACE SwigBoost
#endif
#if defined(SWIGJAVA) || defined(SWIGCSHARP)
#define INTRUSIVE_PTR_WRAPPERS_IMPLEMENTED
#endif
#if defined(INTRUSIVE_PTR_WRAPPERS_IMPLEMENTED)
%include <boost_intrusive_ptr.i>
%intrusive_ptr(Space::Klass)
%intrusive_ptr_no_wrap(Space::KlassWithoutRefCount)
%intrusive_ptr(Space::KlassDerived)
%intrusive_ptr(Space::KlassDerivedDerived)
//For the use_count shared_ptr functions
#if defined(SWIGJAVA)
%typemap(in) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::Klass > & ($*1_ltype tempnull) %{
$1 = $input ? *($&1_ltype)&$input : &tempnull;
%}
%typemap (jni) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::Klass > & "jlong"
%typemap (jtype) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::Klass > & "long"
%typemap (jstype) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::Klass > & "Klass"
%typemap(javain) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::Klass > & "Klass.getCPtr($javainput)"
%typemap(in) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::KlassDerived > & ($*1_ltype tempnull) %{
$1 = $input ? *($&1_ltype)&$input : &tempnull;
%}
%typemap (jni) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::KlassDerived > & "jlong"
%typemap (jtype) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::KlassDerived > & "long"
%typemap (jstype) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::KlassDerived > & "KlassDerived"
%typemap(javain) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::KlassDerived > & "KlassDerived.getCPtr($javainput)"
%typemap(in) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::KlassDerivedDerived > & ($*1_ltype tempnull) %{
$1 = $input ? *($&1_ltype)&$input : &tempnull;
%}
%typemap (jni) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::KlassDerivedDerived > & "jlong"
%typemap (jtype) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::KlassDerivedDerived > & "long"
%typemap (jstype) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::KlassDerivedDerived > & "KlassDerivedDerived"
%typemap(javain) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::KlassDerivedDerived > & "KlassDerivedDerived.getCPtr($javainput)"
#elif defined(SWIGCSHARP)
// TODO!
#endif
#endif
// TODO:
// const intrusive_ptr
// std::vector
// Add in generic %extend for the Upcast function for derived classes
// Remove proxy upcast method - implement %feature("shadow") ??? which replaces the proxy method
%exception {
if (debug_shared) {
cout << "++++++" << endl << flush;
cout << "calling $name" << endl << flush;
}
$action
if (debug_shared) {
cout << "------" << endl << flush;
}
}
%ignore IgnoredRefCountingBase;
%ignore *::operator=;
%ignore intrusive_ptr_add_ref;
%ignore intrusive_ptr_release;
%newobject pointerownertest();
%newobject smartpointerpointerownertest();
%inline %{
#include <iostream>
using namespace std;
static bool debug_shared = false;
namespace Space {
struct Klass {
Klass() : value("EMPTY"), count(0) { if (debug_shared) cout << "Klass() [" << value << "]" << endl << flush; increment(); }
Klass(const std::string &val) : value(val), count(0) { if (debug_shared) cout << "Klass(string) [" << value << "]" << endl << flush; increment(); }
virtual ~Klass() { if (debug_shared) cout << "~Klass() [" << value << "]" << endl << flush; decrement(); }
virtual std::string getValue() const { return value; }
void append(const std::string &s) { value += s; }
Klass(const Klass &other) : value(other.value), count(0) { if (debug_shared) cout << "Klass(const Klass&) [" << value << "]" << endl << flush; increment(); }
Klass &operator=(const Klass &other) { value = other.value; return *this; }
void addref(void) const { ++count; }
void release(void) const { if (--count == 0) delete this; }
int use_count(void) const { return count; }
static long getTotal_count() { return total_count; }
private:
static void increment() { ++total_count; if (debug_shared) cout << " ++xxxxx Klass::increment tot: " << total_count << endl;}
static void decrement() { --total_count; if (debug_shared) cout << " --xxxxx Klass::decrement tot: " << total_count << endl;}
static boost::detail::atomic_count total_count;
std::string value;
int array[1024];
mutable boost::detail::atomic_count count;
};
struct KlassWithoutRefCount {
KlassWithoutRefCount() : value("EMPTY") { if (debug_shared) cout << "KlassWithoutRefCount() [" << value << "]" << endl << flush; increment(); }
KlassWithoutRefCount(const std::string &val) : value(val) { if (debug_shared) cout << "KlassWithoutRefCount(string) [" << value << "]" << endl << flush; increment(); }
virtual ~KlassWithoutRefCount() { if (debug_shared) cout << "~KlassWithoutRefCount() [" << value << "]" << endl << flush; decrement(); }
virtual std::string getValue() const { return value; }
void append(const std::string &s) { value += s; }
KlassWithoutRefCount(const KlassWithoutRefCount &other) : value(other.value) { if (debug_shared) cout << "KlassWithoutRefCount(const KlassWithoutRefCount&) [" << value << "]" << endl << flush; increment(); }
std::string getSpecialValueFromUnwrappableClass() { return "this class cannot be wrapped by intrusive_ptrs but we can still use it"; }
KlassWithoutRefCount &operator=(const KlassWithoutRefCount &other) { value = other.value; return *this; }
static long getTotal_count() { return total_count; }
private:
static void increment() { ++total_count; if (debug_shared) cout << " ++xxxxx KlassWithoutRefCount::increment tot: " << total_count << endl;}
static void decrement() { --total_count; if (debug_shared) cout << " --xxxxx KlassWithoutRefCount::decrement tot: " << total_count << endl;}
static boost::detail::atomic_count total_count;
std::string value;
int array[1024];
};
struct IgnoredRefCountingBase {
IgnoredRefCountingBase() : count(0) { if (debug_shared) cout << "IgnoredRefCountingBase()" << endl << flush; increment(); }
IgnoredRefCountingBase(const IgnoredRefCountingBase &other) : count(0) { if (debug_shared) cout << "IgnoredRefCountingBase(const IgnoredRefCountingBase&)" << endl << flush; increment(); }
IgnoredRefCountingBase &operator=(const IgnoredRefCountingBase& other) {
return *this;
}
virtual ~IgnoredRefCountingBase() { if (debug_shared) cout << "~IgnoredRefCountingBase()" << endl << flush; decrement(); }
void addref(void) const { ++count; }
void release(void) const { if (--count == 0) delete this; }
int use_count(void) const { return count; }
static long getTotal_count() { return total_count; }
private:
static void increment() { ++total_count; if (debug_shared) cout << " ++xxxxx IgnoredRefCountingBase::increment tot: " << total_count << endl;}
static void decrement() { --total_count; if (debug_shared) cout << " --xxxxx IgnoredRefCountingBase::decrement tot: " << total_count << endl;}
static boost::detail::atomic_count total_count;
double d;
double e;
mutable boost::detail::atomic_count count;
};
long getTotal_IgnoredRefCountingBase_count() {
return IgnoredRefCountingBase::getTotal_count();
}
// For most compilers, this use of multiple inheritance results in different derived and base class
// pointer values ... for some more challenging tests :)
struct KlassDerived : IgnoredRefCountingBase, KlassWithoutRefCount {
KlassDerived() : KlassWithoutRefCount() { if (debug_shared) cout << "KlassDerived()" << endl << flush; increment(); }
KlassDerived(const std::string &val) : KlassWithoutRefCount(val) { if (debug_shared) cout << "KlassDerived(string) [" << val << "]" << endl << flush; increment(); }
KlassDerived(const KlassDerived &other) : KlassWithoutRefCount(other) { if (debug_shared) cout << "KlassDerived(const KlassDerived&))" << endl << flush; increment(); }
virtual ~KlassDerived() { if (debug_shared) cout << "~KlassDerived()" << endl << flush; decrement(); }
virtual std::string getValue() const { return KlassWithoutRefCount::getValue() + "-Derived"; }
int use_count(void) const { return IgnoredRefCountingBase::use_count(); }
static long getTotal_count() { return total_count; }
private:
static void increment() { ++total_count; if (debug_shared) cout << " ++xxxxx KlassDerived::increment tot: " << total_count << endl;}
static void decrement() { --total_count; if (debug_shared) cout << " --xxxxx KlassDerived::decrement tot: " << total_count << endl;}
static boost::detail::atomic_count total_count;
};
struct KlassDerivedDerived : KlassDerived {
KlassDerivedDerived() : KlassDerived() { if (debug_shared) cout << "KlassDerivedDerived()" << endl << flush; increment(); }
KlassDerivedDerived(const std::string &val) : KlassDerived(val) { if (debug_shared) cout << "KlassDerivedDerived(string) [" << val << "]" << endl << flush; increment(); }
KlassDerivedDerived(const KlassDerived &other) : KlassDerived(other) { if (debug_shared) cout << "KlassDerivedDerived(const KlassDerivedDerived&))" << endl << flush; increment(); }
virtual ~KlassDerivedDerived() { if (debug_shared) cout << "~KlassDerivedDerived()" << endl << flush; decrement(); }
virtual std::string getValue() const { return KlassWithoutRefCount::getValue() + "-DerivedDerived"; }
static long getTotal_count() { return total_count; }
private:
static void increment() { ++total_count; if (debug_shared) cout << " ++xxxxx KlassDerivedDerived::increment tot: " << total_count << endl;}
static void decrement() { --total_count; if (debug_shared) cout << " --xxxxx KlassDerivedDerived::decrement tot: " << total_count << endl;}
static boost::detail::atomic_count total_count;
};
KlassDerived* derivedpointertest(KlassDerived* kd) {
if (kd)
kd->append(" derivedpointertest");
return kd;
}
KlassDerived derivedvaluetest(KlassDerived kd) {
kd.append(" derivedvaluetest");
return kd;
}
KlassDerived& derivedreftest(KlassDerived& kd) {
kd.append(" derivedreftest");
return kd;
}
SwigBoost::intrusive_ptr<KlassDerived> derivedsmartptrtest(SwigBoost::intrusive_ptr<KlassDerived> kd) {
if (kd)
kd->append(" derivedsmartptrtest");
return kd;
}
SwigBoost::intrusive_ptr<KlassDerived>* derivedsmartptrpointertest(SwigBoost::intrusive_ptr<KlassDerived>* kd) {
if (kd && *kd)
(*kd)->append(" derivedsmartptrpointertest");
return kd;
}
SwigBoost::intrusive_ptr<KlassDerived>* derivedsmartptrreftest(SwigBoost::intrusive_ptr<KlassDerived>* kd) {
if (kd && *kd)
(*kd)->append(" derivedsmartptrreftest");
return kd;
}
SwigBoost::intrusive_ptr<KlassDerived>*& derivedsmartptrpointerreftest(SwigBoost::intrusive_ptr<KlassDerived>*& kd) {
if (kd && *kd)
(*kd)->append(" derivedsmartptrpointerreftest");
return kd;
}
SwigBoost::intrusive_ptr<Klass> factorycreate() {
return SwigBoost::intrusive_ptr<Klass>(new Klass("factorycreate"));
}
// smart pointer
SwigBoost::intrusive_ptr<Klass> smartpointertest(SwigBoost::intrusive_ptr<Klass> k) {
if (k)
k->append(" smartpointertest");
return SwigBoost::intrusive_ptr<Klass>(k);
}
SwigBoost::intrusive_ptr<Klass>* smartpointerpointertest(SwigBoost::intrusive_ptr<Klass>* k) {
if (k && *k)
(*k)->append(" smartpointerpointertest");
return k;
}
SwigBoost::intrusive_ptr<Klass>& smartpointerreftest(SwigBoost::intrusive_ptr<Klass>& k) {
if (k)
k->append(" smartpointerreftest");
return k;
}
SwigBoost::intrusive_ptr<Klass>*& smartpointerpointerreftest(SwigBoost::intrusive_ptr<Klass>*& k) {
if (k && *k)
(*k)->append(" smartpointerpointerreftest");
return k;
}
// const
SwigBoost::intrusive_ptr<const Klass> constsmartpointertest(SwigBoost::intrusive_ptr<const Klass> k) {
return SwigBoost::intrusive_ptr<const Klass>(k);
}
SwigBoost::intrusive_ptr<const Klass>* constsmartpointerpointertest(SwigBoost::intrusive_ptr<const Klass>* k) {
return k;
}
SwigBoost::intrusive_ptr<const Klass>& constsmartpointerreftest(SwigBoost::intrusive_ptr<const Klass>& k) {
return k;
}
// plain pointer
Klass valuetest(Klass k) {
k.append(" valuetest");
return k;
}
Klass *pointertest(Klass *k) {
if (k)
k->append(" pointertest");
return k;
}
Klass& reftest(Klass& k) {
k.append(" reftest");
return k;
}
Klass *const& pointerreftest(Klass *const& k) {
k->append(" pointerreftest");
return k;
}
// null
std::string nullsmartpointerpointertest(SwigBoost::intrusive_ptr<Klass>* k) {
if (k && *k)
return "not null";
else if (!k)
return "null smartpointer pointer";
else if (!*k)
return "null pointer";
else
return "also not null";
}
// $owner
Klass *pointerownertest() {
return new Klass("pointerownertest");
}
SwigBoost::intrusive_ptr<Klass>* smartpointerpointerownertest() {
return new SwigBoost::intrusive_ptr<Klass>(new Klass("smartpointerpointerownertest"));
}
const SwigBoost::intrusive_ptr<Klass>& ref_1() {
static SwigBoost::intrusive_ptr<Klass> sptr;
return sptr;
}
// overloading tests
std::string overload_rawbyval(int i) { return "int"; }
std::string overload_rawbyval(Klass k) { return "rawbyval"; }
std::string overload_rawbyref(int i) { return "int"; }
std::string overload_rawbyref(Klass &k) { return "rawbyref"; }
std::string overload_rawbyptr(int i) { return "int"; }
std::string overload_rawbyptr(Klass *k) { return "rawbyptr"; }
std::string overload_rawbyptrref(int i) { return "int"; }
std::string overload_rawbyptrref(Klass *const&k) { return "rawbyptrref"; }
std::string overload_smartbyval(int i) { return "int"; }
std::string overload_smartbyval(SwigBoost::intrusive_ptr<Klass> k) { return "smartbyval"; }
std::string overload_smartbyref(int i) { return "int"; }
std::string overload_smartbyref(SwigBoost::intrusive_ptr<Klass> &k) { return "smartbyref"; }
std::string overload_smartbyptr(int i) { return "int"; }
std::string overload_smartbyptr(SwigBoost::intrusive_ptr<Klass> *k) { return "smartbyptr"; }
std::string overload_smartbyptrref(int i) { return "int"; }
std::string overload_smartbyptrref(SwigBoost::intrusive_ptr<Klass> *&k) { return "smartbyptrref"; }
} // namespace Space
%}
%{
boost::detail::atomic_count Space::Klass::total_count(0);
boost::detail::atomic_count Space::KlassWithoutRefCount::total_count(0);
boost::detail::atomic_count Space::IgnoredRefCountingBase::total_count(0);
boost::detail::atomic_count Space::KlassDerived::total_count(0);
boost::detail::atomic_count Space::KlassDerivedDerived::total_count(0);
%}
// Member variables
%inline %{
struct MemberVariables {
MemberVariables() : SmartMemberPointer(new SwigBoost::intrusive_ptr<Space::Klass>()), SmartMemberReference(*(new SwigBoost::intrusive_ptr<Space::Klass>())), MemberPointer(0), MemberReference(MemberValue) {}
virtual ~MemberVariables() {
delete SmartMemberPointer;
delete &SmartMemberReference;
}
SwigBoost::intrusive_ptr<Space::Klass> SmartMemberValue;
SwigBoost::intrusive_ptr<Space::Klass> * SmartMemberPointer;
SwigBoost::intrusive_ptr<Space::Klass> & SmartMemberReference;
Space::Klass MemberValue;
Space::Klass * MemberPointer;
Space::Klass & MemberReference;
};
// Global variables
SwigBoost::intrusive_ptr<Space::Klass> GlobalSmartValue;
Space::Klass GlobalValue;
Space::Klass * GlobalPointer = 0;
Space::Klass & GlobalReference = GlobalValue;
%}
#if defined(INTRUSIVE_PTR_WRAPPERS_IMPLEMENTED)
// Note: %template after the intrusive_ptr typemaps
%intrusive_ptr(Base<int, double>)
%intrusive_ptr(Pair<int, double>)
#endif
// Templates
%inline %{
template <class T1, class T2> struct Base {
Space::Klass klassBase;
T1 baseVal1;
T2 baseVal2;
Base(T1 t1, T2 t2) : baseVal1(t1*2), baseVal2(t2*2) {}
virtual std::string getValue() const { return "Base<>"; };
mutable int count;
void addref(void) const { count++; }
void release(void) const { if (--count == 0) delete this; }
int use_count(void) const { return count; }
};
%}
%template(BaseIntDouble) Base<int, double>;
%inline %{
template <class T1, class T2> struct Pair : Base<T1, T2> {
Space::Klass klassPair;
T1 val1;
T2 val2;
Pair(T1 t1, T2 t2) : Base<T1, T2>(t1, t2), val1(t1), val2(t2) {}
virtual std::string getValue() const { return "Pair<>"; };
};
Pair<int, double> pair_id2(Pair<int, double> p) { return p; }
SwigBoost::intrusive_ptr< Pair<int, double> > pair_id1(SwigBoost::intrusive_ptr< Pair<int, double> > p) { return p; }
template<typename T> void intrusive_ptr_add_ref(const T* r) { r->addref(); }
template<typename T> void intrusive_ptr_release(const T* r) { r->release(); }
long use_count(const SwigBoost::shared_ptr<Space::Klass>& sptr) {
return sptr.use_count();
}
long use_count(const SwigBoost::shared_ptr<Space::KlassDerived>& sptr) {
return sptr.use_count();
}
long use_count(const SwigBoost::shared_ptr<Space::KlassDerivedDerived>& sptr) {
return sptr.use_count();
}
%}
%template(PairIntDouble) Pair<int, double>;
// For counting the instances of intrusive_ptr (all of which are created on the heap)
// intrusive_ptr_wrapper_count() gives overall count
%inline %{
namespace SwigBoost {
const int NOT_COUNTING = -123456;
int intrusive_ptr_wrapper_count() {
#ifdef INTRUSIVE_PTR_WRAPPER
return SwigBoost::IntrusivePtrWrapper::getTotalCount();
#else
return NOT_COUNTING;
#endif
}
#ifdef INTRUSIVE_PTR_WRAPPER
template<> std::string show_message(boost::intrusive_ptr<Space::Klass >*t) {
if (!t)
return "null intrusive_ptr!!!";
if (*t)
return "Klass: " + (*t)->getValue();
else
return "Klass: NULL";
}
template<> std::string show_message(boost::intrusive_ptr<const Space::Klass >*t) {
if (!t)
return "null intrusive_ptr!!!";
if (*t)
return "Klass: " + (*t)->getValue();
else
return "Klass: NULL";
}
template<> std::string show_message(boost::intrusive_ptr<Space::KlassDerived >*t) {
if (!t)
return "null intrusive_ptr!!!";
if (*t)
return "KlassDerived: " + (*t)->getValue();
else
return "KlassDerived: NULL";
}
template<> std::string show_message(boost::intrusive_ptr<const Space::KlassDerived >*t) {
if (!t)
return "null intrusive_ptr!!!";
if (*t)
return "KlassDerived: " + (*t)->getValue();
else
return "KlassDerived: NULL";
}
#endif
}
%}
// This tests intrusive_ptr is working okay. It also checks that there are no memory leaks in the
// class that intrusive_ptr is pointing via a counting mechanism in the constructors and destructor of Klass.
// In order to test that there are no leaks of the intrusive_ptr class itself (as it is created on the heap)
// the runtime tests can be run for a long time to monitor memory leaks using memory monitor tools
// like 'top'. There is a wrapper for intrusive_ptr in intrusive_ptr_wrapper.h which enables one to
// count the instances of intrusive_ptr. Uncomment the INTRUSIVE_PTR_WRAPPER macro to turn this on.
//
// Also note the debug_shared flag which can be set from the target language.
%module li_boost_intrusive_ptr
%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK);
%warnfilter(SWIGWARN_LANG_SMARTPTR_MISSING) KlassDerived;
%warnfilter(SWIGWARN_LANG_SMARTPTR_MISSING) KlassDerivedDerived;
%inline %{
#include "boost/shared_ptr.hpp"
#include "boost/intrusive_ptr.hpp"
#include <boost/detail/atomic_count.hpp>
// Uncomment macro below to turn on intrusive_ptr memory leak checking as described above
//#define INTRUSIVE_PTR_WRAPPER
#ifdef INTRUSIVE_PTR_WRAPPER
# include "intrusive_ptr_wrapper.h"
# include "shared_ptr_wrapper.h"
#endif
%}
%{
#ifndef INTRUSIVE_PTR_WRAPPER
# define SwigBoost boost
#endif
%}
%include "std_string.i"
#ifndef INTRUSIVE_PTR_WRAPPER
# define SWIG_INTRUSIVE_PTR_NAMESPACE SwigBoost
# define SWIG_SHARED_PTR_NAMESPACE SwigBoost
#endif
#if defined(SWIGJAVA) || defined(SWIGCSHARP)
#define INTRUSIVE_PTR_WRAPPERS_IMPLEMENTED
#endif
#if defined(INTRUSIVE_PTR_WRAPPERS_IMPLEMENTED)
%include <boost_intrusive_ptr.i>
%intrusive_ptr(Space::Klass)
%intrusive_ptr_no_wrap(Space::KlassWithoutRefCount)
%intrusive_ptr(Space::KlassDerived)
%intrusive_ptr(Space::KlassDerivedDerived)
//For the use_count shared_ptr functions
#if defined(SWIGJAVA)
%typemap(in) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::Klass > & ($*1_ltype tempnull) %{
$1 = $input ? *($&1_ltype)&$input : &tempnull;
%}
%typemap (jni) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::Klass > & "jlong"
%typemap (jtype) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::Klass > & "long"
%typemap (jstype) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::Klass > & "Klass"
%typemap(javain) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::Klass > & "Klass.getCPtr($javainput)"
%typemap(in) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::KlassDerived > & ($*1_ltype tempnull) %{
$1 = $input ? *($&1_ltype)&$input : &tempnull;
%}
%typemap (jni) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::KlassDerived > & "jlong"
%typemap (jtype) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::KlassDerived > & "long"
%typemap (jstype) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::KlassDerived > & "KlassDerived"
%typemap(javain) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::KlassDerived > & "KlassDerived.getCPtr($javainput)"
%typemap(in) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::KlassDerivedDerived > & ($*1_ltype tempnull) %{
$1 = $input ? *($&1_ltype)&$input : &tempnull;
%}
%typemap (jni) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::KlassDerivedDerived > & "jlong"
%typemap (jtype) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::KlassDerivedDerived > & "long"
%typemap (jstype) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::KlassDerivedDerived > & "KlassDerivedDerived"
%typemap(javain) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::KlassDerivedDerived > & "KlassDerivedDerived.getCPtr($javainput)"
#elif defined(SWIGCSHARP)
// TODO!
#endif
#endif
// TODO:
// const intrusive_ptr
// std::vector
// Add in generic %extend for the Upcast function for derived classes
// Remove proxy upcast method - implement %feature("shadow") ??? which replaces the proxy method
%exception {
if (debug_shared) {
cout << "++++++" << endl << flush;
cout << "calling $name" << endl << flush;
}
$action
if (debug_shared) {
cout << "------" << endl << flush;
}
}
%ignore IgnoredRefCountingBase;
%ignore *::operator=;
%ignore intrusive_ptr_add_ref;
%ignore intrusive_ptr_release;
%newobject pointerownertest();
%newobject smartpointerpointerownertest();
%inline %{
#include <iostream>
using namespace std;
static bool debug_shared = false;
namespace Space {
struct Klass {
Klass() : value("EMPTY"), count(0) { if (debug_shared) cout << "Klass() [" << value << "]" << endl << flush; increment(); }
Klass(const std::string &val) : value(val), count(0) { if (debug_shared) cout << "Klass(string) [" << value << "]" << endl << flush; increment(); }
virtual ~Klass() { if (debug_shared) cout << "~Klass() [" << value << "]" << endl << flush; decrement(); }
virtual std::string getValue() const { return value; }
void append(const std::string &s) { value += s; }
Klass(const Klass &other) : value(other.value), count(0) { if (debug_shared) cout << "Klass(const Klass&) [" << value << "]" << endl << flush; increment(); }
Klass &operator=(const Klass &other) { value = other.value; return *this; }
void addref(void) const { ++count; }
void release(void) const { if (--count == 0) delete this; }
int use_count(void) const { return count; }
static long getTotal_count() { return total_count; }
private:
static void increment() { ++total_count; if (debug_shared) cout << " ++xxxxx Klass::increment tot: " << total_count << endl;}
static void decrement() { --total_count; if (debug_shared) cout << " --xxxxx Klass::decrement tot: " << total_count << endl;}
static boost::detail::atomic_count total_count;
std::string value;
int array[1024];
mutable boost::detail::atomic_count count;
};
struct KlassWithoutRefCount {
KlassWithoutRefCount() : value("EMPTY") { if (debug_shared) cout << "KlassWithoutRefCount() [" << value << "]" << endl << flush; increment(); }
KlassWithoutRefCount(const std::string &val) : value(val) { if (debug_shared) cout << "KlassWithoutRefCount(string) [" << value << "]" << endl << flush; increment(); }
virtual ~KlassWithoutRefCount() { if (debug_shared) cout << "~KlassWithoutRefCount() [" << value << "]" << endl << flush; decrement(); }
virtual std::string getValue() const { return value; }
void append(const std::string &s) { value += s; }
KlassWithoutRefCount(const KlassWithoutRefCount &other) : value(other.value) { if (debug_shared) cout << "KlassWithoutRefCount(const KlassWithoutRefCount&) [" << value << "]" << endl << flush; increment(); }
std::string getSpecialValueFromUnwrappableClass() { return "this class cannot be wrapped by intrusive_ptrs but we can still use it"; }
KlassWithoutRefCount &operator=(const KlassWithoutRefCount &other) { value = other.value; return *this; }
static long getTotal_count() { return total_count; }
private:
static void increment() { ++total_count; if (debug_shared) cout << " ++xxxxx KlassWithoutRefCount::increment tot: " << total_count << endl;}
static void decrement() { --total_count; if (debug_shared) cout << " --xxxxx KlassWithoutRefCount::decrement tot: " << total_count << endl;}
static boost::detail::atomic_count total_count;
std::string value;
int array[1024];
};
struct IgnoredRefCountingBase {
IgnoredRefCountingBase() : count(0) { if (debug_shared) cout << "IgnoredRefCountingBase()" << endl << flush; increment(); }
IgnoredRefCountingBase(const IgnoredRefCountingBase &other) : count(0) { if (debug_shared) cout << "IgnoredRefCountingBase(const IgnoredRefCountingBase&)" << endl << flush; increment(); }
IgnoredRefCountingBase &operator=(const IgnoredRefCountingBase& other) {
return *this;
}
virtual ~IgnoredRefCountingBase() { if (debug_shared) cout << "~IgnoredRefCountingBase()" << endl << flush; decrement(); }
void addref(void) const { ++count; }
void release(void) const { if (--count == 0) delete this; }
int use_count(void) const { return count; }
static long getTotal_count() { return total_count; }
private:
static void increment() { ++total_count; if (debug_shared) cout << " ++xxxxx IgnoredRefCountingBase::increment tot: " << total_count << endl;}
static void decrement() { --total_count; if (debug_shared) cout << " --xxxxx IgnoredRefCountingBase::decrement tot: " << total_count << endl;}
static boost::detail::atomic_count total_count;
double d;
double e;
mutable boost::detail::atomic_count count;
};
long getTotal_IgnoredRefCountingBase_count() {
return IgnoredRefCountingBase::getTotal_count();
}
// For most compilers, this use of multiple inheritance results in different derived and base class
// pointer values ... for some more challenging tests :)
struct KlassDerived : IgnoredRefCountingBase, KlassWithoutRefCount {
KlassDerived() : KlassWithoutRefCount() { if (debug_shared) cout << "KlassDerived()" << endl << flush; increment(); }
KlassDerived(const std::string &val) : KlassWithoutRefCount(val) { if (debug_shared) cout << "KlassDerived(string) [" << val << "]" << endl << flush; increment(); }
KlassDerived(const KlassDerived &other) : KlassWithoutRefCount(other) { if (debug_shared) cout << "KlassDerived(const KlassDerived&))" << endl << flush; increment(); }
virtual ~KlassDerived() { if (debug_shared) cout << "~KlassDerived()" << endl << flush; decrement(); }
virtual std::string getValue() const { return KlassWithoutRefCount::getValue() + "-Derived"; }
int use_count(void) const { return IgnoredRefCountingBase::use_count(); }
static long getTotal_count() { return total_count; }
private:
static void increment() { ++total_count; if (debug_shared) cout << " ++xxxxx KlassDerived::increment tot: " << total_count << endl;}
static void decrement() { --total_count; if (debug_shared) cout << " --xxxxx KlassDerived::decrement tot: " << total_count << endl;}
static boost::detail::atomic_count total_count;
};
struct KlassDerivedDerived : KlassDerived {
KlassDerivedDerived() : KlassDerived() { if (debug_shared) cout << "KlassDerivedDerived()" << endl << flush; increment(); }
KlassDerivedDerived(const std::string &val) : KlassDerived(val) { if (debug_shared) cout << "KlassDerivedDerived(string) [" << val << "]" << endl << flush; increment(); }
KlassDerivedDerived(const KlassDerived &other) : KlassDerived(other) { if (debug_shared) cout << "KlassDerivedDerived(const KlassDerivedDerived&))" << endl << flush; increment(); }
virtual ~KlassDerivedDerived() { if (debug_shared) cout << "~KlassDerivedDerived()" << endl << flush; decrement(); }
virtual std::string getValue() const { return KlassWithoutRefCount::getValue() + "-DerivedDerived"; }
static long getTotal_count() { return total_count; }
private:
static void increment() { ++total_count; if (debug_shared) cout << " ++xxxxx KlassDerivedDerived::increment tot: " << total_count << endl;}
static void decrement() { --total_count; if (debug_shared) cout << " --xxxxx KlassDerivedDerived::decrement tot: " << total_count << endl;}
static boost::detail::atomic_count total_count;
};
KlassDerived* derivedpointertest(KlassDerived* kd) {
if (kd)
kd->append(" derivedpointertest");
return kd;
}
KlassDerived derivedvaluetest(KlassDerived kd) {
kd.append(" derivedvaluetest");
return kd;
}
KlassDerived& derivedreftest(KlassDerived& kd) {
kd.append(" derivedreftest");
return kd;
}
SwigBoost::intrusive_ptr<KlassDerived> derivedsmartptrtest(SwigBoost::intrusive_ptr<KlassDerived> kd) {
if (kd)
kd->append(" derivedsmartptrtest");
return kd;
}
SwigBoost::intrusive_ptr<KlassDerived>* derivedsmartptrpointertest(SwigBoost::intrusive_ptr<KlassDerived>* kd) {
if (kd && *kd)
(*kd)->append(" derivedsmartptrpointertest");
return kd;
}
SwigBoost::intrusive_ptr<KlassDerived>* derivedsmartptrreftest(SwigBoost::intrusive_ptr<KlassDerived>* kd) {
if (kd && *kd)
(*kd)->append(" derivedsmartptrreftest");
return kd;
}
SwigBoost::intrusive_ptr<KlassDerived>*& derivedsmartptrpointerreftest(SwigBoost::intrusive_ptr<KlassDerived>*& kd) {
if (kd && *kd)
(*kd)->append(" derivedsmartptrpointerreftest");
return kd;
}
SwigBoost::intrusive_ptr<Klass> factorycreate() {
return SwigBoost::intrusive_ptr<Klass>(new Klass("factorycreate"));
}
// smart pointer
SwigBoost::intrusive_ptr<Klass> smartpointertest(SwigBoost::intrusive_ptr<Klass> k) {
if (k)
k->append(" smartpointertest");
return SwigBoost::intrusive_ptr<Klass>(k);
}
SwigBoost::intrusive_ptr<Klass>* smartpointerpointertest(SwigBoost::intrusive_ptr<Klass>* k) {
if (k && *k)
(*k)->append(" smartpointerpointertest");
return k;
}
SwigBoost::intrusive_ptr<Klass>& smartpointerreftest(SwigBoost::intrusive_ptr<Klass>& k) {
if (k)
k->append(" smartpointerreftest");
return k;
}
SwigBoost::intrusive_ptr<Klass>*& smartpointerpointerreftest(SwigBoost::intrusive_ptr<Klass>*& k) {
if (k && *k)
(*k)->append(" smartpointerpointerreftest");
return k;
}
// const
SwigBoost::intrusive_ptr<const Klass> constsmartpointertest(SwigBoost::intrusive_ptr<const Klass> k) {
return SwigBoost::intrusive_ptr<const Klass>(k);
}
SwigBoost::intrusive_ptr<const Klass>* constsmartpointerpointertest(SwigBoost::intrusive_ptr<const Klass>* k) {
return k;
}
SwigBoost::intrusive_ptr<const Klass>& constsmartpointerreftest(SwigBoost::intrusive_ptr<const Klass>& k) {
return k;
}
// plain pointer
Klass valuetest(Klass k) {
k.append(" valuetest");
return k;
}
Klass *pointertest(Klass *k) {
if (k)
k->append(" pointertest");
return k;
}
Klass& reftest(Klass& k) {
k.append(" reftest");
return k;
}
Klass *const& pointerreftest(Klass *const& k) {
k->append(" pointerreftest");
return k;
}
// null
std::string nullsmartpointerpointertest(SwigBoost::intrusive_ptr<Klass>* k) {
if (k && *k)
return "not null";
else if (!k)
return "null smartpointer pointer";
else if (!*k)
return "null pointer";
else
return "also not null";
}
// $owner
Klass *pointerownertest() {
return new Klass("pointerownertest");
}
SwigBoost::intrusive_ptr<Klass>* smartpointerpointerownertest() {
return new SwigBoost::intrusive_ptr<Klass>(new Klass("smartpointerpointerownertest"));
}
const SwigBoost::intrusive_ptr<Klass>& ref_1() {
static SwigBoost::intrusive_ptr<Klass> sptr;
return sptr;
}
// overloading tests
std::string overload_rawbyval(int i) { return "int"; }
std::string overload_rawbyval(Klass k) { return "rawbyval"; }
std::string overload_rawbyref(int i) { return "int"; }
std::string overload_rawbyref(Klass &k) { return "rawbyref"; }
std::string overload_rawbyptr(int i) { return "int"; }
std::string overload_rawbyptr(Klass *k) { return "rawbyptr"; }
std::string overload_rawbyptrref(int i) { return "int"; }
std::string overload_rawbyptrref(Klass *const&k) { return "rawbyptrref"; }
std::string overload_smartbyval(int i) { return "int"; }
std::string overload_smartbyval(SwigBoost::intrusive_ptr<Klass> k) { return "smartbyval"; }
std::string overload_smartbyref(int i) { return "int"; }
std::string overload_smartbyref(SwigBoost::intrusive_ptr<Klass> &k) { return "smartbyref"; }
std::string overload_smartbyptr(int i) { return "int"; }
std::string overload_smartbyptr(SwigBoost::intrusive_ptr<Klass> *k) { return "smartbyptr"; }
std::string overload_smartbyptrref(int i) { return "int"; }
std::string overload_smartbyptrref(SwigBoost::intrusive_ptr<Klass> *&k) { return "smartbyptrref"; }
} // namespace Space
%}
%{
boost::detail::atomic_count Space::Klass::total_count(0);
boost::detail::atomic_count Space::KlassWithoutRefCount::total_count(0);
boost::detail::atomic_count Space::IgnoredRefCountingBase::total_count(0);
boost::detail::atomic_count Space::KlassDerived::total_count(0);
boost::detail::atomic_count Space::KlassDerivedDerived::total_count(0);
%}
// Member variables
%inline %{
struct MemberVariables {
MemberVariables() : SmartMemberPointer(new SwigBoost::intrusive_ptr<Space::Klass>()), SmartMemberReference(*(new SwigBoost::intrusive_ptr<Space::Klass>())), MemberPointer(0), MemberReference(MemberValue) {}
virtual ~MemberVariables() {
delete SmartMemberPointer;
delete &SmartMemberReference;
}
SwigBoost::intrusive_ptr<Space::Klass> SmartMemberValue;
SwigBoost::intrusive_ptr<Space::Klass> * SmartMemberPointer;
SwigBoost::intrusive_ptr<Space::Klass> & SmartMemberReference;
Space::Klass MemberValue;
Space::Klass * MemberPointer;
Space::Klass & MemberReference;
};
// Global variables
SwigBoost::intrusive_ptr<Space::Klass> GlobalSmartValue;
Space::Klass GlobalValue;
Space::Klass * GlobalPointer = 0;
Space::Klass & GlobalReference = GlobalValue;
%}
#if defined(INTRUSIVE_PTR_WRAPPERS_IMPLEMENTED)
// Note: %template after the intrusive_ptr typemaps
%intrusive_ptr(Base<int, double>)
%intrusive_ptr(Pair<int, double>)
#endif
// Templates
%inline %{
template <class T1, class T2> struct Base {
Space::Klass klassBase;
T1 baseVal1;
T2 baseVal2;
Base(T1 t1, T2 t2) : baseVal1(t1*2), baseVal2(t2*2) {}
virtual std::string getValue() const { return "Base<>"; };
mutable int count;
void addref(void) const { count++; }
void release(void) const { if (--count == 0) delete this; }
int use_count(void) const { return count; }
};
%}
%template(BaseIntDouble) Base<int, double>;
%inline %{
template <class T1, class T2> struct Pair : Base<T1, T2> {
Space::Klass klassPair;
T1 val1;
T2 val2;
Pair(T1 t1, T2 t2) : Base<T1, T2>(t1, t2), val1(t1), val2(t2) {}
virtual std::string getValue() const { return "Pair<>"; };
};
Pair<int, double> pair_id2(Pair<int, double> p) { return p; }
SwigBoost::intrusive_ptr< Pair<int, double> > pair_id1(SwigBoost::intrusive_ptr< Pair<int, double> > p) { return p; }
template<typename T> void intrusive_ptr_add_ref(const T* r) { r->addref(); }
template<typename T> void intrusive_ptr_release(const T* r) { r->release(); }
long use_count(const SwigBoost::shared_ptr<Space::Klass>& sptr) {
return sptr.use_count();
}
long use_count(const SwigBoost::shared_ptr<Space::KlassDerived>& sptr) {
return sptr.use_count();
}
long use_count(const SwigBoost::shared_ptr<Space::KlassDerivedDerived>& sptr) {
return sptr.use_count();
}
%}
%template(PairIntDouble) Pair<int, double>;
// For counting the instances of intrusive_ptr (all of which are created on the heap)
// intrusive_ptr_wrapper_count() gives overall count
%inline %{
namespace SwigBoost {
const int NOT_COUNTING = -123456;
int intrusive_ptr_wrapper_count() {
#ifdef INTRUSIVE_PTR_WRAPPER
return SwigBoost::IntrusivePtrWrapper::getTotalCount();
#else
return NOT_COUNTING;
#endif
}
#ifdef INTRUSIVE_PTR_WRAPPER
template<> std::string show_message(boost::intrusive_ptr<Space::Klass >*t) {
if (!t)
return "null intrusive_ptr!!!";
if (*t)
return "Klass: " + (*t)->getValue();
else
return "Klass: NULL";
}
template<> std::string show_message(boost::intrusive_ptr<const Space::Klass >*t) {
if (!t)
return "null intrusive_ptr!!!";
if (*t)
return "Klass: " + (*t)->getValue();
else
return "Klass: NULL";
}
template<> std::string show_message(boost::intrusive_ptr<Space::KlassDerived >*t) {
if (!t)
return "null intrusive_ptr!!!";
if (*t)
return "KlassDerived: " + (*t)->getValue();
else
return "KlassDerived: NULL";
}
template<> std::string show_message(boost::intrusive_ptr<const Space::KlassDerived >*t) {
if (!t)
return "null intrusive_ptr!!!";
if (*t)
return "KlassDerived: " + (*t)->getValue();
else
return "KlassDerived: NULL";
}
#endif
}
%}

View file

@ -1,42 +1,42 @@
require("import") -- the import fn
import("li_typemaps") -- import code
-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
-- Check double INPUT typemaps
assert(li_typemaps.in_double(22.22) == 22.22)
assert(li_typemaps.inr_double(22.22) == 22.22)
-- Check double OUTPUT typemaps
assert(li_typemaps.out_double(22.22) == 22.22)
assert(li_typemaps.outr_double(22.22) == 22.22)
-- Check double INOUT typemaps
assert(li_typemaps.inout_double(22.22) == 22.22)
assert(li_typemaps.inoutr_double(22.22) == 22.22)
-- check long long
assert(li_typemaps.in_ulonglong(20)==20)
assert(li_typemaps.inr_ulonglong(20)==20)
assert(li_typemaps.out_ulonglong(20)==20)
assert(li_typemaps.outr_ulonglong(20)==20)
assert(li_typemaps.inout_ulonglong(20)==20)
assert(li_typemaps.inoutr_ulonglong(20)==20)
-- check bools
assert(li_typemaps.in_bool(true)==true)
assert(li_typemaps.inr_bool(false)==false)
assert(li_typemaps.out_bool(true)==true)
assert(li_typemaps.outr_bool(false)==false)
assert(li_typemaps.inout_bool(true)==true)
assert(li_typemaps.inoutr_bool(false)==false)
-- the others
a,b=li_typemaps.inoutr_int2(1,2)
assert(a==1 and b==2)
f,i=li_typemaps.out_foo(10)
assert(f.a==10 and i==20)
require("import") -- the import fn
import("li_typemaps") -- import code
-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
-- Check double INPUT typemaps
assert(li_typemaps.in_double(22.22) == 22.22)
assert(li_typemaps.inr_double(22.22) == 22.22)
-- Check double OUTPUT typemaps
assert(li_typemaps.out_double(22.22) == 22.22)
assert(li_typemaps.outr_double(22.22) == 22.22)
-- Check double INOUT typemaps
assert(li_typemaps.inout_double(22.22) == 22.22)
assert(li_typemaps.inoutr_double(22.22) == 22.22)
-- check long long
assert(li_typemaps.in_ulonglong(20)==20)
assert(li_typemaps.inr_ulonglong(20)==20)
assert(li_typemaps.out_ulonglong(20)==20)
assert(li_typemaps.outr_ulonglong(20)==20)
assert(li_typemaps.inout_ulonglong(20)==20)
assert(li_typemaps.inoutr_ulonglong(20)==20)
-- check bools
assert(li_typemaps.in_bool(true)==true)
assert(li_typemaps.inr_bool(false)==false)
assert(li_typemaps.out_bool(true)==true)
assert(li_typemaps.outr_bool(false)==false)
assert(li_typemaps.inout_bool(true)==true)
assert(li_typemaps.inoutr_bool(false)==false)
-- the others
a,b=li_typemaps.inoutr_int2(1,2)
assert(a==1 and b==2)
f,i=li_typemaps.out_foo(10)
assert(f.a==10 and i==20)