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
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.
53 ------------------------------------------------------
55 finish smart pointer support
56 * the adopt policy should not be able to adopt pointers to held_types. This
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>
78 #include <boost/bind.hpp>
79 #include <boost/preprocessor/repetition/enum_params.hpp>
80 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
81 #include <boost/preprocessor/repetition/repeat.hpp>
82 #include <boost/type_traits/is_same.hpp>
83 #include <boost/type_traits/is_member_object_pointer.hpp>
84 #include <boost/mpl/apply.hpp>
85 #include <boost/mpl/lambda.hpp>
86 #include <boost/mpl/logical.hpp>
87 #include <boost/mpl/find_if.hpp>
88 #include <boost/mpl/eval_if.hpp>
89 #include <boost/mpl/logical.hpp>
91 #include <luabind/config.hpp>
92 #include <luabind/scope.hpp>
93 #include <luabind/back_reference.hpp>
94 #include <luabind/function.hpp>
95 #include <luabind/dependency_policy.hpp>
96 #include <luabind/detail/constructor.hpp>
97 #include <luabind/detail/call.hpp>
98 #include <luabind/detail/deduce_signature.hpp>
99 #include <luabind/detail/primitives.hpp>
100 #include <luabind/detail/property.hpp>
101 #include <luabind/detail/typetraits.hpp>
102 #include <luabind/detail/class_rep.hpp>
103 #include <luabind/detail/call.hpp>
104 #include <luabind/detail/object_rep.hpp>
105 #include <luabind/detail/call_member.hpp>
106 #include <luabind/detail/enum_maker.hpp>
107 #include <luabind/detail/get_signature.hpp>
108 #include <luabind/detail/operator_id.hpp>
109 #include <luabind/detail/pointee_typeid.hpp>
110 #include <luabind/detail/link_compatibility.hpp>
111 #include <luabind/detail/inheritance.hpp>
112 #include <luabind/typeid.hpp>
114 // to remove the 'this' used in initialization list-warning
116 #pragma warning(push)
117 #pragma warning(disable: 4355)
123 template <class T
> class shared_ptr
;
131 struct unspecified
{};
133 template<class Derived
> struct operator_
;
135 struct you_need_to_define_a_get_const_holder_function_for_your_smart_ptr
{};
138 template<class T
, class X1
= detail::unspecified
, class X2
= detail::unspecified
, class X3
= detail::unspecified
>
141 // TODO: this function will only be invoked if the user hasn't defined a correct overload
142 // maybe we should have a static assert in here?
143 inline detail::you_need_to_define_a_get_const_holder_function_for_your_smart_ptr
*
144 get_const_holder(...)
150 boost::shared_ptr
<T
const>* get_const_holder(boost::shared_ptr
<T
>*)
156 BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
157 LUABIND_MAX_BASES
, class A
, detail::null_type
)
162 typedef bases
<detail::null_type
> no_bases
;
171 template <BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES
, class A
)>
172 struct is_bases
<bases
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES
, A
)> >
176 template <class T
, class P
>
177 struct is_unspecified
182 struct is_unspecified
<unspecified
, P
>
187 struct is_unspecified_mfn
191 : is_unspecified
<T
, P
>
195 template<class Predicate
>
198 typedef mpl::protect
<is_unspecified_mfn
<Predicate
> > type
;
201 template <class Result
, class Default
>
202 struct result_or_default
207 template <class Default
>
208 struct result_or_default
<unspecified
, Default
>
210 typedef Default type
;
213 template<class Parameters
, class Predicate
, class DefaultValue
>
214 struct extract_parameter
216 typedef typename get_predicate
<Predicate
>::type pred
;
217 typedef typename
boost::mpl::find_if
<Parameters
, pred
>::type iterator
;
218 typedef typename result_or_default
<
219 typename
iterator::type
, DefaultValue
223 // prints the types of the values on the stack, in the
224 // range [start_index, lua_gettop()]
226 LUABIND_API
std::string
stack_content_by_name(lua_State
* L
, int start_index
);
228 struct LUABIND_API create_class
230 static int stage1(lua_State
* L
);
231 static int stage2(lua_State
* L
);
241 static_scope(T
& self_
) : self(self_
)
245 T
& operator[](scope s
) const
247 self
.add_inner_scope(s
);
252 template<class U
> void operator,(U
const&) const;
253 void operator=(static_scope
const&);
258 struct class_registration
;
260 struct LUABIND_API class_base
: scope
263 class_base(char const* name
);
272 type_id
const& type
, class_id id
273 , type_id
const& wrapped_type
, class_id wrapper_id
);
275 void add_base(type_id
const& base
, cast_function cast
);
277 void add_member(registration
* member
);
278 void add_default_member(registration
* member
);
280 const char* name() const;
282 void add_static_constant(const char* name
, int val
);
283 void add_inner_scope(scope
& s
);
285 void add_cast(class_id src
, class_id target
, cast_function cast
);
288 class_registration
* m_registration
;
291 // MSVC complains about member being sensitive to alignment (C4121)
292 // when F is a pointer to member of a class with virtual bases.
298 template <class Class
, class F
, class Policies
>
299 struct memfun_registration
: registration
301 memfun_registration(char const* name
, F f
, Policies
const& policies
)
307 void register_(lua_State
* L
) const
309 object fn
= make_function(
310 L
, f
, deduce_signature(f
, (Class
*)0), policies
);
313 object(from_stack(L
, -1))
328 template <class P
, class T
>
329 struct default_pointer
335 struct default_pointer
<null_type
, T
>
337 typedef std::auto_ptr
<T
> type
;
340 template <class Class
, class Pointer
, class Signature
, class Policies
>
341 struct constructor_registration
: registration
343 constructor_registration(Policies
const& policies
)
347 void register_(lua_State
* L
) const
349 typedef typename default_pointer
<Pointer
, Class
>::type pointer
;
351 object fn
= make_function(
353 , construct
<Class
, pointer
, Signature
>(), Signature()
358 object(from_stack(L
, -1))
368 struct reference_result
370 mpl::or_
<boost::is_pointer
<T
>, is_primitive
<T
> >
372 , typename
boost::add_reference
<T
>::type
377 struct reference_argument
379 mpl::or_
<boost::is_pointer
<T
>, is_primitive
<T
> >
381 , typename
boost::add_reference
<
382 typename
boost::add_const
<T
>::type
387 template <class T
, class Policies
>
388 struct inject_dependency_policy
392 , policy_cons
<dependency_policy
<0, 1>, Policies
>
398 , class Get
, class GetPolicies
399 , class Set
= null_type
, class SetPolicies
= null_type
401 struct property_registration
: registration
403 property_registration(
406 , GetPolicies
const& get_policies
407 , Set
const& set
= Set()
408 , SetPolicies
const& set_policies
= SetPolicies()
412 , get_policies(get_policies
)
414 , set_policies(set_policies
)
417 void register_(lua_State
* L
) const
419 object
context(from_stack(L
, -1));
423 , make_get(L
, get
, boost::is_member_object_pointer
<Get
>())
429 object
make_get(lua_State
* L
, F
const& f
, mpl::false_
) const
431 return make_function(
432 L
, f
, deduce_signature(f
, (Class
*)0), get_policies
);
435 template <class T
, class D
>
436 object
make_get(lua_State
* L
, D
T::* mem_ptr
, mpl::true_
) const
438 typedef typename reference_result
<D
>::type result_type
;
439 typedef typename inject_dependency_policy
<
440 D
, GetPolicies
>::type policies
;
442 return make_function(
444 , access_member_ptr
<T
, D
, result_type
>(mem_ptr
)
445 , mpl::vector2
<result_type
, Class
const&>()
451 object
make_set(lua_State
* L
, F
const& f
, mpl::false_
) const
453 return make_function(
454 L
, f
, deduce_signature(f
, (Class
*)0), set_policies
);
457 template <class T
, class D
>
458 object
make_set(lua_State
* L
, D
T::* mem_ptr
, mpl::true_
) const
460 typedef typename reference_argument
<D
>::type argument_type
;
462 return make_function(
464 , access_member_ptr
<T
, D
>(mem_ptr
)
465 , mpl::vector3
<void, Class
&, argument_type
>()
472 lua_State
* L
, object
const& context
473 , object
const& get_
, S
const&) const
475 context
[name
] = property(
477 , make_set(L
, set
, boost::is_member_object_pointer
<Set
>())
482 lua_State
*, object
const& context
483 , object
const& get_
, null_type
) const
485 context
[name
] = property(get_
);
490 GetPolicies get_policies
;
492 SetPolicies set_policies
;
495 } // namespace detail
497 // registers a class in the lua environment
498 template<class T
, class X1
, class X2
, class X3
>
499 struct class_
: detail::class_base
501 typedef class_
<T
, X1
, X2
, X3
> self_t
;
505 template<class A
, class B
, class C
, class D
>
506 class_(const class_
<A
,B
,C
,D
>&);
510 typedef boost::mpl::vector4
<X1
, X2
, X3
, detail::unspecified
> parameters_type
;
512 // WrappedType MUST inherit from T
513 typedef typename
detail::extract_parameter
<
515 , boost::is_base_and_derived
<T
, boost::mpl::_
>
519 typedef typename
detail::extract_parameter
<
523 detail::is_bases
<boost::mpl::_
>
524 , boost::is_base_and_derived
<boost::mpl::_
, T
>
525 , boost::is_base_and_derived
<T
, boost::mpl::_
>
531 template <class Src
, class Target
>
532 void add_downcast(Src
*, Target
*, boost::mpl::true_
)
535 detail::registered_class
<Src
>::id
536 , detail::registered_class
<Target
>::id
537 , detail::dynamic_cast_
<Src
, Target
>::execute
541 template <class Src
, class Target
>
542 void add_downcast(Src
*, Target
*, boost::mpl::false_
)
545 // this function generates conversion information
546 // in the given class_rep structure. It will be able
547 // to implicitly cast to the given template type
549 void gen_base_info(detail::type_
<To
>)
551 add_base(typeid(To
), detail::static_cast_
<T
, To
>::execute
);
553 detail::registered_class
<T
>::id
554 , detail::registered_class
<To
>::id
555 , detail::static_cast_
<T
, To
>::execute
558 add_downcast((To
*)0, (T
*)0, boost::is_polymorphic
<To
>());
561 void gen_base_info(detail::type_
<detail::null_type
>)
564 #define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type_<BaseClass##n>());
566 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES
, class BaseClass
)>
567 void generate_baseclass_list(detail::type_
<bases
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES
, BaseClass
)> >)
569 BOOST_PP_REPEAT(LUABIND_MAX_BASES
, LUABIND_GEN_BASE_INFO
, _
)
572 #undef LUABIND_GEN_BASE_INFO
574 class_(const char* name
): class_base(name
), scope(*this)
577 detail::check_link_compatibility();
583 class_
& def(const char* name
, F f
)
585 return this->virtual_def(
586 name
, f
, detail::null_type()
587 , detail::null_type(), boost::mpl::true_());
591 template<class F
, class DefaultOrPolicies
>
592 class_
& def(char const* name
, F fn
, DefaultOrPolicies default_or_policies
)
594 return this->virtual_def(
595 name
, fn
, default_or_policies
, detail::null_type()
596 , LUABIND_MSVC_TYPENAME
detail::is_policy_cons
<DefaultOrPolicies
>::type());
599 template<class F
, class Default
, class Policies
>
600 class_
& def(char const* name
, F fn
601 , Default default_
, Policies
const& policies
)
603 return this->virtual_def(
605 , policies
, boost::mpl::false_());
608 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, class A
)>
609 class_
& def(constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> sig
)
611 return this->def_constructor(&sig
, detail::null_type());
614 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, class A
), class Policies
>
615 class_
& def(constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> sig
, const Policies
& policies
)
617 return this->def_constructor(&sig
, policies
);
620 template <class Getter
>
621 class_
& property(const char* name
, Getter g
)
624 new detail::property_registration
<T
, Getter
, detail::null_type
>(
625 name
, g
, detail::null_type()));
629 template <class Getter
, class MaybeSetter
>
630 class_
& property(const char* name
, Getter g
, MaybeSetter s
)
632 return property_impl(
634 , boost::mpl::bool_
<detail::is_policy_cons
<MaybeSetter
>::value
>()
638 template<class Getter
, class Setter
, class GetPolicies
>
639 class_
& property(const char* name
, Getter g
, Setter s
, const GetPolicies
& get_policies
)
641 typedef detail::property_registration
<
642 T
, Getter
, GetPolicies
, Setter
, detail::null_type
646 new registration_type(name
, g
, get_policies
, s
));
650 template<class Getter
, class Setter
, class GetPolicies
, class SetPolicies
>
654 , GetPolicies
const& get_policies
655 , SetPolicies
const& set_policies
)
657 typedef detail::property_registration
<
658 T
, Getter
, GetPolicies
, Setter
, SetPolicies
662 new registration_type(name
, g
, get_policies
, s
, set_policies
));
666 template <class C
, class D
>
667 class_
& def_readonly(const char* name
, D
C::*mem_ptr
)
669 typedef detail::property_registration
<T
, D
C::*, detail::null_type
>
673 new registration_type(name
, mem_ptr
, detail::null_type()));
677 template <class C
, class D
, class Policies
>
678 class_
& def_readonly(const char* name
, D
C::*mem_ptr
, Policies
const& policies
)
680 typedef detail::property_registration
<T
, D
C::*, Policies
>
684 new registration_type(name
, mem_ptr
, policies
));
688 template <class C
, class D
>
689 class_
& def_readwrite(const char* name
, D
C::*mem_ptr
)
691 typedef detail::property_registration
<
692 T
, D
C::*, detail::null_type
, D
C::*
696 new registration_type(
697 name
, mem_ptr
, detail::null_type(), mem_ptr
));
701 template <class C
, class D
, class GetPolicies
>
702 class_
& def_readwrite(
703 const char* name
, D
C::*mem_ptr
, GetPolicies
const& get_policies
)
705 typedef detail::property_registration
<
706 T
, D
C::*, GetPolicies
, D
C::*
710 new registration_type(
711 name
, mem_ptr
, get_policies
, mem_ptr
));
715 template <class C
, class D
, class GetPolicies
, class SetPolicies
>
716 class_
& def_readwrite(
719 , GetPolicies
const& get_policies
720 , SetPolicies
const& set_policies
723 typedef detail::property_registration
<
724 T
, D
C::*, GetPolicies
, D
C::*, SetPolicies
728 new registration_type(
729 name
, mem_ptr
, get_policies
, mem_ptr
, set_policies
));
733 template<class Derived
, class Policies
>
734 class_
& def(detail::operator_
<Derived
>, Policies
const& policies
)
738 , &Derived::template apply
<T
, Policies
>::execute
743 template<class Derived
>
744 class_
& def(detail::operator_
<Derived
>)
748 , &Derived::template apply
<T
, detail::null_type
>::execute
752 detail::enum_maker
<self_t
> enum_(const char*)
754 return detail::enum_maker
<self_t
>(*this);
757 detail::static_scope
<self_t
> scope
;
760 void operator=(class_
const&);
762 void add_wrapper_cast(detail::null_type
*)
766 void add_wrapper_cast(U
*)
769 detail::registered_class
<U
>::id
770 , detail::registered_class
<T
>::id
771 , detail::static_cast_
<U
,T
>::execute
774 add_downcast((T
*)0, (U
*)0, boost::is_polymorphic
<T
>());
779 typedef typename
detail::extract_parameter
<
782 detail::is_bases
<boost::mpl::_
>
783 , boost::is_base_and_derived
<boost::mpl::_
, T
>
789 boost::mpl::if_
<detail::is_bases
<bases_t
>
796 , detail::registered_class
<T
>::id
797 , typeid(WrappedType
)
798 , detail::registered_class
<WrappedType
>::id
801 add_wrapper_cast((WrappedType
*)0);
803 generate_baseclass_list(detail::type_
<Base
>());
806 template<class Getter
, class GetPolicies
>
807 class_
& property_impl(const char* name
,
809 GetPolicies policies
,
810 boost::mpl::bool_
<true>)
813 new detail::property_registration
<T
, Getter
, GetPolicies
>(
818 template<class Getter
, class Setter
>
819 class_
& property_impl(const char* name
,
822 boost::mpl::bool_
<false>)
824 typedef detail::property_registration
<
825 T
, Getter
, detail::null_type
, Setter
, detail::null_type
829 new registration_type(name
, g
, detail::null_type(), s
));
833 // these handle default implementation of virtual functions
834 template<class F
, class Policies
>
835 class_
& virtual_def(char const* name
, F
const& fn
836 , Policies
const&, detail::null_type
, boost::mpl::true_
)
839 new detail::memfun_registration
<T
, F
, Policies
>(
840 name
, fn
, Policies()));
844 template<class F
, class Default
, class Policies
>
845 class_
& virtual_def(char const* name
, F
const& fn
846 , Default
const& default_
, Policies
const&, boost::mpl::false_
)
849 new detail::memfun_registration
<T
, F
, Policies
>(
850 name
, fn
, Policies()));
852 this->add_default_member(
853 new detail::memfun_registration
<T
, Default
, Policies
>(
854 name
, default_
, Policies()));
859 template<class Signature
, class Policies
>
860 class_
& def_constructor(Signature
*, Policies
const&)
862 typedef typename
Signature::signature signature
;
864 typedef typename
boost::mpl::if_
<
865 boost::is_same
<WrappedType
, detail::null_type
>
868 >::type construct_type
;
871 new detail::constructor_registration
<
872 construct_type
, HeldType
, signature
, Policies
>(
875 this->add_default_member(
876 new detail::constructor_registration
<
877 construct_type
, HeldType
, signature
, Policies
>(
890 #endif // LUABIND_CLASS_HPP_INCLUDED