cstrings can now accept nil
[luabind.git] / luabind / class.hpp
blobb56ab39e5cc787f68f1b791e4d2888317451810b
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/apply_if.hpp>
92 #include <boost/mpl/logical.hpp>
94 #include <luabind/config.hpp>
95 #include <luabind/scope.hpp>
96 #include <luabind/back_reference.hpp>
97 #include <luabind/detail/constructor.hpp>
98 #include <luabind/detail/call.hpp>
99 #include <luabind/detail/signature_match.hpp>
100 #include <luabind/detail/primitives.hpp>
101 #include <luabind/detail/property.hpp>
102 #include <luabind/detail/typetraits.hpp>
103 #include <luabind/detail/class_rep.hpp>
104 #include <luabind/detail/method_rep.hpp>
105 #include <luabind/detail/construct_rep.hpp>
106 #include <luabind/detail/object_rep.hpp>
107 #include <luabind/detail/calc_arity.hpp>
108 #include <luabind/detail/call_member.hpp>
109 #include <luabind/detail/enum_maker.hpp>
110 #include <luabind/detail/get_signature.hpp>
111 #include <luabind/detail/implicit_cast.hpp>
112 #include <luabind/detail/operator_id.hpp>
113 #include <luabind/detail/pointee_typeid.hpp>
114 #include <luabind/detail/link_compatibility.hpp>
116 // to remove the 'this' used in initialization list-warning
117 #ifdef _MSC_VER
118 #pragma warning(push)
119 #pragma warning(disable: 4355)
120 #endif
123 namespace luabind
125 namespace detail
127 struct unspecified {};
129 template<class Derived> struct operator_;
132 using detail::type;
134 template<class T, class X1 = detail::unspecified, class X2 = detail::unspecified, class X3 = detail::unspecified>
135 struct class_;
137 // TODO: this function will only be invoked if the user hasn't defined a correct overload
138 // maybe we should have a static assert in here?
139 inline detail::null_type* get_const_holder(...)
141 return 0;
144 namespace detail
146 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class A)>
147 double is_bases_helper(const bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, A)>&);
149 #ifndef BOOST_MSVC
150 template<class T>
151 char is_bases_helper(const T&);
152 #else
153 char is_bases_helper(...);
154 #endif
156 template<class T>
157 struct is_bases
159 static const T& t;
161 BOOST_STATIC_CONSTANT(bool, value = sizeof(is_bases_helper(t)) == sizeof(double));
162 typedef boost::mpl::bool_<value> type;
163 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_bases,(T))
166 double is_not_unspecified_helper(const unspecified*);
167 char is_not_unspecified_helper(...);
169 template<class T>
170 struct is_not_unspecified
172 BOOST_STATIC_CONSTANT(bool, value = sizeof(is_not_unspecified_helper(static_cast<T*>(0))) == sizeof(char));
173 typedef boost::mpl::bool_<value> type;
174 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_not_unspecified,(T))
177 template<class Predicate>
178 struct get_predicate
180 typedef typename boost::mpl::and_<
181 Predicate
182 , is_not_unspecified<boost::mpl::_1>
183 > type;
186 template<class Parameters, class Predicate, class DefaultValue>
187 struct extract_parameter
189 typedef typename get_predicate<Predicate>::type pred;
190 typedef typename boost::mpl::find_if<Parameters, pred>::type iterator;
191 typedef typename boost::mpl::apply_if<boost::is_same<iterator, typename boost::mpl::end<Parameters>::type>
192 , boost::mpl::identity<DefaultValue>
193 , iterator
194 >::type type;
197 template<class Fn, class Class, class Policies>
198 struct mem_fn_callback
200 typedef int result_type;
202 int operator()(lua_State* L) const
204 return call(fn, (Class*)0, L, (Policies*)0);
207 mem_fn_callback(Fn fn_)
208 : fn(fn_)
212 Fn fn;
215 template<class Fn, class Class, class Policies>
216 struct mem_fn_matcher
218 typedef int result_type;
220 int operator()(lua_State* L) const
222 return match(fn, L, (Class*)0, (Policies*)0);
225 mem_fn_matcher(Fn fn_)
226 : fn(fn_)
230 Fn fn;
233 struct pure_virtual_tag
235 static void precall(lua_State*, index_map const&) {}
236 static void postcall(lua_State*, index_map const&) {}
239 template<class Policies>
240 struct has_pure_virtual
242 typedef typename boost::mpl::apply_if<
243 boost::is_same<pure_virtual_tag, typename Policies::head>
244 , boost::mpl::true_
245 , has_pure_virtual<typename Policies::tail>
246 >::type type;
248 BOOST_STATIC_CONSTANT(bool, value = type::value);
251 template<>
252 struct has_pure_virtual<null_type>
254 BOOST_STATIC_CONSTANT(bool, value = false);
255 typedef boost::mpl::bool_<value> type;
258 // prints the types of the values on the stack, in the
259 // range [start_index, lua_gettop()]
261 LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index);
263 struct LUABIND_API create_class
265 static int stage1(lua_State* L);
266 static int stage2(lua_State* L);
269 // if the class is held by a smart pointer, we need to be able to
270 // implicitly dereference the pointer when needed.
272 template<class UnderlyingT, class HeldT>
273 struct extract_underlying_type
275 static void* extract(void* ptr)
277 HeldT& held_obj = *reinterpret_cast<HeldT*>(ptr);
278 UnderlyingT* underlying_ptr = static_cast<UnderlyingT*>(get_pointer(held_obj));
279 return underlying_ptr;
283 template<class UnderlyingT, class HeldT>
284 struct extract_underlying_const_type
286 static const void* extract(void* ptr)
288 HeldT& held_obj = *reinterpret_cast<HeldT*>(ptr);
289 const UnderlyingT* underlying_ptr = static_cast<const UnderlyingT*>(get_pointer(held_obj));
290 return underlying_ptr;
294 template<class HeldType>
295 struct internal_holder_extractor
297 typedef void*(*extractor_fun)(void*);
299 template<class T>
300 static extractor_fun apply(detail::type<T>)
302 return &detail::extract_underlying_type<T, HeldType>::extract;
306 template<>
307 struct internal_holder_extractor<detail::null_type>
309 typedef void*(*extractor_fun)(void*);
311 template<class T>
312 static extractor_fun apply(detail::type<T>)
314 return 0;
319 template<class HeldType, class ConstHolderType>
320 struct convert_holder
322 static void apply(void* holder, void* target)
324 new(target) ConstHolderType(*reinterpret_cast<HeldType*>(holder));
329 template<class HeldType>
330 struct const_converter
332 typedef void(*converter_fun)(void*, void*);
334 template<class ConstHolderType>
335 static converter_fun apply(ConstHolderType*)
337 return &detail::convert_holder<HeldType, ConstHolderType>::apply;
341 template<>
342 struct const_converter<detail::null_type>
344 typedef void(*converter_fun)(void*, void*);
346 template<class T>
347 static converter_fun apply(T*)
349 return 0;
356 template<class HeldType>
357 struct internal_const_holder_extractor
359 typedef const void*(*extractor_fun)(void*);
361 template<class T>
362 static extractor_fun apply(detail::type<T>)
364 return get_extractor(detail::type<T>(), luabind::get_const_holder(static_cast<HeldType*>(0)));
366 private:
367 template<class T, class ConstHolderType>
368 static extractor_fun get_extractor(detail::type<T>, ConstHolderType*)
370 return &detail::extract_underlying_const_type<T, ConstHolderType>::extract;
374 template<>
375 struct internal_const_holder_extractor<detail::null_type>
377 typedef const void*(*extractor_fun)(void*);
379 template<class T>
380 static extractor_fun apply(detail::type<T>)
382 return 0;
388 // this is simply a selector that returns the type_info
389 // of the held type, or invalid_type_info if we don't have
390 // a held_type
391 template<class HeldType>
392 struct internal_holder_type
394 static LUABIND_TYPE_INFO apply()
396 return LUABIND_TYPEID(HeldType);
400 template<>
401 struct internal_holder_type<detail::null_type>
403 static LUABIND_TYPE_INFO apply()
405 return LUABIND_INVALID_TYPE_INFO;
410 // this is the actual held_type constructor
411 template<class HeldType, class T>
412 struct internal_construct_holder
414 static void apply(void* target, void* raw_pointer)
416 new(target) HeldType(static_cast<T*>(raw_pointer));
420 // this is the actual held_type default constructor
421 template<class HeldType, class T>
422 struct internal_default_construct_holder
424 static void apply(void* target)
426 new(target) HeldType();
430 // the following two functions are the ones that returns
431 // a pointer to a held_type_constructor, or 0 if there
432 // is no held_type
433 template<class HeldType>
434 struct holder_constructor
436 typedef void(*constructor)(void*,void*);
437 template<class T>
438 static constructor apply(detail::type<T>)
440 return &internal_construct_holder<HeldType, T>::apply;
444 template<>
445 struct holder_constructor<detail::null_type>
447 typedef void(*constructor)(void*,void*);
448 template<class T>
449 static constructor apply(detail::type<T>)
451 return 0;
455 // the following two functions are the ones that returns
456 // a pointer to a const_held_type_constructor, or 0 if there
457 // is no held_type
458 template<class HolderType>
459 struct const_holder_constructor
461 typedef void(*constructor)(void*,void*);
462 template<class T>
463 static constructor apply(detail::type<T>)
465 return get_const_holder_constructor(detail::type<T>(), luabind::get_const_holder(static_cast<HolderType*>(0)));
468 private:
470 template<class T, class ConstHolderType>
471 static constructor get_const_holder_constructor(detail::type<T>, ConstHolderType*)
473 return &internal_construct_holder<ConstHolderType, T>::apply;
477 template<>
478 struct const_holder_constructor<detail::null_type>
480 typedef void(*constructor)(void*,void*);
481 template<class T>
482 static constructor apply(detail::type<T>)
484 return 0;
489 // the following two functions are the ones that returns
490 // a pointer to a held_type_constructor, or 0 if there
491 // is no held_type. The holder_type is default constructed
492 template<class HeldType>
493 struct holder_default_constructor
495 typedef void(*constructor)(void*);
496 template<class T>
497 static constructor apply(detail::type<T>)
499 return &internal_default_construct_holder<HeldType, T>::apply;
503 template<>
504 struct holder_default_constructor<detail::null_type>
506 typedef void(*constructor)(void*);
507 template<class T>
508 static constructor apply(detail::type<T>)
510 return 0;
515 // the following two functions are the ones that returns
516 // a pointer to a const_held_type_constructor, or 0 if there
517 // is no held_type. The constructed held_type is default
518 // constructed
519 template<class HolderType>
520 struct const_holder_default_constructor
522 typedef void(*constructor)(void*);
523 template<class T>
524 static constructor apply(detail::type<T>)
526 return get_const_holder_default_constructor(detail::type<T>(), luabind::get_const_holder(static_cast<HolderType*>(0)));
529 private:
531 template<class T, class ConstHolderType>
532 static constructor get_const_holder_default_constructor(detail::type<T>, ConstHolderType*)
534 return &internal_default_construct_holder<ConstHolderType, T>::apply;
538 template<>
539 struct const_holder_default_constructor<detail::null_type>
541 typedef void(*constructor)(void*);
542 template<class T>
543 static constructor apply(detail::type<T>)
545 return 0;
552 // this is a selector that returns the size of the held_type
553 // or 0 if we don't have a held_type
554 template <class HolderType>
555 struct internal_holder_size
557 static int apply() { return get_internal_holder_size(luabind::get_const_holder(static_cast<HolderType*>(0))); }
558 private:
559 template<class ConstHolderType>
560 static int get_internal_holder_size(ConstHolderType*)
562 return max_c<sizeof(HolderType), sizeof(ConstHolderType)>::value;
566 template <>
567 struct internal_holder_size<detail::null_type>
569 static int apply() { return 0; }
573 // if we have a held type, return the destructor to it
574 // note the difference. The held_type should only be destructed (not deleted)
575 // since it's constructed in the lua userdata
576 template<class HeldType>
577 struct internal_holder_destructor
579 typedef void(*destructor_t)(void*);
580 template<class T>
581 static destructor_t apply(detail::type<T>)
583 return &detail::destruct_only_s<HeldType>::apply;
587 // if we don't have a held type, return the destructor of the raw type
588 template<>
589 struct internal_holder_destructor<detail::null_type>
591 typedef void(*destructor_t)(void*);
592 template<class T>
593 static destructor_t apply(detail::type<T>)
595 return &detail::delete_s<T>::apply;
600 // if we have a held type, return the destructor to it's const version
601 template<class HolderType>
602 struct internal_const_holder_destructor
604 typedef void(*destructor_t)(void*);
605 template<class T>
606 static destructor_t apply(detail::type<T>)
608 return const_holder_type_destructor(luabind::get_const_holder(static_cast<HolderType*>(0)));
611 private:
613 template<class ConstHolderType>
614 static destructor_t const_holder_type_destructor(ConstHolderType*)
616 return &detail::destruct_only_s<ConstHolderType>::apply;
621 // if we don't have a held type, return the destructor of the raw type
622 template<>
623 struct internal_const_holder_destructor<detail::null_type>
625 typedef void(*destructor_t)(void*);
626 template<class T>
627 static destructor_t apply(detail::type<T>)
629 return 0;
636 template<class HolderType>
637 struct get_holder_alignment
639 static int apply()
641 return internal_alignment(luabind::get_const_holder(static_cast<HolderType*>(0)));
644 private:
646 template<class ConstHolderType>
647 static int internal_alignment(ConstHolderType*)
649 return detail::max_c<boost::alignment_of<HolderType>::value
650 , boost::alignment_of<ConstHolderType>::value>::value;
654 template<>
655 struct get_holder_alignment<detail::null_type>
657 static int apply()
659 return 1;
664 } // detail
666 namespace detail {
668 template<class T>
669 struct static_scope
671 static_scope(T& self_) : self(self_)
675 T& operator[](scope s) const
677 self.add_inner_scope(s);
678 return self;
681 private:
682 template<class U> void operator,(U const&) const;
683 void operator=(static_scope const&);
685 T& self;
688 struct class_registration;
690 struct LUABIND_API class_base : scope
692 public:
693 class_base(char const* name);
695 struct base_desc
697 LUABIND_TYPE_INFO type;
698 int ptr_offset;
701 void init(
702 LUABIND_TYPE_INFO type
703 , LUABIND_TYPE_INFO holder_type
704 , LUABIND_TYPE_INFO const_holder_type
705 , void*(*extractor)(void*)
706 , const void*(*const_extractor)(void*)
707 , void(*const_converter)(void*,void*)
708 , void(*holder_constructor)(void*,void*)
709 , void(*const_holder_constructor)(void*,void*)
710 , void(*holder_default_constructor)(void*)
711 , void(*const_holder_default_constructor)(void*)
712 , void(*destructor)(void*)
713 , void(*const_holder_destructor)(void*)
714 , void(*m_adopt_fun)(void*)
715 , int holder_size
716 , int holder_alignment);
718 void add_getter(
719 const char* name
720 , const boost::function2<int, lua_State*, int>& g);
722 #ifdef LUABIND_NO_ERROR_CHECKING
723 void class_base::add_setter(
724 const char* name
725 , const boost::function2<int, lua_State*, int>& s);
726 #else
727 void class_base::add_setter(
728 const char* name
729 , const boost::function2<int, lua_State*, int>& s
730 , int (*match)(lua_State*, int)
731 , void (*get_sig_ptr)(lua_State*, std::string&));
732 #endif
734 void add_base(const base_desc& b);
735 void add_constructor(const detail::construct_rep::overload_t& o);
736 void add_method(const char* name, const detail::overload_rep& o);
738 #ifndef LUABIND_NO_ERROR_CHECKING
739 void add_operator(
740 int op_id
741 , int(*func)(lua_State*)
742 , int(*matcher)(lua_State*)
743 , void(*sig)(lua_State*
744 , std::string&)
745 , int arity);
746 #else
747 void add_operator(
748 int op_id
749 , int(*func)(lua_State*)
750 , int(*matcher)(lua_State*)
751 , int arity);
752 #endif
754 const char* name() const;
756 void add_static_constant(const char* name, int val);
757 void add_inner_scope(scope& s);
759 private:
760 class_registration* m_registration;
763 template<class T, class W>
764 struct adopt_function
766 static void execute(void* p)
768 wrapped_self_t& self = wrap_access::ref(
769 *static_cast<W*>(static_cast<T*>(p))
772 LUABIND_CHECK_STACK(self.state());
774 self.get(self.state());
775 self.m_strong_ref.set(self.state());
779 } // namespace detail
781 // registers a class in the lua environment
782 template<class T, class X1, class X2, class X3>
783 struct class_: detail::class_base
785 typedef class_<T, X1, X2, X3> self_t;
787 private:
789 template<class A, class B, class C, class D>
790 class_(const class_<A,B,C,D>&);
792 public:
794 // WrappedType MUST inherit from T
795 typedef typename detail::extract_parameter<
796 boost::mpl::vector3<X1,X2,X3>
797 , boost::is_base_and_derived<T, boost::mpl::_>
798 , detail::null_type
799 >::type WrappedType;
801 typedef typename detail::extract_parameter<
802 boost::mpl::list3<X1,X2,X3>
803 , boost::mpl::not_<
804 boost::mpl::or_<
805 boost::mpl::or_<
806 detail::is_bases<boost::mpl::_>
807 , boost::is_base_and_derived<boost::mpl::_, T>
809 , boost::is_base_and_derived<T, boost::mpl::_>
812 , detail::null_type
813 >::type HeldType;
815 // this function generates conversion information
816 // in the given class_rep structure. It will be able
817 // to implicitly cast to the given template type
818 template<class To>
819 void gen_base_info(detail::type<To>)
821 // fist, make sure the given base class is registered.
822 // if it's not registered we can't push it's lua table onto
823 // the stack because it doesn't have a table
825 // try to cast this type to the base type and remember
826 // the pointer offset. For multiple inheritance the pointer
827 // may change when casting. Since we need to be able to
828 // cast we need this pointer offset.
829 // store the information in this class' base class-vector
830 base_desc base;
831 base.type = LUABIND_TYPEID(To);
832 base.ptr_offset = detail::ptr_offset(detail::type<T>(), detail::type<To>());
833 add_base(base);
836 void gen_base_info(detail::type<detail::null_type>)
839 #define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type<B##n>());
841 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class B)>
842 void generate_baseclass_list(detail::type<bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, B)> >)
844 BOOST_PP_REPEAT(LUABIND_MAX_BASES, LUABIND_GEN_BASE_INFO, _)
847 #undef LUABIND_GEN_BASE_INFO
849 class_(const char* name): class_base(name), scope(*this)
851 #ifndef NDEBUG
852 detail::check_link_compatibility();
853 #endif
854 init();
857 template<class F>
858 class_& def(const char* name, F f)
860 return this->virtual_def(
861 name, f, detail::null_type()
862 , detail::null_type(), boost::mpl::true_());
865 // virtual functions
866 template<class F, class DefaultOrPolicies>
867 class_& def(char const* name, F fn, DefaultOrPolicies default_or_policies)
869 return this->virtual_def(
870 name, fn, default_or_policies, detail::null_type()
871 , LUABIND_MSVC_TYPENAME detail::is_policy_cons<DefaultOrPolicies>::type());
874 template<class F, class Default, class Policies>
875 class_& def(char const* name, F fn
876 , Default default_, Policies const& policies)
878 return this->virtual_def(
879 name, fn, default_
880 , policies, boost::mpl::false_());
883 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)>
884 class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig)
886 return this->def_constructor(
887 boost::is_same<WrappedType, detail::null_type>()
888 , &sig
889 , detail::null_type()
893 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A), class Policies>
894 class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig, const Policies& policies)
896 return this->def_constructor(
897 boost::is_same<WrappedType, detail::null_type>()
898 , &sig
899 , policies
903 template<class Getter>
904 class_& property(const char* name, Getter g)
906 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, detail::null_type>(), _1, _2, g));
907 return *this;
910 template<class Getter, class MaybeSetter>
911 class_& property(const char* name, Getter g, MaybeSetter s)
913 return property_impl(name, g, s, boost::mpl::bool_<detail::is_policy_cons<MaybeSetter>::value>());
916 template<class Getter, class Setter, class GetPolicies>
917 class_& property(const char* name, Getter g, Setter s, const GetPolicies& get_policies)
919 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, GetPolicies>(get_policies), _1, _2, g));
920 #ifndef LUABIND_NO_ERROR_CHECKING
921 add_setter(
922 name
923 , boost::bind<int>(detail::set_caller<T, Setter, detail::null_type>(), _1, _2, s)
924 , detail::gen_set_matcher((Setter)0, (detail::null_type*)0)
925 , &detail::get_member_signature<Setter>::apply);
926 #else
927 add_setter(
928 name
929 , boost::bind<int>(detail::set_caller<T, Setter, detail::null_type>(), _1, _2, s));
930 #endif
931 return *this;
934 template<class Getter, class Setter, class GetPolicies, class SetPolicies>
935 class_& property(const char* name
936 , Getter g, Setter s
937 , const GetPolicies& get_policies
938 , const SetPolicies& set_policies)
940 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, GetPolicies>(get_policies), _1, _2, g));
941 #ifndef LUABIND_NO_ERROR_CHECKING
942 add_setter(
943 name
944 , boost::bind<int>(detail::set_caller<T, Setter, SetPolicies>(), _1, _2, s)
945 , detail::gen_set_matcher((Setter)0, (SetPolicies*)0)
946 , &detail::get_member_signature<Setter>::apply);
947 #else
948 add_setter(name, boost::bind<int>(detail::set_caller<T, Setter, SetPolicies>(set_policies), _1, _2, s));
949 #endif
950 return *this;
953 template<class D>
954 class_& def_readonly(const char* name, D T::*member_ptr)
956 add_getter(name, boost::bind<int>(detail::auto_get<T,D,detail::null_type>(), _1, _2, member_ptr));
957 return *this;
960 template<class D, class Policies>
961 class_& def_readonly(const char* name, D T::*member_ptr, const Policies& policies)
963 add_getter(name, boost::bind<int>(detail::auto_get<T,D,Policies>(policies), _1, _2, member_ptr));
964 return *this;
967 template<class D>
968 class_& def_readwrite(const char* name, D T::*member_ptr)
970 add_getter(name, boost::bind<int>(detail::auto_get<T,D,detail::null_type>(), _1, _2, member_ptr));
971 #ifndef LUABIND_NO_ERROR_CHECKING
972 add_setter(
973 name
974 , boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr)
975 , &detail::set_matcher<D, detail::null_type>::apply
976 , &detail::get_setter_signature<D>::apply);
977 #else
978 add_setter(name, boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr));
979 #endif
980 return *this;
983 template<class D, class GetPolicies>
984 class_& def_readwrite(const char* name, D T::*member_ptr, const GetPolicies& get_policies)
986 add_getter(name, boost::bind<int>(detail::auto_get<T,D,GetPolicies>(get_policies), _1, _2, member_ptr));
987 #ifndef LUABIND_NO_ERROR_CHECKING
988 add_setter(
989 name
990 , boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr)
991 , &detail::set_matcher<D, detail::null_type>::apply
992 , &detail::get_setter_signature<D>::apply);
993 #else
994 add_setter(name, boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr));
995 #endif
996 return *this;
999 template<class D, class GetPolicies, class SetPolicies>
1000 class_& def_readwrite(const char* name, D T::*member_ptr, const GetPolicies& get_policies, const SetPolicies& set_policies)
1002 add_getter(name, boost::bind<int>(detail::auto_get<T,D,GetPolicies>(get_policies), _1, _2, member_ptr));
1003 #ifndef LUABIND_NO_ERROR_CHECKING
1004 add_setter(
1005 name
1006 , boost::bind<int>(detail::auto_set<T,D,SetPolicies>(), _1, _2, member_ptr)
1007 , &detail::set_matcher<D, SetPolicies>::apply
1008 , &detail::get_setter_signature<D>::apply);
1009 #else
1010 add_setter(name, boost::bind<int>(detail::auto_set<T,D,SetPolicies>(set_policies), _1, _2, member_ptr));
1011 #endif
1012 return *this;
1015 template<class Derived, class Policies>
1016 class_& def(detail::operator_<Derived>, Policies const& policies)
1018 return this->def(
1019 Derived::name()
1020 , &Derived::template apply<T, Policies>::execute
1021 , raw(_1) + policies
1025 template<class Derived>
1026 class_& def(detail::operator_<Derived>)
1028 return this->def(
1029 Derived::name()
1030 , &Derived::template apply<T, detail::null_type>::execute
1031 , raw(_1)
1036 template<class op_id, class Left, class Right, class Policies>
1037 class_& def(detail::operator_<op_id, Left, Right>, const Policies& policies)
1039 typedef typename detail::operator_unwrapper<Policies, op_id, T, Left, Right> op_type;
1040 #ifndef LUABIND_NO_ERROR_CHECKING
1041 add_operator(op_type::get_id()
1042 , &op_type::execute
1043 , &op_type::match
1044 , &detail::get_signature<constructor<typename op_type::left_t, typename op_type::right_t> >::apply
1045 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1046 #else
1047 add_operator(op_type::get_id()
1048 , &op_type::execute
1049 , &op_type::match
1050 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1051 #endif
1052 return *this;
1055 template<class op_id, class Left, class Right>
1056 class_& def(detail::operator_<op_id, Left, Right>)
1058 typedef typename detail::operator_unwrapper<detail::null_type, op_id, T, Left, Right> op_type;
1060 #ifndef LUABIND_NO_ERROR_CHECKING
1061 add_operator(op_type::get_id()
1062 , &op_type::execute
1063 , &op_type::match
1064 , &detail::get_signature<constructor<LUABIND_MSVC_TYPENAME op_type::left_t, LUABIND_MSVC_TYPENAME op_type::right_t> >::apply
1065 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1066 #else
1067 add_operator(op_type::get_id()
1068 , &op_type::execute
1069 , &op_type::match
1070 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1071 #endif
1072 return *this;
1075 template<class Signature, bool Constant>
1076 class_& def(detail::application_operator<Signature, Constant>*)
1078 typedef detail::application_operator<Signature, Constant, detail::null_type> op_t;
1080 int arity = detail::calc_arity<Signature::arity>::apply(
1081 Signature(), static_cast<detail::null_type*>(0));
1083 #ifndef LUABIND_NO_ERROR_CHECKING
1084 add_operator(
1085 detail::op_call
1086 , &op_t::template apply<T>::execute
1087 , &op_t::match
1088 , &detail::get_signature<Signature>::apply
1089 , arity + 1);
1090 #else
1091 add_operator(
1092 detail::op_call
1093 , &op_t::template apply<T>::execute
1094 , &op_t::match
1095 , arity + 1);
1096 #endif
1098 return *this;
1101 template<class Signature, bool Constant, class Policies>
1102 class_& def(detail::application_operator<Signature, Constant>*, const Policies& policies)
1104 typedef detail::application_operator<Signature, Constant, Policies> op_t;
1106 int arity = detail::calc_arity<Signature::arity>::apply(Signature(), static_cast<Policies*>(0));
1108 #ifndef LUABIND_NO_ERROR_CHECKING
1109 add_operator(
1110 detail::op_call
1111 , &op_t::template apply<T>::execute
1112 , &op_t::match
1113 , &detail::get_signature<Signature>::apply
1114 , arity + 1);
1115 #else
1116 add_operator(
1117 detail::op_call
1118 , &op_t::template apply<T>::execute
1119 , &op_t::match
1120 , arity + 1);
1121 #endif
1123 return *this;
1126 detail::enum_maker<self_t> enum_(const char*)
1128 return detail::enum_maker<self_t>(*this);
1131 detail::static_scope<self_t> scope;
1133 private:
1134 void operator=(class_ const&);
1136 void init()
1138 set_back_reference((back_reference<T>*)0);
1140 typedef typename detail::extract_parameter<
1141 boost::mpl::list3<X1,X2,X3>
1142 , boost::mpl::or_<
1143 detail::is_bases<boost::mpl::_>
1144 , boost::is_base_and_derived<boost::mpl::_, T>
1146 , no_bases
1147 >::type bases_t;
1149 typedef typename
1150 boost::mpl::if_<detail::is_bases<bases_t>
1151 , bases_t
1152 , bases<bases_t>
1153 >::type Base;
1155 class_base::init(LUABIND_TYPEID(T)
1156 , detail::internal_holder_type<HeldType>::apply()
1157 , detail::pointee_typeid(
1158 get_const_holder(static_cast<HeldType*>(0)))
1159 , detail::internal_holder_extractor<HeldType>::apply(detail::type<T>())
1160 , detail::internal_const_holder_extractor<HeldType>::apply(detail::type<T>())
1161 , detail::const_converter<HeldType>::apply(
1162 luabind::get_const_holder((HeldType*)0))
1163 , detail::holder_constructor<HeldType>::apply(detail::type<T>())
1164 , detail::const_holder_constructor<HeldType>::apply(detail::type<T>())
1165 , detail::holder_default_constructor<HeldType>::apply(detail::type<T>())
1166 , detail::const_holder_default_constructor<HeldType>::apply(detail::type<T>())
1167 , get_adopt_fun((WrappedType*)0) // adopt fun
1168 , detail::internal_holder_destructor<HeldType>::apply(detail::type<T>())
1169 , detail::internal_const_holder_destructor<HeldType>::apply(detail::type<T>())
1170 , detail::internal_holder_size<HeldType>::apply()
1171 , detail::get_holder_alignment<HeldType>::apply());
1173 generate_baseclass_list(detail::type<Base>());
1176 template<class Getter, class GetPolicies>
1177 class_& property_impl(const char* name,
1178 Getter g,
1179 GetPolicies policies,
1180 boost::mpl::bool_<true>)
1182 add_getter(name, boost::bind<int>(detail::get_caller<T,Getter,GetPolicies>(policies), _1, _2, g));
1183 return *this;
1186 template<class Getter, class Setter>
1187 class_& property_impl(const char* name,
1188 Getter g,
1189 Setter s,
1190 boost::mpl::bool_<false>)
1192 add_getter(name, boost::bind<int>(detail::get_caller<T,Getter,detail::null_type>(), _1, _2, g));
1193 #ifndef LUABIND_NO_ERROR_CHECKING
1194 add_setter(
1195 name
1196 , boost::bind<int>(detail::set_caller<T, Setter, detail::null_type>(), _1, _2, s)
1197 , detail::gen_set_matcher((Setter)0, (detail::null_type*)0)
1198 , &detail::get_member_signature<Setter>::apply);
1199 #else
1200 add_setter(name, boost::bind<int>(detail::set_caller<T,Setter,detail::null_type>(), _1, _2, s));
1201 #endif
1202 return *this;
1205 // these handle default implementation of virtual functions
1206 template<class F, class Policies>
1207 class_& virtual_def(char const* name, F const& fn
1208 , Policies const& policies, detail::null_type, boost::mpl::true_)
1210 // normal def() call
1211 detail::overload_rep o(fn, static_cast<Policies*>(0));
1213 o.set_match_fun(detail::mem_fn_matcher<F, T, Policies>(fn));
1214 o.set_fun(detail::mem_fn_callback<F, T, Policies>(fn));
1216 #ifndef LUABIND_NO_ERROR_CHECKING
1217 o.set_sig_fun(&detail::get_member_signature<F>::apply);
1218 #endif
1219 this->add_method(name, o);
1220 return *this;
1223 template<class F, class Default, class Policies>
1224 class_& virtual_def(char const* name, F const& fn
1225 , Default const& default_, Policies const& policies, boost::mpl::false_)
1227 // default_ is a default implementation
1228 // policies is either null_type or a policy list
1230 // normal def() call
1231 detail::overload_rep o(fn, (Policies*)0);
1233 o.set_match_fun(detail::mem_fn_matcher<F, T, Policies>(fn));
1234 o.set_fun(detail::mem_fn_callback<F, T, Policies>(fn));
1236 o.set_fun_static(
1237 detail::mem_fn_callback<Default, T, Policies>(default_));
1239 #ifndef LUABIND_NO_ERROR_CHECKING
1240 o.set_sig_fun(&detail::get_member_signature<F>::apply);
1241 #endif
1243 this->add_method(name, o);
1244 // register virtual function
1245 return *this;
1248 template<class Signature, class Policies>
1249 class_& def_constructor(
1250 boost::mpl::true_ /* HasWrapper */
1251 , Signature*
1252 , Policies const& policies)
1254 detail::construct_rep::overload_t o;
1256 o.set_constructor(
1257 &detail::construct_class<
1259 , Policies
1260 , Signature
1261 >::apply);
1263 o.set_match_fun(
1264 &detail::constructor_match<
1265 Signature
1267 , Policies
1268 >::apply);
1270 #ifndef LUABIND_NO_ERROR_CHECKING
1271 o.set_sig_fun(&detail::get_signature<Signature>::apply);
1272 #endif
1273 o.set_arity(detail::calc_arity<Signature::arity>::apply(Signature(), (Policies*)0));
1274 this->add_constructor(o);
1275 return *this;
1278 template<class Signature, class Policies>
1279 class_& def_constructor(
1280 boost::mpl::false_ /* !HasWrapper */
1281 , Signature*
1282 , Policies const& policies)
1284 detail::construct_rep::overload_t o;
1286 o.set_constructor(
1287 &detail::construct_wrapped_class<
1289 , WrappedType
1290 , Policies
1291 , Signature
1292 >::apply);
1294 o.set_match_fun(
1295 &detail::constructor_match<
1296 Signature
1298 , Policies
1299 >::apply);
1301 #ifndef LUABIND_NO_ERROR_CHECKING
1302 o.set_sig_fun(&detail::get_signature<Signature>::apply);
1303 #endif
1304 o.set_arity(detail::calc_arity<Signature::arity>::apply(Signature(), (Policies*)0));
1305 this->add_constructor(o);
1306 return *this;
1309 void set_back_reference(detail::default_back_reference*)
1311 back_reference<T>::has_wrapper
1312 = !boost::is_same<WrappedType, detail::null_type>::value;
1315 void set_back_reference(void*)
1319 typedef void(*adopt_fun_t)(void*);
1321 template<class W>
1322 adopt_fun_t get_adopt_fun(W*)
1324 return &detail::adopt_function<T, W>::execute;
1327 adopt_fun_t get_adopt_fun(detail::null_type*)
1329 return 0;
1333 namespace
1335 LUABIND_ANONYMOUS_FIX detail::policy_cons<
1336 detail::pure_virtual_tag
1337 , detail::null_type
1338 > pure_virtual;
1342 #ifdef _MSC_VER
1343 #pragma warning(pop)
1344 #endif
1346 #endif // LUABIND_CLASS_HPP_INCLUDED