Skip to content

Commit 41fddf6

Browse files
committed
Add Lua support for std::unique_ptr and std::auto_ptr
Equivalent to Python/Ruby implementations.
1 parent 63632f8 commit 41fddf6

File tree

7 files changed

+186
-11
lines changed

7 files changed

+186
-11
lines changed

CHANGES.current

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
77
Version 4.1.0 (in progress)
88
===========================
99

10+
2022-08-11: wsfulton
11+
[Lua] Add support for std::unique_ptr in std_unique_ptr.i.
12+
Add support for std::auto_ptr in std_auto_ptr.i.
13+
1014
2022-08-05: wsfulton
1115
[D] Fix occasional undefined behaviour with inheritance hierarchies, particularly
1216
when using virtual inheritance as the pointers weren't correctly upcast from derived

Examples/test-suite/cpp11_std_unique_ptr.i

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
%module cpp11_std_unique_ptr
22

3-
#if defined(SWIGCSHARP) || defined(SWIGJAVA) || defined(SWIGPYTHON) || defined(SWIGRUBY) || defined(SWIGPERL) || defined(SWIGTCL) || defined(SWIGOCTAVE) || defined(SWIGJAVASCRIPT) || defined(SWIGD) || defined(SWIGPHP)
3+
#if !(defined(SWIGGO) || defined(SWIGOCAML) || defined(SWIGMZSCHEME) || defined(SWIGR) || defined(SWIGSCILAB))
44

55
%include "std_string.i"
66
%include "std_unique_ptr.i"

Examples/test-suite/li_std_auto_ptr.i

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#endif
1313
%}
1414

15-
#if defined(SWIGCSHARP) || defined(SWIGJAVA) || defined(SWIGPYTHON) || defined(SWIGRUBY) || defined(SWIGPERL) || defined(SWIGTCL) || defined(SWIGOCTAVE) || defined(SWIGJAVASCRIPT) || defined(SWIGD) || (SWIGPHP)
15+
#if !(defined(SWIGGO) || defined(SWIGOCAML) || defined(SWIGMZSCHEME) || defined(SWIGR) || defined(SWIGSCILAB))
1616

