added finalizers
[luabind.git] / luabind / detail / class_rep.hpp
blob3fbe93d41afa16d177e76266c45a650b350d3900
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/detail/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
69 #ifdef LUABIND_NO_HEADERS_ONLY
71 class class_rep
73 friend struct luabind::class_base;
74 friend int super_callback(lua_State*);
75 //TODO: avoid the lua-prefix
76 friend int lua_class_gettable(lua_State*);
77 friend int lua_class_settable(lua_State*);
78 friend int static_class_gettable(lua_State*);
79 public:
81 enum class_type
83 cpp_class = 0,
84 lua_class = 1
87 // destructor is a lua callback function that is hooked as garbage collector event on every instance
88 // of this class (including those that is not owned by lua). It gets an object_rep as argument
89 // on the lua stack. It should delete the object pointed to by object_rep::ptr if object_pre::flags
90 // is object_rep::owner (which means that lua owns the object)
92 // EXPECTS THE TOP VALUE ON THE LUA STACK TO
93 // BE THE USER DATA WHERE THIS CLASS IS BEING
94 // INSTANTIATED!
95 class_rep(LUABIND_TYPE_INFO t, const char* name, lua_State* L, void(*destructor)(void*), LUABIND_TYPE_INFO held_t, void*(*extractor)(void*));
97 // used when creating a lua class
98 // EXPECTS THE TOP VALUE ON THE LUA STACK TO
99 // BE THE USER DATA WHERE THIS CLASS IS BEING
100 // INSTANTIATED!
101 class_rep(lua_State* L, const char* name);
103 ~class_rep();
105 // called from the metamethod for __index
106 // the object pointer is passed on the lua stack
107 int gettable(lua_State* L);
109 // called from the metamethod for __newindex
110 // the object pointer is passed on the lua stack
111 bool settable(lua_State* L);
113 // this is called as __index metamethod on every instance of this class
114 static int gettable_dispatcher(lua_State* L);
116 // this is called as __newindex metamethod on every instance of this class
117 static int settable_dispatcher(lua_State* L);
118 static int operator_dispatcher(lua_State* L);
120 // this is called as metamethod __call on the class_rep.
121 static int constructor_dispatcher(lua_State* L);
123 static int implicit_cast(const class_rep* from, const class_rep* to, int& pointer_offset);
125 // the functions dispatcher assumes the following:
126 // there is one upvalue that points to the method_rep that this dispatcher is to call
127 // the first parameter on the lua stack is an object_rep that points to the object the
128 // call is being made on
129 static int function_dispatcher(lua_State* L);
131 struct base_info
133 int pointer_offset; // the offset added to the pointer to obtain a basepointer (due to multiple-inheritance)
134 class_rep* base;
138 void add_base_class(const base_info& binfo);
140 inline const std::vector<base_info>& bases() const throw() { return m_bases; }
141 inline LUABIND_TYPE_INFO type() const throw() { return m_type; }
142 inline void set_type(LUABIND_TYPE_INFO t) { m_type = t; }
144 void add_function(const char* name, const overload_rep& o);
146 inline void add_constructor(const detail::construct_rep::overload_t& o)
148 m_constructor.overloads.push_back(o);
151 inline void add_wrapped_constructor(const detail::construct_rep::overload_t& o)
153 m_wrapped_constructor.overloads.push_back(o);
156 inline const char* name() const throw()
158 #ifdef LUABIND_DONT_COPY_STRINGS
159 return m_name;
160 #else
161 return m_name.c_str();
162 #endif
165 void add_getter(const char* name, const boost::function2<int, lua_State*, int>& g);
166 void add_setter(const char* name, const boost::function2<int, lua_State*, int>& s);
168 #ifndef LUABIND_NO_ERROR_CHECKING
169 void add_operator(lua_State*, int op_id, int(*func)(lua_State*), int(*matcher)(lua_State*), void(*sig)(lua_State*, std::string&), int arity);
170 #else
171 void add_operator(lua_State*, int op_id, int(*func)(lua_State*), int(*matcher)(lua_State*), int arity);
172 #endif
174 // the lua reference to this class_rep
175 inline int self_ref() const throw() { return m_self_ref; }
177 // the lua reference to the metatable for this class' instances
178 inline int metatable_ref() const throw() { return m_instance_metatable; }
180 inline int table_ref() const { return m_table_ref; }
182 inline void(*destructor() const)(void*) { return m_destructor; }
184 inline class_type get_class_type() const { return m_class_type; }
186 void add_static_constant(const char* name, int val);
188 static int super_callback(lua_State* L);
190 static int lua_settable_dispatcher(lua_State* L);
192 static int construct_lua_class_callback(lua_State* L);
194 // called from the metamethod for __index
195 // obj is the object pointer
196 static int lua_class_gettable(lua_State* L);
198 // called from the metamethod for __newindex
199 // obj is the object pointer
200 static int lua_class_settable(lua_State* L);
202 static int static_class_gettable(lua_State* L);
204 private:
206 // this is a pointer to the type_info structure for
207 // this type
208 // warning: this may be a problem when using dll:s, since
209 // typeid() may actually return different pointers for the same
210 // type.
211 LUABIND_TYPE_INFO m_type;
212 LUABIND_TYPE_INFO m_held_type;
214 typedef void*(*extract_ptr_t)(void*);
215 extract_ptr_t m_extract_underlying_fun;
217 // a list of info for every class this class derives from
218 // the information stored here is sufficient to do
219 // type casts to the base classes
220 std::vector<base_info> m_bases;
222 // the class' name (as given when registered to lua with class_)
223 #ifdef LUABIND_DONT_COPY_STRINGS
224 const char* m_name;
225 #else
226 std::string m_name;
227 #endif
229 // contains signatures for all constructors
230 construct_rep m_constructor;
231 construct_rep m_wrapped_constructor;
233 // a reference to this structure itself. Since this struct
234 // is kept inside lua (to let lua collect it when lua_close()
235 // is called) we need to lock it to prevent collection.
236 // the actual reference is not currently used.
237 int m_self_ref;
239 // a reference to the lua table that represents this class
240 // (only used if it is a lua class)
241 int m_table_ref;
243 // the type of this class.. determines if it's written in c++ or lua
244 class_type m_class_type;
246 // this is a lua reference that points to the lua table
247 // that is to be used as meta table for all instances
248 // of this class.
249 int m_instance_metatable;
251 // ***** the maps below contains all members in this class *****
253 // maps method names to a structure with more
254 // information about that method.
255 // that struct contains the function-signatures
256 // for every overload
257 std::map<const char*, method_rep, ltstr> m_methods;
259 #ifndef LUABIND_DONT_COPY_STRINGS
260 // this is where the strings that the maps contains
261 // pointer to are kept. To make sure they are destructed.
262 std::vector<char*> m_strings;
263 #endif
265 struct callback
267 boost::function2<int, lua_State*, int> func;
268 int pointer_offset;
271 // datamembers, some members may be readonly, and
272 // only have a getter function
273 std::map<const char*, callback, ltstr> m_getters;
274 std::map<const char*, callback, ltstr> m_setters;
276 struct operator_callback: public overload_rep_base
278 inline void set_fun(int (*f)(lua_State*)) { func = f; }
279 inline int call(lua_State* L) { return func(L); }
280 inline void set_arity(int arity) { m_arity = arity; }
282 private:
284 int(*func)(lua_State*);
287 std::vector<operator_callback> m_operators[number_of_operators]; // the operators in lua
289 void(*m_destructor)(void*);
291 std::map<const char*, int, ltstr> m_static_constants;
294 bool is_class_rep(lua_State* L, int index);
296 #else // HEADERS ONLY
298 class class_rep
300 friend struct luabind::class_base;
301 friend int super_callback(lua_State*);
302 //TODO: avoid the lua-prefix
303 friend int lua_class_gettable(lua_State*);
304 friend int lua_class_settable(lua_State*);
305 friend int static_class_gettable(lua_State*);
306 public:
308 enum class_type
310 cpp_class = 0,
311 lua_class = 1
314 // destructor is a lua callback function that is hooked as garbage collector event on every instance
315 // of this class (including those that is not owned by lua). It gets an object_rep as argument
316 // on the lua stack. It should delete the object pointed to by object_rep::ptr if object_pre::flags
317 // is object_rep::owner (which means that lua owns the object)
319 // EXPECTS THE TOP VALUE ON THE LUA STACK TO
320 // BE THE USER DATA WHERE THIS CLASS IS BEING
321 // INSTANTIATED!
322 class_rep(LUABIND_TYPE_INFO t, const char* name, lua_State* L, void(*destructor)(void*), LUABIND_TYPE_INFO held_t, void*(*extractor)(void*))
323 : m_type(t)
324 , m_held_type(held_t)
325 , m_extract_underlying_fun(extractor)
326 , m_name(name)
327 , m_class_type(cpp_class)
328 , m_destructor(destructor)
331 // TODO: don't we need to copy the name?
332 class_registry* r = class_registry::get_registry(L);
333 assert((r->cpp_class() != LUA_NOREF) && "you must call luabind::open()"); // you must call luabind::open()
335 detail::getref(L, r->cpp_class());
336 lua_setmetatable(L, -2);
338 lua_pushvalue(L, -1); // duplicate our user data
339 m_self_ref = detail::ref(L); // pop one of them
341 m_instance_metatable = r->cpp_instance();
344 // used when creating a lua class
345 // EXPECTS THE TOP VALUE ON THE LUA STACK TO
346 // BE THE USER DATA WHERE THIS CLASS IS BEING
347 // INSTANTIATED!
348 class_rep(lua_State* L, const char* name)
349 : m_type(LUABIND_TYPEID(int))
350 , m_held_type(0)
351 , m_extract_underlying_fun(0)
352 , m_name(name)
353 , m_class_type(lua_class)
355 // TODO: don't we need to copy the name?
356 lua_newtable(L);
357 m_table_ref = detail::ref(L);
359 class_registry* r = class_registry::get_registry(L);
360 assert((r->cpp_class() != LUA_NOREF) && "you must call luabind::open()"); // you must call luabind::open()
362 detail::getref(L, r->lua_class());
363 lua_setmetatable(L, -2);
364 lua_pushvalue(L, -1); // duplicate our user data
365 m_self_ref = detail::ref(L); // pop one of them
367 m_instance_metatable = r->lua_instance();
370 ~class_rep()
372 #ifndef LUABIND_DONT_COPY_STRINGS
373 for (std::vector<char*>::iterator i = m_strings.begin(); i != m_strings.end(); ++i)
375 delete[] *i;
377 #endif
381 // called from the metamethod for __index
382 // the object pointer is passed on the lua stack
383 int gettable(lua_State* L)
385 if (lua_isnil(L, 2))
387 lua_pushnil(L);
388 return 1;
391 // we have to ignore the first argument since this may point to
392 // a method that is not present in this class (but in a subclass)
393 const char* key = lua_tostring(L, 2);
394 std::map<const char*, method_rep, ltstr>::iterator i = m_methods.find(key);
395 if (i != m_methods.end())
397 // the name is a method, return it
398 lua_pushlightuserdata(L, &i->second);
399 lua_pushcclosure(L, function_dispatcher, 1);
400 return 1;
403 std::map<const char*, callback, ltstr>::iterator j = m_getters.find(key);
404 if (j != m_getters.end())
406 // the name is a data member
407 return j->second.func(L, j->second.pointer_offset);
410 lua_pushnil(L);
411 return 1;
414 // called from the metamethod for __newindex
415 // the object pointer is passed on the lua stack
416 bool settable(lua_State* L)
418 if (lua_isnil(L, 2))
420 return false;
423 // we have to ignore the first argument since this may point to
424 // a method that is not present in this class (but in a subclass)
425 const char* key = lua_tostring(L, 2);
426 std::map<const char*, callback, ltstr>::iterator j = m_setters.find(key);
427 if (j != m_setters.end())
429 // the name is a data member
430 j->second.func(L, j->second.pointer_offset);
431 return true;
434 return false; // false means that we don't have a member with the given name
437 // this is called as __index metamethod on every instance of this class
438 static int gettable_dispatcher(lua_State* L)
440 object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, 1));
441 return obj->crep()->gettable(L);
444 // this is called as __newindex metamethod on every instance of this class
445 static int settable_dispatcher(lua_State* L)
447 object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, 1));
449 bool success = obj->crep()->settable(L);
451 #ifndef LUABIND_NO_ERROR_CHECKING
453 if (!success)
455 // this block is needed to make sure the std::string is destructed before
456 // lua_error() is called
457 #ifdef BOOST_MSVC
459 // msvc has a bug which deletes the string twice, that's
460 // why we have to create it on the heap
461 std::string* msg = new std::string("cannot set attribute '");
462 *msg += obj->crep()->m_name;
463 *msg += ".";
464 *msg += lua_tostring(L, -2);
465 *msg += "'";
466 lua_pushstring(L, msg->c_str());
467 delete msg;
469 #else
471 std::string msg = "cannot set attribute '";
472 msg += obj->crep()->m_name;
473 msg += ".";
474 msg += lua_tostring(L, -2);
475 msg += "'";
476 lua_pushstring(L, msg.c_str());
478 #endif
479 lua_error(L);
482 #endif
484 return 0;
487 static int operator_dispatcher(lua_State* L)
489 int id = static_cast<int>(lua_tonumber(L, lua_upvalueindex(1)));
491 int operand_id = 0;
493 object_rep* operand[2];
494 for (int i = 0; i < 2; ++i)
495 operand[i] = detail::is_class_object(L, i + 1);
497 if (operand[0] && operand[1])
498 if (LUABIND_TYPE_INFO_EQUAL(operand[0]->crep()->type(), operand[1]->crep()->type())) operand[1] = 0;
500 std::vector<operator_callback>* overloads[2];
501 for (int i = 0; i < 2; ++i)
502 if (operand[i]) overloads[i] = &operand[i]->crep()->m_operators[id]; else overloads[i] = 0;
504 std::size_t num_overloads[2];
505 for (int i = 0; i < 2; ++i)
506 if (overloads[i]) num_overloads[i] = overloads[i]->size(); else num_overloads[i] = 0;
508 bool ambiguous = false;
509 int match_index = -1;
510 int min_match = std::numeric_limits<int>::max();
512 // std::cout << "operator_dispatcher\n";
513 // std::cout << "num overloads: " << num_overloads[0] + num_overloads[1] << "\n";
514 // std::cout << "operator: " << id << "\n";
516 #ifdef LUABIND_NO_ERROR_CHECKING
518 if (num_overloads[0] == 1 && num_overloads[1] == 0)
520 operand_id = 0;
521 match_index = 0;
523 else if (num_overloads[0] == 0 && num_overloads[1] == 1)
525 operand_id = 1;
526 match_index = 0;
528 else
531 #endif
533 int num_params = lua_gettop(L);
534 if (overloads[0])
536 if (find_best_match(L, &overloads[0]->front(), overloads[0]->size(), sizeof(operator_callback), ambiguous, min_match, match_index, num_params))
537 operand_id = 0;
540 // have look at the right operand.
541 // if the right operand is a class and
542 // not the same class as this, we have to
543 // try to match it's operators too
545 if (overloads[1])
547 if(find_best_match(L, &overloads[1]->front(), overloads[1]->size(), sizeof(operator_callback), ambiguous, min_match, match_index, num_params))
548 operand_id = 1;
551 #ifdef LUABIND_NO_ERROR_CHECKING
555 #else
557 if (match_index == -1)
559 // this block is needed to make sure the std::string is destructed before
560 // lua_error() is called
562 std::string msg = "no operator ";
563 msg += get_operator_symbol(id);
564 msg += " matched the arguments (";
565 msg += stack_content_by_name(L, 1);
566 msg += ")\ncandidates are:\n";
568 if (overloads[0])
569 msg += get_overload_signatures(L, overloads[0]->begin(), overloads[0]->end(), get_operator_symbol(id));
571 if (overloads[1])
572 msg += get_overload_signatures(L, overloads[1]->begin(), overloads[1]->end(), get_operator_symbol(id));
574 lua_pushstring(L, msg.c_str());
576 lua_error(L);
578 else if (ambiguous)
580 // this block is needed to make sure the std::string is destructed before
581 // lua_error() is called
583 std::string msg = "call of overloaded operator ";
584 msg += get_operator_symbol(id);
585 msg += " (";
586 msg += stack_content_by_name(L, 1);
587 msg += ")' is ambiguous\nnone of the overloads have a best conversion:\n";
589 std::vector<const overload_rep_base*> candidates;
590 if (overloads[0])
591 find_exact_match(L, &overloads[0]->front(), overloads[0]->size(), sizeof(operator_callback), min_match, num_params, candidates);
593 if (overloads[1])
594 find_exact_match(L, &overloads[1]->front(), overloads[1]->size(), sizeof(operator_callback), min_match, num_params, candidates);
596 msg += get_overload_signatures_candidates(L, candidates.begin(), candidates.end(), get_operator_symbol(id));
599 lua_pushstring(L, msg.c_str());
601 lua_error(L);
604 #endif
606 return (*overloads[operand_id])[match_index].call(L);
610 // this is called as metamethod __call on the class_rep.
611 static int constructor_dispatcher(lua_State* L)
613 class_rep* crep = static_cast<class_rep*>(lua_touserdata(L, 1));
614 construct_rep* rep = &crep->m_constructor;
616 bool ambiguous = false;
617 int match_index = -1;
618 int min_match = std::numeric_limits<int>::max();
619 bool found;
621 #ifdef LUABIND_NO_ERROR_CHECKING
623 if (rep->overloads.size() == 1)
625 match_index = 0;
627 else
630 #endif
632 int num_params = lua_gettop(L) - 1;
633 found = find_best_match(L, &rep->overloads.front(), rep->overloads.size(), sizeof(construct_rep::overload_t), ambiguous, min_match, match_index, num_params);
635 #ifdef LUABIND_NO_ERROR_CHECKING
639 #else
641 if (!found)
643 // this block is needed to make sure the std::string is destructed before
644 // lua_error() is called
646 std::string msg = "no constructor of '";
647 msg += crep->name();
648 msg += "' matched the arguments (";
649 msg += stack_content_by_name(L, 2);
650 msg += ")\n candidates are:\n";
652 msg += get_overload_signatures(L, rep->overloads.begin(), rep->overloads.end(), crep->name());
654 lua_pushstring(L, msg.c_str());
656 lua_error(L);
658 else if (ambiguous)
660 // this block is needed to make sure the std::string is destructed before
661 // lua_error() is called
663 std::string msg = "call of overloaded constructor '";
664 msg += crep->m_name;
665 msg += "(";
666 msg += stack_content_by_name(L, 2);
667 msg += ")' is ambiguous\nnone of the overloads have a best conversion:\n";
669 std::vector<const overload_rep_base*> candidates;
670 find_exact_match(L, &rep->overloads.front(), rep->overloads.size(), sizeof(construct_rep::overload_t), min_match, num_params, candidates);
671 msg += get_overload_signatures_candidates(L, candidates.begin(), candidates.end(), crep->name());
673 lua_pushstring(L, msg.c_str());
675 lua_error(L);
678 #endif
680 #ifndef LUABIND_NO_EXCEPTIONS
685 #endif
687 void* object_ptr = rep->overloads[match_index].construct(L);
689 void* obj_rep = lua_newuserdata(L, sizeof(object_rep));
690 new(obj_rep) object_rep(object_ptr, crep, object_rep::owner, crep->destructor());
692 detail::getref(L, crep->m_instance_metatable);
693 lua_setmetatable(L, -2);
694 return 1;
696 #ifndef LUABIND_NO_EXCEPTIONS
700 catch(const std::exception& e)
702 lua_pushstring(L, e.what());
704 catch(const char* s)
706 lua_pushstring(L, s);
708 catch(...)
711 std::string msg = crep->name();
712 msg += "() threw an exception";
713 lua_pushstring(L, msg.c_str());
717 // we can only reach this line if an exception was thrown
718 lua_error(L);
719 return 0; // will never be reached
721 #endif
725 static int implicit_cast(const class_rep* from, const class_rep* to, int& pointer_offset)
727 int offset = 0;
728 if (LUABIND_TYPE_INFO_EQUAL(from->type(), to->type())) return 0;
730 for (std::vector<class_rep::base_info>::const_iterator i = from->bases().begin(); i != from->bases().end(); ++i)
732 int steps = implicit_cast(i->base, to, offset);
733 pointer_offset = offset + i->pointer_offset;
734 if (steps >= 0) return steps + 2;
736 return -1;
739 // the functions dispatcher assumes the following:
740 // there is one upvalue that points to the method_rep that this dispatcher is to call
741 // the first parameter on the lua stack is an object_rep that points to the object the
742 // call is being made on
743 static int function_dispatcher(lua_State* L)
745 method_rep* rep = static_cast<method_rep*>(lua_touserdata(L, lua_upvalueindex(1)));
746 object_rep* obj = reinterpret_cast<object_rep*>(lua_touserdata(L, 1));
748 #ifndef LUABIND_NO_ERROR_CHECKING
750 if (is_class_object(L, 1) == 0)
753 std::string msg = "No self reference given as first parameter to member function '";
754 msg += rep->crep->name();
755 msg += ":";
756 msg += rep->name;
757 msg += "'. Have you used '.' instead of ':'?";
759 lua_pushstring(L, msg.c_str());
761 lua_error(L);
764 int p;
765 if (implicit_cast(obj->crep(), rep->crep, p) < 0)
768 std::string msg = "invalid self reference given to '";
769 msg += rep->crep->name();
770 msg += ":";
771 msg += rep->name;
772 msg += "'";
773 lua_pushstring(L, msg.c_str());
775 lua_error(L);
778 #endif
780 bool ambiguous = false;
781 int match_index = -1;
782 int min_match = std::numeric_limits<int>::max();
783 bool found;
785 #ifdef LUABIND_NO_ERROR_CHECKING
786 if (rep->overloads().size() == 1)
788 match_index = 0;
790 else
792 #endif
794 int num_params = lua_gettop(L) - 1;
795 found = find_best_match(L, &rep->overloads().front(), rep->overloads().size(), sizeof(overload_rep), ambiguous, min_match, match_index, num_params);
797 #ifdef LUABIND_NO_ERROR_CHECKING
801 #else
803 if (!found)
806 std::string msg = "no overload of '";
807 msg += rep->crep->name();
808 msg += ":";
809 msg += rep->name;
810 msg += "' matched the arguments (";
811 msg += stack_content_by_name(L, 2);
812 msg += ")\ncandidates are:\n";
814 std::string function_name;
815 function_name += rep->crep->name();
816 function_name += ":";
817 function_name += rep->name;
819 msg += get_overload_signatures(L, rep->overloads().begin(), rep->overloads().end(), function_name);
821 lua_pushstring(L, msg.c_str());
823 lua_error(L);
825 else if (ambiguous)
828 std::string msg = "call of overloaded '";
829 msg += rep->crep->name();
830 msg += ":";
831 msg += rep->name;
832 msg += "(";
833 msg += stack_content_by_name(L, 2);
834 msg += ")' is ambiguous\nnone of the overloads have a best conversion:\n";
836 std::vector<const overload_rep_base*> candidates;
837 find_exact_match(L, &rep->overloads().front(), rep->overloads().size(), sizeof(overload_rep), min_match, num_params, candidates);
839 std::string function_name;
840 function_name += rep->crep->name();
841 function_name += ":";
842 function_name += rep->name;
844 msg += get_overload_signatures_candidates(L, candidates.begin(), candidates.end(), function_name);
846 lua_pushstring(L, msg.c_str());
848 lua_error(L);
851 #endif
853 #ifndef LUABIND_NO_EXCEPTIONS
858 #endif
860 const overload_rep& o = rep->overloads()[match_index];
861 return o.call(L, *obj);
863 #ifndef LUABIND_NO_EXCEPTIONS
866 catch(const std::exception& e)
868 lua_pushstring(L, e.what());
870 catch (const char* s)
872 lua_pushstring(L, s);
874 catch(...)
876 std::string msg = rep->crep->name();
877 msg += ":";
878 msg += rep->name;
879 msg += "() threw an exception";
880 lua_pushstring(L, msg.c_str());
882 // we can only reach this line if an exception was thrown
883 lua_error(L);
884 return 0; // will never be reached
886 #endif
895 struct base_info
897 int pointer_offset; // the offset added to the pointer to obtain a basepointer (due to multiple-inheritance)
898 class_rep* base;
902 inline void add_base_class(const base_info& binfo)
904 // If you hit this assert you are deriving from a type that is not registered
905 // in lua. That is, in the class_<> you are giving a baseclass that isn't registered.
906 // Please note that if you don't need to have access to the base class or the
907 // conversion from the derived class to the base class, you don't need
908 // to tell luabind that it derives.
909 assert(binfo.base && "You cannot derive from an unregistered type");
911 class_rep* bcrep = binfo.base;
913 // import all functions from the base
914 for (std::map<const char*, method_rep, ltstr>::const_iterator i = bcrep->m_methods.begin(); i != bcrep->m_methods.end(); ++i)
916 #ifndef LUABIND_DONT_COPY_STRINGS
917 m_strings.push_back(dup_string(i->first));
918 method_rep& m = m_methods[m_strings.back()];
919 #else
920 method_rep& m = m_methods[i->first];
921 #endif
922 m.name = i->first;
923 m.crep = this;
925 for (std::vector<overload_rep>::const_iterator j = i->second.overloads().begin(); j != i->second.overloads().end(); ++j)
927 overload_rep o = *j;
928 o.add_offset(binfo.pointer_offset);
929 m.add_overload(o);
933 // import all getters from the base
934 for (std::map<const char*, callback, ltstr>::const_iterator i = bcrep->m_getters.begin(); i != bcrep->m_getters.end(); ++i)
936 #ifndef LUABIND_DONT_COPY_STRINGS
937 m_strings.push_back(dup_string(i->first));
938 callback& m = m_getters[m_strings.back()];
939 #else
940 callback& m = m_getters[i->first];
941 #endif
942 m.pointer_offset = i->second.pointer_offset + binfo.pointer_offset;
943 m.func = i->second.func;
946 // import all setters from the base
947 for (std::map<const char*, callback, ltstr>::const_iterator i = bcrep->m_setters.begin(); i != bcrep->m_setters.end(); ++i)
949 #ifndef LUABIND_DONT_COPY_STRINGS
950 // TODO: optimize this by not copying the string if it already exists in m_setters.
951 // This goes for m_getters, m_static_constants and m_functions too. Both here
952 // in add_base() and in the add_function(), add_getter() ... functions.
953 m_strings.push_back(dup_string(i->first));
954 callback& m = m_setters[m_strings.back()];
955 #else
956 callback& m = m_setters[i->first];
957 #endif
958 m.pointer_offset = i->second.pointer_offset + binfo.pointer_offset;
959 m.func = i->second.func;
962 // import all static constants
963 for (std::map<const char*, int, ltstr>::const_iterator i = bcrep->m_static_constants.begin(); i != bcrep->m_static_constants.end(); ++i)
965 #ifndef LUABIND_DONT_COPY_STRINGS
966 m_strings.push_back(dup_string(i->first));
967 int& v = m_static_constants[m_strings.back()];
968 #else
969 int& v = m_static_constants[i->first];
970 #endif
971 v = i->second;
974 // import all operators
975 for (int i = 0; i < number_of_operators; ++i)
977 for (std::vector<operator_callback>::const_iterator j = bcrep->m_operators[i].begin(); j != bcrep->m_operators[i].end(); ++j)
978 m_operators[i].push_back(*j);
981 // also, save the baseclass info to be used for typecasts
982 m_bases.push_back(binfo);
986 inline const std::vector<base_info>& bases() const throw() { return m_bases; }
987 inline LUABIND_TYPE_INFO type() const throw() { return m_type; }
988 inline void set_type(LUABIND_TYPE_INFO t) { m_type = t; }
990 inline void add_function(const char* name, const overload_rep& o)
993 #ifdef LUABIND_DONT_COPY_STRINGS
994 detail::method_rep& method = m_methods[name];
995 method.name = name;
996 #else
997 m_strings.push_back(dup_string(name));
998 detail::method_rep& method = m_methods[m_strings.back()];
999 method.name = m_strings.back();
1000 #endif
1002 method.add_overload(o);
1003 method.crep = this;
1006 inline void add_constructor(const detail::construct_rep::overload_t& o)
1008 m_constructor.overloads.push_back(o);
1011 inline void add_wrapped_constructor(const detail::construct_rep::overload_t& o)
1013 m_wrapped_constructor.overloads.push_back(o);
1016 inline const char* name() const throw()
1018 #ifdef LUABIND_DONT_COPY_STRINGS
1019 return m_name;
1020 #else
1021 return m_name.c_str();
1022 #endif
1025 inline void add_getter(const char* name, const boost::function2<int, lua_State*, int>& g)
1027 callback c;
1028 c.func = g;
1029 c.pointer_offset = 0;
1030 #ifndef LUABIND_DONT_COPY_STRINGS
1031 m_strings.push_back(dup_string(name));
1032 m_getters[m_strings.back()] = c;
1033 #else
1034 m_getters[name] = c;
1035 #endif
1038 inline void add_setter(const char* name, const boost::function2<int, lua_State*, int>& s)
1040 callback c;
1041 c.func = s;
1042 c.pointer_offset = 0;
1043 #ifndef LUABIND_DONT_COPY_STRINGS
1044 m_strings.push_back(dup_string(name));
1045 m_setters[m_strings.back()] = c;
1046 #else
1047 m_setters[name] = c;
1048 #endif
1051 #ifndef LUABIND_NO_ERROR_CHECKING
1052 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)
1053 #else
1054 inline void add_operator(lua_State*, int op_id, int(*func)(lua_State*), int(*matcher)(lua_State*), int arity)
1055 #endif
1057 operator_callback o;
1058 o.set_fun(func);
1059 o.set_match_fun(matcher);
1060 o.set_arity(arity);
1062 #ifndef LUABIND_NO_ERROR_CHECKING
1064 o.set_sig_fun(sig);
1066 #endif
1067 m_operators[op_id].push_back(o);
1070 // the lua reference to this class_rep
1071 inline int self_ref() const throw() { return m_self_ref; }
1073 // the lua reference to the metatable for this class' instances
1074 inline int metatable_ref() const throw() { return m_instance_metatable; }
1076 inline int table_ref() const { return m_table_ref; }
1078 inline void(*destructor() const)(void*) { return m_destructor; }
1080 inline class_type get_class_type() const { return m_class_type; }
1082 void add_static_constant(const char* name, int val)
1084 #ifndef LUABIND_DONT_COPY_STRINGS
1085 m_strings.push_back(dup_string(name));
1086 m_static_constants[m_strings.back()] = val;
1087 #else
1088 m_static_constants[name] = val;
1089 #endif
1092 static inline int super_callback(lua_State* L)
1094 int args = lua_gettop(L);
1096 object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, lua_upvalueindex(2)));
1097 class_rep* crep = static_cast<class_rep*>(lua_touserdata(L, lua_upvalueindex(1)));
1098 class_rep* base = crep->bases()[0].base;
1100 // std::cout << "__super of " << base->name() << "\n";
1102 if (base->get_class_type() == class_rep::lua_class)
1104 if (base->bases().empty())
1106 obj->set_flags(obj->flags() & ~object_rep::call_super);
1108 lua_pushstring(L, "super");
1109 lua_pushnil(L);
1110 lua_settable(L, LUA_GLOBALSINDEX);
1112 else
1114 lua_pushstring(L, "super");
1115 lua_pushlightuserdata(L, base);
1116 lua_pushvalue(L, lua_upvalueindex(2));
1117 lua_pushcclosure(L, super_callback, 2);
1118 lua_settable(L, LUA_GLOBALSINDEX);
1121 // std::cout << " lua_class\n";
1122 detail::getref(L, base->table_ref());
1123 lua_pushstring(L, "__init");
1124 lua_gettable(L, -2);
1125 lua_insert(L, 1);
1126 lua_pop(L, 1);
1128 lua_pushvalue(L, lua_upvalueindex(2));
1129 lua_insert(L, 2);
1131 lua_call(L, args + 1, 0);
1133 // TODO: instead of clearing the global variable "super"
1134 // store it temporarily in the registry. maybe we should
1135 // have some kind of warning if the super global is used?
1136 lua_pushstring(L, "super");
1137 lua_pushnil(L);
1138 lua_settable(L, LUA_GLOBALSINDEX);
1140 else
1142 obj->set_flags(obj->flags() & ~object_rep::call_super);
1143 // std::cout << " cpp_class\n";
1145 // we need to push some garbage at index 1 to make the construction work
1146 lua_pushboolean(L, 1);
1147 lua_insert(L, 1);
1149 construct_rep* rep = &base->m_constructor;
1151 bool ambiguous = false;
1152 int match_index = -1;
1153 int min_match = std::numeric_limits<int>::max();
1154 bool found;
1156 #ifdef LUABIND_NO_ERROR_CHECKING
1158 if (rep->overloads.size() == 1)
1160 match_index = 0;
1162 else
1165 #endif
1167 int num_params = lua_gettop(L) - 1;
1168 found = find_best_match(L, &rep->overloads.front(), rep->overloads.size(), sizeof(construct_rep::overload_t), ambiguous, min_match, match_index, num_params);
1170 #ifdef LUABIND_NO_ERROR_CHECKING
1174 #else
1176 if (!found)
1179 std::string msg = "no constructor of '";
1180 msg += base->m_name;
1181 msg += "' matched the arguments (";
1182 msg += stack_content_by_name(L, 2);
1183 msg += ")";
1184 lua_pushstring(L, msg.c_str());
1186 lua_error(L);
1188 else if (ambiguous)
1191 std::string msg = "call of overloaded constructor '";
1192 msg += base->m_name;
1193 msg += "(";
1194 msg += stack_content_by_name(L, 2);
1195 msg += ")' is ambiguous";
1196 lua_pushstring(L, msg.c_str());
1198 lua_error(L);
1201 // TODO: should this be a warning or something?
1203 // since the derived class is a lua class
1204 // it may have reimplemented virtual functions
1205 // therefore, we have to instantiate the Basewrapper
1206 // if there is no basewrapper, throw a run-time error
1207 if (!rep->overloads[match_index].has_wrapped_construct())
1210 std::string msg = "Cannot derive from C++ class '";
1211 msg += base->name();
1212 msg += "'. It does not have a wrapped type";
1213 lua_pushstring(L, msg.c_str());
1215 lua_error(L);
1218 #endif
1220 #ifndef LUABIND_NO_EXCEPTIONS
1225 #endif
1227 if (!rep->overloads[match_index].has_wrapped_construct())
1229 // if the type doesn't have a wrapped type, use the ordinary constructor
1230 obj->set_object(rep->overloads[match_index].construct(L));
1232 else
1234 // get reference to lua object
1235 lua_pushvalue(L, lua_upvalueindex(2));
1236 int ref = detail::ref(L);
1237 obj->set_object(rep->overloads[match_index].construct_wrapped(L, ref));
1239 // TODO: is the wrapped type destructed correctly?
1240 // it should, since the destructor is either the wrapped type's
1241 // destructor or the base type's destructor, depending on wether
1242 // the type has a wrapped type or not.
1243 obj->set_destructor(base->destructor());
1244 return 0;
1246 #ifndef LUABIND_NO_EXCEPTIONS
1249 catch(const std::exception& e)
1251 lua_pushstring(L, e.what());
1253 catch(const char* s)
1255 lua_pushstring(L, s);
1257 catch(...)
1259 std::string msg = base->m_name;
1260 msg += "() threw an exception";
1261 lua_pushstring(L, msg.c_str());
1263 // can only be reached if an exception was thrown
1264 lua_error(L);
1265 #endif
1268 return 0;
1272 static int lua_settable_dispatcher(lua_State* L)
1274 class_rep* crep = static_cast<class_rep*>(lua_touserdata(L, 1));
1275 detail::getref(L, crep->m_table_ref);
1276 lua_replace(L, 1);
1277 lua_rawset(L, -3);
1278 return 0;
1281 static int construct_lua_class_callback(lua_State* L)
1283 class_rep* crep = static_cast<class_rep*>(lua_touserdata(L, 1));
1285 int args = lua_gettop(L);
1287 // lua stack: crep <arguments>
1289 lua_newtable(L);
1290 int ref = detail::ref(L);
1292 bool has_bases = !crep->bases().empty();
1294 if (has_bases)
1296 lua_pushstring(L, "super");
1297 lua_pushvalue(L, 1); // crep
1300 // lua stack: crep <arguments> "super" crep
1301 // or
1302 // lua stack: crep <arguments>
1305 // if we have a baseclass we set the flag to say that the super has not yet been called
1306 // we will use this flag later to check that it actually was called from __init()
1307 int flags = object_rep::lua_class | object_rep::owner | (has_bases ? object_rep::call_super : 0);
1309 void* obj_ptr = lua_newuserdata(L, sizeof(object_rep));
1310 new(obj_ptr) object_rep(crep, flags, ref);
1312 detail::getref(L, crep->metatable_ref());
1313 lua_setmetatable(L, -2);
1315 // lua stack: crep <arguments> "super" crep obj_ptr
1316 // or
1317 // lua stack: crep <arguments> obj_ptr
1319 if (has_bases) lua_pushvalue(L, -1); // obj_ptr
1320 lua_replace(L, 1); // obj_ptr
1322 // lua stack: obj_ptr <arguments> "super" crep obj_ptr
1323 // or
1324 // lua stack: obj_ptr <arguments>
1326 if (has_bases)
1328 lua_pushcclosure(L, super_callback, 2);
1329 // lua stack: crep <arguments> "super" function
1330 lua_settable(L, LUA_GLOBALSINDEX);
1333 // lua stack: crep <arguments>
1335 lua_pushvalue(L, 1);
1336 lua_insert(L, 1);
1338 detail::getref(L, crep->table_ref());
1339 lua_pushstring(L, "__init");
1340 lua_gettable(L, -2);
1342 #ifndef LUABIND_NO_ERROR_CHECKING
1344 // TODO: should this be a run-time error?
1345 // maybe the default behavior should be to just call
1346 // the base calss' constructor. We should register
1347 // the super callback funktion as __init
1348 if (!lua_isfunction(L, -1))
1351 std::string msg = crep->name();
1352 msg += ":__init is not defined";
1353 lua_pushstring(L, msg.c_str());
1355 lua_error(L);
1358 #endif
1360 lua_insert(L, 2); // function first on stack
1361 lua_pop(L, 1);
1362 // TODO: lua_call may invoke longjump! make sure we don't have any memory leaks!
1363 // we don't have any stack objects here
1364 lua_call(L, args, 0);
1366 #ifndef LUABIND_NO_ERROR_CHECKING
1368 object_rep* obj = static_cast<object_rep*>(obj_ptr);
1369 if (obj->flags() & object_rep::call_super)
1371 lua_pushstring(L, "derived class must call super on base");
1372 lua_error(L);
1375 #endif
1377 return 1;
1380 // called from the metamethod for __index
1381 // obj is the object pointer
1382 static int lua_class_gettable(lua_State* L)
1384 object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, 1));
1385 class_rep* crep = obj->crep();
1387 #ifndef LUABIND_NO_ERROR_CHECKING
1389 if (obj->flags() & object_rep::call_super)
1391 lua_pushstring(L, "derived class must call super on base");
1392 lua_error(L);
1395 #endif
1397 detail::getref(L, obj->lua_table_ref());
1398 lua_pushvalue(L, 2);
1399 lua_gettable(L, -2);
1401 if (!lua_isnil(L, -1)) return 1;
1403 lua_pop(L, 2);
1405 detail::getref(L, crep->table_ref());
1406 lua_pushvalue(L, 2);
1407 lua_gettable(L, -2);
1409 if (!lua_isnil(L, -1)) return 1;
1411 lua_pop(L, 2);
1414 if (lua_isnil(L, 2))
1416 lua_pushnil(L);
1417 return 1;
1420 // we have to ignore the first argument since this may point to
1421 // a method that is not present in this class (but in a subclass)
1422 const char* key = lua_tostring(L, 2);
1424 std::map<const char*, method_rep, ltstr>::iterator i = crep->m_methods.find(key);
1425 if (i != crep->m_methods.end())
1427 // the name is a method, return it
1428 lua_pushlightuserdata(L, &i->second);
1429 lua_pushcclosure(L, class_rep::function_dispatcher, 1);
1430 return 1;
1433 std::map<const char*, class_rep::callback, ltstr>::iterator j = crep->m_getters.find(key);
1434 if (j != crep->m_getters.end())
1436 // the name is a data member
1437 return j->second.func(L, j->second.pointer_offset);
1440 lua_pushnil(L);
1441 return 1;
1444 // called from the metamethod for __newindex
1445 // obj is the object pointer
1446 static int lua_class_settable(lua_State* L)
1448 object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, 1));
1449 class_rep* crep = obj->crep();
1451 #ifndef LUABIND_NO_ERROR_CHECKING
1453 if (obj->flags() & object_rep::call_super)
1455 // this block makes sure the std::string is destructed
1456 // before lua_error is called
1458 std::string msg = "derived class '";
1459 msg += crep->name();
1460 msg += "'must call super on base";
1461 lua_pushstring(L, msg.c_str());
1463 lua_error(L);
1466 #endif
1468 // we have to ignore the first argument since this may point to
1469 // a method that is not present in this class (but in a subclass)
1470 const char* key = lua_tostring(L, 2);
1471 std::map<const char*, class_rep::callback, ltstr>::iterator j = crep->m_setters.find(key);
1473 if (j == crep->m_setters.end())
1475 std::map<const char*, class_rep::callback, ltstr>::iterator k = crep->m_getters.find(key);
1477 #ifndef LUABIND_NO_ERROR_CHECKING
1479 if (k != crep->m_getters.end())
1482 std::string msg = "cannot set property '";
1483 msg += crep->name();
1484 msg += ".";
1485 msg += key;
1486 msg += "', because it's read only";
1487 lua_pushstring(L, msg.c_str());
1489 lua_error(L);
1492 #endif
1494 detail::getref(L, obj->lua_table_ref());
1495 lua_replace(L, 1);
1496 lua_settable(L, 1);
1498 else
1500 // the name is a data member
1501 j->second.func(L, j->second.pointer_offset);
1504 return 0;
1507 static int static_class_gettable(lua_State* L)
1509 class_rep* crep = static_cast<class_rep*>(lua_touserdata(L, 1));
1511 if (crep->get_class_type() == class_rep::lua_class)
1513 detail::getref(L, crep->m_table_ref);
1514 lua_pushvalue(L, 2);
1515 lua_gettable(L, -2);
1516 if (!lua_isnil(L, -1)) return 1;
1517 else lua_pop(L, 2);
1520 const char* key = lua_tostring(L, 2);
1522 std::map<const char*, method_rep, ltstr>::iterator i = crep->m_methods.find(key);
1523 if (i != crep->m_methods.end())
1525 // the name is a method, return it
1526 lua_pushlightuserdata(L, &i->second);
1527 lua_pushcclosure(L, class_rep::function_dispatcher, 1);
1528 return 1;
1531 #ifndef LUABIND_NO_ERROR_CHECKING
1533 std::map<const char*, int, ltstr>::const_iterator j = crep->m_static_constants.find(key);
1535 if (j != crep->m_static_constants.end())
1537 lua_pushnumber(L, j->second);
1538 return 1;
1542 std::string msg = "no static '";
1543 msg += key;
1544 msg += "' in class '";
1545 msg += crep->name();
1546 msg += "'";
1547 lua_pushstring(L, msg.c_str());
1549 lua_error(L);
1551 #endif
1553 return 0;
1556 private:
1558 // this is a pointer to the type_info structure for
1559 // this type
1560 // warning: this may be a problem when using dll:s, since
1561 // typeid() may actually return different pointers for the same
1562 // type.
1563 LUABIND_TYPE_INFO m_type;
1564 LUABIND_TYPE_INFO m_held_type;
1566 typedef void*(*extract_ptr_t)(void*);
1567 extract_ptr_t m_extract_underlying_fun;
1569 // a list of info for every class this class derives from
1570 // the information stored here is sufficient to do
1571 // type casts to the base classes
1572 std::vector<base_info> m_bases;
1574 // the class' name (as given when registered to lua with class_)
1575 #ifdef LUABIND_DONT_COPY_STRINGS
1576 const char* m_name;
1577 #else
1578 std::string m_name;
1579 #endif
1581 // contains signatures for all constructors
1582 construct_rep m_constructor;
1583 construct_rep m_wrapped_constructor;
1585 // a reference to this structure itself. Since this struct
1586 // is kept inside lua (to let lua collect it when lua_close()
1587 // is called) we need to lock it to prevent collection.
1588 // the actual reference is not currently used.
1589 int m_self_ref;
1591 // a reference to the lua table that represents this class
1592 // (only used if it is a lua class)
1593 int m_table_ref;
1595 // the type of this class.. determines if it's written in c++ or lua
1596 class_type m_class_type;
1598 // this is a lua reference that points to the lua table
1599 // that is to be used as meta table for all instances
1600 // of this class.
1601 int m_instance_metatable;
1603 // ***** the maps below contains all members in this class *****
1605 // maps method names to a structure with more
1606 // information about that method.
1607 // that struct contains the function-signatures
1608 // for every overload
1609 std::map<const char*, method_rep, ltstr> m_methods;
1611 #ifndef LUABIND_DONT_COPY_STRINGS
1612 // this is where the strings that the maps contains
1613 // pointer to are kept. To make sure they are destructed.
1614 std::vector<char*> m_strings;
1615 #endif
1617 struct callback
1619 boost::function2<int, lua_State*, int> func;
1620 int pointer_offset;
1623 // datamembers, some members may be readonly, and
1624 // only have a getter function
1625 std::map<const char*, callback, ltstr> m_getters;
1626 std::map<const char*, callback, ltstr> m_setters;
1628 struct operator_callback: public overload_rep_base
1630 inline void set_fun(int (*f)(lua_State*)) { func = f; }
1631 inline int call(lua_State* L) { return func(L); }
1632 inline void set_arity(int arity) { m_arity = arity; }
1634 private:
1636 int(*func)(lua_State*);
1639 std::vector<operator_callback> m_operators[number_of_operators]; // the operators in lua
1641 void(*m_destructor)(void*);
1643 std::map<const char*, int, ltstr> m_static_constants;
1647 inline bool is_class_rep(lua_State* L, int index)
1649 if (lua_getmetatable(L, index) == 0) return false;
1651 lua_pushstring(L, "__luabind_classrep");
1652 lua_gettable(L, -2);
1653 if (lua_toboolean(L, -1))
1655 lua_pop(L, 2);
1656 return true;
1659 lua_pop(L, 2);
1660 return false;
1664 #endif // HEADERS ONLY
1668 #endif // LUABIND_CLASS_REP_HPP_INCLUDED