Initial C++0x support.
[luabind.git] / luabind / class.hpp
blobb8fd3619061e03c7cfe03c616790e13a5f5ad86b
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 <cassert>
76 #ifndef LUABIND_CPP0x
77 #include <boost/preprocessor/repetition/enum_params.hpp>
78 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
79 #include <boost/preprocessor/repetition/repeat.hpp>
80 #endif
81 #include <boost/type_traits/is_same.hpp>
82 #include <boost/type_traits/is_member_object_pointer.hpp>
83 #include <boost/mpl/apply.hpp>
84 #include <boost/mpl/lambda.hpp>
85 #include <boost/mpl/logical.hpp>
86 #include <boost/mpl/find_if.hpp>
87 #include <boost/mpl/eval_if.hpp>
88 #include <boost/mpl/logical.hpp>
89 #include <boost/mpl/vector/vector10.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/operator_id.hpp>
108 #include <luabind/detail/pointee_typeid.hpp>
109 #include <luabind/detail/link_compatibility.hpp>
110 #include <luabind/detail/inheritance.hpp>
111 #include <luabind/detail/signature_match.hpp>
112 #include <luabind/no_dependency.hpp>
113 #include <luabind/typeid.hpp>
115 // to remove the 'this' used in initialization list-warning
116 #ifdef _MSC_VER
117 #pragma warning(push)
118 #pragma warning(disable: 4355)
119 #endif
121 namespace boost
124 template <class T> class shared_ptr;
126 } // namespace boost
128 namespace luabind
130 namespace detail
132 struct unspecified {};
134 template<class Derived> struct operator_;
136 struct you_need_to_define_a_get_const_holder_function_for_your_smart_ptr {};
139 template<class T, class X1 = detail::unspecified, class X2 = detail::unspecified, class X3 = detail::unspecified>
140 struct class_;
142 // TODO: this function will only be invoked if the user hasn't defined a correct overload
143 // maybe we should have a static assert in here?
144 inline detail::you_need_to_define_a_get_const_holder_function_for_your_smart_ptr*
145 get_const_holder(...)
147 return 0;
150 template <class T>
151 boost::shared_ptr<T const>* get_const_holder(boost::shared_ptr<T>*)
153 return 0;
156 # ifdef LUABIND_CPP0x
158 template <class... Args>
159 struct bases
162 typedef bases<> no_bases;
164 # else
166 template <
167 BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
168 LUABIND_MAX_BASES, class A, detail::null_type)
170 struct bases
173 typedef bases<detail::null_type> no_bases;
175 # endif // LUABIND_CPP0x
177 namespace detail
179 template <class T>
180 struct is_bases
181 : mpl::false_
184 # ifdef LUABIND_CPP0x
185 template <class... Args>
186 struct is_bases<bases<Args...> >
187 : mpl::true_
189 # else
190 template <BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class A)>
191 struct is_bases<bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, A)> >
192 : mpl::true_
194 # endif
196 template <class T, class P>
197 struct is_unspecified
198 : mpl::apply1<P, T>
201 template <class P>
202 struct is_unspecified<unspecified, P>
203 : mpl::true_
206 template <class P>
207 struct is_unspecified_mfn
209 template <class T>
210 struct apply
211 : is_unspecified<T, P>
215 template<class Predicate>
216 struct get_predicate
218 typedef mpl::protect<is_unspecified_mfn<Predicate> > type;
221 template <class Result, class Default>
222 struct result_or_default
224 typedef Result type;
227 template <class Default>
228 struct result_or_default<unspecified, Default>
230 typedef Default type;
233 template<class Parameters, class Predicate, class DefaultValue>
234 struct extract_parameter
236 typedef typename get_predicate<Predicate>::type pred;
237 typedef typename boost::mpl::find_if<Parameters, pred>::type iterator;
238 typedef typename result_or_default<
239 typename iterator::type, DefaultValue
240 >::type type;
243 // prints the types of the values on the stack, in the
244 // range [start_index, lua_gettop()]
246 LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index);
248 struct LUABIND_API create_class
250 static int stage1(lua_State* L);
251 static int stage2(lua_State* L);
254 } // detail
256 namespace detail {
258 template<class T>
259 struct static_scope
261 static_scope(T& self_) : self(self_)
265 T& operator[](scope s) const
267 self.add_inner_scope(s);
268 return self;
271 private:
272 template<class U> void operator,(U const&) const;
273 void operator=(static_scope const&);
275 T& self;
278 struct class_registration;
280 struct LUABIND_API class_base : scope
282 public:
283 class_base(char const* name);
285 struct base_desc
287 type_id type;
288 int ptr_offset;
291 void init(
292 type_id const& type, class_id id
293 , type_id const& wrapped_type, class_id wrapper_id);
295 void add_base(type_id const& base, cast_function cast);
297 void add_member(registration* member);
298 void add_default_member(registration* member);
300 const char* name() const;
302 void add_static_constant(const char* name, int val);
303 void add_inner_scope(scope& s);
305 void add_cast(class_id src, class_id target, cast_function cast);
307 private:
308 class_registration* m_registration;
311 // MSVC complains about member being sensitive to alignment (C4121)
312 // when F is a pointer to member of a class with virtual bases.
313 # ifdef BOOST_MSVC
314 # pragma pack(push)
315 # pragma pack(16)
316 # endif
318 template <class Class, class F, class Policies>
319 struct memfun_registration : registration
321 memfun_registration(char const* name, F f, Policies const& policies)
322 : name(name)
323 , f(f)
324 , policies(policies)
327 void register_(lua_State* L) const
329 object fn = make_function(
330 L, f, deduce_signature(f, (Class*)0), policies);
332 add_overload(
333 object(from_stack(L, -1))
334 , name
335 , fn
339 char const* name;
340 F f;
341 Policies policies;
344 # ifdef BOOST_MSVC
345 # pragma pack(pop)
346 # endif
348 template <class P, class T>
349 struct default_pointer
351 typedef P type;
354 template <class T>
355 struct default_pointer<null_type, T>
357 typedef std::auto_ptr<T> type;
360 template <class Class, class Pointer, class Signature, class Policies>
361 struct constructor_registration : registration
363 constructor_registration(Policies const& policies)
364 : policies(policies)
367 void register_(lua_State* L) const
369 typedef typename default_pointer<Pointer, Class>::type pointer;
371 object fn = make_function(
373 , construct<Class, pointer, Signature>(), Signature()
374 , policies
377 add_overload(
378 object(from_stack(L, -1))
379 , "__init"
380 , fn
384 Policies policies;
387 template <class T>
388 struct reference_result
389 : mpl::if_<
390 mpl::or_<boost::is_pointer<T>, is_primitive<T> >
392 , typename boost::add_reference<T>::type
396 template <class T>
397 struct reference_argument
398 : mpl::if_<
399 mpl::or_<boost::is_pointer<T>, is_primitive<T> >
401 , typename boost::add_reference<
402 typename boost::add_const<T>::type
403 >::type
407 template <class T, class Policies>
408 struct inject_dependency_policy
409 : mpl::if_<
410 mpl::or_<
411 is_primitive<T>
412 , has_policy<Policies, detail::no_dependency_policy>
414 , Policies
415 , policy_cons<dependency_policy<0, 1>, Policies>
419 template <
420 class Class
421 , class Get, class GetPolicies
422 , class Set = null_type, class SetPolicies = null_type
424 struct property_registration : registration
426 property_registration(
427 char const* name
428 , Get const& get
429 , GetPolicies const& get_policies
430 , Set const& set = Set()
431 , SetPolicies const& set_policies = SetPolicies()
433 : name(name)
434 , get(get)
435 , get_policies(get_policies)
436 , set(set)
437 , set_policies(set_policies)
440 void register_(lua_State* L) const
442 object context(from_stack(L, -1));
443 register_aux(
445 , context
446 , make_get(L, get, boost::is_member_object_pointer<Get>())
447 , set
451 template <class F>
452 object make_get(lua_State* L, F const& f, mpl::false_) const
454 return make_function(
455 L, f, deduce_signature(f, (Class*)0), get_policies);
458 template <class T, class D>
459 object make_get(lua_State* L, D T::* mem_ptr, mpl::true_) const
461 typedef typename reference_result<D>::type result_type;
462 typedef typename inject_dependency_policy<
463 D, GetPolicies>::type policies;
465 return make_function(
467 , access_member_ptr<T, D, result_type>(mem_ptr)
468 , mpl::vector2<result_type, Class const&>()
469 , policies()
473 template <class F>
474 object make_set(lua_State* L, F const& f, mpl::false_) const
476 return make_function(
477 L, f, deduce_signature(f, (Class*)0), set_policies);
480 template <class T, class D>
481 object make_set(lua_State* L, D T::* mem_ptr, mpl::true_) const
483 typedef typename reference_argument<D>::type argument_type;
485 return make_function(
487 , access_member_ptr<T, D>(mem_ptr)
488 , mpl::vector3<void, Class&, argument_type>()
489 , set_policies
493 template <class S>
494 void register_aux(
495 lua_State* L, object const& context
496 , object const& get_, S const&) const
498 context[name] = property(
499 get_
500 , make_set(L, set, boost::is_member_object_pointer<Set>())
504 void register_aux(
505 lua_State*, object const& context
506 , object const& get_, null_type) const
508 context[name] = property(get_);
511 char const* name;
512 Get get;
513 GetPolicies get_policies;
514 Set set;
515 SetPolicies set_policies;
518 } // namespace detail
520 // registers a class in the lua environment
521 template<class T, class X1, class X2, class X3>
522 struct class_: detail::class_base
524 typedef class_<T, X1, X2, X3> self_t;
526 private:
528 template<class A, class B, class C, class D>
529 class_(const class_<A,B,C,D>&);
531 public:
533 typedef boost::mpl::vector4<X1, X2, X3, detail::unspecified> parameters_type;
535 // WrappedType MUST inherit from T
536 typedef typename detail::extract_parameter<
537 parameters_type
538 , boost::is_base_and_derived<T, boost::mpl::_>
539 , detail::null_type
540 >::type WrappedType;
542 typedef typename detail::extract_parameter<
543 parameters_type
544 , boost::mpl::not_<
545 boost::mpl::or_<
546 detail::is_bases<boost::mpl::_>
547 , boost::is_base_and_derived<boost::mpl::_, T>
548 , boost::is_base_and_derived<T, boost::mpl::_>
551 , detail::null_type
552 >::type HeldType;
554 template <class Src, class Target>
555 void add_downcast(Src*, Target*, boost::mpl::true_)
557 add_cast(
558 detail::registered_class<Src>::id
559 , detail::registered_class<Target>::id
560 , detail::dynamic_cast_<Src, Target>::execute
564 template <class Src, class Target>
565 void add_downcast(Src*, Target*, boost::mpl::false_)
568 // this function generates conversion information
569 // in the given class_rep structure. It will be able
570 // to implicitly cast to the given template type
571 template<class To>
572 void gen_base_info(detail::type_<To>)
574 add_base(typeid(To), detail::static_cast_<T, To>::execute);
575 add_cast(
576 detail::registered_class<T>::id
577 , detail::registered_class<To>::id
578 , detail::static_cast_<T, To>::execute
581 add_downcast((To*)0, (T*)0, boost::is_polymorphic<To>());
584 void gen_base_info(detail::type_<detail::null_type>)
587 # ifndef LUABIND_CPP0x
589 #define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type_<BaseClass##n>());
591 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class BaseClass)>
592 void generate_baseclass_list(detail::type_<bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, BaseClass)> >)
594 BOOST_PP_REPEAT(LUABIND_MAX_BASES, LUABIND_GEN_BASE_INFO, _)
597 #undef LUABIND_GEN_BASE_INFO
599 # else // !LUABIND_CPP0x
601 template <class... Args>
602 void ignore(Args&&...)
605 template <class... Bases>
606 void generate_baseclass_list(detail::type_<bases<Bases...> >)
608 ignore((gen_base_info(detail::type_<Bases>()), 0)...);
611 # endif // !LUABIND_CPP0x
613 class_(const char* name): class_base(name), scope(*this)
615 #ifndef NDEBUG
616 detail::check_link_compatibility();
617 #endif
618 init();
621 template<class F>
622 class_& def(const char* name, F f)
624 return this->virtual_def(
625 name, f, detail::null_type()
626 , detail::null_type(), boost::mpl::true_());
629 // virtual functions
630 template<class F, class DefaultOrPolicies>
631 class_& def(char const* name, F fn, DefaultOrPolicies default_or_policies)
633 return this->virtual_def(
634 name, fn, default_or_policies, detail::null_type()
635 , LUABIND_MSVC_TYPENAME detail::is_policy_cons<DefaultOrPolicies>::type());
638 template<class F, class Default, class Policies>
639 class_& def(char const* name, F fn
640 , Default default_, Policies const& policies)
642 return this->virtual_def(
643 name, fn, default_
644 , policies, boost::mpl::false_());
647 # ifdef LUABIND_CPP0x
649 template <class... Args, class Policies = detail::null_type>
650 class_& def(constructor<Args...>, Policies const& policies = Policies())
652 return this->def_constructor((constructor<Args...>*)0, policies);
655 # else
657 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)>
658 class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig)
660 return this->def_constructor(&sig, detail::null_type());
663 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A), class Policies>
664 class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig, const Policies& policies)
666 return this->def_constructor(&sig, policies);
669 # endif // LUABIND_CPP0x
671 template <class Getter>
672 class_& property(const char* name, Getter g)
674 this->add_member(
675 new detail::property_registration<T, Getter, detail::null_type>(
676 name, g, detail::null_type()));
677 return *this;
680 template <class Getter, class MaybeSetter>
681 class_& property(const char* name, Getter g, MaybeSetter s)
683 return property_impl(
684 name, g, s
685 , boost::mpl::bool_<detail::is_policy_cons<MaybeSetter>::value>()
689 template<class Getter, class Setter, class GetPolicies>
690 class_& property(const char* name, Getter g, Setter s, const GetPolicies& get_policies)
692 typedef detail::property_registration<
693 T, Getter, GetPolicies, Setter, detail::null_type
694 > registration_type;
696 this->add_member(
697 new registration_type(name, g, get_policies, s));
698 return *this;
701 template<class Getter, class Setter, class GetPolicies, class SetPolicies>
702 class_& property(
703 const char* name
704 , Getter g, Setter s
705 , GetPolicies const& get_policies
706 , SetPolicies const& set_policies)
708 typedef detail::property_registration<
709 T, Getter, GetPolicies, Setter, SetPolicies
710 > registration_type;
712 this->add_member(
713 new registration_type(name, g, get_policies, s, set_policies));
714 return *this;
717 template <class C, class D>
718 class_& def_readonly(const char* name, D C::*mem_ptr)
720 typedef detail::property_registration<T, D C::*, detail::null_type>
721 registration_type;
723 this->add_member(
724 new registration_type(name, mem_ptr, detail::null_type()));
725 return *this;
728 template <class C, class D, class Policies>
729 class_& def_readonly(const char* name, D C::*mem_ptr, Policies const& policies)
731 typedef detail::property_registration<T, D C::*, Policies>
732 registration_type;
734 this->add_member(
735 new registration_type(name, mem_ptr, policies));
736 return *this;
739 template <class C, class D>
740 class_& def_readwrite(const char* name, D C::*mem_ptr)
742 typedef detail::property_registration<
743 T, D C::*, detail::null_type, D C::*
744 > registration_type;
746 this->add_member(
747 new registration_type(
748 name, mem_ptr, detail::null_type(), mem_ptr));
749 return *this;
752 template <class C, class D, class GetPolicies>
753 class_& def_readwrite(
754 const char* name, D C::*mem_ptr, GetPolicies const& get_policies)
756 typedef detail::property_registration<
757 T, D C::*, GetPolicies, D C::*
758 > registration_type;
760 this->add_member(
761 new registration_type(
762 name, mem_ptr, get_policies, mem_ptr));
763 return *this;
766 template <class C, class D, class GetPolicies, class SetPolicies>
767 class_& def_readwrite(
768 const char* name
769 , D C::*mem_ptr
770 , GetPolicies const& get_policies
771 , SetPolicies const& set_policies
774 typedef detail::property_registration<
775 T, D C::*, GetPolicies, D C::*, SetPolicies
776 > registration_type;
778 this->add_member(
779 new registration_type(
780 name, mem_ptr, get_policies, mem_ptr, set_policies));
781 return *this;
784 template<class Derived, class Policies>
785 class_& def(detail::operator_<Derived>, Policies const& policies)
787 return this->def(
788 Derived::name()
789 , &Derived::template apply<T, Policies>::execute
790 , policies
794 template<class Derived>
795 class_& def(detail::operator_<Derived>)
797 return this->def(
798 Derived::name()
799 , &Derived::template apply<T, detail::null_type>::execute
803 detail::enum_maker<self_t> enum_(const char*)
805 return detail::enum_maker<self_t>(*this);
808 detail::static_scope<self_t> scope;
810 private:
811 void operator=(class_ const&);
813 void add_wrapper_cast(detail::null_type*)
816 template <class U>
817 void add_wrapper_cast(U*)
819 add_cast(
820 detail::registered_class<U>::id
821 , detail::registered_class<T>::id
822 , detail::static_cast_<U,T>::execute
825 add_downcast((T*)0, (U*)0, boost::is_polymorphic<T>());
828 void init()
830 typedef typename detail::extract_parameter<
831 parameters_type
832 , boost::mpl::or_<
833 detail::is_bases<boost::mpl::_>
834 , boost::is_base_and_derived<boost::mpl::_, T>
836 , no_bases
837 >::type bases_t;
839 typedef typename
840 boost::mpl::if_<detail::is_bases<bases_t>
841 , bases_t
842 , bases<bases_t>
843 >::type Base;
845 class_base::init(
846 typeid(T)
847 , detail::registered_class<T>::id
848 , typeid(WrappedType)
849 , detail::registered_class<WrappedType>::id
852 add_wrapper_cast((WrappedType*)0);
854 generate_baseclass_list(detail::type_<Base>());
857 template<class Getter, class GetPolicies>
858 class_& property_impl(const char* name,
859 Getter g,
860 GetPolicies policies,
861 boost::mpl::bool_<true>)
863 this->add_member(
864 new detail::property_registration<T, Getter, GetPolicies>(
865 name, g, policies));
866 return *this;
869 template<class Getter, class Setter>
870 class_& property_impl(const char* name,
871 Getter g,
872 Setter s,
873 boost::mpl::bool_<false>)
875 typedef detail::property_registration<
876 T, Getter, detail::null_type, Setter, detail::null_type
877 > registration_type;
879 this->add_member(
880 new registration_type(name, g, detail::null_type(), s));
881 return *this;
884 // these handle default implementation of virtual functions
885 template<class F, class Policies>
886 class_& virtual_def(char const* name, F const& fn
887 , Policies const&, detail::null_type, boost::mpl::true_)
889 this->add_member(
890 new detail::memfun_registration<T, F, Policies>(
891 name, fn, Policies()));
892 return *this;
895 template<class F, class Default, class Policies>
896 class_& virtual_def(char const* name, F const& fn
897 , Default const& default_, Policies const&, boost::mpl::false_)
899 this->add_member(
900 new detail::memfun_registration<T, F, Policies>(
901 name, fn, Policies()));
903 this->add_default_member(
904 new detail::memfun_registration<T, Default, Policies>(
905 name, default_, Policies()));
907 return *this;
910 template<class Signature, class Policies>
911 class_& def_constructor(Signature*, Policies const&)
913 typedef typename Signature::signature signature;
915 typedef typename boost::mpl::if_<
916 boost::is_same<WrappedType, detail::null_type>
918 , WrappedType
919 >::type construct_type;
921 this->add_member(
922 new detail::constructor_registration<
923 construct_type, HeldType, signature, Policies>(
924 Policies()));
926 this->add_default_member(
927 new detail::constructor_registration<
928 construct_type, HeldType, signature, Policies>(
929 Policies()));
931 return *this;
937 #ifdef _MSC_VER
938 #pragma warning(pop)
939 #endif
941 #endif // LUABIND_CLASS_HPP_INCLUDED