fixed #59. Wrong return value in two-argument object::operator().
[luabind.git] / luabind / class.hpp
blob65059f9c53c5ea2e2d081af8a32ec039206c02be
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
124 namespace luabind
126 namespace detail
128 struct unspecified {};
130 template<class Derived> struct operator_;
132 struct you_need_to_define_a_get_const_holder_function_for_your_smart_ptr {};
135 template<class T, class X1 = detail::unspecified, class X2 = detail::unspecified, class X3 = detail::unspecified>
136 struct class_;
138 // TODO: this function will only be invoked if the user hasn't defined a correct overload
139 // maybe we should have a static assert in here?
140 inline detail::you_need_to_define_a_get_const_holder_function_for_your_smart_ptr*
141 get_const_holder(...)
143 return 0;
146 namespace detail
148 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class A)>
149 double is_bases_helper(const bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, A)>&);
151 #ifndef BOOST_MSVC
152 template<class T>
153 char is_bases_helper(const T&);
154 #else
155 char is_bases_helper(...);
156 #endif
158 template<class T>
159 struct is_bases
161 static const T& t;
163 BOOST_STATIC_CONSTANT(bool, value = sizeof(is_bases_helper(t)) == sizeof(double));
164 typedef boost::mpl::bool_<value> type;
165 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_bases,(T))
168 double is_not_unspecified_helper(const unspecified*);
169 char is_not_unspecified_helper(...);
171 template<class T>
172 struct is_not_unspecified
174 BOOST_STATIC_CONSTANT(bool, value = sizeof(is_not_unspecified_helper(static_cast<T*>(0))) == sizeof(char));
175 typedef boost::mpl::bool_<value> type;
176 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_not_unspecified,(T))
179 template<class Predicate>
180 struct get_predicate
182 typedef typename boost::mpl::and_<
183 is_not_unspecified<boost::mpl::_1>
184 , Predicate
185 > type;
188 template<class Parameters, class Predicate, class DefaultValue>
189 struct extract_parameter
191 typedef typename get_predicate<Predicate>::type pred;
192 typedef typename boost::mpl::find_if<Parameters, pred>::type iterator;
193 typedef typename boost::mpl::eval_if<
194 boost::is_same<
195 iterator
196 , typename boost::mpl::end<Parameters>::type
198 , boost::mpl::identity<DefaultValue>
199 , boost::mpl::deref<iterator>
200 >::type type;
203 template<class Fn, class Class, class Policies>
204 struct mem_fn_callback
206 typedef int result_type;
208 int operator()(lua_State* L) const
210 return call(fn, (Class*)0, L, (Policies*)0);
213 mem_fn_callback(Fn fn_)
214 : fn(fn_)
218 Fn fn;
221 template<class Fn, class Class, class Policies>
222 struct mem_fn_matcher
224 typedef int result_type;
226 int operator()(lua_State* L) const
228 return match(fn, L, (Class*)0, (Policies*)0);
231 mem_fn_matcher(Fn fn_)
232 : fn(fn_)
236 Fn fn;
239 struct pure_virtual_tag
241 static void precall(lua_State*, index_map const&) {}
242 static void postcall(lua_State*, index_map const&) {}
245 template<class Policies>
246 struct has_pure_virtual
248 typedef typename boost::mpl::eval_if<
249 boost::is_same<pure_virtual_tag, typename Policies::head>
250 , boost::mpl::true_
251 , has_pure_virtual<typename Policies::tail>
252 >::type type;
254 BOOST_STATIC_CONSTANT(bool, value = type::value);
257 template<>
258 struct has_pure_virtual<null_type>
260 BOOST_STATIC_CONSTANT(bool, value = false);
261 typedef boost::mpl::bool_<value> type;
264 // prints the types of the values on the stack, in the
265 // range [start_index, lua_gettop()]
267 LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index);
269 struct LUABIND_API create_class
271 static int stage1(lua_State* L);
272 static int stage2(lua_State* L);
275 // if the class is held by a smart pointer, we need to be able to
276 // implicitly dereference the pointer when needed.
278 template<class UnderlyingT, class HeldT>
279 struct extract_underlying_type
281 static void* extract(void* ptr)
283 HeldT& held_obj = *reinterpret_cast<HeldT*>(ptr);
284 UnderlyingT* underlying_ptr = static_cast<UnderlyingT*>(get_pointer(held_obj));
285 return underlying_ptr;
289 template<class UnderlyingT, class HeldT>
290 struct extract_underlying_const_type
292 static const void* extract(void* ptr)
294 HeldT& held_obj = *reinterpret_cast<HeldT*>(ptr);
295 const UnderlyingT* underlying_ptr = static_cast<const UnderlyingT*>(get_pointer(held_obj));
296 return underlying_ptr;
300 template<class HeldType>
301 struct internal_holder_extractor
303 typedef void*(*extractor_fun)(void*);
305 template<class T>
306 static extractor_fun apply(detail::type_<T>)
308 return &detail::extract_underlying_type<T, HeldType>::extract;
312 template<>
313 struct internal_holder_extractor<detail::null_type>
315 typedef void*(*extractor_fun)(void*);
317 template<class T>
318 static extractor_fun apply(detail::type_<T>)
320 return 0;
325 template<class HeldType, class ConstHolderType>
326 struct convert_holder
328 static void apply(void* holder, void* target)
330 new(target) ConstHolderType(*reinterpret_cast<HeldType*>(holder));
335 template<class HeldType>
336 struct const_converter
338 typedef void(*converter_fun)(void*, void*);
340 template<class ConstHolderType>
341 static converter_fun apply(ConstHolderType*)
343 return &detail::convert_holder<HeldType, ConstHolderType>::apply;
347 template<>
348 struct const_converter<detail::null_type>
350 typedef void(*converter_fun)(void*, void*);
352 template<class T>
353 static converter_fun apply(T*)
355 return 0;
362 template<class HeldType>
363 struct internal_const_holder_extractor
365 typedef const void*(*extractor_fun)(void*);
367 template<class T>
368 static extractor_fun apply(detail::type_<T>)
370 return get_extractor(detail::type_<T>(), get_const_holder(static_cast<HeldType*>(0)));
372 private:
373 template<class T, class ConstHolderType>
374 static extractor_fun get_extractor(detail::type_<T>, ConstHolderType*)
376 return &detail::extract_underlying_const_type<T, ConstHolderType>::extract;
380 template<>
381 struct internal_const_holder_extractor<detail::null_type>
383 typedef const void*(*extractor_fun)(void*);
385 template<class T>
386 static extractor_fun apply(detail::type_<T>)
388 return 0;
394 // this is simply a selector that returns the type_info
395 // of the held type, or invalid_type_info if we don't have
396 // a held_type
397 template<class HeldType>
398 struct internal_holder_type
400 static LUABIND_TYPE_INFO apply()
402 return LUABIND_TYPEID(HeldType);
406 template<>
407 struct internal_holder_type<detail::null_type>
409 static LUABIND_TYPE_INFO apply()
411 return LUABIND_INVALID_TYPE_INFO;
416 // this is the actual held_type constructor
417 template<class HeldType, class T>
418 struct internal_construct_holder
420 static void apply(void* target, void* raw_pointer)
422 new(target) HeldType(static_cast<T*>(raw_pointer));
426 // this is the actual held_type default constructor
427 template<class HeldType, class T>
428 struct internal_default_construct_holder
430 static void apply(void* target)
432 new(target) HeldType();
436 // the following two functions are the ones that returns
437 // a pointer to a held_type_constructor, or 0 if there
438 // is no held_type
439 template<class HeldType>
440 struct holder_constructor
442 typedef void(*constructor)(void*,void*);
443 template<class T>
444 static constructor apply(detail::type_<T>)
446 return &internal_construct_holder<HeldType, T>::apply;
450 template<>
451 struct holder_constructor<detail::null_type>
453 typedef void(*constructor)(void*,void*);
454 template<class T>
455 static constructor apply(detail::type_<T>)
457 return 0;
461 // the following two functions are the ones that returns
462 // a pointer to a const_held_type_constructor, or 0 if there
463 // is no held_type
464 template<class HolderType>
465 struct const_holder_constructor
467 typedef void(*constructor)(void*,void*);
468 template<class T>
469 static constructor apply(detail::type_<T>)
471 return get_const_holder_constructor(detail::type_<T>(), get_const_holder(static_cast<HolderType*>(0)));
474 private:
476 template<class T, class ConstHolderType>
477 static constructor get_const_holder_constructor(detail::type_<T>, ConstHolderType*)
479 return &internal_construct_holder<ConstHolderType, T>::apply;
483 template<>
484 struct const_holder_constructor<detail::null_type>
486 typedef void(*constructor)(void*,void*);
487 template<class T>
488 static constructor apply(detail::type_<T>)
490 return 0;
495 // the following two functions are the ones that returns
496 // a pointer to a held_type_constructor, or 0 if there
497 // is no held_type. The holder_type is default constructed
498 template<class HeldType>
499 struct holder_default_constructor
501 typedef void(*constructor)(void*);
502 template<class T>
503 static constructor apply(detail::type_<T>)
505 return &internal_default_construct_holder<HeldType, T>::apply;
509 template<>
510 struct holder_default_constructor<detail::null_type>
512 typedef void(*constructor)(void*);
513 template<class T>
514 static constructor apply(detail::type_<T>)
516 return 0;
521 // the following two functions are the ones that returns
522 // a pointer to a const_held_type_constructor, or 0 if there
523 // is no held_type. The constructed held_type is default
524 // constructed
525 template<class HolderType>
526 struct const_holder_default_constructor
528 typedef void(*constructor)(void*);
529 template<class T>
530 static constructor apply(detail::type_<T>)
532 return get_const_holder_default_constructor(detail::type_<T>(), get_const_holder(static_cast<HolderType*>(0)));
535 private:
537 template<class T, class ConstHolderType>
538 static constructor get_const_holder_default_constructor(detail::type_<T>, ConstHolderType*)
540 return &internal_default_construct_holder<ConstHolderType, T>::apply;
544 template<>
545 struct const_holder_default_constructor<detail::null_type>
547 typedef void(*constructor)(void*);
548 template<class T>
549 static constructor apply(detail::type_<T>)
551 return 0;
558 // this is a selector that returns the size of the held_type
559 // or 0 if we don't have a held_type
560 template <class HolderType>
561 struct internal_holder_size
563 static int apply() { return get_internal_holder_size(get_const_holder(static_cast<HolderType*>(0))); }
564 private:
565 template<class ConstHolderType>
566 static int get_internal_holder_size(ConstHolderType*)
568 return max_c<sizeof(HolderType), sizeof(ConstHolderType)>::value;
572 template <>
573 struct internal_holder_size<detail::null_type>
575 static int apply() { return 0; }
579 // if we have a held type, return the destructor to it
580 // note the difference. The held_type should only be destructed (not deleted)
581 // since it's constructed in the lua userdata
582 template<class HeldType>
583 struct internal_holder_destructor
585 typedef void(*destructor_t)(void*);
586 template<class T>
587 static destructor_t apply(detail::type_<T>)
589 return &detail::destruct_only_s<HeldType>::apply;
593 // if we don't have a held type, return the destructor of the raw type
594 template<>
595 struct internal_holder_destructor<detail::null_type>
597 typedef void(*destructor_t)(void*);
598 template<class T>
599 static destructor_t apply(detail::type_<T>)
601 return &detail::delete_s<T>::apply;
606 // if we have a held type, return the destructor to it's const version
607 template<class HolderType>
608 struct internal_const_holder_destructor
610 typedef void(*destructor_t)(void*);
611 template<class T>
612 static destructor_t apply(detail::type_<T>)
614 return const_holder_type_destructor(get_const_holder(static_cast<HolderType*>(0)));
617 private:
619 template<class ConstHolderType>
620 static destructor_t const_holder_type_destructor(ConstHolderType*)
622 return &detail::destruct_only_s<ConstHolderType>::apply;
627 // if we don't have a held type, return the destructor of the raw type
628 template<>
629 struct internal_const_holder_destructor<detail::null_type>
631 typedef void(*destructor_t)(void*);
632 template<class T>
633 static destructor_t apply(detail::type_<T>)
635 return 0;
642 template<class HolderType>
643 struct get_holder_alignment
645 static int apply()
647 return internal_alignment(get_const_holder(static_cast<HolderType*>(0)));
650 private:
652 template<class ConstHolderType>
653 static int internal_alignment(ConstHolderType*)
655 return detail::max_c<boost::alignment_of<HolderType>::value
656 , boost::alignment_of<ConstHolderType>::value>::value;
660 template<>
661 struct get_holder_alignment<detail::null_type>
663 static int apply()
665 return 1;
670 } // detail
672 namespace detail {
674 template<class T>
675 struct static_scope
677 static_scope(T& self_) : self(self_)
681 T& operator[](scope s) const
683 self.add_inner_scope(s);
684 return self;
687 private:
688 template<class U> void operator,(U const&) const;
689 void operator=(static_scope const&);
691 T& self;
694 struct class_registration;
696 struct LUABIND_API class_base : scope
698 public:
699 class_base(char const* name);
701 struct base_desc
703 LUABIND_TYPE_INFO type;
704 int ptr_offset;
707 void init(
708 LUABIND_TYPE_INFO type
709 , LUABIND_TYPE_INFO holder_type
710 , LUABIND_TYPE_INFO const_holder_type
711 , void*(*extractor)(void*)
712 , const void*(*const_extractor)(void*)
713 , void(*const_converter)(void*,void*)
714 , void(*holder_constructor)(void*,void*)
715 , void(*const_holder_constructor)(void*,void*)
716 , void(*holder_default_constructor)(void*)
717 , void(*const_holder_default_constructor)(void*)
718 , void(*destructor)(void*)
719 , void(*const_holder_destructor)(void*)
720 , void(*m_adopt_fun)(void*)
721 , int holder_size
722 , int holder_alignment);
724 void add_getter(
725 const char* name
726 , const boost::function2<int, lua_State*, int>& g);
728 #ifdef LUABIND_NO_ERROR_CHECKING
729 void add_setter(
730 const char* name
731 , const boost::function2<int, lua_State*, int>& s);
732 #else
733 void add_setter(
734 const char* name
735 , const boost::function2<int, lua_State*, int>& s
736 , int (*match)(lua_State*, int)
737 , void (*get_sig_ptr)(lua_State*, std::string&));
738 #endif
740 void add_base(const base_desc& b);
741 void add_constructor(const detail::construct_rep::overload_t& o);
742 void add_method(const char* name, const detail::overload_rep& o);
744 #ifndef LUABIND_NO_ERROR_CHECKING
745 void add_operator(
746 int op_id
747 , int(*func)(lua_State*)
748 , int(*matcher)(lua_State*)
749 , void(*sig)(lua_State*
750 , std::string&)
751 , int arity);
752 #else
753 void add_operator(
754 int op_id
755 , int(*func)(lua_State*)
756 , int(*matcher)(lua_State*)
757 , int arity);
758 #endif
760 const char* name() const;
762 void add_static_constant(const char* name, int val);
763 void add_inner_scope(scope& s);
765 private:
766 class_registration* m_registration;
769 template<class T, class W>
770 struct adopt_function
772 static void execute(void* p)
774 wrapped_self_t& self = wrap_access::ref(
775 *static_cast<W*>(static_cast<T*>(p))
778 LUABIND_CHECK_STACK(self.state());
780 self.get(self.state());
781 self.m_strong_ref.set(self.state());
785 } // namespace detail
787 // registers a class in the lua environment
788 template<class T, class X1, class X2, class X3>
789 struct class_: detail::class_base
791 typedef class_<T, X1, X2, X3> self_t;
793 private:
795 template<class A, class B, class C, class D>
796 class_(const class_<A,B,C,D>&);
798 public:
800 // WrappedType MUST inherit from T
801 typedef typename detail::extract_parameter<
802 boost::mpl::vector3<X1,X2,X3>
803 , boost::is_base_and_derived<T, boost::mpl::_>
804 , detail::null_type
805 >::type WrappedType;
807 typedef typename detail::extract_parameter<
808 boost::mpl::list3<X1,X2,X3>
809 , boost::mpl::not_<
810 boost::mpl::or_<
811 boost::mpl::or_<
812 detail::is_bases<boost::mpl::_>
813 , boost::is_base_and_derived<boost::mpl::_, T>
815 , boost::is_base_and_derived<T, boost::mpl::_>
818 , detail::null_type
819 >::type HeldType;
821 // this function generates conversion information
822 // in the given class_rep structure. It will be able
823 // to implicitly cast to the given template type
824 template<class To>
825 void gen_base_info(detail::type_<To>)
827 // fist, make sure the given base class is registered.
828 // if it's not registered we can't push it's lua table onto
829 // the stack because it doesn't have a table
831 // try to cast this type to the base type and remember
832 // the pointer offset. For multiple inheritance the pointer
833 // may change when casting. Since we need to be able to
834 // cast we need this pointer offset.
835 // store the information in this class' base class-vector
836 base_desc base;
837 base.type = LUABIND_TYPEID(To);
838 base.ptr_offset = detail::ptr_offset(detail::type_<T>(), detail::type_<To>());
839 add_base(base);
842 void gen_base_info(detail::type_<detail::null_type>)
845 #define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type_<B##n>());
847 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class B)>
848 void generate_baseclass_list(detail::type_<bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, B)> >)
850 BOOST_PP_REPEAT(LUABIND_MAX_BASES, LUABIND_GEN_BASE_INFO, _)
853 #undef LUABIND_GEN_BASE_INFO
855 class_(const char* name): class_base(name), scope(*this)
857 #ifndef NDEBUG
858 detail::check_link_compatibility();
859 #endif
860 init();
863 template<class F>
864 class_& def(const char* name, F f)
866 return this->virtual_def(
867 name, f, detail::null_type()
868 , detail::null_type(), boost::mpl::true_());
871 // virtual functions
872 template<class F, class DefaultOrPolicies>
873 class_& def(char const* name, F fn, DefaultOrPolicies default_or_policies)
875 return this->virtual_def(
876 name, fn, default_or_policies, detail::null_type()
877 , LUABIND_MSVC_TYPENAME detail::is_policy_cons<DefaultOrPolicies>::type());
880 template<class F, class Default, class Policies>
881 class_& def(char const* name, F fn
882 , Default default_, Policies const& policies)
884 return this->virtual_def(
885 name, fn, default_
886 , policies, boost::mpl::false_());
889 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)>
890 class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig)
892 return this->def_constructor(
893 boost::is_same<WrappedType, detail::null_type>()
894 , &sig
895 , detail::null_type()
899 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A), class Policies>
900 class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig, const Policies& policies)
902 return this->def_constructor(
903 boost::is_same<WrappedType, detail::null_type>()
904 , &sig
905 , policies
909 template<class Getter>
910 class_& property(const char* name, Getter g)
912 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, detail::null_type>(), _1, _2, g));
913 return *this;
916 template<class Getter, class MaybeSetter>
917 class_& property(const char* name, Getter g, MaybeSetter s)
919 return property_impl(name, g, s, boost::mpl::bool_<detail::is_policy_cons<MaybeSetter>::value>());
922 template<class Getter, class Setter, class GetPolicies>
923 class_& property(const char* name, Getter g, Setter s, const GetPolicies& get_policies)
925 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, GetPolicies>(get_policies), _1, _2, g));
926 #ifndef LUABIND_NO_ERROR_CHECKING
927 add_setter(
928 name
929 , boost::bind<int>(detail::set_caller<T, Setter, detail::null_type>(), _1, _2, s)
930 , detail::gen_set_matcher((Setter)0, (detail::null_type*)0)
931 , &detail::get_member_signature<Setter>::apply);
932 #else
933 add_setter(
934 name
935 , boost::bind<int>(detail::set_caller<T, Setter, detail::null_type>(), _1, _2, s));
936 #endif
937 return *this;
940 template<class Getter, class Setter, class GetPolicies, class SetPolicies>
941 class_& property(const char* name
942 , Getter g, Setter s
943 , const GetPolicies& get_policies
944 , const SetPolicies& set_policies)
946 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, GetPolicies>(get_policies), _1, _2, g));
947 #ifndef LUABIND_NO_ERROR_CHECKING
948 add_setter(
949 name
950 , boost::bind<int>(detail::set_caller<T, Setter, SetPolicies>(), _1, _2, s)
951 , detail::gen_set_matcher((Setter)0, (SetPolicies*)0)
952 , &detail::get_member_signature<Setter>::apply);
953 #else
954 add_setter(name, boost::bind<int>(detail::set_caller<T, Setter, SetPolicies>(set_policies), _1, _2, s));
955 #endif
956 return *this;
959 template<class D>
960 class_& def_readonly(const char* name, D T::*member_ptr)
962 add_getter(name, boost::bind<int>(detail::auto_get<T,D,detail::null_type>(), _1, _2, member_ptr));
963 return *this;
966 template<class D, class Policies>
967 class_& def_readonly(const char* name, D T::*member_ptr, const Policies& policies)
969 add_getter(name, boost::bind<int>(detail::auto_get<T,D,Policies>(policies), _1, _2, member_ptr));
970 return *this;
973 template<class D>
974 class_& def_readwrite(const char* name, D T::*member_ptr)
976 add_getter(name, boost::bind<int>(detail::auto_get<T,D,detail::null_type>(), _1, _2, member_ptr));
977 #ifndef LUABIND_NO_ERROR_CHECKING
978 add_setter(
979 name
980 , boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr)
981 , &detail::set_matcher<D, detail::null_type>::apply
982 , &detail::get_setter_signature<D>::apply);
983 #else
984 add_setter(name, boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr));
985 #endif
986 return *this;
989 template<class D, class GetPolicies>
990 class_& def_readwrite(const char* name, D T::*member_ptr, const GetPolicies& get_policies)
992 add_getter(name, boost::bind<int>(detail::auto_get<T,D,GetPolicies>(get_policies), _1, _2, member_ptr));
993 #ifndef LUABIND_NO_ERROR_CHECKING
994 add_setter(
995 name
996 , boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr)
997 , &detail::set_matcher<D, detail::null_type>::apply
998 , &detail::get_setter_signature<D>::apply);
999 #else
1000 add_setter(name, boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr));
1001 #endif
1002 return *this;
1005 template<class D, class GetPolicies, class SetPolicies>
1006 class_& def_readwrite(const char* name, D T::*member_ptr, const GetPolicies& get_policies, const SetPolicies& set_policies)
1008 add_getter(name, boost::bind<int>(detail::auto_get<T,D,GetPolicies>(get_policies), _1, _2, member_ptr));
1009 #ifndef LUABIND_NO_ERROR_CHECKING
1010 add_setter(
1011 name
1012 , boost::bind<int>(detail::auto_set<T,D,SetPolicies>(), _1, _2, member_ptr)
1013 , &detail::set_matcher<D, SetPolicies>::apply
1014 , &detail::get_setter_signature<D>::apply);
1015 #else
1016 add_setter(name, boost::bind<int>(detail::auto_set<T,D,SetPolicies>(set_policies), _1, _2, member_ptr));
1017 #endif
1018 return *this;
1021 template<class Derived, class Policies>
1022 class_& def(detail::operator_<Derived>, Policies const& policies)
1024 return this->def(
1025 Derived::name()
1026 , &Derived::template apply<T, Policies>::execute
1027 , raw(_1) + policies
1031 template<class Derived>
1032 class_& def(detail::operator_<Derived>)
1034 return this->def(
1035 Derived::name()
1036 , &Derived::template apply<T, detail::null_type>::execute
1037 , raw(_1)
1042 template<class op_id, class Left, class Right, class Policies>
1043 class_& def(detail::operator_<op_id, Left, Right>, const Policies& policies)
1045 typedef typename detail::operator_unwrapper<Policies, op_id, T, Left, Right> op_type;
1046 #ifndef LUABIND_NO_ERROR_CHECKING
1047 add_operator(op_type::get_id()
1048 , &op_type::execute
1049 , &op_type::match
1050 , &detail::get_signature<constructor<typename op_type::left_t, typename op_type::right_t> >::apply
1051 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1052 #else
1053 add_operator(op_type::get_id()
1054 , &op_type::execute
1055 , &op_type::match
1056 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1057 #endif
1058 return *this;
1061 template<class op_id, class Left, class Right>
1062 class_& def(detail::operator_<op_id, Left, Right>)
1064 typedef typename detail::operator_unwrapper<detail::null_type, op_id, T, Left, Right> op_type;
1066 #ifndef LUABIND_NO_ERROR_CHECKING
1067 add_operator(op_type::get_id()
1068 , &op_type::execute
1069 , &op_type::match
1070 , &detail::get_signature<constructor<LUABIND_MSVC_TYPENAME op_type::left_t, LUABIND_MSVC_TYPENAME op_type::right_t> >::apply
1071 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1072 #else
1073 add_operator(op_type::get_id()
1074 , &op_type::execute
1075 , &op_type::match
1076 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1077 #endif
1078 return *this;
1081 template<class Signature, bool Constant>
1082 class_& def(detail::application_operator<Signature, Constant>*)
1084 typedef detail::application_operator<Signature, Constant, detail::null_type> op_t;
1086 int arity = detail::calc_arity<Signature::arity>::apply(
1087 Signature(), static_cast<detail::null_type*>(0));
1089 #ifndef LUABIND_NO_ERROR_CHECKING
1090 add_operator(
1091 detail::op_call
1092 , &op_t::template apply<T>::execute
1093 , &op_t::match
1094 , &detail::get_signature<Signature>::apply
1095 , arity + 1);
1096 #else
1097 add_operator(
1098 detail::op_call
1099 , &op_t::template apply<T>::execute
1100 , &op_t::match
1101 , arity + 1);
1102 #endif
1104 return *this;
1107 template<class Signature, bool Constant, class Policies>
1108 class_& def(detail::application_operator<Signature, Constant>*, const Policies& policies)
1110 typedef detail::application_operator<Signature, Constant, Policies> op_t;
1112 int arity = detail::calc_arity<Signature::arity>::apply(Signature(), static_cast<Policies*>(0));
1114 #ifndef LUABIND_NO_ERROR_CHECKING
1115 add_operator(
1116 detail::op_call
1117 , &op_t::template apply<T>::execute
1118 , &op_t::match
1119 , &detail::get_signature<Signature>::apply
1120 , arity + 1);
1121 #else
1122 add_operator(
1123 detail::op_call
1124 , &op_t::template apply<T>::execute
1125 , &op_t::match
1126 , arity + 1);
1127 #endif
1129 return *this;
1132 detail::enum_maker<self_t> enum_(const char*)
1134 return detail::enum_maker<self_t>(*this);
1137 detail::static_scope<self_t> scope;
1139 private:
1140 void operator=(class_ const&);
1142 void init()
1144 typedef typename detail::extract_parameter<
1145 boost::mpl::list3<X1,X2,X3>
1146 , boost::mpl::or_<
1147 detail::is_bases<boost::mpl::_>
1148 , boost::is_base_and_derived<boost::mpl::_, T>
1150 , no_bases
1151 >::type bases_t;
1153 typedef typename
1154 boost::mpl::if_<detail::is_bases<bases_t>
1155 , bases_t
1156 , bases<bases_t>
1157 >::type Base;
1159 class_base::init(LUABIND_TYPEID(T)
1160 , detail::internal_holder_type<HeldType>::apply()
1161 , detail::pointee_typeid(
1162 get_const_holder(static_cast<HeldType*>(0)))
1163 , detail::internal_holder_extractor<HeldType>::apply(detail::type_<T>())
1164 , detail::internal_const_holder_extractor<HeldType>::apply(detail::type_<T>())
1165 , detail::const_converter<HeldType>::apply(
1166 get_const_holder((HeldType*)0))
1167 , detail::holder_constructor<HeldType>::apply(detail::type_<T>())
1168 , detail::const_holder_constructor<HeldType>::apply(detail::type_<T>())
1169 , detail::holder_default_constructor<HeldType>::apply(detail::type_<T>())
1170 , detail::const_holder_default_constructor<HeldType>::apply(detail::type_<T>())
1171 , get_adopt_fun((WrappedType*)0) // adopt fun
1172 , detail::internal_holder_destructor<HeldType>::apply(detail::type_<T>())
1173 , detail::internal_const_holder_destructor<HeldType>::apply(detail::type_<T>())
1174 , detail::internal_holder_size<HeldType>::apply()
1175 , detail::get_holder_alignment<HeldType>::apply());
1177 generate_baseclass_list(detail::type_<Base>());
1180 template<class Getter, class GetPolicies>
1181 class_& property_impl(const char* name,
1182 Getter g,
1183 GetPolicies policies,
1184 boost::mpl::bool_<true>)
1186 add_getter(name, boost::bind<int>(detail::get_caller<T,Getter,GetPolicies>(policies), _1, _2, g));
1187 return *this;
1190 template<class Getter, class Setter>
1191 class_& property_impl(const char* name,
1192 Getter g,
1193 Setter s,
1194 boost::mpl::bool_<false>)
1196 add_getter(name, boost::bind<int>(detail::get_caller<T,Getter,detail::null_type>(), _1, _2, g));
1197 #ifndef LUABIND_NO_ERROR_CHECKING
1198 add_setter(
1199 name
1200 , boost::bind<int>(detail::set_caller<T, Setter, detail::null_type>(), _1, _2, s)
1201 , detail::gen_set_matcher((Setter)0, (detail::null_type*)0)
1202 , &detail::get_member_signature<Setter>::apply);
1203 #else
1204 add_setter(name, boost::bind<int>(detail::set_caller<T,Setter,detail::null_type>(), _1, _2, s));
1205 #endif
1206 return *this;
1209 // these handle default implementation of virtual functions
1210 template<class F, class Policies>
1211 class_& virtual_def(char const* name, F const& fn
1212 , Policies const&, detail::null_type, boost::mpl::true_)
1214 // normal def() call
1215 detail::overload_rep o(fn, static_cast<Policies*>(0));
1217 o.set_match_fun(detail::mem_fn_matcher<F, T, Policies>(fn));
1218 o.set_fun(detail::mem_fn_callback<F, T, Policies>(fn));
1220 #ifndef LUABIND_NO_ERROR_CHECKING
1221 o.set_sig_fun(&detail::get_member_signature<F>::apply);
1222 #endif
1223 this->add_method(name, o);
1224 return *this;
1227 template<class F, class Default, class Policies>
1228 class_& virtual_def(char const* name, F const& fn
1229 , Default const& default_, Policies const&, boost::mpl::false_)
1231 // default_ is a default implementation
1232 // policies is either null_type or a policy list
1234 // normal def() call
1235 detail::overload_rep o(fn, (Policies*)0);
1237 o.set_match_fun(detail::mem_fn_matcher<F, T, Policies>(fn));
1238 o.set_fun(detail::mem_fn_callback<F, T, Policies>(fn));
1240 o.set_fun_static(
1241 detail::mem_fn_callback<Default, T, Policies>(default_));
1243 #ifndef LUABIND_NO_ERROR_CHECKING
1244 o.set_sig_fun(&detail::get_member_signature<F>::apply);
1245 #endif
1247 this->add_method(name, o);
1248 // register virtual function
1249 return *this;
1252 template<class Signature, class Policies>
1253 class_& def_constructor(
1254 boost::mpl::true_ /* HasWrapper */
1255 , Signature*
1256 , Policies const&)
1258 detail::construct_rep::overload_t o;
1260 o.set_constructor(
1261 &detail::construct_class<
1263 , Policies
1264 , Signature
1265 >::apply);
1267 o.set_match_fun(
1268 &detail::constructor_match<
1269 Signature
1271 , Policies
1272 >::apply);
1274 #ifndef LUABIND_NO_ERROR_CHECKING
1275 o.set_sig_fun(&detail::get_signature<Signature>::apply);
1276 #endif
1277 o.set_arity(detail::calc_arity<Signature::arity>::apply(Signature(), (Policies*)0));
1278 this->add_constructor(o);
1279 return *this;
1282 template<class Signature, class Policies>
1283 class_& def_constructor(
1284 boost::mpl::false_ /* !HasWrapper */
1285 , Signature*
1286 , Policies const&)
1288 detail::construct_rep::overload_t o;
1290 o.set_constructor(
1291 &detail::construct_wrapped_class<
1293 , WrappedType
1294 , Policies
1295 , Signature
1296 >::apply);
1298 o.set_match_fun(
1299 &detail::constructor_match<
1300 Signature
1302 , Policies
1303 >::apply);
1305 #ifndef LUABIND_NO_ERROR_CHECKING
1306 o.set_sig_fun(&detail::get_signature<Signature>::apply);
1307 #endif
1308 o.set_arity(detail::calc_arity<Signature::arity>::apply(Signature(), (Policies*)0));
1309 this->add_constructor(o);
1310 return *this;
1313 typedef void(*adopt_fun_t)(void*);
1315 template<class W>
1316 adopt_fun_t get_adopt_fun(W*)
1318 return &detail::adopt_function<T, W>::execute;
1321 adopt_fun_t get_adopt_fun(detail::null_type*)
1323 return 0;
1327 namespace
1329 LUABIND_ANONYMOUS_FIX detail::policy_cons<
1330 detail::pure_virtual_tag
1331 , detail::null_type
1332 > pure_virtual;
1336 #ifdef _MSC_VER
1337 #pragma warning(pop)
1338 #endif
1340 #endif // LUABIND_CLASS_HPP_INCLUDED