Really get rid of unused global warning.
[luabind.git] / luabind / class.hpp
blob3da0a723cc8c9af08deb24891a019cdfb5997024
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/type_traits/is_member_object_pointer.hpp>
87 #include <boost/mpl/list.hpp>
88 #include <boost/mpl/apply.hpp>
89 #include <boost/mpl/lambda.hpp>
90 #include <boost/mpl/logical.hpp>
91 #include <boost/mpl/find_if.hpp>
92 #include <boost/mpl/eval_if.hpp>
93 #include <boost/mpl/logical.hpp>
95 #include <luabind/config.hpp>
96 #include <luabind/scope.hpp>
97 #include <luabind/raw_policy.hpp>
98 #include <luabind/back_reference.hpp>
99 #include <luabind/function.hpp>
100 #include <luabind/dependency_policy.hpp>
101 #include <luabind/detail/constructor.hpp>
102 #include <luabind/detail/call.hpp>
103 #include <luabind/detail/deduce_signature.hpp>
104 #include <luabind/detail/compute_score.hpp>
105 #include <luabind/detail/primitives.hpp>
106 #include <luabind/detail/property.hpp>
107 #include <luabind/detail/typetraits.hpp>
108 #include <luabind/detail/class_rep.hpp>
109 #include <luabind/detail/call.hpp>
110 #include <luabind/detail/construct_rep.hpp>
111 #include <luabind/detail/object_rep.hpp>
112 #include <luabind/detail/calc_arity.hpp>
113 #include <luabind/detail/call_member.hpp>
114 #include <luabind/detail/enum_maker.hpp>
115 #include <luabind/detail/get_signature.hpp>
116 #include <luabind/detail/implicit_cast.hpp>
117 #include <luabind/detail/operator_id.hpp>
118 #include <luabind/detail/pointee_typeid.hpp>
119 #include <luabind/detail/link_compatibility.hpp>
121 // to remove the 'this' used in initialization list-warning
122 #ifdef _MSC_VER
123 #pragma warning(push)
124 #pragma warning(disable: 4355)
125 #endif
127 namespace boost
130 template <class T> class shared_ptr;
132 } // namespace boost
134 namespace luabind
136 namespace detail
138 struct unspecified {};
140 template<class Derived> struct operator_;
142 struct you_need_to_define_a_get_const_holder_function_for_your_smart_ptr {};
145 template<class T, class X1 = detail::unspecified, class X2 = detail::unspecified, class X3 = detail::unspecified>
146 struct class_;
148 // TODO: this function will only be invoked if the user hasn't defined a correct overload
149 // maybe we should have a static assert in here?
150 inline detail::you_need_to_define_a_get_const_holder_function_for_your_smart_ptr*
151 get_const_holder(...)
153 return 0;
156 template <class T>
157 boost::shared_ptr<T const>* get_const_holder(boost::shared_ptr<T>*)
159 return 0;
162 namespace detail
164 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class A)>
165 double is_bases_helper(const bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, A)>&);
167 #ifndef BOOST_MSVC
168 template<class T>
169 char is_bases_helper(const T&);
170 #else
171 char is_bases_helper(...);
172 #endif
174 template<class T>
175 struct is_bases
177 static const T& t;
179 BOOST_STATIC_CONSTANT(bool, value = sizeof(is_bases_helper(t)) == sizeof(double));
180 typedef boost::mpl::bool_<value> type;
181 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_bases,(T))
184 double is_not_unspecified_helper(const unspecified*);
185 char is_not_unspecified_helper(...);
187 template<class T>
188 struct is_not_unspecified
190 BOOST_STATIC_CONSTANT(bool, value = sizeof(is_not_unspecified_helper(static_cast<T*>(0))) == sizeof(char));
191 typedef boost::mpl::bool_<value> type;
192 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_not_unspecified,(T))
195 template<class Predicate>
196 struct get_predicate
198 typedef typename boost::mpl::and_<
199 is_not_unspecified<boost::mpl::_1>
200 , Predicate
201 > type;
204 template<class Parameters, class Predicate, class DefaultValue>
205 struct extract_parameter
207 typedef typename get_predicate<Predicate>::type pred;
208 typedef typename boost::mpl::find_if<Parameters, pred>::type iterator;
209 typedef typename boost::mpl::eval_if<
210 boost::is_same<
211 iterator
212 , typename boost::mpl::end<Parameters>::type
214 , boost::mpl::identity<DefaultValue>
215 , boost::mpl::deref<iterator>
216 >::type type;
219 template<class Fn, class Class, class Policies>
220 struct mem_fn_callback
222 typedef int result_type;
224 int operator()(lua_State* L) const
226 return invoke(L, fn, deduce_signature(fn, (Class*)0), Policies());
229 mem_fn_callback(Fn fn_)
230 : fn(fn_)
234 Fn fn;
237 template<class Fn, class Class, class Policies>
238 struct mem_fn_matcher
240 typedef int result_type;
242 int operator()(lua_State* L) const
244 return compute_score(L, deduce_signature(fn, (Class*)0), Policies());
247 mem_fn_matcher(Fn fn_)
248 : fn(fn_)
252 Fn fn;
255 struct pure_virtual_tag
257 static void precall(lua_State*, index_map const&) {}
258 static void postcall(lua_State*, index_map const&) {}
261 template<class Policies>
262 struct has_pure_virtual
264 typedef typename boost::mpl::eval_if<
265 boost::is_same<pure_virtual_tag, typename Policies::head>
266 , boost::mpl::true_
267 , has_pure_virtual<typename Policies::tail>
268 >::type type;
270 BOOST_STATIC_CONSTANT(bool, value = type::value);
273 template<>
274 struct has_pure_virtual<null_type>
276 BOOST_STATIC_CONSTANT(bool, value = false);
277 typedef boost::mpl::bool_<value> type;
280 // prints the types of the values on the stack, in the
281 // range [start_index, lua_gettop()]
283 LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index);
285 struct LUABIND_API create_class
287 static int stage1(lua_State* L);
288 static int stage2(lua_State* L);
291 // if the class is held by a smart pointer, we need to be able to
292 // implicitly dereference the pointer when needed.
294 template<class UnderlyingT, class HeldT>
295 struct extract_underlying_type
297 static void* extract(void* ptr)
299 HeldT& held_obj = *reinterpret_cast<HeldT*>(ptr);
300 UnderlyingT* underlying_ptr = static_cast<UnderlyingT*>(get_pointer(held_obj));
301 return underlying_ptr;
305 template<class UnderlyingT, class HeldT>
306 struct extract_underlying_const_type
308 static const void* extract(void* ptr)
310 HeldT& held_obj = *reinterpret_cast<HeldT*>(ptr);
311 const UnderlyingT* underlying_ptr = static_cast<const UnderlyingT*>(get_pointer(held_obj));
312 return underlying_ptr;
316 template<class HeldType>
317 struct internal_holder_extractor
319 typedef void*(*extractor_fun)(void*);
321 template<class T>
322 static extractor_fun apply(detail::type_<T>)
324 return &detail::extract_underlying_type<T, HeldType>::extract;
328 template<>
329 struct internal_holder_extractor<detail::null_type>
331 typedef void*(*extractor_fun)(void*);
333 template<class T>
334 static extractor_fun apply(detail::type_<T>)
336 return 0;
341 template<class HeldType, class ConstHolderType>
342 struct convert_holder
344 static void apply(void* holder, void* target)
346 new(target) ConstHolderType(*reinterpret_cast<HeldType*>(holder));
351 template<class HeldType>
352 struct const_converter
354 typedef void(*converter_fun)(void*, void*);
356 template<class ConstHolderType>
357 static converter_fun apply(ConstHolderType*)
359 return &detail::convert_holder<HeldType, ConstHolderType>::apply;
363 template<>
364 struct const_converter<detail::null_type>
366 typedef void(*converter_fun)(void*, void*);
368 template<class T>
369 static converter_fun apply(T*)
371 return 0;
378 template<class HeldType>
379 struct internal_const_holder_extractor
381 typedef const void*(*extractor_fun)(void*);
383 template<class T>
384 static extractor_fun apply(detail::type_<T>)
386 return get_extractor(detail::type_<T>(), get_const_holder(static_cast<HeldType*>(0)));
388 private:
389 template<class T, class ConstHolderType>
390 static extractor_fun get_extractor(detail::type_<T>, ConstHolderType*)
392 return &detail::extract_underlying_const_type<T, ConstHolderType>::extract;
396 template<>
397 struct internal_const_holder_extractor<detail::null_type>
399 typedef const void*(*extractor_fun)(void*);
401 template<class T>
402 static extractor_fun apply(detail::type_<T>)
404 return 0;
410 // this is simply a selector that returns the type_info
411 // of the held type, or invalid_type_info if we don't have
412 // a held_type
413 template<class HeldType>
414 struct internal_holder_type
416 static LUABIND_TYPE_INFO apply()
418 return LUABIND_TYPEID(HeldType);
422 template<>
423 struct internal_holder_type<detail::null_type>
425 static LUABIND_TYPE_INFO apply()
427 return LUABIND_INVALID_TYPE_INFO;
432 // this is the actual held_type constructor
433 template<class HeldType, class T>
434 struct internal_construct_holder
436 static void apply(void* target, void* raw_pointer)
438 new(target) HeldType(static_cast<T*>(raw_pointer));
442 // this is the actual held_type default constructor
443 template<class HeldType, class T>
444 struct internal_default_construct_holder
446 static void apply(void* target)
448 new(target) HeldType();
452 // the following two functions are the ones that returns
453 // a pointer to a held_type_constructor, or 0 if there
454 // is no held_type
455 template<class HeldType>
456 struct holder_constructor
458 typedef void(*constructor)(void*,void*);
459 template<class T>
460 static constructor apply(detail::type_<T>)
462 return &internal_construct_holder<HeldType, T>::apply;
466 template<>
467 struct holder_constructor<detail::null_type>
469 typedef void(*constructor)(void*,void*);
470 template<class T>
471 static constructor apply(detail::type_<T>)
473 return 0;
477 // the following two functions are the ones that returns
478 // a pointer to a const_held_type_constructor, or 0 if there
479 // is no held_type
480 template<class HolderType>
481 struct const_holder_constructor
483 typedef void(*constructor)(void*,void*);
484 template<class T>
485 static constructor apply(detail::type_<T>)
487 return get_const_holder_constructor(detail::type_<T>(), get_const_holder(static_cast<HolderType*>(0)));
490 private:
492 template<class T, class ConstHolderType>
493 static constructor get_const_holder_constructor(detail::type_<T>, ConstHolderType*)
495 return &internal_construct_holder<ConstHolderType, T>::apply;
499 template<>
500 struct const_holder_constructor<detail::null_type>
502 typedef void(*constructor)(void*,void*);
503 template<class T>
504 static constructor apply(detail::type_<T>)
506 return 0;
511 // the following two functions are the ones that returns
512 // a pointer to a held_type_constructor, or 0 if there
513 // is no held_type. The holder_type is default constructed
514 template<class HeldType>
515 struct holder_default_constructor
517 typedef void(*constructor)(void*);
518 template<class T>
519 static constructor apply(detail::type_<T>)
521 return &internal_default_construct_holder<HeldType, T>::apply;
525 template<>
526 struct holder_default_constructor<detail::null_type>
528 typedef void(*constructor)(void*);
529 template<class T>
530 static constructor apply(detail::type_<T>)
532 return 0;
537 // the following two functions are the ones that returns
538 // a pointer to a const_held_type_constructor, or 0 if there
539 // is no held_type. The constructed held_type is default
540 // constructed
541 template<class HolderType>
542 struct const_holder_default_constructor
544 typedef void(*constructor)(void*);
545 template<class T>
546 static constructor apply(detail::type_<T>)
548 return get_const_holder_default_constructor(detail::type_<T>(), get_const_holder(static_cast<HolderType*>(0)));
551 private:
553 template<class T, class ConstHolderType>
554 static constructor get_const_holder_default_constructor(detail::type_<T>, ConstHolderType*)
556 return &internal_default_construct_holder<ConstHolderType, T>::apply;
560 template<>
561 struct const_holder_default_constructor<detail::null_type>
563 typedef void(*constructor)(void*);
564 template<class T>
565 static constructor apply(detail::type_<T>)
567 return 0;
574 // this is a selector that returns the size of the held_type
575 // or 0 if we don't have a held_type
576 template <class HolderType>
577 struct internal_holder_size
579 static int apply() { return get_internal_holder_size(get_const_holder(static_cast<HolderType*>(0))); }
580 private:
581 template<class ConstHolderType>
582 static int get_internal_holder_size(ConstHolderType*)
584 return max_c<sizeof(HolderType), sizeof(ConstHolderType)>::value;
588 template <>
589 struct internal_holder_size<detail::null_type>
591 static int apply() { return 0; }
595 // if we have a held type, return the destructor to it
596 // note the difference. The held_type should only be destructed (not deleted)
597 // since it's constructed in the lua userdata
598 template<class HeldType>
599 struct internal_holder_destructor
601 typedef void(*destructor_t)(void*);
602 template<class T>
603 static destructor_t apply(detail::type_<T>)
605 return &detail::destruct_only_s<HeldType>::apply;
609 // if we don't have a held type, return the destructor of the raw type
610 template<>
611 struct internal_holder_destructor<detail::null_type>
613 typedef void(*destructor_t)(void*);
614 template<class T>
615 static destructor_t apply(detail::type_<T>)
617 return &detail::delete_s<T>::apply;
622 // if we have a held type, return the destructor to it's const version
623 template<class HolderType>
624 struct internal_const_holder_destructor
626 typedef void(*destructor_t)(void*);
627 template<class T>
628 static destructor_t apply(detail::type_<T>)
630 return const_holder_type_destructor(get_const_holder(static_cast<HolderType*>(0)));
633 private:
635 template<class ConstHolderType>
636 static destructor_t const_holder_type_destructor(ConstHolderType*)
638 return &detail::destruct_only_s<ConstHolderType>::apply;
643 // if we don't have a held type, return the destructor of the raw type
644 template<>
645 struct internal_const_holder_destructor<detail::null_type>
647 typedef void(*destructor_t)(void*);
648 template<class T>
649 static destructor_t apply(detail::type_<T>)
651 return 0;
658 template<class HolderType>
659 struct get_holder_alignment
661 static int apply()
663 return internal_alignment(get_const_holder(static_cast<HolderType*>(0)));
666 private:
668 template<class ConstHolderType>
669 static int internal_alignment(ConstHolderType*)
671 return detail::max_c<boost::alignment_of<HolderType>::value
672 , boost::alignment_of<ConstHolderType>::value>::value;
676 template<>
677 struct get_holder_alignment<detail::null_type>
679 static int apply()
681 return 1;
686 } // detail
688 namespace detail {
690 template<class T>
691 struct static_scope
693 static_scope(T& self_) : self(self_)
697 T& operator[](scope s) const
699 self.add_inner_scope(s);
700 return self;
703 private:
704 template<class U> void operator,(U const&) const;
705 void operator=(static_scope const&);
707 T& self;
710 struct class_registration;
712 struct LUABIND_API class_base : scope
714 public:
715 class_base(char const* name);
717 struct base_desc
719 LUABIND_TYPE_INFO type;
720 int ptr_offset;
723 void init(
724 LUABIND_TYPE_INFO type
725 , LUABIND_TYPE_INFO holder_type
726 , LUABIND_TYPE_INFO const_holder_type
727 , void*(*extractor)(void*)
728 , const void*(*const_extractor)(void*)
729 , void(*const_converter)(void*,void*)
730 , void(*holder_constructor)(void*,void*)
731 , void(*const_holder_constructor)(void*,void*)
732 , void(*holder_default_constructor)(void*)
733 , void(*const_holder_default_constructor)(void*)
734 , void(*adopt_fun)(void*)
735 , void(*destructor)(void*)
736 , void(*const_holder_destructor)(void*)
737 , int holder_size
738 , int holder_alignment);
740 void add_getter(
741 const char* name
742 , const boost::function2<int, lua_State*, int>& g);
744 #ifdef LUABIND_NO_ERROR_CHECKING
745 void add_setter(
746 const char* name
747 , const boost::function2<int, lua_State*, int>& s);
748 #else
749 void add_setter(
750 const char* name
751 , const boost::function2<int, lua_State*, int>& s
752 , int (*match)(lua_State*, int)
753 , void (*get_sig_ptr)(lua_State*, std::string&));
754 #endif
756 void add_base(const base_desc& b);
757 void add_constructor(const detail::construct_rep::overload_t& o);
759 #ifndef LUABIND_NO_ERROR_CHECKING
760 void add_operator(
761 int op_id
762 , int(*func)(lua_State*)
763 , int(*matcher)(lua_State*)
764 , void(*sig)(lua_State*
765 , std::string&)
766 , int arity);
767 #else
768 void add_operator(
769 int op_id
770 , int(*func)(lua_State*)
771 , int(*matcher)(lua_State*)
772 , int arity);
773 #endif
775 void add_member(registration* member);
776 void add_default_member(registration* member);
778 const char* name() const;
780 void add_static_constant(const char* name, int val);
781 void add_inner_scope(scope& s);
783 private:
784 class_registration* m_registration;
787 template<class T, class W>
788 struct adopt_function
790 static void execute(void* p)
792 wrapped_self_t& self = wrap_access::ref(
793 *static_cast<W*>(static_cast<T*>(p))
796 LUABIND_CHECK_STACK(self.state());
798 self.get(self.state());
799 self.m_strong_ref.set(self.state());
803 template <class Class, class F, class Policies>
804 struct memfun_registration : registration
806 memfun_registration(char const* name, F f, Policies const& policies)
807 : name(name)
808 , f(f)
809 , policies(policies)
812 void register_(lua_State* L) const
814 object fn = make_function(
815 L, f, deduce_signature(f, (Class*)0), policies);
817 add_overload(
818 object(from_stack(L, -1))
819 , name
820 , fn
824 char const* name;
825 F f;
826 Policies policies;
829 template <class Class, class Signature, class Policies>
830 struct constructor_registration : registration
832 constructor_registration(Policies const& policies)
833 : policies(policies)
836 void register_(lua_State* L) const
838 object fn = make_function(
839 L, construct<Class, Signature>(), Signature(), policies);
841 add_overload(
842 object(from_stack(L, -1))
843 , "__init"
844 , fn
848 Policies policies;
851 template <class T>
852 struct reference_result
853 : mpl::if_<
854 mpl::or_<boost::is_pointer<T>, is_primitive<T> >
856 , typename boost::add_reference<T>::type
860 template <class T, class Policies>
861 struct inject_dependency_policy
862 : mpl::if_<
863 is_primitive<T>
864 , Policies
865 , policy_cons<dependency_policy<0, 1>, Policies>
869 template <
870 class Class
871 , class Get, class GetPolicies
872 , class Set = null_type, class SetPolicies = null_type
874 struct property_registration : registration
876 property_registration(
877 char const* name
878 , Get const& get
879 , GetPolicies const& get_policies
880 , Set const& set = Set()
881 , SetPolicies const& set_policies = SetPolicies()
883 : name(name)
884 , get(get)
885 , get_policies(get_policies)
886 , set(set)
887 , set_policies(set_policies)
890 void register_(lua_State* L) const
892 object context(from_stack(L, -1));
893 register_aux(
895 , context
896 , make_get(L, get, boost::is_member_object_pointer<Get>())
897 , set
901 template <class F>
902 object make_get(lua_State* L, F const& f, mpl::false_) const
904 return make_function(
905 L, f, deduce_signature(f, (Class*)0), get_policies);
908 template <class T, class D>
909 object make_get(lua_State* L, D T::* mem_ptr, mpl::true_) const
911 typedef typename reference_result<D>::type result_type;
912 typedef typename inject_dependency_policy<
913 D, GetPolicies>::type policies;
915 return make_function(
917 , access_member_ptr<T, D, result_type>(mem_ptr)
918 , mpl::vector2<result_type, Class const&>()
919 , policies()
923 template <class F>
924 object make_set(lua_State* L, F const& f, mpl::false_) const
926 return make_function(
927 L, f, deduce_signature(f, (Class*)0), set_policies);
930 template <class T, class D>
931 object make_set(lua_State* L, D T::* mem_ptr, mpl::true_) const
933 return make_function(
935 , access_member_ptr<T, D>(mem_ptr)
936 , mpl::vector3<void, Class&, D const&>()
937 , set_policies
941 template <class S>
942 void register_aux(
943 lua_State* L, object const& context
944 , object const& get_, S const&) const
946 context[name] = property(
947 get_
948 , make_set(L, set, boost::is_member_object_pointer<Set>())
952 void register_aux(
953 lua_State* L, object const& context
954 , object const& get_, null_type) const
956 context[name] = property(get_);
959 char const* name;
960 Get get;
961 GetPolicies get_policies;
962 Set set;
963 SetPolicies set_policies;
966 } // namespace detail
968 // registers a class in the lua environment
969 template<class T, class X1, class X2, class X3>
970 struct class_: detail::class_base
972 typedef class_<T, X1, X2, X3> self_t;
974 private:
976 template<class A, class B, class C, class D>
977 class_(const class_<A,B,C,D>&);
979 public:
981 // WrappedType MUST inherit from T
982 typedef typename detail::extract_parameter<
983 boost::mpl::vector3<X1,X2,X3>
984 , boost::is_base_and_derived<T, boost::mpl::_>
985 , detail::null_type
986 >::type WrappedType;
988 typedef typename detail::extract_parameter<
989 boost::mpl::list3<X1,X2,X3>
990 , boost::mpl::not_<
991 boost::mpl::or_<
992 boost::mpl::or_<
993 detail::is_bases<boost::mpl::_>
994 , boost::is_base_and_derived<boost::mpl::_, T>
996 , boost::is_base_and_derived<T, boost::mpl::_>
999 , detail::null_type
1000 >::type HeldType;
1002 // this function generates conversion information
1003 // in the given class_rep structure. It will be able
1004 // to implicitly cast to the given template type
1005 template<class To>
1006 void gen_base_info(detail::type_<To>)
1008 // fist, make sure the given base class is registered.
1009 // if it's not registered we can't push it's lua table onto
1010 // the stack because it doesn't have a table
1012 // try to cast this type to the base type and remember
1013 // the pointer offset. For multiple inheritance the pointer
1014 // may change when casting. Since we need to be able to
1015 // cast we need this pointer offset.
1016 // store the information in this class' base class-vector
1017 base_desc base;
1018 base.type = LUABIND_TYPEID(To);
1019 base.ptr_offset = detail::ptr_offset(detail::type_<T>(), detail::type_<To>());
1020 add_base(base);
1023 void gen_base_info(detail::type_<detail::null_type>)
1026 #define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type_<B##n>());
1028 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class B)>
1029 void generate_baseclass_list(detail::type_<bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, B)> >)
1031 BOOST_PP_REPEAT(LUABIND_MAX_BASES, LUABIND_GEN_BASE_INFO, _)
1034 #undef LUABIND_GEN_BASE_INFO
1036 class_(const char* name): class_base(name), scope(*this)
1038 #ifndef NDEBUG
1039 detail::check_link_compatibility();
1040 #endif
1041 init();
1044 template<class F>
1045 class_& def(const char* name, F f)
1047 return this->virtual_def(
1048 name, f, detail::null_type()
1049 , detail::null_type(), boost::mpl::true_());
1052 // virtual functions
1053 template<class F, class DefaultOrPolicies>
1054 class_& def(char const* name, F fn, DefaultOrPolicies default_or_policies)
1056 return this->virtual_def(
1057 name, fn, default_or_policies, detail::null_type()
1058 , LUABIND_MSVC_TYPENAME detail::is_policy_cons<DefaultOrPolicies>::type());
1061 template<class F, class Default, class Policies>
1062 class_& def(char const* name, F fn
1063 , Default default_, Policies const& policies)
1065 return this->virtual_def(
1066 name, fn, default_
1067 , policies, boost::mpl::false_());
1070 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)>
1071 class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig)
1073 return this->def_constructor(&sig, detail::null_type());
1076 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A), class Policies>
1077 class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig, const Policies& policies)
1079 return this->def_constructor(&sig, policies);
1082 template <class Getter>
1083 class_& property(const char* name, Getter g)
1085 this->add_member(
1086 new detail::property_registration<T, Getter, detail::null_type>(
1087 name, g, detail::null_type()));
1088 return *this;
1091 template <class Getter, class MaybeSetter>
1092 class_& property(const char* name, Getter g, MaybeSetter s)
1094 return property_impl(
1095 name, g, s
1096 , boost::mpl::bool_<detail::is_policy_cons<MaybeSetter>::value>()
1100 template<class Getter, class Setter, class GetPolicies>
1101 class_& property(const char* name, Getter g, Setter s, const GetPolicies& get_policies)
1103 typedef detail::property_registration<
1104 T, Getter, GetPolicies, Setter, detail::null_type
1105 > registration_type;
1107 this->add_member(
1108 new registration_type(name, g, get_policies, s));
1109 return *this;
1112 template<class Getter, class Setter, class GetPolicies, class SetPolicies>
1113 class_& property(
1114 const char* name
1115 , Getter g, Setter s
1116 , GetPolicies const& get_policies
1117 , SetPolicies const& set_policies)
1119 typedef detail::property_registration<
1120 T, Getter, GetPolicies, Setter, SetPolicies
1121 > registration_type;
1123 this->add_member(
1124 new registration_type(name, g, get_policies, s, set_policies));
1125 return *this;
1128 template <class C, class D>
1129 class_& def_readonly(const char* name, D C::*mem_ptr)
1131 typedef detail::property_registration<T, D C::*, detail::null_type>
1132 registration_type;
1134 this->add_member(
1135 new registration_type(name, mem_ptr, detail::null_type()));
1136 return *this;
1139 template <class C, class D, class Policies>
1140 class_& def_readonly(const char* name, D C::*mem_ptr, Policies const& policies)
1142 typedef detail::property_registration<T, D C::*, Policies>
1143 registration_type;
1145 this->add_member(
1146 new registration_type(name, mem_ptr, policies));
1147 return *this;
1150 template <class C, class D>
1151 class_& def_readwrite(const char* name, D C::*mem_ptr)
1153 typedef detail::property_registration<
1154 T, D C::*, detail::null_type, D C::*
1155 > registration_type;
1157 this->add_member(
1158 new registration_type(
1159 name, mem_ptr, detail::null_type(), mem_ptr));
1160 return *this;
1163 template <class C, class D, class GetPolicies>
1164 class_& def_readwrite(
1165 const char* name, D C::*mem_ptr, GetPolicies const& get_policies)
1167 typedef detail::property_registration<
1168 T, D C::*, GetPolicies, D C::*
1169 > registration_type;
1171 this->add_member(
1172 new registration_type(
1173 name, mem_ptr, get_policies, mem_ptr));
1174 return *this;
1177 template <class C, class D, class GetPolicies, class SetPolicies>
1178 class_& def_readwrite(
1179 const char* name
1180 , D C::*mem_ptr
1181 , GetPolicies const& get_policies
1182 , SetPolicies const& set_policies
1185 typedef detail::property_registration<
1186 T, D C::*, GetPolicies, D C::*, SetPolicies
1187 > registration_type;
1189 this->add_member(
1190 new registration_type(
1191 name, mem_ptr, get_policies, mem_ptr, set_policies));
1192 return *this;
1195 template<class Derived, class Policies>
1196 class_& def(detail::operator_<Derived>, Policies const& policies)
1198 return this->def(
1199 Derived::name()
1200 , &Derived::template apply<T, Policies>::execute
1201 , raw(_1) + policies
1205 template<class Derived>
1206 class_& def(detail::operator_<Derived>)
1208 return this->def(
1209 Derived::name()
1210 , &Derived::template apply<T, detail::null_type>::execute
1211 , raw(_1)
1216 template<class op_id, class Left, class Right, class Policies>
1217 class_& def(detail::operator_<op_id, Left, Right>, const Policies& policies)
1219 typedef typename detail::operator_unwrapper<Policies, op_id, T, Left, Right> op_type;
1220 #ifndef LUABIND_NO_ERROR_CHECKING
1221 add_operator(op_type::get_id()
1222 , &op_type::execute
1223 , &op_type::match
1224 , &detail::get_signature<constructor<typename op_type::left_t, typename op_type::right_t> >::apply
1225 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1226 #else
1227 add_operator(op_type::get_id()
1228 , &op_type::execute
1229 , &op_type::match
1230 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1231 #endif
1232 return *this;
1235 template<class op_id, class Left, class Right>
1236 class_& def(detail::operator_<op_id, Left, Right>)
1238 typedef typename detail::operator_unwrapper<detail::null_type, op_id, T, Left, Right> op_type;
1240 #ifndef LUABIND_NO_ERROR_CHECKING
1241 add_operator(op_type::get_id()
1242 , &op_type::execute
1243 , &op_type::match
1244 , &detail::get_signature<constructor<LUABIND_MSVC_TYPENAME op_type::left_t, LUABIND_MSVC_TYPENAME op_type::right_t> >::apply
1245 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1246 #else
1247 add_operator(op_type::get_id()
1248 , &op_type::execute
1249 , &op_type::match
1250 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1251 #endif
1252 return *this;
1255 template<class Signature, bool Constant>
1256 class_& def(detail::application_operator<Signature, Constant>*)
1258 typedef detail::application_operator<Signature, Constant, detail::null_type> op_t;
1260 int arity = detail::calc_arity<Signature::arity>::apply(
1261 Signature(), static_cast<detail::null_type*>(0));
1263 #ifndef LUABIND_NO_ERROR_CHECKING
1264 add_operator(
1265 detail::op_call
1266 , &op_t::template apply<T>::execute
1267 , &op_t::match
1268 , &detail::get_signature<Signature>::apply
1269 , arity + 1);
1270 #else
1271 add_operator(
1272 detail::op_call
1273 , &op_t::template apply<T>::execute
1274 , &op_t::match
1275 , arity + 1);
1276 #endif
1278 return *this;
1281 template<class Signature, bool Constant, class Policies>
1282 class_& def(detail::application_operator<Signature, Constant>*, const Policies& policies)
1284 typedef detail::application_operator<Signature, Constant, Policies> op_t;
1286 int arity = detail::calc_arity<Signature::arity>::apply(Signature(), static_cast<Policies*>(0));
1288 #ifndef LUABIND_NO_ERROR_CHECKING
1289 add_operator(
1290 detail::op_call
1291 , &op_t::template apply<T>::execute
1292 , &op_t::match
1293 , &detail::get_signature<Signature>::apply
1294 , arity + 1);
1295 #else
1296 add_operator(
1297 detail::op_call
1298 , &op_t::template apply<T>::execute
1299 , &op_t::match
1300 , arity + 1);
1301 #endif
1303 return *this;
1306 detail::enum_maker<self_t> enum_(const char*)
1308 return detail::enum_maker<self_t>(*this);
1311 detail::static_scope<self_t> scope;
1313 private:
1314 void operator=(class_ const&);
1316 void init()
1318 typedef typename detail::extract_parameter<
1319 boost::mpl::list3<X1,X2,X3>
1320 , boost::mpl::or_<
1321 detail::is_bases<boost::mpl::_>
1322 , boost::is_base_and_derived<boost::mpl::_, T>
1324 , no_bases
1325 >::type bases_t;
1327 typedef typename
1328 boost::mpl::if_<detail::is_bases<bases_t>
1329 , bases_t
1330 , bases<bases_t>
1331 >::type Base;
1333 class_base::init(LUABIND_TYPEID(T)
1334 , detail::internal_holder_type<HeldType>::apply()
1335 , detail::pointee_typeid(
1336 get_const_holder(static_cast<HeldType*>(0)))
1337 , detail::internal_holder_extractor<HeldType>::apply(detail::type_<T>())
1338 , detail::internal_const_holder_extractor<HeldType>::apply(detail::type_<T>())
1339 , detail::const_converter<HeldType>::apply(
1340 get_const_holder((HeldType*)0))
1341 , detail::holder_constructor<HeldType>::apply(detail::type_<T>())
1342 , detail::const_holder_constructor<HeldType>::apply(detail::type_<T>())
1343 , detail::holder_default_constructor<HeldType>::apply(detail::type_<T>())
1344 , detail::const_holder_default_constructor<HeldType>::apply(detail::type_<T>())
1345 , get_adopt_fun((WrappedType*)0) // adopt fun
1346 , detail::internal_holder_destructor<HeldType>::apply(detail::type_<T>())
1347 , detail::internal_const_holder_destructor<HeldType>::apply(detail::type_<T>())
1348 , detail::internal_holder_size<HeldType>::apply()
1349 , detail::get_holder_alignment<HeldType>::apply());
1351 generate_baseclass_list(detail::type_<Base>());
1354 template<class Getter, class GetPolicies>
1355 class_& property_impl(const char* name,
1356 Getter g,
1357 GetPolicies policies,
1358 boost::mpl::bool_<true>)
1360 this->add_member(
1361 new detail::property_registration<T, Getter, GetPolicies>(
1362 name, g, policies));
1363 return *this;
1366 template<class Getter, class Setter>
1367 class_& property_impl(const char* name,
1368 Getter g,
1369 Setter s,
1370 boost::mpl::bool_<false>)
1372 typedef detail::property_registration<
1373 T, Getter, detail::null_type, Setter, detail::null_type
1374 > registration_type;
1376 this->add_member(
1377 new registration_type(name, g, detail::null_type(), s));
1378 return *this;
1381 // these handle default implementation of virtual functions
1382 template<class F, class Policies>
1383 class_& virtual_def(char const* name, F const& fn
1384 , Policies const&, detail::null_type, boost::mpl::true_)
1386 this->add_member(
1387 new detail::memfun_registration<T, F, Policies>(
1388 name, fn, Policies()));
1389 return *this;
1392 template<class F, class Default, class Policies>
1393 class_& virtual_def(char const* name, F const& fn
1394 , Default const& default_, Policies const&, boost::mpl::false_)
1396 this->add_member(
1397 new detail::memfun_registration<T, F, Policies>(
1398 name, fn, Policies()));
1400 this->add_default_member(
1401 new detail::memfun_registration<T, Default, Policies>(
1402 name, default_, Policies()));
1404 return *this;
1407 template<class Signature, class Policies>
1408 class_& def_constructor(Signature*, Policies const&)
1410 typedef typename Signature::signature signature;
1412 typedef typename boost::mpl::if_<
1413 boost::is_same<WrappedType, detail::null_type>
1415 , WrappedType
1416 >::type construct_type;
1418 this->add_member(
1419 new detail::constructor_registration<
1420 construct_type, signature, Policies>(
1421 Policies()));
1423 this->add_default_member(
1424 new detail::constructor_registration<
1425 construct_type, signature, Policies>(
1426 Policies()));
1428 return *this;
1431 typedef void(*adopt_fun_t)(void*);
1433 template<class W>
1434 adopt_fun_t get_adopt_fun(W*)
1436 return &detail::adopt_function<T, W>::execute;
1439 adopt_fun_t get_adopt_fun(detail::null_type*)
1441 return 0;
1445 detail::policy_cons<
1446 detail::pure_virtual_tag, detail::null_type> const pure_virtual = {};
1448 namespace detail
1450 inline void ignore_unused_pure_virtual()
1452 (void)pure_virtual;
1457 #ifdef _MSC_VER
1458 #pragma warning(pop)
1459 #endif
1461 #endif // LUABIND_CLASS_HPP_INCLUDED