1717
%include "std_string.i"
1818
//#include <iostream>
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
require("import") -- the import fn
2+
import("li_std_auto_ptr") -- import code
3+
4+
-- catch "undefined" global variables
5+
local env = _ENV -- Lua 5.2
6+
if not env then env = getfenv () end -- Lua 5.1
7+
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
8+
9+
10+
function checkCount(expected_count)
11+
-- call gc to make unused objects are collected
12+
collectgarbage()
13+
actual_count = li_std_auto_ptr.Klass.getTotal_count()
14+
if not (actual_count == expected_count) then
15+
error("Counts incorrect, expected:"..expected_count.." actual:"..actual_count)
16+
end
17+
end
18+
19+
--Test raw pointer handling involving virtual inheritance
20+
kini = li_std_auto_ptr.KlassInheritance("KlassInheritanceInput")
21+
checkCount(1)
22+
s = li_std_auto_ptr.useKlassRawPtr(kini)
23+
if not (s == "KlassInheritanceInput") then
24+
error("Incorrect string: "..s)
25+
end
26+
kini = nil
27+
checkCount(0)
28+
29+
-- auto_ptr as input
30+
kin = li_std_auto_ptr.Klass("KlassInput")
31+
checkCount(1)
32+
s = li_std_auto_ptr.takeKlassAutoPtr(kin)
33+
checkCount(0)
34+
if not (s == "KlassInput") then
35+
error("Incorrect string: "..s)
36+
end
37+
if not (li_std_auto_ptr.is_nullptr(kin)) then
38+
error("is_nullptr failed")
39+
end
40+
kin = nil -- Should not fail, even though already deleted
41+
checkCount(0)
42+
43+
kin = li_std_auto_ptr.Klass("KlassInput")
44+
checkCount(1)
45+
s = li_std_auto_ptr.takeKlassAutoPtr(kin)
46+
checkCount(0)
47+
if not (s == "KlassInput") then
48+
error("Incorrect string: "..s)
49+
end
50+
if not (li_std_auto_ptr.is_nullptr(kin)) then
51+
error("is_nullptr failed")
52+
end
53+
s, msg = pcall(function() li_std_auto_ptr.takeKlassAutoPtr(kin) end)
54+
assert(s == false and msg == "Cannot release ownership as memory is not owned for argument 1 of type 'Klass *' in takeKlassAutoPtr")
55+
56+
kin = nil -- Should not fail, even though already deleted
57+
checkCount(0)
58+
59+
kin = li_std_auto_ptr.Klass("KlassInput")
60+
notowned = li_std_auto_ptr.get_not_owned_ptr(kin)
61+
s, msg = pcall(function() li_std_auto_ptr.takeKlassAutoPtr(notowned) end)
62+
assert(s == false and msg == "Cannot release ownership as memory is not owned for argument 1 of type 'Klass *' in takeKlassAutoPtr")
63+
checkCount(1)
64+
kin = nil
65+
checkCount(0)
66+
67+
kini = li_std_auto_ptr.KlassInheritance("KlassInheritanceInput")
68+
checkCount(1)
69+
s = li_std_auto_ptr.takeKlassAutoPtr(kini)
70+
checkCount(0)
71+
if not (s == "KlassInheritanceInput") then
72+
error("Incorrect string: "..s)
73+
end
74+
if not (li_std_auto_ptr.is_nullptr(kini)) then
75+
error("is_nullptr failed")
76+
end
77+
kini = nil -- Should not fail, even though already deleted
78+
checkCount(0)
79+
80+
-- auto_ptr as output
81+
k1 = li_std_auto_ptr.makeKlassAutoPtr("first")
82+
k2 = li_std_auto_ptr.makeKlassAutoPtr("second")
83+
checkCount(2)
84+
85+
k1 = nil
86+
checkCount(1)
87+
88+
if not (k2:getLabel() == "second") then
89+
error("wrong object label")
90+
end
91+
92+
k2 = nil
93+
checkCount(0)

