1 // Copyright (c) 2004 Daniel Wallin and Arvid Norberg
2
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:
9
10 // The above copyright notice and this permission notice shall be included
11 // in all copies or substantial portions of the Software.
12
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.
22
23 #include "test.hpp"
24
25 #include <luabind/luabind.hpp>
26
27 using namespace luabind;
28
29 namespace {
30
31 struct abstract
32 {
~abstract__anon2ef562d90111::abstract33 virtual ~abstract() {}
34 virtual std::string hello() = 0;
35 };
36
37 COUNTER_GUARD(abstract);
38
39 struct concrete : abstract
40 {
hello__anon2ef562d90111::concrete41 std::string hello()
42 {
43 return "test string";
44 }
45 };
46
47 struct abstract_wrap : abstract, wrap_base
48 {
hello__anon2ef562d90111::abstract_wrap49 std::string hello()
50 {
51 return call_member<std::string>(this, "hello");
52 }
53 };
54
call_hello(abstract & a)55 static std::string call_hello(abstract& a)
56 {
57 return a.hello();
58 }
59
return_abstract_ref()60 static abstract& return_abstract_ref()
61 {
62 static concrete c;
63 return c;
64 }
65
return_const_abstract_ref()66 static abstract const& return_const_abstract_ref()
67 {
68 static concrete c;
69 return c;
70 }
71
72 } // namespace unnamed
73
74
test_main(lua_State * L)75 void test_main(lua_State* L)
76 {
77 module(L)
78 [
79 class_<abstract, abstract_wrap>("abstract")
80 .def(constructor<>())
81 .def("hello", &abstract::hello),
82
83 def("call_hello", &call_hello),
84 def("return_abstract_ref", &return_abstract_ref),
85 def("return_const_abstract_ref", &return_const_abstract_ref)
86 ];
87
88 DOSTRING_EXPECTED(L,
89 "x = abstract()\n"
90 "x:hello()\n"
91 , "std::runtime_error: 'Attempt to call nonexistent function'");
92
93 DOSTRING_EXPECTED(L,
94 "call_hello(x)\n"
95 , "std::runtime_error: 'Attempt to call nonexistent function'");
96
97 DOSTRING(L,
98 "class 'concrete' (abstract)\n"
99 " function concrete:__init()\n"
100 " abstract.__init(self)\n"
101 " end\n"
102
103 " function concrete:hello()\n"
104 " return 'hello from lua'\n"
105 " end\n");
106
107 DOSTRING(L,
108 "y = concrete()\n"
109 "y:hello()\n");
110
111 DOSTRING(L, "call_hello(y)\n");
112
113 DOSTRING(L,
114 "x = abstract()\n"
115 "x.hello = function(self) return 'hello from instance' end\n"
116 "print(x.hello)\n"
117 "assert(x:hello() == 'hello from instance')\n"
118 "assert(call_hello(x) == 'hello from instance')\n"
119 );
120 }
121