1 // Copyright (c) 2004 Daniel Wallin and 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.
24 #include <luabind/luabind.hpp>
25 #include <luabind/wrapper_base.hpp>
26 #include <luabind/adopt_policy.hpp>
27 #include <boost/shared_ptr.hpp>
32 T
* get_pointer(boost::shared_ptr
<T
>& p
) { return p
.get(); }
35 boost::shared_ptr
<const A
>* get_const_holder(boost::shared_ptr
<A
>*)
41 using namespace luabind
;
45 struct A
: counted_type
<A
>
49 virtual std::string
f()
52 virtual std::string
g() const
56 struct A_wrap
: A
, wrap_base
60 return call_member
<std::string
>(this, "f");
63 static std::string
default_f(A
* p
)
68 return call_member
<std::string
>(this, "g");
71 static std::string
default_g(A
const* p
)
77 virtual std::string
f()
81 struct B_wrap
: B
, wrap_base
83 virtual std::string
f()
84 { return call_member
<std::string
>(this, "f"); }
86 static std::string
default_f(B
* p
)
89 virtual std::string
g() const
90 { return call_member
<std::string
>(this, "g"); }
92 static std::string
default_g(B
const* p
)
97 struct base
: counted_type
<base
>
101 virtual std::string
f()
106 virtual std::string
g() const { return ""; }
109 base
* filter(base
* p
) { return p
; }
111 struct base_wrap
: base
, wrap_base
113 virtual std::string
f()
115 return call_member
<std::string
>(this, "f");
118 static std::string
default_f(base
* p
)
123 virtual std::string
g() const
125 return call_member
<std::string
>(this, "g");
129 struct T_
// vc6.5, don't name your types T!
131 int f(int) { return 1; }
136 int g() { return 3; }
137 int f(int, int) { return 2; }
140 } // namespace unnamed
142 void test_lua_classes()
151 class_
<A
, A_wrap
, boost::shared_ptr
<A
> >("A")
152 .def(constructor
<>())
153 .def("f", &A::f
, &A_wrap::default_f
)
154 .def("g", &A::g
, &A_wrap::default_g
),
156 class_
<B
, A
, B_wrap
, boost::shared_ptr
<A
> >("B")
157 .def(constructor
<>())
158 .def("f", &B::f
, &B_wrap::default_f
)
159 .def("g", &B::g
, &B_wrap::default_g
),
161 def("filter", &filter
),
163 class_
<base
, base_wrap
>("base")
164 .def(constructor
<>())
165 .def("f", &base::f
, &base_wrap::default_f
)
172 .def(constructor
<>())
179 "assert(u:f(0) == 1)\n"
180 "assert(u:f(0,0) == 2)\n"
181 "assert(u:g() == 3)\n");
184 "function base:fun()\n"
188 "assert(ba:fun() == 4)");
191 "class 'derived' (base)\n"
192 " function derived:__init() super() end\n"
193 " function derived:f()\n"
194 " return 'derived:f() : ' .. base.f(self)\n"
197 "class 'empty_derived' (base)\n"
198 " function empty_derived:__init() super() end\n"
201 " function C:__init() super() end\n"
202 " function C:f() return 'C:f()' end\n"
204 "function make_derived()\n"
205 " return derived()\n"
208 "function make_empty_derived()\n"
209 " return empty_derived()\n"
212 "function adopt_ptr(x)\n"
217 "function gen_error()\n"
226 "assert(c:f() == 'C:f()')\n"
227 "assert(b:f() == 'B:f()')\n"
228 "assert(a:f() == 'A:f()')\n"
229 "assert(b:g() == 'A:g()')\n"
230 "assert(c:g() == 'A:g()')\n"
232 "assert(C.f(c) == 'C:f()')\n"
233 "assert(B.f(c) == 'B:f()')\n"
234 "assert(A.f(c) == 'A:f()')\n"
235 "assert(A.g(c) == 'A:g()')\n");
237 #ifndef LUABIND_NO_EXCEPTONS
239 LUABIND_CHECK_STACK(L
);
241 try { call_function
<int>(L
, "gen_error"); }
242 catch (luabind::error
&)
245 lua_tostring(L
, -1) == std::string("[string \"function "
246 "gen_error()...\"]:2: assertion failed!"));
255 DOSTRING(L
, "function test_ref(x) end");
256 call_function
<void>(L
, "test_ref", boost::ref(a
));
260 LUABIND_CHECK_STACK(L
);
262 try { call_function
<void>(L
, "gen_error"); }
263 catch (luabind::error
&)
266 lua_tostring(L
, -1) == std::string("[string \"function "
267 "gen_error()...\"]:2: assertion failed!"));
274 LUABIND_CHECK_STACK(L
);
276 try { call_function
<void*>(L
, "gen_error") [ adopt(result
) ]; }
277 catch (luabind::error
&)
280 lua_tostring(L
, -1) == std::string("[string \"function "
281 "gen_error()...\"]:2: assertion failed!"));
291 LUABIND_CHECK_STACK(L
);
293 BOOST_CHECK_NO_THROW(
294 object a
= get_globals(L
)["ba"];
295 BOOST_CHECK(call_member
<int>(a
, "fun") == 4);
300 LUABIND_CHECK_STACK(L
);
302 object make_derived
= get_globals(L
)["make_derived"];
303 BOOST_CHECK_NO_THROW(
304 call_function
<void>(make_derived
)
308 std::auto_ptr
<base
> own_ptr
;
310 LUABIND_CHECK_STACK(L
);
312 BOOST_CHECK_NO_THROW(
313 own_ptr
= std::auto_ptr
<base
>(
314 call_function
<base
*>(L
, "make_derived") [ adopt(result
) ])
318 // make sure the derived lua-part is still referenced by
319 // the adopted c++ pointer
325 "collectgarbage()\n");
327 BOOST_CHECK_NO_THROW(
328 BOOST_CHECK(own_ptr
->f() == "derived:f() : base:f()")
330 own_ptr
= std::auto_ptr
<base
>();
332 // test virtual functions that are not overridden by lua
333 BOOST_CHECK_NO_THROW(
334 own_ptr
= std::auto_ptr
<base
>(
335 call_function
<base
*>(L
, "make_empty_derived") [ adopt(result
) ])
337 BOOST_CHECK_NO_THROW(
338 BOOST_CHECK(own_ptr
->f() == "base:f()")
340 BOOST_CHECK_NO_THROW(
341 call_function
<void>(L
, "adopt_ptr", own_ptr
.get()) [ adopt(_1
) ]
345 // test virtual functions that are overridden by lua
346 BOOST_CHECK_NO_THROW(
347 ptr
= call_function
<base
*>(L
, "derived")
350 BOOST_CHECK_NO_THROW(
351 BOOST_CHECK(ptr
->f() == "derived:f() : base:f()")
354 // test virtual function dispatch from within lua
358 "assert(b:f() == 'derived:f() : base:f()')\n");
360 // test back references
363 "assert(a == filter(a))\n");