fixed correct function overloading with scopes.
[luabind.git] / luabind / class.hpp
blob29b4ba039b91ac83ceb3d3b31740dc3206a2b892
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 ------------------------------------------------------
31 * solved for member functions, not application operator *
32 if we have a base class that defines a function a derived class must be able to
33 override that function (not just overload). Right now we just add the other overload
34 to the overloads list and will probably get an ambiguity. If we want to support this
35 each method_rep must include a vector of type_info pointers for each parameter.
36 Operators do not have this problem, since operators always have to have
37 it's own type as one of the arguments, no ambiguity can occur. Application
38 operator, on the other hand, would have this problem.
39 Properties cannot be overloaded, so they should always be overridden.
40 If this is to work for application operator, we really need to specify if an application
41 operator is const or not.
43 If one class registers two functions with the same name and the same
44 signature, there's currently no error. The last registered function will
45 be the one that's used.
46 How do we know which class registered the function? If the function was
47 defined by the base class, it is a legal operation, to override it.
48 we cannot look at the pointer offset, since it always will be zero for one of the bases.
52 TODO:
53 ------------------------------------------------------
55 scopes
56 classes with the same name in different scopes will have the same name.
58 finish smart pointer support
59 * holder_type<const A> should be constructed as it's correct class, not constructed
60 as holder_type<A> and then reinterpret_casted. We will need another constructor
61 function and another extractor function.
62 * the adopt policy should not be able to adopt pointers to held_types. This
63 must be prohibited.
64 * name_of_type must recognize holder_types and not return "custom"
66 document the new yield-policy
68 chache operators and finalizers in the class_rep. For lua classes
69 we currently do a lookup each time we need to know if a lua class
70 has a finalizer or an operator.
72 static functions, this could be implemented by letting classes contain
73 other declarations (classes or functions)
75 document custom policies, custom converters
77 store the instance object for policies.
79 support the __concat metamethod. This is a bit tricky, since it cannot be
80 treated as a normal operator. It is a binary operator but we want to use the
81 __tostring implementation for both arguments.
85 #include <luabind/config.hpp>
87 #include <string>
88 #include <map>
89 #include <vector>
90 #include <cassert>
92 #include <boost/static_assert.hpp>
93 #include <boost/type_traits.hpp>
94 #include <boost/bind.hpp>
95 #include <boost/function.hpp>
96 #include <boost/preprocessor/repetition/enum_params.hpp>
97 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
98 #include <boost/preprocessor/repetition/repeat.hpp>
99 #include <boost/type_traits/is_same.hpp>
100 #include <boost/mpl/list.hpp>
101 #include <boost/mpl/apply.hpp>
102 #include <boost/mpl/lambda.hpp>
103 #include <boost/mpl/logical.hpp>
104 #include <boost/mpl/find_if.hpp>
105 #include <boost/mpl/apply_if.hpp>
106 #include <boost/mpl/logical.hpp>
108 #include <luabind/config.hpp>
109 #include <luabind/scope.hpp>
110 #include <luabind/detail/constructor.hpp>
111 #include <luabind/detail/call.hpp>
112 #include <luabind/detail/signature_match.hpp>
113 #include <luabind/detail/primitives.hpp>
114 #include <luabind/detail/property.hpp>
115 #include <luabind/detail/typetraits.hpp>
116 #include <luabind/detail/class_rep.hpp>
117 #include <luabind/detail/method_rep.hpp>
118 #include <luabind/detail/construct_rep.hpp>
119 #include <luabind/detail/object_rep.hpp>
120 #include <luabind/detail/operators.hpp>
121 #include <luabind/detail/calc_arity.hpp>
122 #include <luabind/detail/call_member.hpp>
123 #include <luabind/detail/enum_maker.hpp>
124 #include <luabind/detail/get_signature.hpp>
125 #include <luabind/detail/implicit_cast.hpp>
126 #include <luabind/detail/operator_id.hpp>
128 namespace luabind
130 namespace detail
132 struct unspecified {};
135 using detail::type;
137 template<class T, class X1 = detail::unspecified, class X2 = detail::unspecified, class X3 = detail::unspecified>
138 struct class_;
140 inline type<detail::null_type> get_const_holder(...)
142 return type<detail::null_type>();
145 namespace detail
147 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class A)>
148 double is_bases_helper(const bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, A)>&);
150 #ifndef BOOST_MSVC
151 template<class T>
152 char is_bases_helper(const T&);
153 #else
154 char is_bases_helper(...);
155 #endif
157 template<class T>
158 struct is_bases
160 static const T& t;
162 BOOST_STATIC_CONSTANT(bool, value = sizeof(is_bases_helper(t)) == sizeof(double));
163 typedef boost::mpl::bool_<value> type;
164 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_bases,(T))
167 double is_not_unspecified_helper(const unspecified*);
168 char is_not_unspecified_helper(...);
170 template<class T>
171 struct is_not_unspecified
173 BOOST_STATIC_CONSTANT(bool, value = sizeof(is_not_unspecified_helper(static_cast<T*>(0))) == sizeof(char));
174 typedef boost::mpl::bool_<value> type;
175 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_not_unspecified,(T))
178 template<class Predicate>
179 struct get_predicate
181 typedef typename boost::mpl::and_<
182 Predicate
183 , is_not_unspecified<boost::mpl::_1>
184 > type;
187 template<class Parameters, class Predicate, class DefaultValue>
188 struct extract_parameter
190 typedef typename get_predicate<Predicate>::type pred;
191 typedef typename boost::mpl::find_if<Parameters, pred>::type iterator;
192 typedef typename boost::mpl::apply_if<boost::is_same<iterator, typename boost::mpl::end<Parameters>::type>
193 , boost::mpl::identity<DefaultValue>
194 , iterator
195 >::type type;
198 int function_dispatcher(lua_State* L);
200 // this should know about the smart pointer type.
201 // and should really do:
202 // get_pointer(*static_cast<SmartPointer*>(obj_ptr))
203 // to extract the held pointer.
204 template<class HeldType, class T, class F, class Policies>
205 struct function_callback_non_null : Policies
207 function_callback_non_null(F f_): f(f_) {}
208 inline int operator()(lua_State* L, void* obj_ptr)
210 HeldType& held_obj = *static_cast<HeldType*>(obj_ptr);
212 T* ptr = static_cast<T*>(luabind::get_pointer(held_obj));
214 return call(f, ptr, L, static_cast<Policies*>(this));
216 F f;
219 template<class T, class F, class Policies>
220 struct function_callback_null_type : Policies
222 function_callback_null_type(F f_): f(f_) {}
223 inline int operator()(lua_State* L, void* obj_ptr)
225 // std::cout << "HeldType: null_type\n";
226 T* ptr = static_cast<T*>(obj_ptr);
227 return call(f, ptr, L, static_cast<Policies*>(this));
229 F f;
232 template<class HeldType, class T, class F, class Policies>
233 struct function_callback_s
235 typedef typename
236 boost::mpl::if_<boost::is_same<HeldType,detail::null_type>
237 , function_callback_null_type<T,F,Policies>
238 , function_callback_non_null<HeldType,T,F,Policies>
239 >::type type;
242 template<class T, class F, class Policies>
243 struct match_function_callback_s
245 static inline int apply(lua_State* L)
247 object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, 1));
248 F fptr = 0;
249 return match(fptr, L, obj->flags() & object_rep::constant, static_cast<Policies*>(0));
253 // prints the types of the values on the stack, in the
254 // range [start_index, lua_gettop()]
256 std::string stack_content_by_name(lua_State* L, int start_index);
258 struct create_class
260 static int stage1(lua_State* L);
261 static int stage2(lua_State* L);
264 template<class Type>
265 struct register_wrapped_type
267 template<class Signature, class Policies>
268 static void apply(detail::construct_rep::overload_t& o, const Signature*, const Policies*)
270 o.set_wrapped_constructor(
271 &detail::construct_wrapped_class<Type, Policies, Signature>::apply
276 template<>
277 struct register_wrapped_type<detail::null_type>
279 template<class Signature, class Policies>
280 static void apply(detail::construct_rep::overload_t&, const Signature*, const Policies*) {}
284 // if the class is held by a smart pointer, we need to be able to
285 // implicitly dereference the pointer when needed.
287 template<class UnderlyingT, class HeldT>
288 struct extract_underlying_type
290 static void* extract(void* ptr)
292 HeldT& held_obj = *reinterpret_cast<HeldT*>(ptr);
293 UnderlyingT* underlying_ptr = static_cast<UnderlyingT*>(get_pointer(held_obj));
294 return underlying_ptr;
299 template<class HeldType>
300 struct internal_held_type_extractor
302 typedef void*(*extractor_fun)(void*);
304 template<class T>
305 static extractor_fun apply(detail::type<T>)
307 return detail::extract_underlying_type<T, HeldType>::extract;
311 template<>
312 struct internal_held_type_extractor<detail::null_type>
314 typedef void*(*extractor_fun)(void*);
316 template<class T>
317 static extractor_fun apply(detail::type<T>)
319 return 0;
324 // this is simply a selector that returns the type_info
325 // of the held type, or invalid_type_info if we don't have
326 // a held_type
327 template<class HeldType>
328 struct internal_held_type
330 static LUABIND_TYPE_INFO apply()
332 return LUABIND_TYPEID(HeldType);
336 template<>
337 struct internal_held_type<detail::null_type>
339 static LUABIND_TYPE_INFO apply()
341 return LUABIND_INVALID_TYPE_INFO;
346 // this is the actual held_type constructor
347 template<class HeldType, class T>
348 struct internal_construct_held_type
350 static void apply(void* target, void* raw_pointer)
352 new(target) HeldType(static_cast<T*>(raw_pointer));
356 // the followinf two functions are the ones that returns
357 // a pointer to a held_type_constructor, or 0 if there
358 // is no held_type
359 template<class HeldType>
360 struct internal_held_type_constructor
362 typedef void(*constructor)(void*,void*);
363 template<class T>
364 static constructor apply(detail::type<T>)
366 return &internal_construct_held_type<HeldType, T>::apply;
370 template<>
371 struct internal_held_type_constructor<detail::null_type>
373 typedef void(*constructor)(void*,void*);
374 template<class T>
375 static constructor apply(detail::type<T>)
377 return 0;
382 // this is a selector that returns the size of the held_type
383 // or 0 if we don't have a held_type
384 template <class HeldType>
385 struct internal_held_type_size
387 static int apply() { return sizeof(HeldType); }
390 template <>
391 struct internal_held_type_size<detail::null_type>
393 static int apply() { return 0; }
397 // if we have a held type, return the destructor to it
398 // note the difference. The held_type should only be destructed (not deleted)
399 // since it's constructed in the lua userdata
400 template<class HeldType>
401 struct internal_held_type_destructor
403 typedef void(*destructor_t)(void*);
404 template<class T>
405 static destructor_t apply(detail::type<T>)
407 return &detail::destruct_only_s<HeldType>::apply;
411 // if we don't have a held type, return the destructor of the raw type
412 template<>
413 struct internal_held_type_destructor<detail::null_type>
415 typedef void(*destructor_t)(void*);
416 template<class T>
417 static destructor_t apply(detail::type<T>)
419 return &detail::delete_s<T>::apply;
423 template<class T>
424 struct get_holder_alignment
426 static int apply()
428 return boost::alignment_of<T>::value;
432 template<>
433 struct get_holder_alignment<detail::null_type>
435 static int apply()
437 return 0;
442 } // detail
457 struct class_base: detail::scoped_object
459 protected:
461 struct base_desc
463 LUABIND_TYPE_INFO type;
464 int ptr_offset;
467 private:
469 #ifndef NDEBUG
470 bool m_cloned;
471 #endif
473 const char* m_name;
475 std::map<const char*, detail::method_rep, detail::ltstr> m_methods;
477 // datamembers, some members may be readonly, and
478 // only have a getter function
479 std::map<const char*, detail::class_rep::callback, detail::ltstr> m_getters;
480 std::map<const char*, detail::class_rep::callback, detail::ltstr> m_setters;
482 // the operators in lua
483 std::vector<detail::class_rep::operator_callback> m_operators[detail::number_of_operators];
484 std::map<const char*, int, detail::ltstr> m_static_constants;
486 std::vector<base_desc> m_bases;
487 detail::construct_rep m_constructor;
489 void(*m_destructor)(void*);
490 void*(*m_extractor)(void*);
491 void(*m_construct_held_type)(void*, void*);
492 int m_held_type_size;
493 int m_held_type_alignment;
495 LUABIND_TYPE_INFO m_type;
496 LUABIND_TYPE_INFO m_held_type;
497 LUABIND_TYPE_INFO m_const_holder_type;
499 #ifndef LUABIND_DONT_COPY_STRINGS
500 // the maps that contains char pointers points into
501 // this vector of strings.
502 std::vector<char*> m_strings;
503 #endif
505 public:
507 // public 'cause of enum_maker, FIX
508 void add_static_constant(const char* name, int val)
510 m_static_constants[name] = val;
513 protected:
515 void set_type(LUABIND_TYPE_INFO t) { m_type = t; }
516 void set_held_type(LUABIND_TYPE_INFO t) { m_held_type = t; }
518 template<class T>
519 void set_const_holder_type(type<T>)
521 m_const_holder_type = LUABIND_TYPEID(T);
524 void set_extractor(void*(*f)(void*)) { m_extractor = f; }
525 void set_held_type_constructor(void(*f)(void*,void*)) { m_construct_held_type = f; }
526 void set_destructor(void(*f)(void*)) { m_destructor = f; }
527 void set_held_type_size(int s) { m_held_type_size = s; }
528 void set_held_type_alignment(int n) { m_held_type_alignment = n; }
530 inline void add_getter(const char* name, const boost::function2<int, lua_State*, int>& g)
532 detail::class_rep::callback c;
533 c.func = g;
534 c.pointer_offset = 0;
535 #ifndef LUABIND_DONT_COPY_STRINGS
536 m_strings.push_back(detail::dup_string(name));
537 m_getters[m_strings.back()] = c;
538 #else
539 m_getters[name] = c;
540 #endif
543 inline void add_setter(const char* name, const boost::function2<int, lua_State*, int>& s)
545 detail::class_rep::callback c;
546 c.func = s;
547 c.pointer_offset = 0;
548 #ifndef LUABIND_DONT_COPY_STRINGS
549 m_strings.push_back(detail::dup_string(name));
550 m_setters[m_strings.back()] = c;
551 #else
552 m_setters[name] = c;
553 #endif
556 void add_base(const base_desc& b)
558 m_bases.push_back(b);
561 public:
563 void add_constructor(const detail::construct_rep::overload_t& o)
565 m_constructor.overloads.push_back(o);
568 void add_method(const char* name, const detail::overload_rep& o)
570 #ifdef LUABIND_DONT_COPY_STRINGS
571 detail::method_rep& method = m_methods[name];
572 method.name = name;
573 #else
574 m_strings.push_back(detail::dup_string(name));
575 detail::method_rep& method = m_methods[m_strings.back()];
576 method.name = m_strings.back();
577 #endif
578 method.add_overload(o);
579 method.crep = 0;
582 #ifndef LUABIND_NO_ERROR_CHECKING
583 inline void add_operator(int op_id, int(*func)(lua_State*), int(*matcher)(lua_State*), void(*sig)(lua_State*, std::string&), int arity)
584 #else
585 inline void add_operator(int op_id, int(*func)(lua_State*), int(*matcher)(lua_State*), int arity)
586 #endif
588 detail::class_rep::operator_callback o;
589 o.set_fun(func);
590 o.set_match_fun(matcher);
591 o.set_arity(arity);
593 #ifndef LUABIND_NO_ERROR_CHECKING
595 o.set_sig_fun(sig);
597 #endif
598 m_operators[op_id].push_back(o);
607 const char* name() const { return m_name; }
609 class_base(const char* name)
611 #ifndef LUABIND_DONT_COPY_STRINGS
612 m_strings.push_back(detail::dup_string(name));
613 m_name = m_strings.back();
614 #else
615 m_name = name;
616 #endif
618 #ifndef NDEBUG
619 m_cloned = false;
620 #endif
623 virtual ~class_base()
625 // if we are copying strings, we have to destroy them too
626 #ifndef LUABIND_DONT_COPY_STRINGS
627 for (std::vector<char*>::iterator i = m_strings.begin(); i != m_strings.end(); ++i)
628 delete[] *i;
629 #endif
632 // pushes the class_rep on the lua stack
633 virtual void commit(lua_State* L)
635 assert(!m_cloned && "class already commited");
637 detail::getref(L, scope_stack::top(L));
638 lua_pushstring(L, m_name);
640 detail::class_rep* crep;
642 detail::class_registry* r = detail::class_registry::get_registry(L);
643 // create a class_rep structure for this class.
644 // allocate it within lua to let lua collect it on
645 // lua_close(). This is better than allocating it
646 // as a static, since it will then be destructed
647 // when the program exits instead.
648 // warning: we assume that lua will not
649 // move the userdata memory.
650 lua_newuserdata(L, sizeof(detail::class_rep));
651 crep = reinterpret_cast<detail::class_rep*>(lua_touserdata(L, -1));
653 new(crep) detail::class_rep(m_type, m_name, L, m_destructor, m_held_type, m_const_holder_type, m_extractor, m_construct_held_type, m_held_type_size, m_held_type_alignment);
655 // register this new type in the class registry
656 r->add_class(m_type, crep);
657 if (!(LUABIND_TYPE_INFO_EQUAL(m_held_type, LUABIND_INVALID_TYPE_INFO)))
659 // if we have a held type
660 // we have to register it in the class-table
661 // but only for the base class, if it already
662 // exists, we don't have to register it
663 detail::class_rep* c = r->find_class(m_held_type);
664 if (c == 0)
666 r->add_class(m_held_type, crep);
667 r->add_class(m_const_holder_type, crep);
671 // add methods
672 for (std::map<const char*, detail::method_rep, detail::ltstr>::iterator i = m_methods.begin();
673 i != m_methods.end();
674 ++i)
676 i->second.crep = crep;
678 std::swap(crep->m_methods, m_methods);
680 // constructors
681 m_constructor.swap(crep->m_constructor);
683 #ifndef LUABIND_DONT_COPY_STRINGS
684 assert(crep->m_strings.empty() && "Internal error");
685 std::swap(crep->m_strings, m_strings);
686 #endif
688 std::swap(crep->m_getters, m_getters);
689 std::swap(crep->m_setters, m_setters);
691 for(int i = 0; i < detail::number_of_operators; ++i)
692 std::swap(crep->m_operators[i], m_operators[i]);
694 std::swap(crep->m_static_constants, m_static_constants);
696 for (std::vector<base_desc>::iterator i = m_bases.begin();
697 i != m_bases.end();
698 ++i)
700 detail::class_registry* r = detail::class_registry::get_registry(L);
702 // the baseclass' class_rep structure
703 detail::class_rep* bcrep = r->find_class(i->type);
705 detail::class_rep::base_info base;
706 base.pointer_offset = i->ptr_offset;
707 base.base = bcrep;
709 crep->add_base_class(base);
712 lua_settable(L, -3);
713 lua_pop(L, 1);
717 // destructive copy
718 virtual luabind::detail::scoped_object* clone()
720 assert(m_cloned == false);
722 #ifndef NDEBUG
723 m_cloned = true;
724 #endif
726 class_base* ret = new class_base(m_name);
728 std::swap(ret->m_getters, m_getters);
729 std::swap(ret->m_setters, m_setters);
731 for(int i = 0; i < detail::number_of_operators; ++i)
732 std::swap(ret->m_operators[i], m_operators[i]);
734 std::swap(ret->m_static_constants, m_static_constants);
735 ret->m_destructor = m_destructor;
736 ret->m_extractor = m_extractor;
737 ret->m_construct_held_type = m_construct_held_type;
738 ret->m_held_type_size = m_held_type_size;
739 ret->m_held_type_alignment = m_held_type_alignment;
741 std::swap(ret->m_bases, m_bases);
742 std::swap(ret->m_methods, m_methods);
743 m_constructor.swap(ret->m_constructor);
745 ret->m_name = m_name;
747 ret->m_type = m_type;
748 ret->m_held_type = m_held_type;
749 ret->m_const_holder_type = m_const_holder_type;
751 #ifndef LUABIND_DONT_COPY_STRINGS
752 std::swap(ret->m_strings, m_strings);
753 #endif
755 return ret;
770 // registers a class in the lua environment
771 template<class T, class X1, class X2, class X3>
772 struct class_: class_base
774 typedef class_<T, X1, X2, X3> self_t;
776 lua_State* m_L;
778 private:
780 template<class A, class B, class C, class D>
781 class_(const class_<A,B,C,D>&);
783 public:
785 // WrappedType MUST inherit from T
786 typedef typename detail::extract_parameter<
787 boost::mpl::vector3<X1,X2,X3>
788 , boost::is_base_and_derived<T, boost::mpl::_>
789 /* , boost::mpl::not_<
790 boost::mpl::or_<
791 detail::is_bases<boost::mpl::_>
792 , boost::is_base_and_derived<boost::mpl::_, T>
795 , detail::null_type
796 >::type WrappedType;
798 typedef typename detail::extract_parameter<
799 boost::mpl::list3<X1,X2,X3>
800 , boost::mpl::not_<
801 boost::mpl::or_<
802 boost::mpl::or_<
803 detail::is_bases<boost::mpl::_>
804 , boost::is_base_and_derived<boost::mpl::_, T>
806 , boost::is_base_and_derived<T, boost::mpl::_>
809 , detail::null_type
810 >::type HeldType;
812 // this function generates conversion information
813 // in the given class_rep structure. It will be able
814 // to implicitly cast to the given template type
815 template<class To>
816 void gen_base_info(detail::type<To>)
818 // fist, make sure the given base class is registered.
819 // if it's not registered we can't push it's lua table onto
820 // the stack because it doesn't have a table
822 // try to cast this type to the base type and remember
823 // the pointer offset. For multiple inheritance the pointer
824 // may change when casting. Since we need to be able to
825 // cast we need this pointer offset.
826 // store the information in this class' base class-vector
827 base_desc base;
828 base.type = LUABIND_TYPEID(To);
829 base.ptr_offset = detail::ptr_offset(detail::type<T>(), detail::type<To>());
830 add_base(base);
833 void gen_base_info(detail::type<detail::null_type>)
836 #define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type<B##n>());
838 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class B)>
839 void generate_baseclass_list(detail::type<bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, B)> >)
841 BOOST_PP_REPEAT(LUABIND_MAX_BASES, LUABIND_GEN_BASE_INFO, _)
844 #undef LUABIND_GEN_BASE_INFO
846 // this is the internal version of def() it is run from both overloads
847 // of def. It has two versions, one where a contstructor is registered
848 // and one where a function is registered
849 template<class Policies>
850 struct internal_def_s
852 template<class F>
853 static void apply(const char* name, F f, class_base* c)
855 // std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";
857 detail::overload_rep o(f, static_cast<Policies*>(0));
859 typedef LUABIND_MSVC_TYPENAME detail::function_callback_s<HeldType,T,F,Policies>::type call_t;
861 o.set_match_fun(&detail::match_function_callback_s<T,F,Policies>::apply);
862 o.call_fun = boost::bind<int>(call_t(f), _1, _2);
864 #ifndef LUABIND_NO_ERROR_CHECKING
866 o.set_sig_fun(&detail::get_member_signature<F>::apply);
868 #endif
870 c->add_method(name, o);
873 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)>
874 static void apply(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>, class_base* c)
876 // std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";
878 detail::construct_rep::overload_t o;
880 o.set_constructor(
881 &detail::construct_class<
883 ,Policies
884 ,constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>
885 >::apply
888 // if we have a WrappedType, we have to register it's constructor
889 // but if it's null_type (no WrappedType) we should not register it
890 detail::register_wrapped_type<WrappedType>::apply(o,
891 static_cast<const constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>*>(0),
892 static_cast<const Policies*>(0));
895 o.set_match_fun(
896 &detail::constructor_match<
897 constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>
899 ,Policies
900 >::apply);
902 #ifndef LUABIND_NO_ERROR_CHECKING
904 o.set_sig_fun(&detail::get_signature<constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> >::apply);
906 #endif
908 typedef constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> con_t;
910 o.set_arity(detail::calc_arity<con_t::arity>::apply(con_t(), static_cast<Policies*>(0)));
912 c->add_constructor(o);
916 class_(lua_State* L, const char* name): class_base(name), m_L(L) { init(); }
917 class_(const char* name): class_base(name), m_L(0) { init(); }
919 ~class_()
921 if (m_L != 0)
923 scope::init(m_L);
924 lua_pushvalue(m_L, LUA_GLOBALSINDEX);
925 scope_stack::push(m_L);
926 commit(m_L);
927 scope_stack::pop(m_L);
931 template<class F>
932 class_& def(const char* name, F f)
934 internal_def_s<detail::null_type>::apply(name, f, this);
935 return *this;
938 template<class F, class Policies>
939 class_& def(const char* name, F f, const Policies&)
941 internal_def_s<Policies>::apply(name, f, this);
942 return *this;
945 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)>
946 class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig)
948 internal_def_s<detail::null_type>::apply(sig, this);
949 return *this;
952 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A), class Policies>
953 class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig, const Policies& policies)
955 internal_def_s<Policies>::apply(sig, this);
956 return *this;
959 template<class Getter>
960 class_& property(const char* name, Getter g)
962 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, detail::null_type>(), _1, _2, g));
963 return *this;
966 template<class Getter, class MaybeSetter>
967 class_& property(const char* name, Getter g, MaybeSetter s)
969 return property_impl(name, g, s, boost::mpl::bool_<detail::is_policy_cons<MaybeSetter>::value>());
972 template<class Getter, class Setter, class GetPolicies>
973 class_& property(const char* name, Getter g, Setter s, const GetPolicies& get_policies)
975 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, GetPolicies>(get_policies), _1, _2, g));
976 add_setter(name, boost::bind<int>(detail::set_caller<T, Setter, detail::null_type>(), _1, _2, s));
977 return *this;
980 template<class Getter, class Setter, class GetPolicies, class SetPolicies>
981 class_& property(const char* name
982 , Getter g, Setter s
983 , const GetPolicies& get_policies
984 , const SetPolicies& set_policies)
986 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, GetPolicies>(get_policies), _1, _2, g));
987 add_setter(name, boost::bind<int>(detail::set_caller<T, Setter, GetPolicies>(set_policies), _1, _2, s));
988 return *this;
991 template<class D>
992 class_& def_readonly(const char* name, D T::*member_ptr)
994 add_getter(name, boost::bind<int>(detail::auto_get<T,D,detail::null_type>(), _1, _2, member_ptr));
995 return *this;
998 template<class D, class Policies>
999 class_& def_readonly(const char* name, D T::*member_ptr, const Policies& policies)
1001 add_getter(name, boost::bind<int>(detail::auto_get<T,D,Policies>(policies), _1, _2, member_ptr));
1002 return *this;
1005 template<class D>
1006 class_& def_readwrite(const char* name, D T::*member_ptr)
1008 add_getter(name, boost::bind<int>(detail::auto_get<T,D,detail::null_type>(), _1, _2, member_ptr));
1009 add_setter(name, boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr));
1010 return *this;
1013 template<class D, class GetPolicies>
1014 class_& def_readwrite(const char* name, D T::*member_ptr, const GetPolicies& get_policies)
1016 add_getter(name, boost::bind<int>(detail::auto_get<T,D,GetPolicies>(get_policies), _1, _2, member_ptr));
1017 add_setter(name, boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr));
1018 return *this;
1021 template<class D, class GetPolicies, class SetPolicies>
1022 class_& def_readwrite(const char* name, D T::*member_ptr, const GetPolicies& get_policies, const SetPolicies& set_policies)
1024 add_getter(name, boost::bind<int>(detail::auto_get<T,D,GetPolicies>(get_policies), _1, _2, member_ptr));
1025 add_setter(name, boost::bind<int>(detail::auto_set<T,D,SetPolicies>(set_policies), _1, _2, member_ptr));
1026 return *this;
1029 template<class op_id, class Left, class Right, class Policies>
1030 class_& def(detail::operator_<op_id, Left, Right>, const Policies& policies)
1032 typedef typename detail::operator_unwrapper<Policies, op_id, T, Left, Right> op_type;
1033 #ifndef LUABIND_NO_ERROR_CHECKING
1034 add_operator(op_type::get_id()
1035 , &op_type::execute
1036 , &op_type::match
1037 , &detail::get_signature<constructor<typename op_type::left_t, typename op_type::right_t> >::apply
1038 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1039 #else
1040 add_operator(op_type::get_id()
1041 , &op_type::execute
1042 , &op_type::match
1043 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1044 #endif
1045 return *this;
1048 template<class op_id, class Left, class Right>
1049 class_& def(detail::operator_<op_id, Left, Right>)
1051 typedef typename detail::operator_unwrapper<detail::null_type, op_id, T, Left, Right> op_type;
1053 #ifndef LUABIND_NO_ERROR_CHECKING
1054 add_operator(op_type::get_id()
1055 , &op_type::execute
1056 , &op_type::match
1057 , &detail::get_signature<constructor<LUABIND_MSVC_TYPENAME op_type::left_t, LUABIND_MSVC_TYPENAME op_type::right_t> >::apply
1058 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1059 #else
1060 add_operator(op_type::get_id()
1061 , &op_type::execute
1062 , &op_type::match
1063 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1064 #endif
1065 return *this;
1068 template<class Signature, bool Constant>
1069 class_& def(detail::application_operator<Signature, Constant>*)
1071 typedef detail::application_operator<Signature, Constant, detail::null_type> op_t;
1073 int arity = detail::calc_arity<Signature::arity>::apply(Signature(), static_cast<detail::null_type*>(0));
1075 #ifndef LUABIND_NO_ERROR_CHECKING
1076 add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, &detail::get_signature<Signature>::apply, arity + 1);
1077 #else
1078 add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, arity + 1);
1079 #endif
1081 return *this;
1084 template<class Signature, bool Constant, class Policies>
1085 class_& def(detail::application_operator<Signature, Constant>*, const Policies& policies)
1087 typedef detail::application_operator<Signature, Constant, Policies> op_t;
1089 int arity = detail::calc_arity<Signature::arity>::apply(Signature(), static_cast<Policies*>(0));
1091 #ifndef LUABIND_NO_ERROR_CHECKING
1092 add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, &detail::get_signature<Signature>::apply, arity + 1);
1093 #else
1094 add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, arity + 1);
1095 #endif
1097 return *this;
1100 detail::enum_maker<self_t> enum_(const char*)
1102 return detail::enum_maker<self_t>(*this);
1105 private:
1107 void init()
1109 typedef typename detail::extract_parameter<
1110 boost::mpl::list3<X1,X2,X3>
1111 , boost::mpl::or_<
1112 detail::is_bases<boost::mpl::_>
1113 , boost::is_base_and_derived<boost::mpl::_, T>
1115 , no_bases
1116 >::type bases_t;
1118 typedef typename
1119 boost::mpl::if_<detail::is_bases<bases_t>
1120 , bases_t
1121 , bases<bases_t>
1122 >::type Base;
1124 set_type(LUABIND_TYPEID(T));
1125 set_held_type(detail::internal_held_type<HeldType>::apply());
1126 set_const_holder_type(get_const_holder(detail::type<HeldType>()));
1127 set_extractor(detail::internal_held_type_extractor<HeldType>::apply(detail::type<T>()));
1128 set_held_type_constructor(detail::internal_held_type_constructor<HeldType>::apply(detail::type<T>()));
1129 set_held_type_size(detail::internal_held_type_size<HeldType>::apply());
1130 set_destructor(detail::internal_held_type_destructor<HeldType>::apply(detail::type<T>()));
1132 set_held_type_alignment(detail::get_holder_alignment<HeldType>::apply());
1134 generate_baseclass_list(detail::type<Base>());
1137 template<class Getter, class GetPolicies>
1138 class_& property_impl(const char* name,
1139 Getter g,
1140 GetPolicies policies,
1141 boost::mpl::bool_<true>)
1143 add_getter(name, boost::bind<int>(detail::get_caller<T,Getter,GetPolicies>(policies), _1, _2, g));
1144 return *this;
1147 template<class Getter, class Setter>
1148 class_& property_impl(const char* name,
1149 Getter g,
1150 Setter s,
1151 boost::mpl::bool_<false>)
1153 add_getter(name, boost::bind<int>(detail::get_caller<T,Getter,detail::null_type>(), _1, _2, g));
1154 add_setter(name, boost::bind<int>(detail::set_caller<T,Setter,detail::null_type>(), _1, _2, s));
1155 return *this;
1161 #endif // LUABIND_CLASS_HPP_INCLUDED