fixed ICE on vc6 (moved around the include order)
[luabind.git] / luabind / class.hpp
blob63b48c5acd24899f44308bf9ce8d393fbdf2fc3a
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_HPP_INCLUDED
25 #define LUABIND_CLASS_HPP_INCLUDED
28 Issues:
29 -------
30 * done *
31 move all exceptions to the exception.hpp header
33 * done *
34 Since functions can be overridden, the constness of the member functions
35 must be taken into account.
37 * solved for member functions, not application operator *
38 if we have a base class that defines a function a derived class must be able to
39 override that function (not just overload). Right now we just add the other overload
40 to the overloads list and will probably get an ambiguity. If we want to support this
41 each method_rep must include a vector of type_info pointers for each parameter.
42 Operators do not have this problem, since operators always have to have
43 it's own type as one of the arguments, no ambiguity can occur. Application
44 operator, on the other hand, would have this problem.
45 Properties cannot be overloaded, so they should always be overridden.
46 If this is to work for application operator, we really need to specify if an application
47 operator is const or not.
49 If one class registers two functions with the same name and the same
50 signature, there's currently no error. The last registered function will
51 be the one that's used.
52 How do we know which class registered the function? If the function was
53 defined by the base class, it is a legal operation, to override it.
54 we cannot look at the pointer offset, since it always will be zero for one of the bases.
56 * done *
57 We do not currently run unwrap_other<> on the parameters given to the application
58 operators when we register them.
60 * done *
61 if the first matched binary operator does not match the parameters we have to manually
62 check if the right parameter has a matching operator.
64 * I think this is resolved *
65 There is currently a restriction that operators must take their parameters as const references
66 or as copies. This could be solved by specifying special wrapper types for const references and
67 non-const references. Binary operators shouldn't implicitly convert it's parameters to const&.
69 * done *
70 The application operator do not currently work on const objects. Again, to solve this we need
71 some kind of wrapper to say that the self object is const.
73 Make sure we don't have any memory leaks when we use lua_error()
75 We should avoid names that begins with lua_ (in our own scopes) since the lua distribution
76 have plenty of defines with that prefix.
78 Optimize by calling lua_rawset/get instead of lua_settable/gettable
80 * done *
81 use ordinary function pointers instead of boost::function.
82 the boost::function is only used on member functions now, We have to use it in order
83 to support free functions as member functions.
85 * solved *
86 when we register classes we should import all methods and properties
87 from the base classes into the class. We will then need to offset the object pointer
88 on a per method/property basis. This will allow methods from the base class to be
89 overloaded without shadowing the base class. The method lookup will also be
90 more efficient.
92 remove methods from methodtable of classrep when overloading them in lua
94 * done *
95 we currently set uninitialized references to -1, they should be set to LUA_NOREF!
97 * done *
98 the error exception class should avoid heap allocations
100 Todo:
101 -----
103 document custom policies, custom converters
105 store the instance object for policies.
107 support the __concat metamethod. This is a bit tricky, since it cannot be
108 treated as a normal operator. It is a binary operator but we want to use the
109 __tostring implementation for both arguments.
111 smart pointer support
113 scopes
115 __finalize function on lua classes
117 make all proxy_callers one policy based class
119 make all proxy_objects one policy based class
121 static functions
125 #include <luabind/config.hpp>
127 #include <string>
128 #include <map>
129 #include <vector>
130 #include <cassert>
132 #include <boost/static_assert.hpp>
133 #include <boost/type_traits.hpp>
134 #include <boost/bind.hpp>
135 #include <boost/function.hpp>
136 #include <boost/preprocessor/repetition/enum_params.hpp>
137 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
138 #include <boost/preprocessor/repetition/repeat.hpp>
139 #include <boost/type_traits/is_same.hpp>
140 #include <boost/mpl/list.hpp>
141 #include <boost/mpl/apply.hpp>
142 #include <boost/mpl/lambda.hpp>
143 #include <boost/mpl/logical.hpp>
144 #include <boost/mpl/find_if.hpp>
145 #include <boost/mpl/apply_if.hpp>
146 #include <boost/mpl/logical.hpp>
148 #include <luabind/config.hpp>
149 #include <luabind/scope.hpp>
150 #include <luabind/detail/constructor.hpp>
151 #include <luabind/detail/call.hpp>
152 #include <luabind/detail/signature_match.hpp>
153 #include <luabind/detail/primitives.hpp>
154 #include <luabind/detail/property.hpp>
155 #include <luabind/detail/typetraits.hpp>
156 #include <luabind/detail/class_rep.hpp>
157 #include <luabind/detail/method_rep.hpp>
158 #include <luabind/detail/construct_rep.hpp>
159 #include <luabind/detail/object_rep.hpp>
160 #include <luabind/detail/operators.hpp>
161 #include <luabind/detail/calc_arity.hpp>
162 #include <luabind/detail/call_member.hpp>
163 #include <luabind/detail/enum_maker.hpp>
164 #include <luabind/detail/get_signature.hpp>
165 #include <luabind/detail/implicit_cast.hpp>
166 #include <luabind/detail/operator_id.hpp>
168 namespace luabind
170 namespace detail
172 struct unspecified {};
175 template<class T, class X1 = detail::unspecified, class X2 = detail::unspecified, class X3 = detail::unspecified>
176 struct class_;
178 namespace detail
180 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class A)>
181 double is_bases_helper(const bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, A)>&);
183 #ifndef BOOST_MSVC
184 template<class T>
185 char is_bases_helper(const T&);
186 #else
187 char is_bases_helper(...);
188 #endif
190 template<class T>
191 struct is_bases
193 static const T& t;
195 BOOST_STATIC_CONSTANT(bool, value = sizeof(is_bases_helper(t)) == sizeof(double));
196 typedef boost::mpl::bool_<value> type;
197 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_bases,(T))
200 double is_not_unspecified_helper(const unspecified*);
201 char is_not_unspecified_helper(...);
203 template<class T>
204 struct is_not_unspecified
206 BOOST_STATIC_CONSTANT(bool, value = sizeof(is_not_unspecified_helper(static_cast<T*>(0))) == sizeof(char));
207 typedef boost::mpl::bool_<value> type;
208 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_not_unspecified,(T))
211 template<class Predicate>
212 struct get_predicate
214 typedef typename boost::mpl::and_<
215 Predicate
216 , is_not_unspecified<boost::mpl::_1>
217 > type;
220 template<class Parameters, class Predicate, class DefaultValue>
221 struct extract_parameter
223 typedef typename get_predicate<Predicate>::type pred;
224 typedef typename boost::mpl::find_if<Parameters, pred>::type iterator;
225 typedef typename boost::mpl::apply_if<boost::is_same<iterator, typename boost::mpl::end<Parameters>::type>
226 , boost::mpl::identity<DefaultValue>
227 , iterator
228 >::type type;
231 int function_dispatcher(lua_State* L);
233 // this should know about the smart pointer type.
234 // and should really do:
235 // get_pointer(*static_cast<SmartPointer*>(obj_ptr))
236 // to extract the held pointer.
237 template<class HeldType, class T, class F, class Policies>
238 struct function_callback_non_null
240 function_callback_non_null(F f_): f(f_) {}
241 inline int operator()(lua_State* L, void* obj_ptr)
243 HeldType& held_obj = *static_cast<HeldType*>(obj_ptr);
245 T* ptr = get_pointer(held_obj);
246 // BOOST_STATIC_ASSERT((boost::is_same<HeldType, detail::null_type>::value == false));
248 // std::cout << "HeldType: " << typeid(HeldType).name() << "\n";
250 return call(f, ptr, L, static_cast<Policies*>(this));
252 F f;
255 template<class T, class F, class Policies>
256 struct function_callback_null_type : Policies
258 function_callback_null_type(F f_): f(f_) {}
259 inline int operator()(lua_State* L, void* obj_ptr)
261 // std::cout << "HeldType: null_type\n";
262 T* ptr = static_cast<T*>(obj_ptr);
263 return call(f, ptr, L, static_cast<Policies*>(this));
265 F f;
268 template<class HeldType, class T, class F, class Policies>
269 struct function_callback_s
271 typedef typename
272 boost::mpl::if_<boost::is_same<HeldType,detail::null_type>
273 , function_callback_null_type<T,F,Policies>
274 , function_callback_non_null<HeldType,T,F,Policies>
275 >::type type;
278 template<class T, class F, class Policies>
279 struct match_function_callback_s
281 static inline int apply(lua_State* L)
283 object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, 1));
284 F fptr = 0;
285 return match(fptr, L, obj->flags() & object_rep::constant, static_cast<Policies*>(0));
289 // prints the types of the values on the stack, in the
290 // range [start_index, lua_gettop()]
291 inline std::string stack_content_by_name(lua_State* L, int start_index)
293 std::string ret;
294 int top = lua_gettop(L);
295 for (int i = start_index; i <= top; ++i)
297 object_rep* obj = is_class_object(L, i);
298 class_rep* crep = is_class_rep(L, i)?(class_rep*)lua_touserdata(L, i):0;
299 if (obj == 0 && crep == 0)
301 int type = lua_type(L, i);
302 ret += lua_typename(L, type);
304 else if (obj)
306 if (obj->flags() & object_rep::constant) ret += "const ";
307 ret += obj->crep()->name();
309 else if (crep)
311 ret += "<";
312 ret += crep->name();
313 ret += ">";
315 if (i < top) ret += ", ";
317 return ret;
320 struct create_class
322 static int stage2(lua_State* L)
325 class_rep* crep = static_cast<class_rep*>(lua_touserdata(L, lua_upvalueindex(1)));
326 assert((crep != 0) && "internal error, please report");
327 assert((is_class_rep(L, lua_upvalueindex(1))) && "internal error, please report");
329 #ifndef LUABIND_NO_ERROR_CHECKING
331 if (!is_class_rep(L, 1))
333 lua_pushstring(L, "expected class to derive from or a newline");
334 lua_error(L);
337 #endif
339 class_rep* base = static_cast<class_rep*>(lua_touserdata(L, 1));
341 class_rep::base_info binfo;
343 binfo.pointer_offset = 0;
344 binfo.base = base;
345 crep->add_base_class(binfo);
347 if (base->get_class_type() == class_rep::lua_class)
349 // copy base class members
351 detail::getref(L, crep->table_ref());
352 detail::getref(L, base->table_ref());
353 lua_pushnil(L);
355 while (lua_next(L, -2))
357 lua_pushvalue(L, -2); // copy key
358 lua_insert(L, -2);
359 lua_settable(L, -5);
363 crep->set_type(base->type());
365 return 0;
368 static int stage1(lua_State* L)
371 #ifndef LUABIND_NO_ERROR_CHECKING
373 if (lua_gettop(L) != 1 || lua_type(L, 1) != LUA_TSTRING || lua_isnumber(L, 1))
375 lua_pushstring(L, "invalid construct, expected class name");
376 lua_error(L);
379 #endif
381 const char* name = lua_tostring(L, 1);
383 void* c = lua_newuserdata(L, sizeof(class_rep));
384 new(c) class_rep(L, name);
386 // make the class globally available
387 lua_pushstring(L, name);
388 lua_pushvalue(L, -2);
389 lua_settable(L, LUA_GLOBALSINDEX);
391 // also add it to the closure as return value
392 lua_pushcclosure(L, &stage2, 1);
394 return 1;
398 template<class Type>
399 struct register_wrapped_type
401 template<class Signature, class Policies>
402 static void apply(detail::construct_rep::overload_t& o, const Signature*, const Policies*)
404 o.set_wrapped_constructor(
405 &detail::construct_wrapped_class<Type, Policies, Signature>::apply
410 template<>
411 struct register_wrapped_type<detail::null_type>
413 template<class Signature, class Policies>
414 static void apply(detail::construct_rep::overload_t&, const Signature*, const Policies*) {}
418 // if the class is held by a smart pointer, we need to be able to
419 // implicitly dereference the pointer when needed.
421 template<class UnderlyingT, class HeldT>
422 struct extract_underlying_type
424 static void* extract(void* ptr)
426 HeldT& held_obj = *reinterpret_cast<HeldT*>(ptr);
427 UnderlyingT* underlying_ptr = get_pointer(held_obj);
428 return underlying_ptr;
433 template<class HeldType>
434 struct internal_held_type_extractor
436 typedef void*(*extractor_fun)(void*);
438 template<class T>
439 static extractor_fun apply(detail::type<T>)
441 return detail::extract_underlying_type<T, HeldType>::extract;
445 template<>
446 struct internal_held_type_extractor<detail::null_type>
448 typedef void*(*extractor_fun)(void*);
450 template<class T>
451 static extractor_fun apply(detail::type<T>)
453 return 0;
457 template<class HeldType>
458 struct internal_held_type
460 static LUABIND_TYPE_INFO apply()
462 return LUABIND_TYPEID(HeldType);
466 template<>
467 struct internal_held_type<detail::null_type>
469 static LUABIND_TYPE_INFO apply()
471 return LUABIND_INVALID_TYPE_INFO;
475 } // detail
490 struct class_base: detail::scoped_object
492 protected:
494 struct base_desc
496 LUABIND_TYPE_INFO type;
497 int ptr_offset;
500 private:
502 #ifndef NDEBUG
503 bool m_cloned;
504 #endif
506 const char* m_name;
508 std::map<const char*, detail::method_rep, detail::ltstr> m_methods;
510 // datamembers, some members may be readonly, and
511 // only have a getter function
512 std::map<const char*, detail::class_rep::callback, detail::ltstr> m_getters;
513 std::map<const char*, detail::class_rep::callback, detail::ltstr> m_setters;
515 // the operators in lua
516 std::vector<detail::class_rep::operator_callback> m_operators[detail::number_of_operators];
517 std::map<const char*, int, detail::ltstr> m_static_constants;
519 std::vector<base_desc> m_bases;
520 detail::construct_rep m_constructor;
522 void(*m_destructor)(void*);
523 void*(*m_extractor)(void*);
525 LUABIND_TYPE_INFO m_type;
526 LUABIND_TYPE_INFO m_held_type;
528 #ifndef LUABIND_DONT_COPY_STRINGS
529 // the maps that contains char pointers points into
530 // this vector of strings.
531 std::vector<char*> m_strings;
532 #endif
534 protected:
536 void set_type(LUABIND_TYPE_INFO t) { m_type = t; }
537 void set_held_type(LUABIND_TYPE_INFO t) { m_held_type = t; }
538 void set_extractor(void*(*f)(void*)) { m_extractor = f; }
539 void set_destructor(void(*f)(void*)) { m_destructor = f; }
541 inline void add_getter(const char* name, const boost::function2<int, lua_State*, int>& g)
543 detail::class_rep::callback c;
544 c.func = g;
545 c.pointer_offset = 0;
546 #ifndef LUABIND_DONT_COPY_STRINGS
547 m_strings.push_back(detail::dup_string(name));
548 m_getters[m_strings.back()] = c;
549 #else
550 m_getters[name] = c;
551 #endif
554 inline void add_setter(const char* name, const boost::function2<int, lua_State*, int>& s)
556 detail::class_rep::callback c;
557 c.func = s;
558 c.pointer_offset = 0;
559 #ifndef LUABIND_DONT_COPY_STRINGS
560 m_strings.push_back(detail::dup_string(name));
561 m_setters[m_strings.back()] = c;
562 #else
563 m_setters[name] = c;
564 #endif
567 void add_base(const base_desc& b)
569 m_bases.push_back(b);
572 public:
574 void add_constructor(const detail::construct_rep::overload_t& o)
576 m_constructor.overloads.push_back(o);
579 void add_method(const char* name, const detail::overload_rep& o)
581 #ifdef LUABIND_DONT_COPY_STRINGS
582 detail::method_rep& method = m_methods[name];
583 method.name = name;
584 #else
585 m_strings.push_back(detail::dup_string(name));
586 detail::method_rep& method = m_methods[m_strings.back()];
587 method.name = m_strings.back();
588 #endif
589 method.add_overload(o);
590 method.crep = 0;
593 #ifndef LUABIND_NO_ERROR_CHECKING
594 inline void add_operator(int op_id, int(*func)(lua_State*), int(*matcher)(lua_State*), void(*sig)(lua_State*, std::string&), int arity)
595 #else
596 inline void add_operator(int op_id, int(*func)(lua_State*), int(*matcher)(lua_State*), int arity)
597 #endif
599 detail::class_rep::operator_callback o;
600 o.set_fun(func);
601 o.set_match_fun(matcher);
602 o.set_arity(arity);
604 #ifndef LUABIND_NO_ERROR_CHECKING
606 o.set_sig_fun(sig);
608 #endif
609 m_operators[op_id].push_back(o);
618 const char* name() const { return m_name; }
620 class_base(const char* name): m_name(name)
622 #ifndef NDEBUG
623 m_cloned = false;
624 #endif
627 virtual ~class_base()
629 // if we are copying strings, we have to destroy them too
630 #ifndef LUABIND_DONT_COPY_STRINGS
631 for (std::vector<char*>::iterator i = m_strings.begin(); i != m_strings.end(); ++i)
632 delete[] *i;
633 #endif
636 // pushes the class_rep on the lua stack
637 virtual void commit(lua_State* L)
639 detail::class_rep* crep;
641 detail::class_registry* r = detail::class_registry::get_registry(L);
642 // create a class_rep structure for this class.
643 // allocate it within lua to let lua collect it on
644 // lua_close(). This is better than allocating it
645 // as a static, since it will then be destructed
646 // when the program exits instead.
647 // warning: we assume that lua will not
648 // move the userdata memory.
649 lua_newuserdata(L, sizeof(detail::class_rep));
650 crep = reinterpret_cast<detail::class_rep*>(lua_touserdata(L, -1));
652 const char* n = lua_typename(L, lua_type(L, -1));
654 new(crep) detail::class_rep(m_type, m_name, L, m_destructor, m_held_type, m_extractor);
656 const char* b = lua_typename(L, lua_type(L, -1));
658 // register this new type in the class registry
659 r->add_class(m_type, crep);
661 // add methods
662 for (std::map<const char*, detail::method_rep, detail::ltstr>::iterator i = m_methods.begin();
663 i != m_methods.end();
664 ++i)
666 i->second.crep = crep;
668 std::swap(crep->m_methods, m_methods);
670 // constructors
671 m_constructor.swap(crep->m_constructor);
673 #ifndef LUABIND_DONT_COPY_STRINGS
674 std::swap(crep->m_strings, m_strings);
675 #endif
677 std::swap(crep->m_getters, m_getters);
678 std::swap(crep->m_setters, m_setters);
680 for(int i = 0; i < detail::number_of_operators; ++i)
681 std::swap(crep->m_operators[i], m_operators[i]);
683 std::swap(crep->m_static_constants, m_static_constants);
685 for (std::vector<base_desc>::iterator i = m_bases.begin();
686 i != m_bases.end();
687 ++i)
689 detail::class_registry* r = detail::class_registry::get_registry(L);
691 // the baseclass' class_rep structure
692 detail::class_rep* bcrep = r->find_class(i->type);
694 detail::class_rep::base_info base;
695 base.pointer_offset = i->ptr_offset;
696 base.base = bcrep;
698 crep->add_base_class(base);
702 // destructive copy
703 virtual luabind::detail::scoped_object* clone()
705 assert(m_cloned == false);
707 #ifndef NDEBUG
708 m_cloned = true;
709 #endif
711 class_base* ret = new class_base(m_name);
713 std::swap(ret->m_getters, m_getters);
714 std::swap(ret->m_setters, m_setters);
716 for(int i = 0; i < detail::number_of_operators; ++i)
717 std::swap(ret->m_operators[i], m_operators[i]);
719 std::swap(ret->m_static_constants, m_static_constants);
720 ret->m_destructor = m_destructor;
722 std::swap(ret->m_bases, m_bases);
723 std::swap(ret->m_methods, m_methods);
724 m_constructor.swap(ret->m_constructor);
726 #ifndef LUABIND_DONT_COPY_STRINGS
727 std::swap(ret->m_strings, m_strings);
728 #endif
730 return ret;
745 // registers a class in the lua environment
746 template<class T, class X1, class X2, class X3>
747 struct class_: class_base
749 typedef class_<T, X1, X2, X3> self_t;
751 private:
753 lua_State* m_L;
755 template<class A, class B, class C, class D>
756 class_(const class_<A,B,C,D>&);
758 public:
760 // WrappedType MUST inherit from T
761 typedef typename detail::extract_parameter<
762 boost::mpl::vector3<X1,X2,X3>
763 , boost::is_base_and_derived<T, boost::mpl::_>
764 /* , boost::mpl::not_<
765 boost::mpl::or_<
766 detail::is_bases<boost::mpl::_>
767 , boost::is_base_and_derived<boost::mpl::_, T>
770 , detail::null_type
771 >::type WrappedType;
773 typedef typename detail::extract_parameter<
774 boost::mpl::vector3<X1,X2,X3>
775 , boost::mpl::not_<
776 boost::mpl::or_<
777 boost::mpl::or_<
778 detail::is_bases<boost::mpl::_>
779 , boost::is_base_and_derived<boost::mpl::_, T>
781 , boost::is_base_and_derived<T, boost::mpl::_>
784 , detail::null_type
785 >::type HeldType;
787 // this function generates conversion information
788 // in the given class_rep structure. It will be able
789 // to implicitly cast to the given template type
790 template<class To>
791 void gen_base_info(detail::type<To>)
793 // fist, make sure the given base class is registered.
794 // if it's not registered we can't push it's lua table onto
795 // the stack because it doesn't have a table
797 // try to cast this type to the base type and remember
798 // the pointer offset. For multiple inheritance the pointer
799 // may change when casting. Since we need to be able to
800 // cast we need this pointer offset.
801 // store the information in this class' base class-vector
802 base_desc base;
803 base.type = LUABIND_TYPEID(To);
804 base.ptr_offset = detail::ptr_offset(detail::type<T>(), detail::type<To>());
805 add_base(base);
808 void gen_base_info(detail::type<detail::null_type>)
811 #define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type<B##n>());
813 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class B)>
814 void generate_baseclass_list(detail::type<bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, B)> >)
816 BOOST_PP_REPEAT(LUABIND_MAX_BASES, LUABIND_GEN_BASE_INFO, _)
819 #undef LUABIND_GEN_BASE_INFO
821 // this is the internal version of def() it is run from both overloads
822 // of def. It has two versions, one where a contstructor is registered
823 // and one where a function is registered
824 template<class Policies>
825 struct internal_def_s
827 template<class F>
828 static void apply(const char* name, F f, class_base* c)
830 // std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";
832 detail::overload_rep o(f, static_cast<Policies*>(0));
834 typedef LUABIND_MSVC_TYPENAME detail::function_callback_s<HeldType,T,F,Policies>::type call_t;
836 o.set_match_fun(&detail::match_function_callback_s<T,F,Policies>::apply);
837 o.call_fun = boost::bind<int>(call_t(f), _1, _2);
839 #ifndef LUABIND_NO_ERROR_CHECKING
841 o.set_sig_fun(&detail::get_member_signature<F>::apply);
843 #endif
845 c->add_method(name, o);
848 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)>
849 static void apply(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>, class_base* c)
851 // std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";
853 detail::construct_rep::overload_t o;
855 o.set_constructor(
856 &detail::construct_class<
858 ,Policies
859 ,constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>
860 >::apply
863 // if we have a WrappedType, we have to register it's constructor
864 // but if it's null_type (no WrappedType) we should not register it
865 detail::register_wrapped_type<WrappedType>::apply(o,
866 static_cast<const constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>*>(0),
867 static_cast<const Policies*>(0));
870 o.set_match_fun(
871 &detail::constructor_match<
872 constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>
874 ,Policies
875 >::apply);
877 #ifndef LUABIND_NO_ERROR_CHECKING
879 o.set_sig_fun(&detail::get_signature<constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> >::apply);
881 #endif
883 typedef constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> con_t;
885 o.set_arity(detail::calc_arity<con_t::arity>::apply(con_t(), static_cast<Policies*>(0)));
887 c->add_constructor(o);
892 class_(lua_State* L_, const char* name): class_base(name), m_L(L_) { init(); }
893 class_(const char* name): class_base(name), m_L(0) { init(); }
895 // TODO: we sould probably commit the object someplace else
896 ~class_()
898 if (m_L)
900 lua_pushstring(m_L, name());
901 commit(m_L);
902 const char* n = lua_typename(m_L, lua_type(m_L, -1));
903 lua_settable(m_L, LUA_GLOBALSINDEX);
907 template<class F>
908 class_& def(const char* name, F f)
910 internal_def_s<detail::null_type>::apply(name, f, this);
911 return *this;
914 template<class F, class Policies>
915 class_& def(const char* name, F f, const Policies&)
917 internal_def_s<Policies>::apply(name, f, this);
918 return *this;
921 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)>
922 class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig)
924 internal_def_s<detail::null_type>::apply(sig, this);
925 return *this;
928 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A), class Policies>
929 class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig, const Policies& policies)
931 internal_def_s<Policies>::apply(sig, this);
932 return *this;
935 template<class Getter>
936 class_& property(const char* name, Getter g)
938 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, detail::null_type>(), _1, _2, g));
939 return *this;
942 template<class Getter, class MaybeSetter>
943 class_& property(const char* name, Getter g, MaybeSetter s)
945 return property_impl(name, g, s, boost::mpl::bool_<detail::is_policy_cons<MaybeSetter>::value>());
948 template<class Getter, class Setter, class GetPolicies>
949 class_& property(const char* name, Getter g, Setter s, const GetPolicies& get_policies)
951 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, GetPolicies>(get_policies), _1, _2, g));
952 add_setter(name, boost::bind<int>(detail::set_caller<T, Setter, detail::null_type>(), _1, _2, s));
953 return *this;
956 template<class Getter, class Setter, class GetPolicies, class SetPolicies>
957 class_& property(const char* name
958 , Getter g, Setter s
959 , const GetPolicies& get_policies
960 , const SetPolicies& set_policies)
962 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, GetPolicies>(get_policies), _1, _2, g));
963 add_setter(name, boost::bind<int>(detail::set_caller<T, Setter, GetPolicies>(set_policies), _1, _2, s));
964 return *this;
967 template<class D>
968 class_& def_readonly(const char* name, D T::*member_ptr)
970 add_getter(name, boost::bind<int>(detail::auto_get<T,D,detail::null_type>(), _1, _2, member_ptr));
971 return *this;
974 template<class D, class Policies>
975 class_& def_readonly(const char* name, D T::*member_ptr, const Policies& policies)
977 add_getter(name, boost::bind<int>(detail::auto_get<T,D,Policies>(policies), _1, _2, member_ptr));
978 return *this;
981 template<class D>
982 class_& def_readwrite(const char* name, D T::*member_ptr)
984 add_getter(name, boost::bind<int>(detail::auto_get<T,D,detail::null_type>(), _1, _2, member_ptr));
985 add_setter(name, boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr));
986 return *this;
989 template<class D, class GetPolicies>
990 class_& def_readwrite(const char* name, D T::*member_ptr, const GetPolicies& get_policies)
992 add_getter(name, boost::bind<int>(detail::auto_get<T,D,GetPolicies>(get_policies), _1, _2, member_ptr));
993 add_setter(name, boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr));
994 return *this;
997 template<class D, class GetPolicies, class SetPolicies>
998 class_& def_readwrite(const char* name, D T::*member_ptr, const GetPolicies& get_policies, const SetPolicies& set_policies)
1000 add_getter(name, boost::bind<int>(detail::auto_get<T,D,GetPolicies>(get_policies), _1, _2, member_ptr));
1001 add_setter(name, boost::bind<int>(detail::auto_set<T,D,SetPolicies>(set_policies), _1, _2, member_ptr));
1002 return *this;
1005 template<class op_id, class Left, class Right, class Policies>
1006 class_& def(detail::operator_<op_id, Left, Right>, const Policies& policies)
1008 typedef typename detail::operator_unwrapper<Policies, op_id, T, Left, Right> op_type;
1009 #ifndef LUABIND_NO_ERROR_CHECKING
1010 add_operator(op_type::get_id()
1011 , &op_type::execute
1012 , &op_type::match
1013 , &detail::get_signature<constructor<typename op_type::left_t, typename op_type::right_t> >::apply
1014 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1015 #else
1016 add_operator(op_type::get_id()
1017 , &op_type::execute
1018 , &op_type::match
1019 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1020 #endif
1021 return *this;
1024 template<class op_id, class Left, class Right>
1025 class_& def(detail::operator_<op_id, Left, Right>)
1027 typedef typename detail::operator_unwrapper<detail::null_type, op_id, T, Left, Right> op_type;
1029 #ifndef LUABIND_NO_ERROR_CHECKING
1030 add_operator(op_type::get_id()
1031 , &op_type::execute
1032 , &op_type::match
1033 , &detail::get_signature<constructor<LUABIND_MSVC_TYPENAME op_type::left_t, LUABIND_MSVC_TYPENAME op_type::right_t> >::apply
1034 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1035 #else
1036 add_operator(op_type::get_id()
1037 , &op_type::execute
1038 , &op_type::match
1039 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1040 #endif
1041 return *this;
1044 template<class Signature, bool Constant>
1045 class_& def(detail::application_operator<Signature, Constant>*)
1047 typedef detail::application_operator<Signature, Constant, detail::null_type> op_t;
1049 int arity = detail::calc_arity<Signature::arity>::apply(Signature(), static_cast<detail::null_type*>(0));
1051 #ifndef LUABIND_NO_ERROR_CHECKING
1052 add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, &detail::get_signature<Signature>::apply, arity + 1);
1053 #else
1054 add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, arity + 1);
1055 #endif
1057 return *this;
1060 template<class Signature, bool Constant, class Policies>
1061 class_& def(detail::application_operator<Signature, Constant>*, const Policies& policies)
1063 typedef detail::application_operator<Signature, Constant, Policies> op_t;
1065 int arity = detail::calc_arity<Signature::arity>::apply(Signature(), static_cast<Policies*>(0));
1067 #ifndef LUABIND_NO_ERROR_CHECKING
1068 add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, &detail::get_signature<Signature>::apply, arity + 1);
1069 #else
1070 add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, arity + 1);
1071 #endif
1073 return *this;
1076 detail::enum_maker<self_t> enum_(const char*)
1078 return detail::enum_maker<self_t>(*this);
1081 private:
1083 void init()
1085 typedef typename detail::extract_parameter<
1086 boost::mpl::vector3<X1,X2,X3>
1087 , boost::mpl::or_<
1088 detail::is_bases<boost::mpl::_>
1089 , boost::is_base_and_derived<boost::mpl::_, T>
1091 , no_bases
1092 >::type bases_t;
1094 typedef typename
1095 boost::mpl::if_<detail::is_bases<bases_t>
1096 , bases_t
1097 , bases<bases_t>
1098 >::type Base;
1100 set_type(LUABIND_TYPEID(T));
1101 set_held_type(detail::internal_held_type<HeldType>::apply());
1102 set_extractor(detail::internal_held_type_extractor<HeldType>::apply(detail::type<T>()));
1103 set_destructor(detail::destructor_s<T>::apply);
1105 generate_baseclass_list(detail::type<Base>());
1108 template<class Getter, class GetPolicies>
1109 class_& property_impl(const char* name,
1110 Getter g,
1111 GetPolicies policies,
1112 boost::mpl::bool_<true>)
1114 add_getter(name, boost::bind<int>(detail::get_caller<T,Getter,GetPolicies>(policies), _1, _2, g));
1115 return *this;
1118 template<class Getter, class Setter>
1119 class_& property_impl(const char* name,
1120 Getter g,
1121 Setter s,
1122 boost::mpl::bool_<false>)
1124 add_getter(name, boost::bind<int>(detail::get_caller<T,Getter,detail::null_type>(), _1, _2, g));
1125 add_setter(name, boost::bind<int>(detail::set_caller<T,Setter,detail::null_type>(), _1, _2, s));
1126 return *this;
1132 #endif // LUABIND_CLASS_HPP_INCLUDED