Lib/lua/luarun.swg

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1757,6 +1757,7 @@ SWIGRUNTIME void SWIG_Lua_NewPointerObj(lua_State *L,void *ptr,swig_type_info *t
17571757
(if possible) */
17581758
SWIGRUNTIME int SWIG_Lua_ConvertPtr(lua_State *L,int index,void **ptr,swig_type_info *type,int flags)
17591759
{
1760+
int ret = SWIG_ERROR;
17601761
swig_lua_userdata *usr;
17611762
swig_cast_info *cast;
17621763
/* special case: lua nil => NULL pointer */
@@ -1773,25 +1774,36 @@ SWIGRUNTIME int SWIG_Lua_ConvertPtr(lua_State *L,int index,void **ptr,swig_type
17731774
usr=(swig_lua_userdata*)lua_touserdata(L,index); /* get data */
17741775
if (usr)
17751776
{
1777+
if (((flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE) && !usr->own)
1778+
{
1779+
return SWIG_ERROR_RELEASE_NOT_OWNED;
1780+
}
17761781
if (flags & SWIG_POINTER_DISOWN) /* must disown the object */
17771782
{
1778-
usr->own=0;
1783+
usr->own = 0;
17791784
}
17801785
if (!type) /* special cast void*, no casting fn */
17811786
{
17821787
*ptr=usr->ptr;
1783-
return SWIG_OK; /* ok */
1788+
ret = SWIG_OK;
17841789
}
1785-
cast=SWIG_TypeCheckStruct(usr->type,type); /* performs normal type checking */
1786-
if (cast)
1790+
else
17871791
{
1788-
int newmemory = 0;
1789-
*ptr=SWIG_TypeCast(cast,usr->ptr,&newmemory);
1790-
assert(!newmemory); /* newmemory handling not yet implemented */
1791-
return SWIG_OK; /* ok */
1792+
cast=SWIG_TypeCheckStruct(usr->type,type); /* performs normal type checking */
1793+
if (cast)
1794+
{
1795+
int newmemory = 0;
1796+
*ptr=SWIG_TypeCast(cast,usr->ptr,&newmemory);
1797+
assert(!newmemory); /* newmemory handling not yet implemented */
1798+
ret = SWIG_OK;
1799+
}
1800+
}
1801+
if ((ret == SWIG_OK) && (flags & SWIG_POINTER_CLEAR))
1802+
{
1803+
usr->ptr = 0;
17921804
}
17931805
}
1794-
return SWIG_ERROR; /* error */
1806+
return ret;
17951807
}
17961808

17971809
SWIGRUNTIME void* SWIG_Lua_MustGetPtr(lua_State *L,int index,swig_type_info *type,int flags,

Lib/lua/std_auto_ptr.i

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/* -----------------------------------------------------------------------------
2+
* std_auto_ptr.i
3+
*
4+
* SWIG library file for handling std::auto_ptr.
5+
* Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
6+
* class when returning a std::auto_ptr from a function.
7+
* Memory ownership is passed from the proxy class to the std::auto_ptr in the
8+
* C++ layer when passed as a parameter to a wrapped function.
9+
* ----------------------------------------------------------------------------- */
10+
11+
%define %auto_ptr(TYPE)
12+
%typemap(in, checkfn="lua_isuserdata", noblock=1) std::auto_ptr< TYPE > (void *argp = 0, int res = 0) {
13+
res = SWIG_ConvertPtr(L, $input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE);
14+
if (!SWIG_IsOK(res)) {
15+
if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
16+
lua_pushfstring(L, "Cannot release ownership as memory is not owned for argument $argnum of type 'TYPE *' in $symname"); SWIG_fail;
17+
} else {
18+
SWIG_fail_ptr("$symname", $argnum, $descriptor(TYPE *));
19+
}
20+
}
21+
$1.reset((TYPE *)argp);
22+
}
23+
24+
%typemap (out) std::auto_ptr< TYPE > %{
25+
SWIG_NewPointerObj(L, $1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN); SWIG_arg++;
26+
%}
27+
28+
%template() std::auto_ptr< TYPE >;
29+
%enddef
30+
31+
namespace std {
32+
template <class T> class auto_ptr {};
33+
}

Lib/lua/std_unique_ptr.i

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/* -----------------------------------------------------------------------------
2+
* std_unique_ptr.i
3+
*
4+
* SWIG library file for handling std::unique_ptr.
5+
* Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
6+
* class when returning a std::unique_ptr from a function.
7+
* Memory ownership is passed from the proxy class to the std::unique_ptr in the
8+
* C++ layer when passed as a parameter to a wrapped function.
9+
* ----------------------------------------------------------------------------- */
10+
11+
%define %unique_ptr(TYPE)
12+
%typemap(in, checkfn="lua_isuserdata", noblock=1) std::unique_ptr< TYPE > (void *argp = 0, int res = 0) {
13+
res = SWIG_ConvertPtr(L, $input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE);
14+
if (!SWIG_IsOK(res)) {
15+
if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
16+
lua_pushfstring(L, "Cannot release ownership as memory is not owned for argument $argnum of type 'TYPE *' in $symname"); SWIG_fail;
17+
} else {
18+
SWIG_fail_ptr("$symname", $argnum, $descriptor(TYPE *));
19+
}
20+
}
21+
$1.reset((TYPE *)argp);
22+
}
23+
24+
%typemap (out) std::unique_ptr< TYPE > %{
25+
SWIG_NewPointerObj(L, $1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN); SWIG_arg++;
26+
%}
27+
28+
%template() std::unique_ptr< TYPE >;
29+
%enddef
30+
31+
namespace std {
32+
template <class T> class unique_ptr {};
33+
}

0 commit comments

Comments
 (0)