Fix destruction of derived Lua classes.
[luabind.git] / luabind / class.hpp
blob844cface8fef911ef78f8c772ecedf31e0352908
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 finish smart pointer support
56 * the adopt policy should not be able to adopt pointers to held_types. This
57 must be prohibited.
58 * name_of_type must recognize holder_types and not return "custom"
60 document custom policies, custom converters
62 store the instance object for policies.
64 support the __concat metamethod. This is a bit tricky, since it cannot be
65 treated as a normal operator. It is a binary operator but we want to use the
66 __tostring implementation for both arguments.
70 #include <luabind/prefix.hpp>
71 #include <luabind/config.hpp>
73 #include <string>
74 #include <map>
75 #include <vector>
76 #include <cassert>
78 #include <boost/static_assert.hpp>
79 #include <boost/type_traits.hpp>
80 #include <boost/bind.hpp>
81 #include <boost/function.hpp>
82 #include <boost/preprocessor/repetition/enum_params.hpp>
83 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
84 #include <boost/preprocessor/repetition/repeat.hpp>
85 #include <boost/type_traits/is_same.hpp>
86 #include <boost/mpl/list.hpp>
87 #include <boost/mpl/apply.hpp>
88 #include <boost/mpl/lambda.hpp>
89 #include <boost/mpl/logical.hpp>
90 #include <boost/mpl/find_if.hpp>
91 #include <boost/mpl/eval_if.hpp>
92 #include <boost/mpl/logical.hpp>
94 #include <luabind/config.hpp>
95 #include <luabind/scope.hpp>
96 #include <luabind/raw_policy.hpp>
97 #include <luabind/back_reference.hpp>
98 #include <luabind/function.hpp>
99 #include <luabind/detail/constructor.hpp>
100 #include <luabind/detail/call.hpp>
101 #include <luabind/detail/deduce_signature.hpp>
102 #include <luabind/detail/compute_score.hpp>
103 #include <luabind/detail/primitives.hpp>
104 #include <luabind/detail/property.hpp>
105 #include <luabind/detail/typetraits.hpp>
106 #include <luabind/detail/class_rep.hpp>
107 #include <luabind/detail/call.hpp>
108 #include <luabind/detail/construct_rep.hpp>
109 #include <luabind/detail/object_rep.hpp>
110 #include <luabind/detail/calc_arity.hpp>
111 #include <luabind/detail/call_member.hpp>
112 #include <luabind/detail/enum_maker.hpp>
113 #include <luabind/detail/get_signature.hpp>
114 #include <luabind/detail/implicit_cast.hpp>
115 #include <luabind/detail/operator_id.hpp>
116 #include <luabind/detail/pointee_typeid.hpp>
117 #include <luabind/detail/link_compatibility.hpp>
119 // to remove the 'this' used in initialization list-warning
120 #ifdef _MSC_VER
121 #pragma warning(push)
122 #pragma warning(disable: 4355)
123 #endif
125 namespace boost
128 template <class T> class shared_ptr;
130 } // namespace boost
132 namespace luabind
134 namespace detail
136 struct unspecified {};
138 template<class Derived> struct operator_;
140 struct you_need_to_define_a_get_const_holder_function_for_your_smart_ptr {};
143 template<class T, class X1 = detail::unspecified, class X2 = detail::unspecified, class X3 = detail::unspecified>
144 struct class_;
146 // TODO: this function will only be invoked if the user hasn't defined a correct overload
147 // maybe we should have a static assert in here?
148 inline detail::you_need_to_define_a_get_const_holder_function_for_your_smart_ptr*
149 get_const_holder(...)
151 return 0;
154 template <class T>
155 boost::shared_ptr<T const>* get_const_holder(boost::shared_ptr<T>*)
157 return 0;
160 namespace detail
162 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class A)>
163 double is_bases_helper(const bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, A)>&);
165 #ifndef BOOST_MSVC
166 template<class T>
167 char is_bases_helper(const T&);
168 #else
169 char is_bases_helper(...);
170 #endif
172 template<class T>
173 struct is_bases
175 static const T& t;
177 BOOST_STATIC_CONSTANT(bool, value = sizeof(is_bases_helper(t)) == sizeof(double));
178 typedef boost::mpl::bool_<value> type;
179 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_bases,(T))
182 double is_not_unspecified_helper(const unspecified*);
183 char is_not_unspecified_helper(...);
185 template<class T>
186 struct is_not_unspecified
188 BOOST_STATIC_CONSTANT(bool, value = sizeof(is_not_unspecified_helper(static_cast<T*>(0))) == sizeof(char));
189 typedef boost::mpl::bool_<value> type;
190 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_not_unspecified,(T))
193 template<class Predicate>
194 struct get_predicate
196 typedef typename boost::mpl::and_<
197 is_not_unspecified<boost::mpl::_1>
198 , Predicate
199 > type;
202 template<class Parameters, class Predicate, class DefaultValue>
203 struct extract_parameter
205 typedef typename get_predicate<Predicate>::type pred;
206 typedef typename boost::mpl::find_if<Parameters, pred>::type iterator;
207 typedef typename boost::mpl::eval_if<
208 boost::is_same<
209 iterator
210 , typename boost::mpl::end<Parameters>::type
212 , boost::mpl::identity<DefaultValue>
213 , boost::mpl::deref<iterator>
214 >::type type;
217 template<class Fn, class Class, class Policies>
218 struct mem_fn_callback
220 typedef int result_type;
222 int operator()(lua_State* L) const
224 return invoke(L, fn, deduce_signature(fn, (Class*)0), Policies());
227 mem_fn_callback(Fn fn_)
228 : fn(fn_)
232 Fn fn;
235 template<class Fn, class Class, class Policies>
236 struct mem_fn_matcher
238 typedef int result_type;
240 int operator()(lua_State* L) const
242 return compute_score(L, deduce_signature(fn, (Class*)0), Policies());
245 mem_fn_matcher(Fn fn_)
246 : fn(fn_)
250 Fn fn;
253 struct pure_virtual_tag
255 static void precall(lua_State*, index_map const&) {}
256 static void postcall(lua_State*, index_map const&) {}
259 template<class Policies>
260 struct has_pure_virtual
262 typedef typename boost::mpl::eval_if<
263 boost::is_same<pure_virtual_tag, typename Policies::head>
264 , boost::mpl::true_
265 , has_pure_virtual<typename Policies::tail>
266 >::type type;
268 BOOST_STATIC_CONSTANT(bool, value = type::value);
271 template<>
272 struct has_pure_virtual<null_type>
274 BOOST_STATIC_CONSTANT(bool, value = false);
275 typedef boost::mpl::bool_<value> type;
278 // prints the types of the values on the stack, in the
279 // range [start_index, lua_gettop()]
281 LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index);
283 struct LUABIND_API create_class
285 static int stage1(lua_State* L);
286 static int stage2(lua_State* L);
289 // if the class is held by a smart pointer, we need to be able to
290 // implicitly dereference the pointer when needed.
292 template<class UnderlyingT, class HeldT>
293 struct extract_underlying_type
295 static void* extract(void* ptr)
297 HeldT& held_obj = *reinterpret_cast<HeldT*>(ptr);
298 UnderlyingT* underlying_ptr = static_cast<UnderlyingT*>(get_pointer(held_obj));
299 return underlying_ptr;
303 template<class UnderlyingT, class HeldT>
304 struct extract_underlying_const_type
306 static const void* extract(void* ptr)
308 HeldT& held_obj = *reinterpret_cast<HeldT*>(ptr);
309 const UnderlyingT* underlying_ptr = static_cast<const UnderlyingT*>(get_pointer(held_obj));
310 return underlying_ptr;
314 template<class HeldType>
315 struct internal_holder_extractor
317 typedef void*(*extractor_fun)(void*);
319 template<class T>
320 static extractor_fun apply(detail::type_<T>)
322 return &detail::extract_underlying_type<T, HeldType>::extract;
326 template<>
327 struct internal_holder_extractor<detail::null_type>
329 typedef void*(*extractor_fun)(void*);
331 template<class T>
332 static extractor_fun apply(detail::type_<T>)
334 return 0;
339 template<class HeldType, class ConstHolderType>
340 struct convert_holder
342 static void apply(void* holder, void* target)
344 new(target) ConstHolderType(*reinterpret_cast<HeldType*>(holder));
349 template<class HeldType>
350 struct const_converter
352 typedef void(*converter_fun)(void*, void*);
354 template<class ConstHolderType>
355 static converter_fun apply(ConstHolderType*)
357 return &detail::convert_holder<HeldType, ConstHolderType>::apply;
361 template<>
362 struct const_converter<detail::null_type>
364 typedef void(*converter_fun)(void*, void*);
366 template<class T>
367 static converter_fun apply(T*)
369 return 0;
376 template<class HeldType>
377 struct internal_const_holder_extractor
379 typedef const void*(*extractor_fun)(void*);
381 template<class T>
382 static extractor_fun apply(detail::type_<T>)
384 return get_extractor(detail::type_<T>(), get_const_holder(static_cast<HeldType*>(0)));
386 private:
387 template<class T, class ConstHolderType>
388 static extractor_fun get_extractor(detail::type_<T>, ConstHolderType*)
390 return &detail::extract_underlying_const_type<T, ConstHolderType>::extract;
394 template<>
395 struct internal_const_holder_extractor<detail::null_type>
397 typedef const void*(*extractor_fun)(void*);
399 template<class T>
400 static extractor_fun apply(detail::type_<T>)
402 return 0;
408 // this is simply a selector that returns the type_info
409 // of the held type, or invalid_type_info if we don't have
410 // a held_type
411 template<class HeldType>
412 struct internal_holder_type
414 static LUABIND_TYPE_INFO apply()
416 return LUABIND_TYPEID(HeldType);
420 template<>
421 struct internal_holder_type<detail::null_type>
423 static LUABIND_TYPE_INFO apply()
425 return LUABIND_INVALID_TYPE_INFO;
430 // this is the actual held_type constructor
431 template<class HeldType, class T>
432 struct internal_construct_holder
434 static void apply(void* target, void* raw_pointer)
436 new(target) HeldType(static_cast<T*>(raw_pointer));
440 // this is the actual held_type default constructor
441 template<class HeldType, class T>
442 struct internal_default_construct_holder
444 static void apply(void* target)
446 new(target) HeldType();
450 // the following two functions are the ones that returns
451 // a pointer to a held_type_constructor, or 0 if there
452 // is no held_type
453 template<class HeldType>
454 struct holder_constructor
456 typedef void(*constructor)(void*,void*);
457 template<class T>
458 static constructor apply(detail::type_<T>)
460 return &internal_construct_holder<HeldType, T>::apply;
464 template<>
465 struct holder_constructor<detail::null_type>
467 typedef void(*constructor)(void*,void*);
468 template<class T>
469 static constructor apply(detail::type_<T>)
471 return 0;
475 // the following two functions are the ones that returns
476 // a pointer to a const_held_type_constructor, or 0 if there
477 // is no held_type
478 template<class HolderType>
479 struct const_holder_constructor
481 typedef void(*constructor)(void*,void*);
482 template<class T>
483 static constructor apply(detail::type_<T>)
485 return get_const_holder_constructor(detail::type_<T>(), get_const_holder(static_cast<HolderType*>(0)));
488 private:
490 template<class T, class ConstHolderType>
491 static constructor get_const_holder_constructor(detail::type_<T>, ConstHolderType*)
493 return &internal_construct_holder<ConstHolderType, T>::apply;
497 template<>
498 struct const_holder_constructor<detail::null_type>
500 typedef void(*constructor)(void*,void*);
501 template<class T>
502 static constructor apply(detail::type_<T>)
504 return 0;
509 // the following two functions are the ones that returns
510 // a pointer to a held_type_constructor, or 0 if there
511 // is no held_type. The holder_type is default constructed
512 template<class HeldType>
513 struct holder_default_constructor
515 typedef void(*constructor)(void*);
516 template<class T>
517 static constructor apply(detail::type_<T>)
519 return &internal_default_construct_holder<HeldType, T>::apply;
523 template<>
524 struct holder_default_constructor<detail::null_type>
526 typedef void(*constructor)(void*);
527 template<class T>
528 static constructor apply(detail::type_<T>)
530 return 0;
535 // the following two functions are the ones that returns
536 // a pointer to a const_held_type_constructor, or 0 if there
537 // is no held_type. The constructed held_type is default
538 // constructed
539 template<class HolderType>
540 struct const_holder_default_constructor
542 typedef void(*constructor)(void*);
543 template<class T>
544 static constructor apply(detail::type_<T>)
546 return get_const_holder_default_constructor(detail::type_<T>(), get_const_holder(static_cast<HolderType*>(0)));
549 private:
551 template<class T, class ConstHolderType>
552 static constructor get_const_holder_default_constructor(detail::type_<T>, ConstHolderType*)
554 return &internal_default_construct_holder<ConstHolderType, T>::apply;
558 template<>
559 struct const_holder_default_constructor<detail::null_type>
561 typedef void(*constructor)(void*);
562 template<class T>
563 static constructor apply(detail::type_<T>)
565 return 0;
572 // this is a selector that returns the size of the held_type
573 // or 0 if we don't have a held_type
574 template <class HolderType>
575 struct internal_holder_size
577 static int apply() { return get_internal_holder_size(get_const_holder(static_cast<HolderType*>(0))); }
578 private:
579 template<class ConstHolderType>
580 static int get_internal_holder_size(ConstHolderType*)
582 return max_c<sizeof(HolderType), sizeof(ConstHolderType)>::value;
586 template <>
587 struct internal_holder_size<detail::null_type>
589 static int apply() { return 0; }
593 // if we have a held type, return the destructor to it
594 // note the difference. The held_type should only be destructed (not deleted)
595 // since it's constructed in the lua userdata
596 template<class HeldType>
597 struct internal_holder_destructor
599 typedef void(*destructor_t)(void*);
600 template<class T>
601 static destructor_t apply(detail::type_<T>)
603 return &detail::destruct_only_s<HeldType>::apply;
607 // if we don't have a held type, return the destructor of the raw type
608 template<>
609 struct internal_holder_destructor<detail::null_type>
611 typedef void(*destructor_t)(void*);
612 template<class T>
613 static destructor_t apply(detail::type_<T>)
615 return &detail::delete_s<T>::apply;
620 // if we have a held type, return the destructor to it's const version
621 template<class HolderType>
622 struct internal_const_holder_destructor
624 typedef void(*destructor_t)(void*);
625 template<class T>
626 static destructor_t apply(detail::type_<T>)
628 return const_holder_type_destructor(get_const_holder(static_cast<HolderType*>(0)));
631 private:
633 template<class ConstHolderType>
634 static destructor_t const_holder_type_destructor(ConstHolderType*)
636 return &detail::destruct_only_s<ConstHolderType>::apply;
641 // if we don't have a held type, return the destructor of the raw type
642 template<>
643 struct internal_const_holder_destructor<detail::null_type>
645 typedef void(*destructor_t)(void*);
646 template<class T>
647 static destructor_t apply(detail::type_<T>)
649 return 0;
656 template<class HolderType>
657 struct get_holder_alignment
659 static int apply()
661 return internal_alignment(get_const_holder(static_cast<HolderType*>(0)));
664 private:
666 template<class ConstHolderType>
667 static int internal_alignment(ConstHolderType*)
669 return detail::max_c<boost::alignment_of<HolderType>::value
670 , boost::alignment_of<ConstHolderType>::value>::value;
674 template<>
675 struct get_holder_alignment<detail::null_type>
677 static int apply()
679 return 1;
684 } // detail
686 namespace detail {
688 template<class T>
689 struct static_scope
691 static_scope(T& self_) : self(self_)
695 T& operator[](scope s) const
697 self.add_inner_scope(s);
698 return self;
701 private:
702 template<class U> void operator,(U const&) const;
703 void operator=(static_scope const&);
705 T& self;
708 struct class_registration;
710 struct LUABIND_API class_base : scope
712 public:
713 class_base(char const* name);
715 struct base_desc
717 LUABIND_TYPE_INFO type;
718 int ptr_offset;
721 void init(
722 LUABIND_TYPE_INFO type
723 , LUABIND_TYPE_INFO holder_type
724 , LUABIND_TYPE_INFO const_holder_type
725 , void*(*extractor)(void*)
726 , const void*(*const_extractor)(void*)
727 , void(*const_converter)(void*,void*)
728 , void(*holder_constructor)(void*,void*)
729 , void(*const_holder_constructor)(void*,void*)
730 , void(*holder_default_constructor)(void*)
731 , void(*const_holder_default_constructor)(void*)
732 , void(*adopt_fun)(void*)
733 , void(*destructor)(void*)
734 , void(*const_holder_destructor)(void*)
735 , int holder_size
736 , int holder_alignment);
738 void add_getter(
739 const char* name
740 , const boost::function2<int, lua_State*, int>& g);
742 #ifdef LUABIND_NO_ERROR_CHECKING
743 void add_setter(
744 const char* name
745 , const boost::function2<int, lua_State*, int>& s);
746 #else
747 void add_setter(
748 const char* name
749 , const boost::function2<int, lua_State*, int>& s
750 , int (*match)(lua_State*, int)
751 , void (*get_sig_ptr)(lua_State*, std::string&));
752 #endif
754 void add_base(const base_desc& b);
755 void add_constructor(const detail::construct_rep::overload_t& o);
757 #ifndef LUABIND_NO_ERROR_CHECKING
758 void add_operator(
759 int op_id
760 , int(*func)(lua_State*)
761 , int(*matcher)(lua_State*)
762 , void(*sig)(lua_State*
763 , std::string&)
764 , int arity);
765 #else
766 void add_operator(
767 int op_id
768 , int(*func)(lua_State*)
769 , int(*matcher)(lua_State*)
770 , int arity);
771 #endif
773 void add_member(registration* member);
774 void add_default_member(registration* member);
776 const char* name() const;
778 void add_static_constant(const char* name, int val);
779 void add_inner_scope(scope& s);
781 private:
782 class_registration* m_registration;
785 template<class T, class W>
786 struct adopt_function
788 static void execute(void* p)
790 wrapped_self_t& self = wrap_access::ref(
791 *static_cast<W*>(static_cast<T*>(p))
794 LUABIND_CHECK_STACK(self.state());
796 self.get(self.state());
797 self.m_strong_ref.set(self.state());
801 template <class Class, class F, class Policies>
802 struct memfun_registration : registration
804 memfun_registration(char const* name, F f, Policies const& policies)
805 : name(name)
806 , f(f)
807 , policies(policies)
810 void register_(lua_State* L) const
812 object fn = make_function(
813 L, f, deduce_signature(f, (Class*)0), policies);
815 add_overload(
816 object(from_stack(L, -1))
817 , name
818 , fn
822 char const* name;
823 F f;
824 Policies policies;
827 template <class Class, class Signature, class Policies>
828 struct constructor_registration : registration
830 constructor_registration(Policies const& policies)
831 : policies(policies)
834 void register_(lua_State* L) const
836 object fn = make_function(
837 L, construct<Class, Signature>(), Signature(), policies);
839 add_overload(
840 object(from_stack(L, -1))
841 , "__init"
842 , fn
846 Policies policies;
849 } // namespace detail
851 // registers a class in the lua environment
852 template<class T, class X1, class X2, class X3>
853 struct class_: detail::class_base
855 typedef class_<T, X1, X2, X3> self_t;
857 private:
859 template<class A, class B, class C, class D>
860 class_(const class_<A,B,C,D>&);
862 public:
864 // WrappedType MUST inherit from T
865 typedef typename detail::extract_parameter<
866 boost::mpl::vector3<X1,X2,X3>
867 , boost::is_base_and_derived<T, boost::mpl::_>
868 , detail::null_type
869 >::type WrappedType;
871 typedef typename detail::extract_parameter<
872 boost::mpl::list3<X1,X2,X3>
873 , boost::mpl::not_<
874 boost::mpl::or_<
875 boost::mpl::or_<
876 detail::is_bases<boost::mpl::_>
877 , boost::is_base_and_derived<boost::mpl::_, T>
879 , boost::is_base_and_derived<T, boost::mpl::_>
882 , detail::null_type
883 >::type HeldType;
885 // this function generates conversion information
886 // in the given class_rep structure. It will be able
887 // to implicitly cast to the given template type
888 template<class To>
889 void gen_base_info(detail::type_<To>)
891 // fist, make sure the given base class is registered.
892 // if it's not registered we can't push it's lua table onto
893 // the stack because it doesn't have a table
895 // try to cast this type to the base type and remember
896 // the pointer offset. For multiple inheritance the pointer
897 // may change when casting. Since we need to be able to
898 // cast we need this pointer offset.
899 // store the information in this class' base class-vector
900 base_desc base;
901 base.type = LUABIND_TYPEID(To);
902 base.ptr_offset = detail::ptr_offset(detail::type_<T>(), detail::type_<To>());
903 add_base(base);
906 void gen_base_info(detail::type_<detail::null_type>)
909 #define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type_<B##n>());
911 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class B)>
912 void generate_baseclass_list(detail::type_<bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, B)> >)
914 BOOST_PP_REPEAT(LUABIND_MAX_BASES, LUABIND_GEN_BASE_INFO, _)
917 #undef LUABIND_GEN_BASE_INFO
919 class_(const char* name): class_base(name), scope(*this)
921 #ifndef NDEBUG
922 detail::check_link_compatibility();
923 #endif
924 init();
927 template<class F>
928 class_& def(const char* name, F f)
930 return this->virtual_def(
931 name, f, detail::null_type()
932 , detail::null_type(), boost::mpl::true_());
935 // virtual functions
936 template<class F, class DefaultOrPolicies>
937 class_& def(char const* name, F fn, DefaultOrPolicies default_or_policies)
939 return this->virtual_def(
940 name, fn, default_or_policies, detail::null_type()
941 , LUABIND_MSVC_TYPENAME detail::is_policy_cons<DefaultOrPolicies>::type());
944 template<class F, class Default, class Policies>
945 class_& def(char const* name, F fn
946 , Default default_, Policies const& policies)
948 return this->virtual_def(
949 name, fn, default_
950 , policies, boost::mpl::false_());
953 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)>
954 class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig)
956 return this->def_constructor(&sig, detail::null_type());
959 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A), class Policies>
960 class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig, const Policies& policies)
962 return this->def_constructor(&sig, policies);
965 template<class Getter>
966 class_& property(const char* name, Getter g)
968 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, detail::null_type>(), _1, _2, g));
969 return *this;
972 template<class Getter, class MaybeSetter>
973 class_& property(const char* name, Getter g, MaybeSetter s)
975 return property_impl(name, g, s, boost::mpl::bool_<detail::is_policy_cons<MaybeSetter>::value>());
978 template<class Getter, class Setter, class GetPolicies>
979 class_& property(const char* name, Getter g, Setter s, const GetPolicies& get_policies)
981 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, GetPolicies>(get_policies), _1, _2, g));
982 #ifndef LUABIND_NO_ERROR_CHECKING
983 add_setter(
984 name
985 , boost::bind<int>(detail::set_caller<T, Setter, detail::null_type>(), _1, _2, s)
986 , detail::gen_set_matcher((Setter)0, (detail::null_type*)0)
987 , &detail::get_member_signature<Setter>::apply);
988 #else
989 add_setter(
990 name
991 , boost::bind<int>(detail::set_caller<T, Setter, detail::null_type>(), _1, _2, s));
992 #endif
993 return *this;
996 template<class Getter, class Setter, class GetPolicies, class SetPolicies>
997 class_& property(const char* name
998 , Getter g, Setter s
999 , const GetPolicies& get_policies
1000 , const SetPolicies& set_policies)
1002 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, GetPolicies>(get_policies), _1, _2, g));
1003 #ifndef LUABIND_NO_ERROR_CHECKING
1004 add_setter(
1005 name
1006 , boost::bind<int>(detail::set_caller<T, Setter, SetPolicies>(), _1, _2, s)
1007 , detail::gen_set_matcher((Setter)0, (SetPolicies*)0)
1008 , &detail::get_member_signature<Setter>::apply);
1009 #else
1010 add_setter(name, boost::bind<int>(detail::set_caller<T, Setter, SetPolicies>(set_policies), _1, _2, s));
1011 #endif
1012 return *this;
1015 template<class D>
1016 class_& def_readonly(const char* name, D T::*member_ptr)
1018 add_getter(name, boost::bind<int>(detail::auto_get<T,D,detail::null_type>(), _1, _2, member_ptr));
1019 return *this;
1022 template<class D, class Policies>
1023 class_& def_readonly(const char* name, D T::*member_ptr, const Policies& policies)
1025 add_getter(name, boost::bind<int>(detail::auto_get<T,D,Policies>(policies), _1, _2, member_ptr));
1026 return *this;
1029 template<class D>
1030 class_& def_readwrite(const char* name, D T::*member_ptr)
1032 add_getter(name, boost::bind<int>(detail::auto_get<T,D,detail::null_type>(), _1, _2, member_ptr));
1033 #ifndef LUABIND_NO_ERROR_CHECKING
1034 add_setter(
1035 name
1036 , boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr)
1037 , &detail::set_matcher<D, detail::null_type>::apply
1038 , &detail::get_setter_signature<D>::apply);
1039 #else
1040 add_setter(name, boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr));
1041 #endif
1042 return *this;
1045 template<class D, class GetPolicies>
1046 class_& def_readwrite(const char* name, D T::*member_ptr, const GetPolicies& get_policies)
1048 add_getter(name, boost::bind<int>(detail::auto_get<T,D,GetPolicies>(get_policies), _1, _2, member_ptr));
1049 #ifndef LUABIND_NO_ERROR_CHECKING
1050 add_setter(
1051 name
1052 , boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr)
1053 , &detail::set_matcher<D, detail::null_type>::apply
1054 , &detail::get_setter_signature<D>::apply);
1055 #else
1056 add_setter(name, boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr));
1057 #endif
1058 return *this;
1061 template<class D, class GetPolicies, class SetPolicies>
1062 class_& def_readwrite(const char* name, D T::*member_ptr, const GetPolicies& get_policies, const SetPolicies& set_policies)
1064 add_getter(name, boost::bind<int>(detail::auto_get<T,D,GetPolicies>(get_policies), _1, _2, member_ptr));
1065 #ifndef LUABIND_NO_ERROR_CHECKING
1066 add_setter(
1067 name
1068 , boost::bind<int>(detail::auto_set<T,D,SetPolicies>(), _1, _2, member_ptr)
1069 , &detail::set_matcher<D, SetPolicies>::apply
1070 , &detail::get_setter_signature<D>::apply);
1071 #else
1072 add_setter(name, boost::bind<int>(detail::auto_set<T,D,SetPolicies>(set_policies), _1, _2, member_ptr));
1073 #endif
1074 return *this;
1077 template<class Derived, class Policies>
1078 class_& def(detail::operator_<Derived>, Policies const& policies)
1080 return this->def(
1081 Derived::name()
1082 , &Derived::template apply<T, Policies>::execute
1083 , raw(_1) + policies
1087 template<class Derived>
1088 class_& def(detail::operator_<Derived>)
1090 return this->def(
1091 Derived::name()
1092 , &Derived::template apply<T, detail::null_type>::execute
1093 , raw(_1)
1098 template<class op_id, class Left, class Right, class Policies>
1099 class_& def(detail::operator_<op_id, Left, Right>, const Policies& policies)
1101 typedef typename detail::operator_unwrapper<Policies, op_id, T, Left, Right> op_type;
1102 #ifndef LUABIND_NO_ERROR_CHECKING
1103 add_operator(op_type::get_id()
1104 , &op_type::execute
1105 , &op_type::match
1106 , &detail::get_signature<constructor<typename op_type::left_t, typename op_type::right_t> >::apply
1107 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1108 #else
1109 add_operator(op_type::get_id()
1110 , &op_type::execute
1111 , &op_type::match
1112 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1113 #endif
1114 return *this;
1117 template<class op_id, class Left, class Right>
1118 class_& def(detail::operator_<op_id, Left, Right>)
1120 typedef typename detail::operator_unwrapper<detail::null_type, op_id, T, Left, Right> op_type;
1122 #ifndef LUABIND_NO_ERROR_CHECKING
1123 add_operator(op_type::get_id()
1124 , &op_type::execute
1125 , &op_type::match
1126 , &detail::get_signature<constructor<LUABIND_MSVC_TYPENAME op_type::left_t, LUABIND_MSVC_TYPENAME op_type::right_t> >::apply
1127 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1128 #else
1129 add_operator(op_type::get_id()
1130 , &op_type::execute
1131 , &op_type::match
1132 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1133 #endif
1134 return *this;
1137 template<class Signature, bool Constant>
1138 class_& def(detail::application_operator<Signature, Constant>*)
1140 typedef detail::application_operator<Signature, Constant, detail::null_type> op_t;
1142 int arity = detail::calc_arity<Signature::arity>::apply(
1143 Signature(), static_cast<detail::null_type*>(0));
1145 #ifndef LUABIND_NO_ERROR_CHECKING
1146 add_operator(
1147 detail::op_call
1148 , &op_t::template apply<T>::execute
1149 , &op_t::match
1150 , &detail::get_signature<Signature>::apply
1151 , arity + 1);
1152 #else
1153 add_operator(
1154 detail::op_call
1155 , &op_t::template apply<T>::execute
1156 , &op_t::match
1157 , arity + 1);
1158 #endif
1160 return *this;
1163 template<class Signature, bool Constant, class Policies>
1164 class_& def(detail::application_operator<Signature, Constant>*, const Policies& policies)
1166 typedef detail::application_operator<Signature, Constant, Policies> op_t;
1168 int arity = detail::calc_arity<Signature::arity>::apply(Signature(), static_cast<Policies*>(0));
1170 #ifndef LUABIND_NO_ERROR_CHECKING
1171 add_operator(
1172 detail::op_call
1173 , &op_t::template apply<T>::execute
1174 , &op_t::match
1175 , &detail::get_signature<Signature>::apply
1176 , arity + 1);
1177 #else
1178 add_operator(
1179 detail::op_call
1180 , &op_t::template apply<T>::execute
1181 , &op_t::match
1182 , arity + 1);
1183 #endif
1185 return *this;
1188 detail::enum_maker<self_t> enum_(const char*)
1190 return detail::enum_maker<self_t>(*this);
1193 detail::static_scope<self_t> scope;
1195 private:
1196 void operator=(class_ const&);
1198 void init()
1200 typedef typename detail::extract_parameter<
1201 boost::mpl::list3<X1,X2,X3>
1202 , boost::mpl::or_<
1203 detail::is_bases<boost::mpl::_>
1204 , boost::is_base_and_derived<boost::mpl::_, T>
1206 , no_bases
1207 >::type bases_t;
1209 typedef typename
1210 boost::mpl::if_<detail::is_bases<bases_t>
1211 , bases_t
1212 , bases<bases_t>
1213 >::type Base;
1215 class_base::init(LUABIND_TYPEID(T)
1216 , detail::internal_holder_type<HeldType>::apply()
1217 , detail::pointee_typeid(
1218 get_const_holder(static_cast<HeldType*>(0)))
1219 , detail::internal_holder_extractor<HeldType>::apply(detail::type_<T>())
1220 , detail::internal_const_holder_extractor<HeldType>::apply(detail::type_<T>())
1221 , detail::const_converter<HeldType>::apply(
1222 get_const_holder((HeldType*)0))
1223 , detail::holder_constructor<HeldType>::apply(detail::type_<T>())
1224 , detail::const_holder_constructor<HeldType>::apply(detail::type_<T>())
1225 , detail::holder_default_constructor<HeldType>::apply(detail::type_<T>())
1226 , detail::const_holder_default_constructor<HeldType>::apply(detail::type_<T>())
1227 , get_adopt_fun((WrappedType*)0) // adopt fun
1228 , detail::internal_holder_destructor<HeldType>::apply(detail::type_<T>())
1229 , detail::internal_const_holder_destructor<HeldType>::apply(detail::type_<T>())
1230 , detail::internal_holder_size<HeldType>::apply()
1231 , detail::get_holder_alignment<HeldType>::apply());
1233 generate_baseclass_list(detail::type_<Base>());
1236 template<class Getter, class GetPolicies>
1237 class_& property_impl(const char* name,
1238 Getter g,
1239 GetPolicies policies,
1240 boost::mpl::bool_<true>)
1242 add_getter(name, boost::bind<int>(detail::get_caller<T,Getter,GetPolicies>(policies), _1, _2, g));
1243 return *this;
1246 template<class Getter, class Setter>
1247 class_& property_impl(const char* name,
1248 Getter g,
1249 Setter s,
1250 boost::mpl::bool_<false>)
1252 add_getter(name, boost::bind<int>(detail::get_caller<T,Getter,detail::null_type>(), _1, _2, g));
1253 #ifndef LUABIND_NO_ERROR_CHECKING
1254 add_setter(
1255 name
1256 , boost::bind<int>(detail::set_caller<T, Setter, detail::null_type>(), _1, _2, s)
1257 , detail::gen_set_matcher((Setter)0, (detail::null_type*)0)
1258 , &detail::get_member_signature<Setter>::apply);
1259 #else
1260 add_setter(name, boost::bind<int>(detail::set_caller<T,Setter,detail::null_type>(), _1, _2, s));
1261 #endif
1262 return *this;
1265 // these handle default implementation of virtual functions
1266 template<class F, class Policies>
1267 class_& virtual_def(char const* name, F const& fn
1268 , Policies const&, detail::null_type, boost::mpl::true_)
1270 this->add_member(
1271 new detail::memfun_registration<T, F, Policies>(
1272 name, fn, Policies()));
1273 return *this;
1276 template<class F, class Default, class Policies>
1277 class_& virtual_def(char const* name, F const& fn
1278 , Default const& default_, Policies const&, boost::mpl::false_)
1280 this->add_member(
1281 new detail::memfun_registration<T, F, Policies>(
1282 name, fn, Policies()));
1284 this->add_default_member(
1285 new detail::memfun_registration<T, Default, Policies>(
1286 name, default_, Policies()));
1288 return *this;
1291 template<class Signature, class Policies>
1292 class_& def_constructor(Signature*, Policies const&)
1294 typedef typename Signature::signature signature;
1296 typedef typename boost::mpl::if_<
1297 boost::is_same<WrappedType, detail::null_type>
1299 , WrappedType
1300 >::type construct_type;
1302 this->add_member(
1303 new detail::constructor_registration<
1304 construct_type, signature, Policies>(
1305 Policies()));
1307 this->add_default_member(
1308 new detail::constructor_registration<
1309 construct_type, signature, Policies>(
1310 Policies()));
1312 return *this;
1315 typedef void(*adopt_fun_t)(void*);
1317 template<class W>
1318 adopt_fun_t get_adopt_fun(W*)
1320 return &detail::adopt_function<T, W>::execute;
1323 adopt_fun_t get_adopt_fun(detail::null_type*)
1325 return 0;
1329 namespace
1331 LUABIND_ANONYMOUS_FIX detail::policy_cons<
1332 detail::pure_virtual_tag
1333 , detail::null_type
1334 > pure_virtual;
1338 #ifdef _MSC_VER
1339 #pragma warning(pop)
1340 #endif
1342 #endif // LUABIND_CLASS_HPP_INCLUDED