moved some headers out of detail/
[luabind.git] / luabind / detail / class_rep_scope.hpp
blob78d02d9cca052d7d5dc28a1c04dcd05af26c8977
1 // Copyright (c) 2003 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 #ifndef LUABIND_CLASS_REP_HPP_INCLUDED
25 #define LUABIND_CLASS_REP_HPP_INCLUDED
27 //#include <cstdlib>
29 #include <boost/limits.hpp>
30 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
32 #include <luabind/config.hpp>
33 #include <luabind/detail/object_rep.hpp>
34 #include <luabind/detail/construct_rep.hpp>
35 #include <luabind/detail/method_rep.hpp>
36 #include <luabind/detail/garbage_collector.hpp>
37 #include <luabind/detail/operator_id.hpp>
38 #include <luabind/detail/signature_match.hpp>
39 #include <luabind/detail/class_registry.hpp>
40 #include <luabind/detail/find_best_match.hpp>
41 #include <luabind/detail/get_overload_signature.hpp>
42 #include <luabind/error.hpp>
44 namespace luabind
47 template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(LUABIND_MAX_BASES, class A, detail::null_type)>
48 struct bases {};
49 typedef bases<detail::null_type> no_bases;
51 struct class_base;
55 namespace luabind { namespace detail
57 std::string stack_content_by_name(lua_State* L, int start_index);
58 int construct_lua_class_callback(lua_State* L);
60 // this is class-specific information, poor man's vtable
61 // this is allocated statically (removed by the compiler)
62 // a pointer to this structure is stored in the lua tables'
63 // metatable with the name __classrep
64 // it is used when matching parameters to function calls
65 // to determine possible implicit casts
66 // it is also used when finding the best match for overloaded
67 // methods
68 class class_rep
70 friend struct luabind::class_base;
71 friend int super_callback(lua_State*);
72 //TODO: avoid the lua-prefix
73 friend int lua_class_gettable(lua_State*);
74 friend int lua_class_settable(lua_State*);
75 friend int static_class_gettable(lua_State*);
76 public:
78 enum class_type
80 cpp_class = 0,
81 lua_class = 1
84 // destructor is a lua callback function that is hooked as garbage collector event on every instance
85 // of this class (including those that is not owned by lua). It gets an object_rep as argument
86 // on the lua stack. It should delete the object pointed to by object_rep::ptr if object_pre::flags
87 // is object_rep::owner (which means that lua owns the object)
89 // EXPECTS THE TOP VALUE ON THE LUA STACK TO
90 // BE THE USER DATA WHERE THIS CLASS IS BEING
91 // INSTANTIATED!
92 class_rep(LUABIND_TYPE_INFO t, const char* name, lua_State* L, void(*destructor)(void*), LUABIND_TYPE_INFO held_t, void*(*extractor)(void*))
93 : m_type(t)
94 , m_held_type(held_t)
95 , m_extract_underlying_fun(extractor)
96 , m_name(name)
97 , m_class_type(cpp_class)
98 , m_destructor(destructor)
101 // TODO: don't we need to copy the name?
102 class_registry* r = class_registry::get_registry(L);
103 assert((r->cpp_class() != LUA_NOREF) && "you must call luabind::open()"); // you must call luabind::open()
105 detail::getref(L, r->cpp_class());
106 lua_setmetatable(L, -2);
108 lua_pushvalue(L, -1); // duplicate our user data
109 m_self_ref = detail::ref(L); // pop one of them
111 m_instance_metatable = r->cpp_instance();
114 // used when creating a lua class
115 // EXPECTS THE TOP VALUE ON THE LUA STACK TO
116 // BE THE USER DATA WHERE THIS CLASS IS BEING
117 // INSTANTIATED!
118 class_rep(lua_State* L, const char* name)
119 : m_type(LUABIND_TYPEID(int))
120 , m_held_type(0)
121 , m_extract_underlying_fun(0)
122 , m_name(name)
123 , m_class_type(lua_class)
125 // TODO: don't we need to copy the name?
126 lua_newtable(L);
127 m_table_ref = detail::ref(L);
129 class_registry* r = class_registry::get_registry(L);
130 assert((r->cpp_class() != LUA_NOREF) && "you must call luabind::open()"); // you must call luabind::open()
132 detail::getref(L, r->lua_class());
133 lua_setmetatable(L, -2);
134 lua_pushvalue(L, -1); // duplicate our user data
135 m_self_ref = detail::ref(L); // pop one of them
137 m_instance_metatable = r->lua_instance();
140 ~class_rep()
142 #ifndef LUABIND_DONT_COPY_STRINGS
143 for (std::vector<char*>::iterator i = m_strings.begin(); i != m_strings.end(); ++i)
145 delete[] *i;
147 #endif
151 // called from the metamethod for __index
152 // the object pointer is passed on the lua stack
153 int gettable(lua_State* L)
155 if (lua_isnil(L, 2))
157 lua_pushnil(L);
158 return 1;
161 // we have to ignore the first argument since this may point to
162 // a method that is not present in this class (but in a subclass)
163 const char* key = lua_tostring(L, 2);
164 std::map<const char*, method_rep, ltstr>::iterator i = m_methods.find(key);
165 if (i != m_methods.end())
167 // the name is a method, return it
168 lua_pushlightuserdata(L, &i->second);
169 lua_pushcclosure(L, function_dispatcher, 1);
170 return 1;
173 std::map<const char*, callback, ltstr>::iterator j = m_getters.find(key);
174 if (j != m_getters.end())
176 // the name is a data member
177 return j->second.func(L, j->second.pointer_offset);
180 lua_pushnil(L);
181 return 1;
184 // called from the metamethod for __newindex
185 // the object pointer is passed on the lua stack
186 bool settable(lua_State* L)
188 if (lua_isnil(L, 2))
190 return false;
193 // we have to ignore the first argument since this may point to
194 // a method that is not present in this class (but in a subclass)
195 const char* key = lua_tostring(L, 2);
196 std::map<const char*, callback, ltstr>::iterator j = m_setters.find(key);
197 if (j != m_setters.end())
199 // the name is a data member
200 j->second.func(L, j->second.pointer_offset);
201 return true;
204 return false; // false means that we don't have a member with the given name
207 // this is called as __index metamethod on every instance of this class
208 static int gettable_dispatcher(lua_State* L)
210 object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, 1));
211 return obj->crep()->gettable(L);
214 // this is called as __newindex metamethod on every instance of this class
215 static int settable_dispatcher(lua_State* L)
217 object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, 1));
219 bool success = obj->crep()->settable(L);
221 #ifndef LUABIND_NO_ERROR_CHECKING
223 if (!success)
225 // this block is needed to make sure the std::string is destructed before
226 // lua_error() is called
227 #ifdef BOOST_MSVC
229 // msvc has a bug which deletes the string twice, that's
230 // why we have to create it on the heap
231 std::string* msg = new std::string("cannot set attribute '");
232 *msg += obj->crep()->m_name;
233 *msg += ".";
234 *msg += lua_tostring(L, -2);
235 *msg += "'";
236 lua_pushstring(L, msg->c_str());
237 delete msg;
239 #else
241 std::string msg = "cannot set attribute '";
242 msg += obj->crep()->m_name;
243 msg += ".";
244 msg += lua_tostring(L, -2);
245 msg += "'";
246 lua_pushstring(L, msg.c_str());
248 #endif
249 lua_error(L);
252 #endif
254 return 0;
257 static int operator_dispatcher(lua_State* L)
259 int id = static_cast<int>(lua_tonumber(L, lua_upvalueindex(1)));
261 int operand_id = 0;
263 object_rep* operand[2];
264 for (int i = 0; i < 2; ++i)
265 operand[i] = detail::is_class_object(L, i + 1);
267 if (operand[0] && operand[1])
268 if (LUABIND_TYPE_INFO_EQUAL(operand[0]->crep()->type(), operand[1]->crep()->type())) operand[1] = 0;
270 std::vector<operator_callback>* overloads[2];
271 for (int i = 0; i < 2; ++i)
272 if (operand[i]) overloads[i] = &operand[i]->crep()->m_operators[id]; else overloads[i] = 0;
274 std::size_t num_overloads[2];
275 for (int i = 0; i < 2; ++i)
276 if (overloads[i]) num_overloads[i] = overloads[i]->size(); else num_overloads[i] = 0;
278 bool ambiguous = false;
279 int match_index = -1;
280 int min_match = std::numeric_limits<int>::max();
282 // std::cout << "operator_dispatcher\n";
283 // std::cout << "num overloads: " << num_overloads[0] + num_overloads[1] << "\n";
284 // std::cout << "operator: " << id << "\n";
286 #ifdef LUABIND_NO_ERROR_CHECKING
288 if (num_overloads[0] == 1 && num_overloads[1] == 0)
290 operand_id = 0;
291 match_index = 0;
293 else if (num_overloads[0] == 0 && num_overloads[1] == 1)
295 operand_id = 1;
296 match_index = 0;
298 else
301 #endif
303 int num_params = lua_gettop(L);
304 if (overloads[0])
306 if (find_best_match(L, overloads[0]->begin(), overloads[0]->end(), ambiguous, min_match, match_index, num_params))
307 operand_id = 0;
310 // have look at the right operand.
311 // if the right operand is a class and
312 // not the same class as this, we have to
313 // try to match it's operators too
315 if (overloads[1])
317 if(find_best_match(L, overloads[1]->begin(), overloads[1]->end(), ambiguous, min_match, match_index, num_params))
318 operand_id = 1;
321 #ifdef LUABIND_NO_ERROR_CHECKING
325 #else
327 if (match_index == -1)
329 // this block is needed to make sure the std::string is destructed before
330 // lua_error() is called
332 std::string msg = "no operator ";
333 msg += get_operator_symbol(id);
334 msg += " matched the arguments (";
335 msg += stack_content_by_name(L, 1);
336 msg += ")\ncandidates are:\n";
338 if (overloads[0])
339 msg += get_overload_signatures(L, overloads[0]->begin(), overloads[0]->end(), get_operator_symbol(id));
341 if (overloads[1])
342 msg += get_overload_signatures(L, overloads[1]->begin(), overloads[1]->end(), get_operator_symbol(id));
344 lua_pushstring(L, msg.c_str());
346 lua_error(L);
348 else if (ambiguous)
350 // this block is needed to make sure the std::string is destructed before
351 // lua_error() is called
353 std::string msg = "call of overloaded operator ";
354 msg += get_operator_symbol(id);
355 msg += " (";
356 msg += stack_content_by_name(L, 1);
357 msg += ")' is ambiguous\nnone of the overloads have a best conversion:\n";
359 std::vector<operator_callback> candidates;
360 if (overloads[0])
361 find_exact_match(L, overloads[0]->begin(), overloads[0]->end(), min_match, num_params, candidates);
363 if (overloads[1])
364 find_exact_match(L, overloads[1]->begin(), overloads[1]->end(), min_match, num_params, candidates);
366 msg += get_overload_signatures(L, candidates.begin(), candidates.end(), get_operator_symbol(id));
369 lua_pushstring(L, msg.c_str());
371 lua_error(L);
374 #endif
376 return (*overloads[operand_id])[match_index].call(L);
380 // this is called as metamethod __call on the class_rep.
381 static int constructor_dispatcher(lua_State* L)
383 class_rep* crep = static_cast<class_rep*>(lua_touserdata(L, 1));
384 construct_rep* rep = &crep->m_constructor;
386 bool ambiguous = false;
387 int match_index = -1;
388 int min_match = std::numeric_limits<int>::max();
389 bool found;
391 #ifdef LUABIND_NO_ERROR_CHECKING
393 if (rep->overloads.size() == 1)
395 match_index = 0;
397 else
400 #endif
402 int num_params = lua_gettop(L) - 1;
403 found = find_best_match(L, rep->overloads.begin(), rep->overloads.end(), ambiguous, min_match, match_index, num_params);
405 #ifdef LUABIND_NO_ERROR_CHECKING
409 #else
411 if (!found)
413 // this block is needed to make sure the std::string is destructed before
414 // lua_error() is called
416 std::string msg = "no constructor of '";
417 msg += crep->name();
418 msg += "' matched the arguments (";
419 msg += stack_content_by_name(L, 2);
420 msg += ")\n candidates are:\n";
422 msg += get_overload_signatures(L, rep->overloads.begin(), rep->overloads.end(), crep->name());
424 lua_pushstring(L, msg.c_str());
426 lua_error(L);
428 else if (ambiguous)
430 // this block is needed to make sure the std::string is destructed before
431 // lua_error() is called
433 std::string msg = "call of overloaded constructor '";
434 msg += crep->m_name;
435 msg += "(";
436 msg += stack_content_by_name(L, 2);
437 msg += ")' is ambiguous\nnone of the overloads have a best conversion:\n";
439 std::vector<construct_rep::overload_t> candidates;
440 find_exact_match(L, rep->overloads.begin(), rep->overloads.end(), min_match, num_params, candidates);
441 msg += get_overload_signatures(L, candidates.begin(), candidates.end(), crep->name());
443 lua_pushstring(L, msg.c_str());
445 lua_error(L);
448 #endif
450 #ifndef LUABIND_NO_EXCEPTIONS
455 #endif
457 void* object_ptr = rep->overloads[match_index].construct(L);
459 void* obj_rep = lua_newuserdata(L, sizeof(object_rep));
460 new(obj_rep) object_rep(object_ptr, crep, object_rep::owner, crep->destructor());
462 detail::getref(L, crep->m_instance_metatable);
463 lua_setmetatable(L, -2);
464 return 1;
466 #ifndef LUABIND_NO_EXCEPTIONS
470 catch(const std::exception& e)
472 lua_pushstring(L, e.what());
474 catch(const char* s)
476 lua_pushstring(L, s);
478 catch(...)
481 std::string msg = crep->name();
482 msg += "() threw an exception";
483 lua_pushstring(L, msg.c_str());
487 // we can only reach this line if an exception was thrown
488 lua_error(L);
489 return 0; // will never be reached
491 #endif
495 static int implicit_cast(const class_rep* from, const class_rep* to, int& pointer_offset)
497 int offset = 0;
498 if (LUABIND_TYPE_INFO_EQUAL(from->type(), to->type())) return 0;
500 for (std::vector<class_rep::base_info>::const_iterator i = from->bases().begin(); i != from->bases().end(); ++i)
502 int steps = implicit_cast(i->base, to, offset);
503 pointer_offset = offset + i->pointer_offset;
504 if (steps >= 0) return steps + 2;
506 return -1;
509 // the functions dispatcher assumes the following:
510 // there is one upvalue that points to the method_rep that this dispatcher is to call
511 // the first parameter on the lua stack is an object_rep that points to the object the
512 // call is being made on
513 static int function_dispatcher(lua_State* L)
515 method_rep* rep = static_cast<method_rep*>(lua_touserdata(L, lua_upvalueindex(1)));
516 object_rep* obj = reinterpret_cast<object_rep*>(lua_touserdata(L, 1));
518 #ifndef LUABIND_NO_ERROR_CHECKING
520 if (is_class_object(L, 1) == 0)
523 std::string msg = "No self reference given as first parameter to member function '";
524 msg += rep->crep->name();
525 msg += ":";
526 msg += rep->name;
527 msg += "'. Have you used '.' instead of ':'?";
529 lua_pushstring(L, msg.c_str());
531 lua_error(L);
534 int p;
535 if (implicit_cast(obj->crep(), rep->crep, p) < 0)
538 std::string msg = "invalid self reference given to '";
539 msg += rep->crep->name();
540 msg += ":";
541 msg += rep->name;
542 msg += "'";
543 lua_pushstring(L, msg.c_str());
545 lua_error(L);
548 #endif
550 bool ambiguous = false;
551 int match_index = -1;
552 int min_match = std::numeric_limits<int>::max();
553 bool found;
555 #ifdef LUABIND_NO_ERROR_CHECKING
556 if (rep->overloads().size() == 1)
558 match_index = 0;
560 else
562 #endif
564 int num_params = lua_gettop(L) - 1;
565 found = find_best_match(L, rep->overloads().begin(), rep->overloads().end(), ambiguous, min_match, match_index, num_params);
567 #ifdef LUABIND_NO_ERROR_CHECKING
571 #else
573 if (!found)
576 std::string msg = "no overload of '";
577 msg += rep->crep->name();
578 msg += ":";
579 msg += rep->name;
580 msg += "' matched the arguments (";
581 msg += stack_content_by_name(L, 2);
582 msg += ")\ncandidates are:\n";
584 std::string function_name;
585 function_name += rep->crep->name();
586 function_name += ":";
587 function_name += rep->name;
589 msg += get_overload_signatures(L, rep->overloads().begin(), rep->overloads().end(), function_name);
591 lua_pushstring(L, msg.c_str());
593 lua_error(L);
595 else if (ambiguous)
598 std::string msg = "call of overloaded '";
599 msg += rep->crep->name();
600 msg += ":";
601 msg += rep->name;
602 msg += "(";
603 msg += stack_content_by_name(L, 2);
604 msg += ")' is ambiguous\nnone of the overloads have a best conversion:\n";
606 std::vector<overload_rep> candidates;
607 find_exact_match(L, rep->overloads().begin(), rep->overloads().end(), min_match, num_params, candidates);
609 std::string function_name;
610 function_name += rep->crep->name();
611 function_name += ":";
612 function_name += rep->name;
614 msg += get_overload_signatures(L, candidates.begin(), candidates.end(), function_name);
616 lua_pushstring(L, msg.c_str());
618 lua_error(L);
621 #endif
623 #ifndef LUABIND_NO_EXCEPTIONS
628 #endif
630 const overload_rep& o = rep->overloads()[match_index];
631 return o.call(L, *obj);
633 #ifndef LUABIND_NO_EXCEPTIONS
636 catch(const std::exception& e)
638 lua_pushstring(L, e.what());
640 catch (const char* s)
642 lua_pushstring(L, s);
644 catch(...)
646 std::string msg = rep->crep->name();
647 msg += ":";
648 msg += rep->name;
649 msg += "() threw an exception";
650 lua_pushstring(L, msg.c_str());
652 // we can only reach this line if an exception was thrown
653 lua_error(L);
654 return 0; // will never be reached
656 #endif
665 struct base_info
667 int pointer_offset; // the offset added to the pointer to obtain a basepointer (due to multiple-inheritance)
668 class_rep* base;
672 inline void add_base_class(const base_info& binfo)
674 // If you hit this assert you are deriving from a type that is not registered
675 // in lua. That is, in the class_<> you are giving a baseclass that isn't registered.
676 // Please note that if you don't need to have access to the base class or the
677 // conversion from the derived class to the base class, you don't need
678 // to tell luabind that it derives.
679 assert(binfo.base && "You cannot derive from an unregistered type");
681 class_rep* bcrep = binfo.base;
683 // import all functions from the base
684 for (std::map<const char*, method_rep, ltstr>::const_iterator i = bcrep->m_methods.begin(); i != bcrep->m_methods.end(); ++i)
686 #ifndef LUABIND_DONT_COPY_STRINGS
687 m_strings.push_back(dup_string(i->first));
688 method_rep& m = m_methods[m_strings.back()];
689 #else
690 method_rep& m = m_methods[i->first];
691 #endif
692 m.name = i->first;
693 m.crep = this;
695 for (std::vector<overload_rep>::const_iterator j = i->second.overloads().begin(); j != i->second.overloads().end(); ++j)
697 overload_rep o = *j;
698 o.add_offset(binfo.pointer_offset);
699 m.add_overload(o);
703 // import all getters from the base
704 for (std::map<const char*, callback, ltstr>::const_iterator i = bcrep->m_getters.begin(); i != bcrep->m_getters.end(); ++i)
706 #ifndef LUABIND_DONT_COPY_STRINGS
707 m_strings.push_back(dup_string(i->first));
708 callback& m = m_getters[m_strings.back()];
709 #else
710 callback& m = m_getters[i->first];
711 #endif
712 m.pointer_offset = i->second.pointer_offset + binfo.pointer_offset;
713 m.func = i->second.func;
716 // import all setters from the base
717 for (std::map<const char*, callback, ltstr>::const_iterator i = bcrep->m_setters.begin(); i != bcrep->m_setters.end(); ++i)
719 #ifndef LUABIND_DONT_COPY_STRINGS
720 // TODO: optimize this by not copying the string if it already exists in m_setters.
721 // This goes for m_getters, m_static_constants and m_functions too. Both here
722 // in add_base() and in the add_function(), add_getter() ... functions.
723 m_strings.push_back(dup_string(i->first));
724 callback& m = m_setters[m_strings.back()];
725 #else
726 callback& m = m_setters[i->first];
727 #endif
728 m.pointer_offset = i->second.pointer_offset + binfo.pointer_offset;
729 m.func = i->second.func;
732 // import all static constants
733 for (std::map<const char*, int, ltstr>::const_iterator i = bcrep->m_static_constants.begin(); i != bcrep->m_static_constants.end(); ++i)
735 #ifndef LUABIND_DONT_COPY_STRINGS
736 m_strings.push_back(dup_string(i->first));
737 int& v = m_static_constants[m_strings.back()];
738 #else
739 int& v = m_static_constants[i->first];
740 #endif
741 v = i->second;
744 // import all operators
745 for (int i = 0; i < number_of_operators; ++i)
747 for (std::vector<operator_callback>::const_iterator j = bcrep->m_operators[i].begin(); j != bcrep->m_operators[i].end(); ++j)
748 m_operators[i].push_back(*j);
751 // also, save the baseclass info to be used for typecasts
752 m_bases.push_back(binfo);
756 inline const std::vector<base_info>& bases() const throw() { return m_bases; }
757 inline LUABIND_TYPE_INFO type() const throw() { return m_type; }
758 inline void set_type(LUABIND_TYPE_INFO t) { m_type = t; }
760 inline void add_function(const char* name, const overload_rep& o)
763 #ifdef LUABIND_DONT_COPY_STRINGS
764 detail::method_rep& method = m_methods[name];
765 method.name = name;
766 #else
767 m_strings.push_back(dup_string(name));
768 detail::method_rep& method = m_methods[m_strings.back()];
769 method.name = m_strings.back();
770 #endif
772 method.add_overload(o);
773 method.crep = this;
776 inline void add_constructor(const detail::construct_rep::overload_t& o)
778 m_constructor.overloads.push_back(o);
781 inline void add_wrapped_constructor(const detail::construct_rep::overload_t& o)
783 m_wrapped_constructor.overloads.push_back(o);
786 inline const char* name() const throw()
788 #ifdef LUABIND_DONT_COPY_STRINGS
789 return m_name;
790 #else
791 return m_name.c_str();
792 #endif
795 inline void add_getter(const char* name, const boost::function2<int, lua_State*, int>& g)
797 callback c;
798 c.func = g;
799 c.pointer_offset = 0;
800 #ifndef LUABIND_DONT_COPY_STRINGS
801 m_strings.push_back(dup_string(name));
802 m_getters[m_strings.back()] = c;
803 #else
804 m_getters[name] = c;
805 #endif
808 inline void add_setter(const char* name, const boost::function2<int, lua_State*, int>& s)
810 callback c;
811 c.func = s;
812 c.pointer_offset = 0;
813 #ifndef LUABIND_DONT_COPY_STRINGS
814 m_strings.push_back(dup_string(name));
815 m_setters[m_strings.back()] = c;
816 #else
817 m_setters[name] = c;
818 #endif
821 #ifndef LUABIND_NO_ERROR_CHECKING
822 inline void add_operator(lua_State*, int op_id, int(*func)(lua_State*), int(*matcher)(lua_State*), void(*sig)(lua_State*, std::string&), int arity)
823 #else
824 inline void add_operator(lua_State*, int op_id, int(*func)(lua_State*), int(*matcher)(lua_State*), int arity)
825 #endif
827 operator_callback o;
828 o.set_fun(func);
829 o.set_match_fun(matcher);
830 o.set_arity(arity);
832 #ifndef LUABIND_NO_ERROR_CHECKING
834 o.set_sig_fun(sig);
836 #endif
837 m_operators[op_id].push_back(o);
840 // the lua reference to this class_rep
841 inline int self_ref() const throw() { return m_self_ref; }
843 // the lua reference to the metatable for this class' instances
844 inline int metatable_ref() const throw() { return m_instance_metatable; }
846 inline int table_ref() const { return m_table_ref; }
848 inline void(*destructor() const)(void*) { return m_destructor; }
850 inline class_type get_class_type() const { return m_class_type; }
852 void add_static_constant(const char* name, int val)
854 #ifndef LUABIND_DONT_COPY_STRINGS
855 m_strings.push_back(dup_string(name));
856 m_static_constants[m_strings.back()] = val;
857 #else
858 m_static_constants[name] = val;
859 #endif
862 static inline int super_callback(lua_State* L)
864 int args = lua_gettop(L);
866 object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, lua_upvalueindex(2)));
867 class_rep* crep = static_cast<class_rep*>(lua_touserdata(L, lua_upvalueindex(1)));
868 class_rep* base = crep->bases()[0].base;
870 // std::cout << "__super of " << base->name() << "\n";
872 if (base->get_class_type() == class_rep::lua_class)
874 if (base->bases().empty())
876 obj->set_flags(obj->flags() & ~object_rep::call_super);
878 lua_pushstring(L, "super");
879 lua_pushnil(L);
880 lua_settable(L, LUA_GLOBALSINDEX);
882 else
884 lua_pushstring(L, "super");
885 lua_pushlightuserdata(L, base);
886 lua_pushvalue(L, lua_upvalueindex(2));
887 lua_pushcclosure(L, super_callback, 2);
888 lua_settable(L, LUA_GLOBALSINDEX);
891 // std::cout << " lua_class\n";
892 detail::getref(L, base->table_ref());
893 lua_pushstring(L, "__init");
894 lua_gettable(L, -2);
895 lua_insert(L, 1);
896 lua_pop(L, 1);
898 lua_pushvalue(L, lua_upvalueindex(2));
899 lua_insert(L, 2);
901 lua_call(L, args + 1, 0);
903 // TODO: instead of clearing the global variable "super"
904 // store it temporarily in the registry. maybe we should
905 // have some kind of warning if the super global is used?
906 lua_pushstring(L, "super");
907 lua_pushnil(L);
908 lua_settable(L, LUA_GLOBALSINDEX);
910 else
912 obj->set_flags(obj->flags() & ~object_rep::call_super);
913 // std::cout << " cpp_class\n";
915 // we need to push some garbage at index 1 to make the construction work
916 lua_pushboolean(L, 1);
917 lua_insert(L, 1);
919 construct_rep* rep = &base->m_constructor;
921 bool ambiguous = false;
922 int match_index = -1;
923 int min_match = std::numeric_limits<int>::max();
924 bool found;
926 #ifdef LUABIND_NO_ERROR_CHECKING
928 if (rep->overloads.size() == 1)
930 match_index = 0;
932 else
935 #endif
937 int num_params = lua_gettop(L) - 1;
938 found = find_best_match(L, rep->overloads.begin(), rep->overloads.end(), ambiguous, min_match, match_index, num_params);
940 #ifdef LUABIND_NO_ERROR_CHECKING
944 #else
946 if (!found)
949 std::string msg = "no constructor of '";
950 msg += base->m_name;
951 msg += "' matched the arguments (";
952 msg += stack_content_by_name(L, 2);
953 msg += ")";
954 lua_pushstring(L, msg.c_str());
956 lua_error(L);
958 else if (ambiguous)
961 std::string msg = "call of overloaded constructor '";
962 msg += base->m_name;
963 msg += "(";
964 msg += stack_content_by_name(L, 2);
965 msg += ")' is ambiguous";
966 lua_pushstring(L, msg.c_str());
968 lua_error(L);
971 // TODO: should this be a warning or something?
973 // since the derived class is a lua class
974 // it may have reimplemented virtual functions
975 // therefore, we have to instantiate the Basewrapper
976 // if there is no basewrapper, throw a run-time error
977 if (!rep->overloads[match_index].has_wrapped_construct())
980 std::string msg = "Cannot derive from C++ class '";
981 msg += base->name();
982 msg += "'. It does not have a wrapped type";
983 lua_pushstring(L, msg.c_str());
985 lua_error(L);
988 #endif
990 #ifndef LUABIND_NO_EXCEPTIONS
995 #endif
997 if (!rep->overloads[match_index].has_wrapped_construct())
999 // if the type doesn't have a wrapped type, use the ordinary constructor
1000 obj->set_object(rep->overloads[match_index].construct(L));
1002 else
1004 // get reference to lua object
1005 lua_pushvalue(L, lua_upvalueindex(2));
1006 int ref = detail::ref(L);
1007 obj->set_object(rep->overloads[match_index].construct_wrapped(L, ref));
1009 // TODO: is the wrapped type destructed correctly?
1010 // it should, since the destructor is either the wrapped type's
1011 // destructor or the base type's destructor, depending on wether
1012 // the type has a wrapped type or not.
1013 obj->set_destructor(base->destructor());
1014 return 0;
1016 #ifndef LUABIND_NO_EXCEPTIONS
1019 catch(const std::exception& e)
1021 lua_pushstring(L, e.what());
1023 catch(const char* s)
1025 lua_pushstring(L, s);
1027 catch(...)
1029 std::string msg = base->m_name;
1030 msg += "() threw an exception";
1031 lua_pushstring(L, msg.c_str());
1033 // can only be reached if an exception was thrown
1034 lua_error(L);
1035 #endif
1038 return 0;
1042 static int lua_settable_dispatcher(lua_State* L)
1044 class_rep* crep = static_cast<class_rep*>(lua_touserdata(L, 1));
1045 detail::getref(L, crep->m_table_ref);
1046 lua_replace(L, 1);
1047 lua_rawset(L, -3);
1048 return 0;
1051 static int construct_lua_class_callback(lua_State* L)
1053 class_rep* crep = static_cast<class_rep*>(lua_touserdata(L, 1));
1055 int args = lua_gettop(L);
1057 // lua stack: crep <arguments>
1059 lua_newtable(L);
1060 int ref = detail::ref(L);
1062 bool has_bases = !crep->bases().empty();
1064 if (has_bases)
1066 lua_pushstring(L, "super");
1067 lua_pushvalue(L, 1); // crep
1070 // lua stack: crep <arguments> "super" crep
1071 // or
1072 // lua stack: crep <arguments>
1075 // if we have a baseclass we set the flag to say that the super has not yet been called
1076 // we will use this flag later to check that it actually was called from __init()
1077 int flags = object_rep::lua_class | object_rep::owner | (has_bases ? object_rep::call_super : 0);
1079 void* obj_ptr = lua_newuserdata(L, sizeof(object_rep));
1080 new(obj_ptr) object_rep(crep, flags, ref);
1082 detail::getref(L, crep->metatable_ref());
1083 lua_setmetatable(L, -2);
1085 // lua stack: crep <arguments> "super" crep obj_ptr
1086 // or
1087 // lua stack: crep <arguments> obj_ptr
1089 if (has_bases) lua_pushvalue(L, -1); // obj_ptr
1090 lua_replace(L, 1); // obj_ptr
1092 // lua stack: obj_ptr <arguments> "super" crep obj_ptr
1093 // or
1094 // lua stack: obj_ptr <arguments>
1096 if (has_bases)
1098 lua_pushcclosure(L, super_callback, 2);
1099 // lua stack: crep <arguments> "super" function
1100 lua_settable(L, LUA_GLOBALSINDEX);
1103 // lua stack: crep <arguments>
1105 lua_pushvalue(L, 1);
1106 lua_insert(L, 1);
1108 detail::getref(L, crep->table_ref());
1109 lua_pushstring(L, "__init");
1110 lua_gettable(L, -2);
1112 #ifndef LUABIND_NO_ERROR_CHECKING
1114 // TODO: should this be a run-time error?
1115 // maybe the default behavior should be to just call
1116 // the base calss' constructor. We should register
1117 // the super callback funktion as __init
1118 if (!lua_isfunction(L, -1))
1121 std::string msg = crep->name();
1122 msg += ":__init is not defined";
1123 lua_pushstring(L, msg.c_str());
1125 lua_error(L);
1128 #endif
1130 lua_insert(L, 2); // function first on stack
1131 lua_pop(L, 1);
1132 // TODO: lua_call may invoke longjump! make sure we don't have any memory leaks!
1133 // we don't have any stack objects here
1134 lua_call(L, args, 0);
1136 #ifndef LUABIND_NO_ERROR_CHECKING
1138 object_rep* obj = static_cast<object_rep*>(obj_ptr);
1139 if (obj->flags() & object_rep::call_super)
1141 lua_pushstring(L, "derived class must call super on base");
1142 lua_error(L);
1145 #endif
1147 return 1;
1150 // called from the metamethod for __index
1151 // obj is the object pointer
1152 static int lua_class_gettable(lua_State* L)
1154 object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, 1));
1155 class_rep* crep = obj->crep();
1157 #ifndef LUABIND_NO_ERROR_CHECKING
1159 if (obj->flags() & object_rep::call_super)
1161 lua_pushstring(L, "derived class must call super on base");
1162 lua_error(L);
1165 #endif
1167 detail::getref(L, obj->lua_table_ref());
1168 lua_pushvalue(L, 2);
1169 lua_gettable(L, -2);
1171 if (!lua_isnil(L, -1)) return 1;
1173 lua_pop(L, 2);
1175 detail::getref(L, crep->table_ref());
1176 lua_pushvalue(L, 2);
1177 lua_gettable(L, -2);
1179 if (!lua_isnil(L, -1)) return 1;
1181 lua_pop(L, 2);
1184 if (lua_isnil(L, 2))
1186 lua_pushnil(L);
1187 return 1;
1190 // we have to ignore the first argument since this may point to
1191 // a method that is not present in this class (but in a subclass)
1192 const char* key = lua_tostring(L, 2);
1194 std::map<const char*, method_rep, ltstr>::iterator i = crep->m_methods.find(key);
1195 if (i != crep->m_methods.end())
1197 // the name is a method, return it
1198 lua_pushlightuserdata(L, &i->second);
1199 lua_pushcclosure(L, class_rep::function_dispatcher, 1);
1200 return 1;
1203 std::map<const char*, class_rep::callback, ltstr>::iterator j = crep->m_getters.find(key);
1204 if (j != crep->m_getters.end())
1206 // the name is a data member
1207 return j->second.func(L, j->second.pointer_offset);
1210 lua_pushnil(L);
1211 return 1;
1214 // called from the metamethod for __newindex
1215 // obj is the object pointer
1216 static int lua_class_settable(lua_State* L)
1218 object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, 1));
1219 class_rep* crep = obj->crep();
1221 #ifndef LUABIND_NO_ERROR_CHECKING
1223 if (obj->flags() & object_rep::call_super)
1225 // this block makes sure the std::string is destructed
1226 // before lua_error is called
1228 std::string msg = "derived class '";
1229 msg += crep->name();
1230 msg += "'must call super on base";
1231 lua_pushstring(L, msg.c_str());
1233 lua_error(L);
1236 #endif
1238 // we have to ignore the first argument since this may point to
1239 // a method that is not present in this class (but in a subclass)
1240 const char* key = lua_tostring(L, 2);
1241 std::map<const char*, class_rep::callback, ltstr>::iterator j = crep->m_setters.find(key);
1243 if (j == crep->m_setters.end())
1245 std::map<const char*, class_rep::callback, ltstr>::iterator k = crep->m_getters.find(key);
1247 #ifndef LUABIND_NO_ERROR_CHECKING
1249 if (k != crep->m_getters.end())
1252 std::string msg = "cannot set property '";
1253 msg += crep->name();
1254 msg += ".";
1255 msg += key;
1256 msg += "', because it's read only";
1257 lua_pushstring(L, msg.c_str());
1259 lua_error(L);
1262 #endif
1264 detail::getref(L, obj->lua_table_ref());
1265 lua_replace(L, 1);
1266 lua_settable(L, 1);
1268 else
1270 // the name is a data member
1271 j->second.func(L, j->second.pointer_offset);
1274 return 0;
1277 static int static_class_gettable(lua_State* L)
1279 class_rep* crep = static_cast<class_rep*>(lua_touserdata(L, 1));
1281 if (crep->get_class_type() == class_rep::lua_class)
1283 detail::getref(L, crep->m_table_ref);
1284 lua_pushvalue(L, 2);
1285 lua_gettable(L, -2);
1286 if (!lua_isnil(L, -1)) return 1;
1287 else lua_pop(L, 2);
1290 const char* key = lua_tostring(L, 2);
1292 std::map<const char*, method_rep, ltstr>::iterator i = crep->m_methods.find(key);
1293 if (i != crep->m_methods.end())
1295 // the name is a method, return it
1296 lua_pushlightuserdata(L, &i->second);
1297 lua_pushcclosure(L, class_rep::function_dispatcher, 1);
1298 return 1;
1301 #ifndef LUABIND_NO_ERROR_CHECKING
1303 std::map<const char*, int, ltstr>::const_iterator j = crep->m_static_constants.find(key);
1305 if (j != crep->m_static_constants.end())
1307 lua_pushnumber(L, j->second);
1308 return 1;
1312 std::string msg = "no static '";
1313 msg += key;
1314 msg += "' in class '";
1315 msg += crep->name();
1316 msg += "'";
1317 lua_pushstring(L, msg.c_str());
1319 lua_error(L);
1321 #endif
1323 return 0;
1326 private:
1328 // this is a pointer to the type_info structure for
1329 // this type
1330 // warning: this may be a problem when using dll:s, since
1331 // typeid() may actually return different pointers for the same
1332 // type.
1333 LUABIND_TYPE_INFO m_type;
1334 LUABIND_TYPE_INFO m_held_type;
1336 typedef void*(*extract_ptr_t)(void*);
1337 extract_ptr_t m_extract_underlying_fun;
1339 // a list of info for every class this class derives from
1340 // the information stored here is sufficient to do
1341 // type casts to the base classes
1342 std::vector<base_info> m_bases;
1344 // the class' name (as given when registered to lua with class_)
1345 #ifdef LUABIND_DONT_COPY_STRINGS
1346 const char* m_name;
1347 #else
1348 std::string m_name;
1349 #endif
1351 // contains signatures for all constructors
1352 construct_rep m_constructor;
1353 construct_rep m_wrapped_constructor;
1355 // a reference to this structure itself. Since this struct
1356 // is kept inside lua (to let lua collect it when lua_close()
1357 // is called) we need to lock it to prevent collection.
1358 // the actual reference is not currently used.
1359 int m_self_ref;
1361 // a reference to the lua table that represents this class
1362 // (only used if it is a lua class)
1363 int m_table_ref;
1365 // the type of this class.. determines if it's written in c++ or lua
1366 class_type m_class_type;
1368 // this is a lua reference that points to the lua table
1369 // that is to be used as meta table for all instances
1370 // of this class.
1371 int m_instance_metatable;
1373 // ***** the maps below contains all members in this class *****
1375 // maps method names to a structure with more
1376 // information about that method.
1377 // that struct contains the function-signatures
1378 // for every overload
1379 std::map<const char*, method_rep, ltstr> m_methods;
1381 #ifndef LUABIND_DONT_COPY_STRINGS
1382 // this is where the strings that the maps contains
1383 // pointer to are kept. To make sure they are destructed.
1384 std::vector<char*> m_strings;
1385 #endif
1387 struct callback
1389 boost::function2<int, lua_State*, int> func;
1390 int pointer_offset;
1393 // datamembers, some members may be readonly, and
1394 // only have a getter function
1395 std::map<const char*, callback, ltstr> m_getters;
1396 std::map<const char*, callback, ltstr> m_setters;
1398 struct operator_callback: public overload_rep_base
1400 inline void set_fun(int (*f)(lua_State*)) { func = f; }
1401 inline int call(lua_State* L) { return func(L); }
1402 inline void set_arity(int arity) { m_arity = arity; }
1404 private:
1406 int(*func)(lua_State*);
1409 std::vector<operator_callback> m_operators[number_of_operators]; // the operators in lua
1411 void(*m_destructor)(void*);
1413 std::map<const char*, int, ltstr> m_static_constants;
1417 inline bool is_class_rep(lua_State* L, int index)
1419 if (lua_getmetatable(L, index) == 0) return false;
1421 lua_pushstring(L, "__luabind_classrep");
1422 lua_gettable(L, -2);
1423 if (lua_toboolean(L, -1))
1425 lua_pop(L, 2);
1426 return true;
1429 lua_pop(L, 2);
1430 return false;
1436 #endif // LUABIND_CLASS_REP_HPP_INCLUDED