diff --git a/Examples/lua/arrays/Makefile b/Examples/lua/arrays/Makefile index bb9cf0b3b..f181818a6 100644 --- a/Examples/lua/arrays/Makefile +++ b/Examples/lua/arrays/Makefile @@ -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 diff --git a/Examples/lua/arrays/example.c b/Examples/lua/arrays/example.c index 56c7b19d9..ed23738c8 100644 --- a/Examples/lua/arrays/example.c +++ b/Examples/lua/arrays/example.c @@ -1,25 +1,25 @@ -/* File : example.c */ - -#include - -/* 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 + +/* 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); +} diff --git a/Examples/lua/arrays/example.i b/Examples/lua/arrays/example.i index 197a5a21b..3d5b60dc6 100644 --- a/Examples/lua/arrays/example.i +++ b/Examples/lua/arrays/example.i @@ -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 // 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 -%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); -%} \ No newline at end of file +/* 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 // 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 +%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); +%} diff --git a/Examples/lua/arrays/runme.lua b/Examples/lua/arrays/runme.lua index b0f5cfc96..7ab6dc42b 100644 --- a/Examples/lua/arrays/runme.lua +++ b/Examples/lua/arrays/runme.lua @@ -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) + diff --git a/Examples/lua/embed/embed.c b/Examples/lua/embed/embed.c index 55ea099be..9df168f94 100644 --- a/Examples/lua/embed/embed.c +++ b/Examples/lua/embed/embed.c @@ -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 -#include - -#include -#include -#include - -/* 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 +#include + +#include +#include +#include + +/* 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; +} diff --git a/Examples/lua/embed/example.c b/Examples/lua/embed/example.c index c6c6d7ba1..efd13f662 100644 --- a/Examples/lua/embed/example.c +++ b/Examples/lua/embed/example.c @@ -1,22 +1,22 @@ -/* File : example.c */ - -#include - -/* 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 + +/* 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"); +} diff --git a/Examples/lua/embed2/embed2.c b/Examples/lua/embed2/embed2.c index dac527eb4..8d28ee6ea 100644 --- a/Examples/lua/embed2/embed2.c +++ b/Examples/lua/embed2/embed2.c @@ -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 -#include - -#include -#include -#include -#include -#include - - -/* 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 +#include + +#include +#include +#include +#include +#include + + +/* 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; +} diff --git a/Examples/lua/embed2/example.c b/Examples/lua/embed2/example.c index c6c6d7ba1..efd13f662 100644 --- a/Examples/lua/embed2/example.c +++ b/Examples/lua/embed2/example.c @@ -1,22 +1,22 @@ -/* File : example.c */ - -#include - -/* 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 + +/* 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"); +} diff --git a/Examples/lua/embed3/example.i b/Examples/lua/embed3/example.i index 032805c0e..950d2549d 100644 --- a/Examples/lua/embed3/example.i +++ b/Examples/lua/embed3/example.i @@ -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" diff --git a/Examples/lua/exception/Makefile b/Examples/lua/exception/Makefile index 8657f1922..0feee14dd 100644 --- a/Examples/lua/exception/Makefile +++ b/Examples/lua/exception/Makefile @@ -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 diff --git a/Examples/lua/exception/example.h b/Examples/lua/exception/example.h index 5148a5962..251ef1132 100644 --- a/Examples/lua/exception/example.h +++ b/Examples/lua/exception/example.h @@ -1,53 +1,53 @@ -/* File : example.h */ - -#include -#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 +#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 + diff --git a/Examples/lua/exception/example.i b/Examples/lua/exception/example.i index 09cd9e812..6187f8eff 100644 --- a/Examples/lua/exception/example.i +++ b/Examples/lua/exception/example.i @@ -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" + diff --git a/Examples/lua/exception/runme.lua b/Examples/lua/exception/runme.lua index 39b2d6da8..d8125caec 100644 --- a/Examples/lua/exception/runme.lua +++ b/Examples/lua/exception/runme.lua @@ -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) diff --git a/Examples/lua/owner/Makefile b/Examples/lua/owner/Makefile index 1fe68ec7f..44888f66f 100644 --- a/Examples/lua/owner/Makefile +++ b/Examples/lua/owner/Makefile @@ -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 diff --git a/Examples/lua/owner/example.cxx b/Examples/lua/owner/example.cxx index d6caeef15..bce484aea 100644 --- a/Examples/lua/owner/example.cxx +++ b/Examples/lua/owner/example.cxx @@ -1,69 +1,69 @@ -/* File : example.c */ - -#include "example.h" -#include - -#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= static_cast(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(shapes.size())) - return NULL; - Shape* ptr=shapes[idx]; - shapes.erase(shapes.begin()+idx); - return ptr; -} +/* File : example.c */ + +#include "example.h" +#include + +#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= static_cast(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(shapes.size())) + return NULL; + Shape* ptr=shapes[idx]; + shapes.erase(shapes.begin()+idx); + return ptr; +} diff --git a/Examples/lua/owner/example.h b/Examples/lua/owner/example.h index b00568025..320bb2569 100644 --- a/Examples/lua/owner/example.h +++ b/Examples/lua/owner/example.h @@ -1,54 +1,54 @@ -/* File : example.h */ -#include - -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 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 + +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 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 +}; + + diff --git a/Examples/lua/owner/example.i b/Examples/lua/owner/example.i index 4e7c331bc..1dfac4a09 100644 --- a/Examples/lua/owner/example.i +++ b/Examples/lua/owner/example.i @@ -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" + diff --git a/Examples/lua/owner/runme.lua b/Examples/lua/owner/runme.lua index d2d8a9c6f..ed745f7b2 100644 --- a/Examples/lua/owner/runme.lua +++ b/Examples/lua/owner/runme.lua @@ -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!" \ No newline at end of file +-- 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!" diff --git a/Examples/test-suite/csharp/li_std_map_runme.cs b/Examples/test-suite/csharp/li_std_map_runme.cs index 551cf2dc1..0fe1ab5cd 100644 --- a/Examples/test-suite/csharp/li_std_map_runme.cs +++ b/Examples/test-suite/csharp/li_std_map_runme.cs @@ -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(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 keys = new List(simap.Keys); - IList values = new List(simap.Values); - Dictionary check = new Dictionary(); - 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(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(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[] outputarray = new KeyValuePair[collectionSize]; - simap.CopyTo(outputarray); - foreach (KeyValuePair val in outputarray) - { - if (simap[val.Key] != val.Value) - throw new Exception("CopyTo (1) test failed, index:" + val.Key); - } - } - { - KeyValuePair[] outputarray = new KeyValuePair[midCollection + collectionSize]; - simap.CopyTo(outputarray, midCollection); - for (int i = midCollection; i < midCollection + collectionSize; i++) - { - KeyValuePair val = outputarray[i]; - if (simap[val.Key] != val.Value) - throw new Exception("CopyTo (2) test failed, index:" + val.Key); - } - } - { - KeyValuePair[] outputarray = new KeyValuePair[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 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 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 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(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 keys = new List(simap.Keys); + IList values = new List(simap.Values); + Dictionary check = new Dictionary(); + 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(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(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[] outputarray = new KeyValuePair[collectionSize]; + simap.CopyTo(outputarray); + foreach (KeyValuePair val in outputarray) + { + if (simap[val.Key] != val.Value) + throw new Exception("CopyTo (1) test failed, index:" + val.Key); + } + } + { + KeyValuePair[] outputarray = new KeyValuePair[midCollection + collectionSize]; + simap.CopyTo(outputarray, midCollection); + for (int i = midCollection; i < midCollection + collectionSize; i++) + { + KeyValuePair val = outputarray[i]; + if (simap[val.Key] != val.Value) + throw new Exception("CopyTo (2) test failed, index:" + val.Key); + } + } + { + KeyValuePair[] outputarray = new KeyValuePair[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 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 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 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 + } +} + diff --git a/Examples/test-suite/java/li_boost_intrusive_ptr_runme.java b/Examples/test-suite/java/li_boost_intrusive_ptr_runme.java index f40c28e9e..9b480e7e0 100644 --- a/Examples/test-suite/java/li_boost_intrusive_ptr_runme.java +++ b/Examples/test-suite/java/li_boost_intrusive_ptr_runme.java @@ -1,701 +1,701 @@ -import li_boost_intrusive_ptr.*; - -public class li_boost_intrusive_ptr_runme { - static { - try { - System.loadLibrary("li_boost_intrusive_ptr"); - } catch (UnsatisfiedLinkError e) { - System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); - System.exit(1); - } - } - - // Debugging flag - public final static boolean debug = false; - - public static void main(String argv[]) - { - if (debug) - System.out.println("Started"); - - li_boost_intrusive_ptr.setDebug_shared(debug); - - // Change loop count to run for a long time to monitor memory - final int loopCount = 5000; //5000; - for (int i=0; i - -// 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 -%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 -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 derivedsmartptrtest(SwigBoost::intrusive_ptr kd) { - if (kd) - kd->append(" derivedsmartptrtest"); - return kd; -} -SwigBoost::intrusive_ptr* derivedsmartptrpointertest(SwigBoost::intrusive_ptr* kd) { - if (kd && *kd) - (*kd)->append(" derivedsmartptrpointertest"); - return kd; -} -SwigBoost::intrusive_ptr* derivedsmartptrreftest(SwigBoost::intrusive_ptr* kd) { - if (kd && *kd) - (*kd)->append(" derivedsmartptrreftest"); - return kd; -} -SwigBoost::intrusive_ptr*& derivedsmartptrpointerreftest(SwigBoost::intrusive_ptr*& kd) { - if (kd && *kd) - (*kd)->append(" derivedsmartptrpointerreftest"); - return kd; -} - -SwigBoost::intrusive_ptr factorycreate() { - return SwigBoost::intrusive_ptr(new Klass("factorycreate")); -} -// smart pointer -SwigBoost::intrusive_ptr smartpointertest(SwigBoost::intrusive_ptr k) { - if (k) - k->append(" smartpointertest"); - return SwigBoost::intrusive_ptr(k); -} -SwigBoost::intrusive_ptr* smartpointerpointertest(SwigBoost::intrusive_ptr* k) { - if (k && *k) - (*k)->append(" smartpointerpointertest"); - return k; -} -SwigBoost::intrusive_ptr& smartpointerreftest(SwigBoost::intrusive_ptr& k) { - if (k) - k->append(" smartpointerreftest"); - return k; -} -SwigBoost::intrusive_ptr*& smartpointerpointerreftest(SwigBoost::intrusive_ptr*& k) { - if (k && *k) - (*k)->append(" smartpointerpointerreftest"); - return k; -} -// const -SwigBoost::intrusive_ptr constsmartpointertest(SwigBoost::intrusive_ptr k) { - return SwigBoost::intrusive_ptr(k); -} -SwigBoost::intrusive_ptr* constsmartpointerpointertest(SwigBoost::intrusive_ptr* k) { - return k; -} -SwigBoost::intrusive_ptr& constsmartpointerreftest(SwigBoost::intrusive_ptr& 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* 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* smartpointerpointerownertest() { - return new SwigBoost::intrusive_ptr(new Klass("smartpointerpointerownertest")); -} - -const SwigBoost::intrusive_ptr& ref_1() { - static SwigBoost::intrusive_ptr 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 k) { return "smartbyval"; } - -std::string overload_smartbyref(int i) { return "int"; } -std::string overload_smartbyref(SwigBoost::intrusive_ptr &k) { return "smartbyref"; } - -std::string overload_smartbyptr(int i) { return "int"; } -std::string overload_smartbyptr(SwigBoost::intrusive_ptr *k) { return "smartbyptr"; } - -std::string overload_smartbyptrref(int i) { return "int"; } -std::string overload_smartbyptrref(SwigBoost::intrusive_ptr *&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()), SmartMemberReference(*(new SwigBoost::intrusive_ptr())), MemberPointer(0), MemberReference(MemberValue) {} - virtual ~MemberVariables() { - delete SmartMemberPointer; - delete &SmartMemberReference; - } - SwigBoost::intrusive_ptr SmartMemberValue; - SwigBoost::intrusive_ptr * SmartMemberPointer; - SwigBoost::intrusive_ptr & SmartMemberReference; - Space::Klass MemberValue; - Space::Klass * MemberPointer; - Space::Klass & MemberReference; -}; - -// Global variables -SwigBoost::intrusive_ptr 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) -%intrusive_ptr(Pair) - -#endif - -// Templates -%inline %{ -template 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; - -%inline %{ -template struct Pair : Base { - Space::Klass klassPair; - T1 val1; - T2 val2; - Pair(T1 t1, T2 t2) : Base(t1, t2), val1(t1), val2(t2) {} - virtual std::string getValue() const { return "Pair<>"; }; -}; - -Pair pair_id2(Pair p) { return p; } -SwigBoost::intrusive_ptr< Pair > pair_id1(SwigBoost::intrusive_ptr< Pair > p) { return p; } - -template void intrusive_ptr_add_ref(const T* r) { r->addref(); } - -template void intrusive_ptr_release(const T* r) { r->release(); } - -long use_count(const SwigBoost::shared_ptr& sptr) { - return sptr.use_count(); -} -long use_count(const SwigBoost::shared_ptr& sptr) { - return sptr.use_count(); -} -long use_count(const SwigBoost::shared_ptr& sptr) { - return sptr.use_count(); -} -%} - -%template(PairIntDouble) Pair; - -// 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*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*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*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*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 + +// 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 +%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 +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 derivedsmartptrtest(SwigBoost::intrusive_ptr kd) { + if (kd) + kd->append(" derivedsmartptrtest"); + return kd; +} +SwigBoost::intrusive_ptr* derivedsmartptrpointertest(SwigBoost::intrusive_ptr* kd) { + if (kd && *kd) + (*kd)->append(" derivedsmartptrpointertest"); + return kd; +} +SwigBoost::intrusive_ptr* derivedsmartptrreftest(SwigBoost::intrusive_ptr* kd) { + if (kd && *kd) + (*kd)->append(" derivedsmartptrreftest"); + return kd; +} +SwigBoost::intrusive_ptr*& derivedsmartptrpointerreftest(SwigBoost::intrusive_ptr*& kd) { + if (kd && *kd) + (*kd)->append(" derivedsmartptrpointerreftest"); + return kd; +} + +SwigBoost::intrusive_ptr factorycreate() { + return SwigBoost::intrusive_ptr(new Klass("factorycreate")); +} +// smart pointer +SwigBoost::intrusive_ptr smartpointertest(SwigBoost::intrusive_ptr k) { + if (k) + k->append(" smartpointertest"); + return SwigBoost::intrusive_ptr(k); +} +SwigBoost::intrusive_ptr* smartpointerpointertest(SwigBoost::intrusive_ptr* k) { + if (k && *k) + (*k)->append(" smartpointerpointertest"); + return k; +} +SwigBoost::intrusive_ptr& smartpointerreftest(SwigBoost::intrusive_ptr& k) { + if (k) + k->append(" smartpointerreftest"); + return k; +} +SwigBoost::intrusive_ptr*& smartpointerpointerreftest(SwigBoost::intrusive_ptr*& k) { + if (k && *k) + (*k)->append(" smartpointerpointerreftest"); + return k; +} +// const +SwigBoost::intrusive_ptr constsmartpointertest(SwigBoost::intrusive_ptr k) { + return SwigBoost::intrusive_ptr(k); +} +SwigBoost::intrusive_ptr* constsmartpointerpointertest(SwigBoost::intrusive_ptr* k) { + return k; +} +SwigBoost::intrusive_ptr& constsmartpointerreftest(SwigBoost::intrusive_ptr& 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* 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* smartpointerpointerownertest() { + return new SwigBoost::intrusive_ptr(new Klass("smartpointerpointerownertest")); +} + +const SwigBoost::intrusive_ptr& ref_1() { + static SwigBoost::intrusive_ptr 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 k) { return "smartbyval"; } + +std::string overload_smartbyref(int i) { return "int"; } +std::string overload_smartbyref(SwigBoost::intrusive_ptr &k) { return "smartbyref"; } + +std::string overload_smartbyptr(int i) { return "int"; } +std::string overload_smartbyptr(SwigBoost::intrusive_ptr *k) { return "smartbyptr"; } + +std::string overload_smartbyptrref(int i) { return "int"; } +std::string overload_smartbyptrref(SwigBoost::intrusive_ptr *&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()), SmartMemberReference(*(new SwigBoost::intrusive_ptr())), MemberPointer(0), MemberReference(MemberValue) {} + virtual ~MemberVariables() { + delete SmartMemberPointer; + delete &SmartMemberReference; + } + SwigBoost::intrusive_ptr SmartMemberValue; + SwigBoost::intrusive_ptr * SmartMemberPointer; + SwigBoost::intrusive_ptr & SmartMemberReference; + Space::Klass MemberValue; + Space::Klass * MemberPointer; + Space::Klass & MemberReference; +}; + +// Global variables +SwigBoost::intrusive_ptr 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) +%intrusive_ptr(Pair) + +#endif + +// Templates +%inline %{ +template 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; + +%inline %{ +template struct Pair : Base { + Space::Klass klassPair; + T1 val1; + T2 val2; + Pair(T1 t1, T2 t2) : Base(t1, t2), val1(t1), val2(t2) {} + virtual std::string getValue() const { return "Pair<>"; }; +}; + +Pair pair_id2(Pair p) { return p; } +SwigBoost::intrusive_ptr< Pair > pair_id1(SwigBoost::intrusive_ptr< Pair > p) { return p; } + +template void intrusive_ptr_add_ref(const T* r) { r->addref(); } + +template void intrusive_ptr_release(const T* r) { r->release(); } + +long use_count(const SwigBoost::shared_ptr& sptr) { + return sptr.use_count(); +} +long use_count(const SwigBoost::shared_ptr& sptr) { + return sptr.use_count(); +} +long use_count(const SwigBoost::shared_ptr& sptr) { + return sptr.use_count(); +} +%} + +%template(PairIntDouble) Pair; + +// 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*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*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*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*t) { + if (!t) + return "null intrusive_ptr!!!"; + if (*t) + return "KlassDerived: " + (*t)->getValue(); + else + return "KlassDerived: NULL"; + } + #endif +} +%} + diff --git a/Examples/test-suite/lua/li_typemaps_runme.lua b/Examples/test-suite/lua/li_typemaps_runme.lua index fd7764cf3..7456d8245 100644 --- a/Examples/test-suite/lua/li_typemaps_runme.lua +++ b/Examples/test-suite/lua/li_typemaps_runme.lua @@ -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)