1 // Copyright (c) 2005 Daniel Wallin, Arvid Norberg
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the "Software"),
5 // to deal in the Software without restriction, including without limitation
6 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 // and/or sell copies of the Software, and to permit persons to whom the
8 // Software is furnished to do so, subject to the following conditions:
10 // The above copyright notice and this permission notice shall be included
11 // in all copies or substantial portions of the Software.
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
14 // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
15 // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
16 // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
17 // SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
18 // ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
21 // OR OTHER DEALINGS IN THE SOFTWARE.
25 #include <luabind/luabind.hpp>
26 #include <luabind/wrapper_base.hpp>
27 #include <luabind/adopt_policy.hpp>
28 #include <boost/shared_ptr.hpp>
32 #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
34 T
* get_pointer(boost::shared_ptr
<T
> const& p
) { return p
.get(); }
39 using namespace luabind
;
41 struct A
: counted_type
<A
>
45 virtual std::string
f()
48 virtual std::string
g() const
52 struct A_wrap
: A
, wrap_base
56 return call_member
<std::string
>(this, "f");
59 static std::string
default_f(A
* p
)
64 return call_member
<std::string
>(this, "g");
67 static std::string
default_g(A
const* p
)
73 virtual std::string
f()
77 struct B_wrap
: B
, wrap_base
79 virtual std::string
f()
80 { return call_member
<std::string
>(this, "f"); }
82 static std::string
default_f(B
* p
)
85 virtual std::string
g() const
86 { return call_member
<std::string
>(this, "g"); }
88 static std::string
default_g(B
const* p
)
93 struct base
: counted_type
<base
>
97 virtual std::string
f()
102 virtual std::string
g() const { return ""; }
105 base
* filter(base
* p
) { return p
; }
107 struct base_wrap
: base
, wrap_base
109 virtual std::string
f()
111 return call_member
<std::string
>(this, "f");
114 static std::string
default_f(base
* p
)
119 virtual std::string
g() const
121 return call_member
<std::string
>(this, "g");
125 struct T_
// vc6.5, don't name your types T!
127 int f(int) { return 1; }
132 int g() { return 3; }
133 int f(int, int) { return 2; }
136 void test_main(lua_State
* L
)
140 class_
<A
, A_wrap
, boost::shared_ptr
<A
> >("A")
141 .def(constructor
<>())
142 .def("f", &A::f
, &A_wrap::default_f
)
143 .def("g", &A::g
, &A_wrap::default_g
),
145 class_
<B
, A
, B_wrap
, boost::shared_ptr
<A
> >("B")
146 .def(constructor
<>())
147 .def("f", &B::f
, &B_wrap::default_f
)
148 .def("g", &B::g
, &B_wrap::default_g
),
150 def("filter", &filter
),
152 class_
<base
, base_wrap
>("base")
153 .def(constructor
<>())
154 .def("f", &base::f
, &base_wrap::default_f
)
161 .def(constructor
<>())
169 "assert(u:f(0) == 1)\n"
170 "assert(u:f(0,0) == 2)\n"
171 "assert(u:g() == 3)\n");
175 "assert(u:f(0) == 1)\n"
176 "assert(u:f(0,0) == 2)\n"
177 "assert(u:g() == 3)\n");
180 "function base:fun()\n"
184 "assert(ba:fun() == 4)");
187 "class 'derived' (base)\n"
188 " function derived:__init() base.__init(self) end\n"
189 " function derived:f()\n"
190 " return 'derived:f() : ' .. base.f(self)\n"
193 "class 'empty_derived' (base)\n"
194 " function empty_derived:__init() base.__init(self) end\n"
197 " function C:__init() B.__init(self) end\n"
198 " function C:f() return 'C:f()' end\n"
200 "function make_derived()\n"
201 " return derived()\n"
204 "function make_empty_derived()\n"
205 " return empty_derived()\n"
208 "function adopt_ptr(x)\n"
213 "function gen_error()\n"
222 "assert(c:f() == 'C:f()')\n"
223 "assert(b:f() == 'B:f()')\n"
224 "assert(a:f() == 'A:f()')\n"
225 "assert(b:g() == 'A:g()')\n"
226 "assert(c:g() == 'A:g()')\n"
228 "assert(C.f(c) == 'C:f()')\n"
229 "assert(B.f(c) == 'B:f()')\n"
230 "assert(A.f(c) == 'A:f()')\n"
231 "assert(A.g(c) == 'A:g()')\n");
233 #ifndef LUABIND_NO_EXCEPTONS
235 LUABIND_CHECK_STACK(L
);
237 try { call_function
<int>(L
, "gen_error"); }
238 catch (luabind::error
&)
241 lua_tostring(L
, -1) == std::string("[string \"function "
242 "gen_error()...\"]:2: assertion failed!"));
251 DOSTRING(L
, "function test_ref(x) end");
252 call_function
<void>(L
, "test_ref", boost::ref(a
));
256 LUABIND_CHECK_STACK(L
);
258 try { call_function
<void>(L
, "gen_error"); }
259 catch (luabind::error
&)
262 lua_tostring(L
, -1) == std::string("[string \"function "
263 "gen_error()...\"]:2: assertion failed!"));
270 LUABIND_CHECK_STACK(L
);
272 try { call_function
<void>(L
, "gen_error") [ adopt(result
) ]; }
273 catch (luabind::error
&)
276 lua_tostring(L
, -1) == std::string("[string \"function "
277 "gen_error()...\"]:2: assertion failed!"));
287 LUABIND_CHECK_STACK(L
);
290 object a
= globals(L
)["ba"];
291 TEST_CHECK(call_member
<int>(a
, "fun") == 4);
296 LUABIND_CHECK_STACK(L
);
298 object make_derived
= globals(L
)["make_derived"];
300 call_function
<void>(make_derived
)
304 std::auto_ptr
<base
> own_ptr
;
306 LUABIND_CHECK_STACK(L
);
309 own_ptr
= std::auto_ptr
<base
>(
310 call_function
<base
*>(L
, "make_derived") [ adopt(result
) ])
314 // make sure the derived lua-part is still referenced by
315 // the adopted c++ pointer
321 "collectgarbage()\n");
324 TEST_CHECK(own_ptr
->f() == "derived:f() : base:f()")
326 own_ptr
= std::auto_ptr
<base
>();
328 // test virtual functions that are not overridden by lua
330 own_ptr
= std::auto_ptr
<base
>(
331 call_function
<base
*>(L
, "make_empty_derived") [ adopt(result
) ])
334 TEST_CHECK(own_ptr
->f() == "base:f()")
337 call_function
<void>(L
, "adopt_ptr", own_ptr
.get()) [ adopt(_1
) ]
341 // test virtual functions that are overridden by lua
343 ptr
= call_function
<base
*>(L
, "derived")
347 TEST_CHECK(ptr
->f() == "derived:f() : base:f()")
350 // test virtual function dispatch from within lua
354 "assert(b:f() == 'derived:f() : base:f()')\n");
356 // test back references
359 "assert(a == filter(a))\n");