Added `get_const_holder()` overload for `boost::shared_ptr`.
[luabind.git] / luabind / class.hpp
blob719a8bc02c9d58c00847ca9e0836646c05cd0567
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/detail/constructor.hpp>
99 #include <luabind/detail/call.hpp>
100 #include <luabind/detail/signature_match.hpp>
101 #include <luabind/detail/primitives.hpp>
102 #include <luabind/detail/property.hpp>
103 #include <luabind/detail/typetraits.hpp>
104 #include <luabind/detail/class_rep.hpp>
105 #include <luabind/detail/method_rep.hpp>
106 #include <luabind/detail/construct_rep.hpp>
107 #include <luabind/detail/object_rep.hpp>
108 #include <luabind/detail/calc_arity.hpp>
109 #include <luabind/detail/call_member.hpp>
110 #include <luabind/detail/enum_maker.hpp>
111 #include <luabind/detail/get_signature.hpp>
112 #include <luabind/detail/implicit_cast.hpp>
113 #include <luabind/detail/operator_id.hpp>
114 #include <luabind/detail/pointee_typeid.hpp>
115 #include <luabind/detail/link_compatibility.hpp>
117 // to remove the 'this' used in initialization list-warning
118 #ifdef _MSC_VER
119 #pragma warning(push)
120 #pragma warning(disable: 4355)
121 #endif
123 namespace boost
126 template <class T> class shared_ptr;
128 } // namespace boost
130 namespace luabind
132 namespace detail
134 struct unspecified {};
136 template<class Derived> struct operator_;
138 struct you_need_to_define_a_get_const_holder_function_for_your_smart_ptr {};
141 template<class T, class X1 = detail::unspecified, class X2 = detail::unspecified, class X3 = detail::unspecified>
142 struct class_;
144 // TODO: this function will only be invoked if the user hasn't defined a correct overload
145 // maybe we should have a static assert in here?
146 inline detail::you_need_to_define_a_get_const_holder_function_for_your_smart_ptr*
147 get_const_holder(...)
149 return 0;
152 template <class T>
153 boost::shared_ptr<T const>* get_const_holder(boost::shared_ptr<T>*)
155 return 0;
158 namespace detail
160 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class A)>
161 double is_bases_helper(const bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, A)>&);
163 #ifndef BOOST_MSVC
164 template<class T>
165 char is_bases_helper(const T&);
166 #else
167 char is_bases_helper(...);
168 #endif
170 template<class T>
171 struct is_bases
173 static const T& t;
175 BOOST_STATIC_CONSTANT(bool, value = sizeof(is_bases_helper(t)) == sizeof(double));
176 typedef boost::mpl::bool_<value> type;
177 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_bases,(T))
180 double is_not_unspecified_helper(const unspecified*);
181 char is_not_unspecified_helper(...);
183 template<class T>
184 struct is_not_unspecified
186 BOOST_STATIC_CONSTANT(bool, value = sizeof(is_not_unspecified_helper(static_cast<T*>(0))) == sizeof(char));
187 typedef boost::mpl::bool_<value> type;
188 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_not_unspecified,(T))
191 template<class Predicate>
192 struct get_predicate
194 typedef typename boost::mpl::and_<
195 is_not_unspecified<boost::mpl::_1>
196 , Predicate
197 > type;
200 template<class Parameters, class Predicate, class DefaultValue>
201 struct extract_parameter
203 typedef typename get_predicate<Predicate>::type pred;
204 typedef typename boost::mpl::find_if<Parameters, pred>::type iterator;
205 typedef typename boost::mpl::eval_if<
206 boost::is_same<
207 iterator
208 , typename boost::mpl::end<Parameters>::type
210 , boost::mpl::identity<DefaultValue>
211 , boost::mpl::deref<iterator>
212 >::type type;
215 template<class Fn, class Class, class Policies>
216 struct mem_fn_callback
218 typedef int result_type;
220 int operator()(lua_State* L) const
222 return call(fn, (Class*)0, L, (Policies*)0);
225 mem_fn_callback(Fn fn_)
226 : fn(fn_)
230 Fn fn;
233 template<class Fn, class Class, class Policies>
234 struct mem_fn_matcher
236 typedef int result_type;
238 int operator()(lua_State* L) const
240 return match(fn, L, (Class*)0, (Policies*)0);
243 mem_fn_matcher(Fn fn_)
244 : fn(fn_)
248 Fn fn;
251 struct pure_virtual_tag
253 static void precall(lua_State*, index_map const&) {}
254 static void postcall(lua_State*, index_map const&) {}
257 template<class Policies>
258 struct has_pure_virtual
260 typedef typename boost::mpl::eval_if<
261 boost::is_same<pure_virtual_tag, typename Policies::head>
262 , boost::mpl::true_
263 , has_pure_virtual<typename Policies::tail>
264 >::type type;
266 BOOST_STATIC_CONSTANT(bool, value = type::value);
269 template<>
270 struct has_pure_virtual<null_type>
272 BOOST_STATIC_CONSTANT(bool, value = false);
273 typedef boost::mpl::bool_<value> type;
276 // prints the types of the values on the stack, in the
277 // range [start_index, lua_gettop()]
279 LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index);
281 struct LUABIND_API create_class
283 static int stage1(lua_State* L);
284 static int stage2(lua_State* L);
287 // if the class is held by a smart pointer, we need to be able to
288 // implicitly dereference the pointer when needed.
290 template<class UnderlyingT, class HeldT>
291 struct extract_underlying_type
293 static void* extract(void* ptr)
295 HeldT& held_obj = *reinterpret_cast<HeldT*>(ptr);
296 UnderlyingT* underlying_ptr = static_cast<UnderlyingT*>(get_pointer(held_obj));
297 return underlying_ptr;
301 template<class UnderlyingT, class HeldT>
302 struct extract_underlying_const_type
304 static const void* extract(void* ptr)
306 HeldT& held_obj = *reinterpret_cast<HeldT*>(ptr);
307 const UnderlyingT* underlying_ptr = static_cast<const UnderlyingT*>(get_pointer(held_obj));
308 return underlying_ptr;
312 template<class HeldType>
313 struct internal_holder_extractor
315 typedef void*(*extractor_fun)(void*);
317 template<class T>
318 static extractor_fun apply(detail::type_<T>)
320 return &detail::extract_underlying_type<T, HeldType>::extract;
324 template<>
325 struct internal_holder_extractor<detail::null_type>
327 typedef void*(*extractor_fun)(void*);
329 template<class T>
330 static extractor_fun apply(detail::type_<T>)
332 return 0;
337 template<class HeldType, class ConstHolderType>
338 struct convert_holder
340 static void apply(void* holder, void* target)
342 new(target) ConstHolderType(*reinterpret_cast<HeldType*>(holder));
347 template<class HeldType>
348 struct const_converter
350 typedef void(*converter_fun)(void*, void*);
352 template<class ConstHolderType>
353 static converter_fun apply(ConstHolderType*)
355 return &detail::convert_holder<HeldType, ConstHolderType>::apply;
359 template<>
360 struct const_converter<detail::null_type>
362 typedef void(*converter_fun)(void*, void*);
364 template<class T>
365 static converter_fun apply(T*)
367 return 0;
374 template<class HeldType>
375 struct internal_const_holder_extractor
377 typedef const void*(*extractor_fun)(void*);
379 template<class T>
380 static extractor_fun apply(detail::type_<T>)
382 return get_extractor(detail::type_<T>(), get_const_holder(static_cast<HeldType*>(0)));
384 private:
385 template<class T, class ConstHolderType>
386 static extractor_fun get_extractor(detail::type_<T>, ConstHolderType*)
388 return &detail::extract_underlying_const_type<T, ConstHolderType>::extract;
392 template<>
393 struct internal_const_holder_extractor<detail::null_type>
395 typedef const void*(*extractor_fun)(void*);
397 template<class T>
398 static extractor_fun apply(detail::type_<T>)
400 return 0;
406 // this is simply a selector that returns the type_info
407 // of the held type, or invalid_type_info if we don't have
408 // a held_type
409 template<class HeldType>
410 struct internal_holder_type
412 static LUABIND_TYPE_INFO apply()
414 return LUABIND_TYPEID(HeldType);
418 template<>
419 struct internal_holder_type<detail::null_type>
421 static LUABIND_TYPE_INFO apply()
423 return LUABIND_INVALID_TYPE_INFO;
428 // this is the actual held_type constructor
429 template<class HeldType, class T>
430 struct internal_construct_holder
432 static void apply(void* target, void* raw_pointer)
434 new(target) HeldType(static_cast<T*>(raw_pointer));
438 // this is the actual held_type default constructor
439 template<class HeldType, class T>
440 struct internal_default_construct_holder
442 static void apply(void* target)
444 new(target) HeldType();
448 // the following two functions are the ones that returns
449 // a pointer to a held_type_constructor, or 0 if there
450 // is no held_type
451 template<class HeldType>
452 struct holder_constructor
454 typedef void(*constructor)(void*,void*);
455 template<class T>
456 static constructor apply(detail::type_<T>)
458 return &internal_construct_holder<HeldType, T>::apply;
462 template<>
463 struct holder_constructor<detail::null_type>
465 typedef void(*constructor)(void*,void*);
466 template<class T>
467 static constructor apply(detail::type_<T>)
469 return 0;
473 // the following two functions are the ones that returns
474 // a pointer to a const_held_type_constructor, or 0 if there
475 // is no held_type
476 template<class HolderType>
477 struct const_holder_constructor
479 typedef void(*constructor)(void*,void*);
480 template<class T>
481 static constructor apply(detail::type_<T>)
483 return get_const_holder_constructor(detail::type_<T>(), get_const_holder(static_cast<HolderType*>(0)));
486 private:
488 template<class T, class ConstHolderType>
489 static constructor get_const_holder_constructor(detail::type_<T>, ConstHolderType*)
491 return &internal_construct_holder<ConstHolderType, T>::apply;
495 template<>
496 struct const_holder_constructor<detail::null_type>
498 typedef void(*constructor)(void*,void*);
499 template<class T>
500 static constructor apply(detail::type_<T>)
502 return 0;
507 // the following two functions are the ones that returns
508 // a pointer to a held_type_constructor, or 0 if there
509 // is no held_type. The holder_type is default constructed
510 template<class HeldType>
511 struct holder_default_constructor
513 typedef void(*constructor)(void*);
514 template<class T>
515 static constructor apply(detail::type_<T>)
517 return &internal_default_construct_holder<HeldType, T>::apply;
521 template<>
522 struct holder_default_constructor<detail::null_type>
524 typedef void(*constructor)(void*);
525 template<class T>
526 static constructor apply(detail::type_<T>)
528 return 0;
533 // the following two functions are the ones that returns
534 // a pointer to a const_held_type_constructor, or 0 if there
535 // is no held_type. The constructed held_type is default
536 // constructed
537 template<class HolderType>
538 struct const_holder_default_constructor
540 typedef void(*constructor)(void*);
541 template<class T>
542 static constructor apply(detail::type_<T>)
544 return get_const_holder_default_constructor(detail::type_<T>(), get_const_holder(static_cast<HolderType*>(0)));
547 private:
549 template<class T, class ConstHolderType>
550 static constructor get_const_holder_default_constructor(detail::type_<T>, ConstHolderType*)
552 return &internal_default_construct_holder<ConstHolderType, T>::apply;
556 template<>
557 struct const_holder_default_constructor<detail::null_type>
559 typedef void(*constructor)(void*);
560 template<class T>
561 static constructor apply(detail::type_<T>)
563 return 0;
570 // this is a selector that returns the size of the held_type
571 // or 0 if we don't have a held_type
572 template <class HolderType>
573 struct internal_holder_size
575 static int apply() { return get_internal_holder_size(get_const_holder(static_cast<HolderType*>(0))); }
576 private:
577 template<class ConstHolderType>
578 static int get_internal_holder_size(ConstHolderType*)
580 return max_c<sizeof(HolderType), sizeof(ConstHolderType)>::value;
584 template <>
585 struct internal_holder_size<detail::null_type>
587 static int apply() { return 0; }
591 // if we have a held type, return the destructor to it
592 // note the difference. The held_type should only be destructed (not deleted)
593 // since it's constructed in the lua userdata
594 template<class HeldType>
595 struct internal_holder_destructor
597 typedef void(*destructor_t)(void*);
598 template<class T>
599 static destructor_t apply(detail::type_<T>)
601 return &detail::destruct_only_s<HeldType>::apply;
605 // if we don't have a held type, return the destructor of the raw type
606 template<>
607 struct internal_holder_destructor<detail::null_type>
609 typedef void(*destructor_t)(void*);
610 template<class T>
611 static destructor_t apply(detail::type_<T>)
613 return &detail::delete_s<T>::apply;
618 // if we have a held type, return the destructor to it's const version
619 template<class HolderType>
620 struct internal_const_holder_destructor
622 typedef void(*destructor_t)(void*);
623 template<class T>
624 static destructor_t apply(detail::type_<T>)
626 return const_holder_type_destructor(get_const_holder(static_cast<HolderType*>(0)));
629 private:
631 template<class ConstHolderType>
632 static destructor_t const_holder_type_destructor(ConstHolderType*)
634 return &detail::destruct_only_s<ConstHolderType>::apply;
639 // if we don't have a held type, return the destructor of the raw type
640 template<>
641 struct internal_const_holder_destructor<detail::null_type>
643 typedef void(*destructor_t)(void*);
644 template<class T>
645 static destructor_t apply(detail::type_<T>)
647 return 0;
654 template<class HolderType>
655 struct get_holder_alignment
657 static int apply()
659 return internal_alignment(get_const_holder(static_cast<HolderType*>(0)));
662 private:
664 template<class ConstHolderType>
665 static int internal_alignment(ConstHolderType*)
667 return detail::max_c<boost::alignment_of<HolderType>::value
668 , boost::alignment_of<ConstHolderType>::value>::value;
672 template<>
673 struct get_holder_alignment<detail::null_type>
675 static int apply()
677 return 1;
682 } // detail
684 namespace detail {
686 template<class T>
687 struct static_scope
689 static_scope(T& self_) : self(self_)
693 T& operator[](scope s) const
695 self.add_inner_scope(s);
696 return self;
699 private:
700 template<class U> void operator,(U const&) const;
701 void operator=(static_scope const&);
703 T& self;
706 struct class_registration;
708 struct LUABIND_API class_base : scope
710 public:
711 class_base(char const* name);
713 struct base_desc
715 LUABIND_TYPE_INFO type;
716 int ptr_offset;
719 void init(
720 LUABIND_TYPE_INFO type
721 , LUABIND_TYPE_INFO holder_type
722 , LUABIND_TYPE_INFO const_holder_type
723 , void*(*extractor)(void*)
724 , const void*(*const_extractor)(void*)
725 , void(*const_converter)(void*,void*)
726 , void(*holder_constructor)(void*,void*)
727 , void(*const_holder_constructor)(void*,void*)
728 , void(*holder_default_constructor)(void*)
729 , void(*const_holder_default_constructor)(void*)
730 , void(*destructor)(void*)
731 , void(*const_holder_destructor)(void*)
732 , void(*m_adopt_fun)(void*)
733 , int holder_size
734 , int holder_alignment);
736 void add_getter(
737 const char* name
738 , const boost::function2<int, lua_State*, int>& g);
740 #ifdef LUABIND_NO_ERROR_CHECKING
741 void add_setter(
742 const char* name
743 , const boost::function2<int, lua_State*, int>& s);
744 #else
745 void add_setter(
746 const char* name
747 , const boost::function2<int, lua_State*, int>& s
748 , int (*match)(lua_State*, int)
749 , void (*get_sig_ptr)(lua_State*, std::string&));
750 #endif
752 void add_base(const base_desc& b);
753 void add_constructor(const detail::construct_rep::overload_t& o);
754 void add_method(const char* name, const detail::overload_rep& o);
756 #ifndef LUABIND_NO_ERROR_CHECKING
757 void add_operator(
758 int op_id
759 , int(*func)(lua_State*)
760 , int(*matcher)(lua_State*)
761 , void(*sig)(lua_State*
762 , std::string&)
763 , int arity);
764 #else
765 void add_operator(
766 int op_id
767 , int(*func)(lua_State*)
768 , int(*matcher)(lua_State*)
769 , int arity);
770 #endif
772 const char* name() const;
774 void add_static_constant(const char* name, int val);
775 void add_inner_scope(scope& s);
777 private:
778 class_registration* m_registration;
781 template<class T, class W>
782 struct adopt_function
784 static void execute(void* p)
786 wrapped_self_t& self = wrap_access::ref(
787 *static_cast<W*>(static_cast<T*>(p))
790 LUABIND_CHECK_STACK(self.state());
792 self.get(self.state());
793 self.m_strong_ref.set(self.state());
797 } // namespace detail
799 // registers a class in the lua environment
800 template<class T, class X1, class X2, class X3>
801 struct class_: detail::class_base
803 typedef class_<T, X1, X2, X3> self_t;
805 private:
807 template<class A, class B, class C, class D>
808 class_(const class_<A,B,C,D>&);
810 public:
812 // WrappedType MUST inherit from T
813 typedef typename detail::extract_parameter<
814 boost::mpl::vector3<X1,X2,X3>
815 , boost::is_base_and_derived<T, boost::mpl::_>
816 , detail::null_type
817 >::type WrappedType;
819 typedef typename detail::extract_parameter<
820 boost::mpl::list3<X1,X2,X3>
821 , boost::mpl::not_<
822 boost::mpl::or_<
823 boost::mpl::or_<
824 detail::is_bases<boost::mpl::_>
825 , boost::is_base_and_derived<boost::mpl::_, T>
827 , boost::is_base_and_derived<T, boost::mpl::_>
830 , detail::null_type
831 >::type HeldType;
833 // this function generates conversion information
834 // in the given class_rep structure. It will be able
835 // to implicitly cast to the given template type
836 template<class To>
837 void gen_base_info(detail::type_<To>)
839 // fist, make sure the given base class is registered.
840 // if it's not registered we can't push it's lua table onto
841 // the stack because it doesn't have a table
843 // try to cast this type to the base type and remember
844 // the pointer offset. For multiple inheritance the pointer
845 // may change when casting. Since we need to be able to
846 // cast we need this pointer offset.
847 // store the information in this class' base class-vector
848 base_desc base;
849 base.type = LUABIND_TYPEID(To);
850 base.ptr_offset = detail::ptr_offset(detail::type_<T>(), detail::type_<To>());
851 add_base(base);
854 void gen_base_info(detail::type_<detail::null_type>)
857 #define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type_<B##n>());
859 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class B)>
860 void generate_baseclass_list(detail::type_<bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, B)> >)
862 BOOST_PP_REPEAT(LUABIND_MAX_BASES, LUABIND_GEN_BASE_INFO, _)
865 #undef LUABIND_GEN_BASE_INFO
867 class_(const char* name): class_base(name), scope(*this)
869 #ifndef NDEBUG
870 detail::check_link_compatibility();
871 #endif
872 init();
875 template<class F>
876 class_& def(const char* name, F f)
878 return this->virtual_def(
879 name, f, detail::null_type()
880 , detail::null_type(), boost::mpl::true_());
883 // virtual functions
884 template<class F, class DefaultOrPolicies>
885 class_& def(char const* name, F fn, DefaultOrPolicies default_or_policies)
887 return this->virtual_def(
888 name, fn, default_or_policies, detail::null_type()
889 , LUABIND_MSVC_TYPENAME detail::is_policy_cons<DefaultOrPolicies>::type());
892 template<class F, class Default, class Policies>
893 class_& def(char const* name, F fn
894 , Default default_, Policies const& policies)
896 return this->virtual_def(
897 name, fn, default_
898 , policies, boost::mpl::false_());
901 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)>
902 class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig)
904 return this->def_constructor(
905 boost::is_same<WrappedType, detail::null_type>()
906 , &sig
907 , detail::null_type()
911 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A), class Policies>
912 class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig, const Policies& policies)
914 return this->def_constructor(
915 boost::is_same<WrappedType, detail::null_type>()
916 , &sig
917 , policies
921 template<class Getter>
922 class_& property(const char* name, Getter g)
924 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, detail::null_type>(), _1, _2, g));
925 return *this;
928 template<class Getter, class MaybeSetter>
929 class_& property(const char* name, Getter g, MaybeSetter s)
931 return property_impl(name, g, s, boost::mpl::bool_<detail::is_policy_cons<MaybeSetter>::value>());
934 template<class Getter, class Setter, class GetPolicies>
935 class_& property(const char* name, Getter g, Setter s, const GetPolicies& get_policies)
937 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, GetPolicies>(get_policies), _1, _2, g));
938 #ifndef LUABIND_NO_ERROR_CHECKING
939 add_setter(
940 name
941 , boost::bind<int>(detail::set_caller<T, Setter, detail::null_type>(), _1, _2, s)
942 , detail::gen_set_matcher((Setter)0, (detail::null_type*)0)
943 , &detail::get_member_signature<Setter>::apply);
944 #else
945 add_setter(
946 name
947 , boost::bind<int>(detail::set_caller<T, Setter, detail::null_type>(), _1, _2, s));
948 #endif
949 return *this;
952 template<class Getter, class Setter, class GetPolicies, class SetPolicies>
953 class_& property(const char* name
954 , Getter g, Setter s
955 , const GetPolicies& get_policies
956 , const SetPolicies& set_policies)
958 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, GetPolicies>(get_policies), _1, _2, g));
959 #ifndef LUABIND_NO_ERROR_CHECKING
960 add_setter(
961 name
962 , boost::bind<int>(detail::set_caller<T, Setter, SetPolicies>(), _1, _2, s)
963 , detail::gen_set_matcher((Setter)0, (SetPolicies*)0)
964 , &detail::get_member_signature<Setter>::apply);
965 #else
966 add_setter(name, boost::bind<int>(detail::set_caller<T, Setter, SetPolicies>(set_policies), _1, _2, s));
967 #endif
968 return *this;
971 template<class D>
972 class_& def_readonly(const char* name, D T::*member_ptr)
974 add_getter(name, boost::bind<int>(detail::auto_get<T,D,detail::null_type>(), _1, _2, member_ptr));
975 return *this;
978 template<class D, class Policies>
979 class_& def_readonly(const char* name, D T::*member_ptr, const Policies& policies)
981 add_getter(name, boost::bind<int>(detail::auto_get<T,D,Policies>(policies), _1, _2, member_ptr));
982 return *this;
985 template<class D>
986 class_& def_readwrite(const char* name, D T::*member_ptr)
988 add_getter(name, boost::bind<int>(detail::auto_get<T,D,detail::null_type>(), _1, _2, member_ptr));
989 #ifndef LUABIND_NO_ERROR_CHECKING
990 add_setter(
991 name
992 , boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr)
993 , &detail::set_matcher<D, detail::null_type>::apply
994 , &detail::get_setter_signature<D>::apply);
995 #else
996 add_setter(name, boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr));
997 #endif
998 return *this;
1001 template<class D, class GetPolicies>
1002 class_& def_readwrite(const char* name, D T::*member_ptr, const GetPolicies& get_policies)
1004 add_getter(name, boost::bind<int>(detail::auto_get<T,D,GetPolicies>(get_policies), _1, _2, member_ptr));
1005 #ifndef LUABIND_NO_ERROR_CHECKING
1006 add_setter(
1007 name
1008 , boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr)
1009 , &detail::set_matcher<D, detail::null_type>::apply
1010 , &detail::get_setter_signature<D>::apply);
1011 #else
1012 add_setter(name, boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr));
1013 #endif
1014 return *this;
1017 template<class D, class GetPolicies, class SetPolicies>
1018 class_& def_readwrite(const char* name, D T::*member_ptr, const GetPolicies& get_policies, const SetPolicies& set_policies)
1020 add_getter(name, boost::bind<int>(detail::auto_get<T,D,GetPolicies>(get_policies), _1, _2, member_ptr));
1021 #ifndef LUABIND_NO_ERROR_CHECKING
1022 add_setter(
1023 name
1024 , boost::bind<int>(detail::auto_set<T,D,SetPolicies>(), _1, _2, member_ptr)
1025 , &detail::set_matcher<D, SetPolicies>::apply
1026 , &detail::get_setter_signature<D>::apply);
1027 #else
1028 add_setter(name, boost::bind<int>(detail::auto_set<T,D,SetPolicies>(set_policies), _1, _2, member_ptr));
1029 #endif
1030 return *this;
1033 template<class Derived, class Policies>
1034 class_& def(detail::operator_<Derived>, Policies const& policies)
1036 return this->def(
1037 Derived::name()
1038 , &Derived::template apply<T, Policies>::execute
1039 , raw(_1) + policies
1043 template<class Derived>
1044 class_& def(detail::operator_<Derived>)
1046 return this->def(
1047 Derived::name()
1048 , &Derived::template apply<T, detail::null_type>::execute
1049 , raw(_1)
1054 template<class op_id, class Left, class Right, class Policies>
1055 class_& def(detail::operator_<op_id, Left, Right>, const Policies& policies)
1057 typedef typename detail::operator_unwrapper<Policies, op_id, T, Left, Right> op_type;
1058 #ifndef LUABIND_NO_ERROR_CHECKING
1059 add_operator(op_type::get_id()
1060 , &op_type::execute
1061 , &op_type::match
1062 , &detail::get_signature<constructor<typename op_type::left_t, typename op_type::right_t> >::apply
1063 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1064 #else
1065 add_operator(op_type::get_id()
1066 , &op_type::execute
1067 , &op_type::match
1068 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1069 #endif
1070 return *this;
1073 template<class op_id, class Left, class Right>
1074 class_& def(detail::operator_<op_id, Left, Right>)
1076 typedef typename detail::operator_unwrapper<detail::null_type, op_id, T, Left, Right> op_type;
1078 #ifndef LUABIND_NO_ERROR_CHECKING
1079 add_operator(op_type::get_id()
1080 , &op_type::execute
1081 , &op_type::match
1082 , &detail::get_signature<constructor<LUABIND_MSVC_TYPENAME op_type::left_t, LUABIND_MSVC_TYPENAME op_type::right_t> >::apply
1083 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1084 #else
1085 add_operator(op_type::get_id()
1086 , &op_type::execute
1087 , &op_type::match
1088 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1089 #endif
1090 return *this;
1093 template<class Signature, bool Constant>
1094 class_& def(detail::application_operator<Signature, Constant>*)
1096 typedef detail::application_operator<Signature, Constant, detail::null_type> op_t;
1098 int arity = detail::calc_arity<Signature::arity>::apply(
1099 Signature(), static_cast<detail::null_type*>(0));
1101 #ifndef LUABIND_NO_ERROR_CHECKING
1102 add_operator(
1103 detail::op_call
1104 , &op_t::template apply<T>::execute
1105 , &op_t::match
1106 , &detail::get_signature<Signature>::apply
1107 , arity + 1);
1108 #else
1109 add_operator(
1110 detail::op_call
1111 , &op_t::template apply<T>::execute
1112 , &op_t::match
1113 , arity + 1);
1114 #endif
1116 return *this;
1119 template<class Signature, bool Constant, class Policies>
1120 class_& def(detail::application_operator<Signature, Constant>*, const Policies& policies)
1122 typedef detail::application_operator<Signature, Constant, Policies> op_t;
1124 int arity = detail::calc_arity<Signature::arity>::apply(Signature(), static_cast<Policies*>(0));
1126 #ifndef LUABIND_NO_ERROR_CHECKING
1127 add_operator(
1128 detail::op_call
1129 , &op_t::template apply<T>::execute
1130 , &op_t::match
1131 , &detail::get_signature<Signature>::apply
1132 , arity + 1);
1133 #else
1134 add_operator(
1135 detail::op_call
1136 , &op_t::template apply<T>::execute
1137 , &op_t::match
1138 , arity + 1);
1139 #endif
1141 return *this;
1144 detail::enum_maker<self_t> enum_(const char*)
1146 return detail::enum_maker<self_t>(*this);
1149 detail::static_scope<self_t> scope;
1151 private:
1152 void operator=(class_ const&);
1154 void init()
1156 typedef typename detail::extract_parameter<
1157 boost::mpl::list3<X1,X2,X3>
1158 , boost::mpl::or_<
1159 detail::is_bases<boost::mpl::_>
1160 , boost::is_base_and_derived<boost::mpl::_, T>
1162 , no_bases
1163 >::type bases_t;
1165 typedef typename
1166 boost::mpl::if_<detail::is_bases<bases_t>
1167 , bases_t
1168 , bases<bases_t>
1169 >::type Base;
1171 class_base::init(LUABIND_TYPEID(T)
1172 , detail::internal_holder_type<HeldType>::apply()
1173 , detail::pointee_typeid(
1174 get_const_holder(static_cast<HeldType*>(0)))
1175 , detail::internal_holder_extractor<HeldType>::apply(detail::type_<T>())
1176 , detail::internal_const_holder_extractor<HeldType>::apply(detail::type_<T>())
1177 , detail::const_converter<HeldType>::apply(
1178 get_const_holder((HeldType*)0))
1179 , detail::holder_constructor<HeldType>::apply(detail::type_<T>())
1180 , detail::const_holder_constructor<HeldType>::apply(detail::type_<T>())
1181 , detail::holder_default_constructor<HeldType>::apply(detail::type_<T>())
1182 , detail::const_holder_default_constructor<HeldType>::apply(detail::type_<T>())
1183 , get_adopt_fun((WrappedType*)0) // adopt fun
1184 , detail::internal_holder_destructor<HeldType>::apply(detail::type_<T>())
1185 , detail::internal_const_holder_destructor<HeldType>::apply(detail::type_<T>())
1186 , detail::internal_holder_size<HeldType>::apply()
1187 , detail::get_holder_alignment<HeldType>::apply());
1189 generate_baseclass_list(detail::type_<Base>());
1192 template<class Getter, class GetPolicies>
1193 class_& property_impl(const char* name,
1194 Getter g,
1195 GetPolicies policies,
1196 boost::mpl::bool_<true>)
1198 add_getter(name, boost::bind<int>(detail::get_caller<T,Getter,GetPolicies>(policies), _1, _2, g));
1199 return *this;
1202 template<class Getter, class Setter>
1203 class_& property_impl(const char* name,
1204 Getter g,
1205 Setter s,
1206 boost::mpl::bool_<false>)
1208 add_getter(name, boost::bind<int>(detail::get_caller<T,Getter,detail::null_type>(), _1, _2, g));
1209 #ifndef LUABIND_NO_ERROR_CHECKING
1210 add_setter(
1211 name
1212 , boost::bind<int>(detail::set_caller<T, Setter, detail::null_type>(), _1, _2, s)
1213 , detail::gen_set_matcher((Setter)0, (detail::null_type*)0)
1214 , &detail::get_member_signature<Setter>::apply);
1215 #else
1216 add_setter(name, boost::bind<int>(detail::set_caller<T,Setter,detail::null_type>(), _1, _2, s));
1217 #endif
1218 return *this;
1221 // these handle default implementation of virtual functions
1222 template<class F, class Policies>
1223 class_& virtual_def(char const* name, F const& fn
1224 , Policies const&, detail::null_type, boost::mpl::true_)
1226 // normal def() call
1227 detail::overload_rep o(fn, static_cast<Policies*>(0));
1229 o.set_match_fun(detail::mem_fn_matcher<F, T, Policies>(fn));
1230 o.set_fun(detail::mem_fn_callback<F, T, Policies>(fn));
1232 #ifndef LUABIND_NO_ERROR_CHECKING
1233 o.set_sig_fun(&detail::get_member_signature<F>::apply);
1234 #endif
1235 this->add_method(name, o);
1236 return *this;
1239 template<class F, class Default, class Policies>
1240 class_& virtual_def(char const* name, F const& fn
1241 , Default const& default_, Policies const&, boost::mpl::false_)
1243 // default_ is a default implementation
1244 // policies is either null_type or a policy list
1246 // normal def() call
1247 detail::overload_rep o(fn, (Policies*)0);
1249 o.set_match_fun(detail::mem_fn_matcher<F, T, Policies>(fn));
1250 o.set_fun(detail::mem_fn_callback<F, T, Policies>(fn));
1252 o.set_fun_static(
1253 detail::mem_fn_callback<Default, T, Policies>(default_));
1255 #ifndef LUABIND_NO_ERROR_CHECKING
1256 o.set_sig_fun(&detail::get_member_signature<F>::apply);
1257 #endif
1259 this->add_method(name, o);
1260 // register virtual function
1261 return *this;
1264 template<class Signature, class Policies>
1265 class_& def_constructor(
1266 boost::mpl::true_ /* HasWrapper */
1267 , Signature*
1268 , Policies const&)
1270 detail::construct_rep::overload_t o;
1272 o.set_constructor(
1273 &detail::construct_class<
1275 , Policies
1276 , Signature
1277 >::apply);
1279 o.set_match_fun(
1280 &detail::constructor_match<
1281 Signature
1283 , Policies
1284 >::apply);
1286 #ifndef LUABIND_NO_ERROR_CHECKING
1287 o.set_sig_fun(&detail::get_signature<Signature>::apply);
1288 #endif
1289 o.set_arity(detail::calc_arity<Signature::arity>::apply(Signature(), (Policies*)0));
1290 this->add_constructor(o);
1291 return *this;
1294 template<class Signature, class Policies>
1295 class_& def_constructor(
1296 boost::mpl::false_ /* !HasWrapper */
1297 , Signature*
1298 , Policies const&)
1300 detail::construct_rep::overload_t o;
1302 o.set_constructor(
1303 &detail::construct_wrapped_class<
1305 , WrappedType
1306 , Policies
1307 , Signature
1308 >::apply);
1310 o.set_match_fun(
1311 &detail::constructor_match<
1312 Signature
1314 , Policies
1315 >::apply);
1317 #ifndef LUABIND_NO_ERROR_CHECKING
1318 o.set_sig_fun(&detail::get_signature<Signature>::apply);
1319 #endif
1320 o.set_arity(detail::calc_arity<Signature::arity>::apply(Signature(), (Policies*)0));
1321 this->add_constructor(o);
1322 return *this;
1325 typedef void(*adopt_fun_t)(void*);
1327 template<class W>
1328 adopt_fun_t get_adopt_fun(W*)
1330 return &detail::adopt_function<T, W>::execute;
1333 adopt_fun_t get_adopt_fun(detail::null_type*)
1335 return 0;
1339 namespace
1341 LUABIND_ANONYMOUS_FIX detail::policy_cons<
1342 detail::pure_virtual_tag
1343 , detail::null_type
1344 > pure_virtual;
1348 #ifdef _MSC_VER
1349 #pragma warning(pop)
1350 #endif
1352 #endif // LUABIND_CLASS_HPP_INCLUDED