Don't construct T* const& types for attribute access.
[luabind.git] / luabind / class.hpp
blob105df9729198b332efcb8067416eadbf9d680b5c
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/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
115 #ifdef _MSC_VER
116 #pragma warning(push)
117 #pragma warning(disable: 4355)
118 #endif
120 namespace boost
123 template <class T> class shared_ptr;
125 } // namespace boost
127 namespace luabind
129 namespace detail
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>
139 struct class_;
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(...)
146 return 0;
149 template <class T>
150 boost::shared_ptr<T const>* get_const_holder(boost::shared_ptr<T>*)
152 return 0;
155 template <
156 BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
157 LUABIND_MAX_BASES, class A, detail::null_type)
159 struct bases
162 typedef bases<detail::null_type> no_bases;
164 namespace detail
166 template <class T>
167 struct is_bases
168 : mpl::false_
171 template <BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class A)>
172 struct is_bases<bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, A)> >
173 : mpl::true_
176 template <class T, class P>
177 struct is_unspecified
178 : mpl::apply1<P, T>
181 template <class P>
182 struct is_unspecified<unspecified, P>
183 : mpl::true_
186 template <class P>
187 struct is_unspecified_mfn
189 template <class T>
190 struct apply
191 : is_unspecified<T, P>
195 template<class Predicate>
196 struct get_predicate
198 typedef mpl::protect<is_unspecified_mfn<Predicate> > type;
201 template <class Result, class Default>
202 struct result_or_default
204 typedef Result type;
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
220 >::type type;
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);
234 } // detail
236 namespace detail {
238 template<class T>
239 struct static_scope
241 static_scope(T& self_) : self(self_)
245 T& operator[](scope s) const
247 self.add_inner_scope(s);
248 return self;
251 private:
252 template<class U> void operator,(U const&) const;
253 void operator=(static_scope const&);
255 T& self;
258 struct class_registration;
260 struct LUABIND_API class_base : scope
262 public:
263 class_base(char const* name);
265 struct base_desc
267 type_id type;
268 int ptr_offset;
271 void init(
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);
287 private:
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.
293 # ifdef BOOST_MSVC
294 # pragma pack(push)
295 # pragma pack(16)
296 # endif
298 template <class Class, class F, class Policies>
299 struct memfun_registration : registration
301 memfun_registration(char const* name, F f, Policies const& policies)
302 : name(name)
303 , f(f)
304 , policies(policies)
307 void register_(lua_State* L) const
309 object fn = make_function(
310 L, f, deduce_signature(f, (Class*)0), policies);
312 add_overload(
313 object(from_stack(L, -1))
314 , name
315 , fn
319 char const* name;
320 F f;
321 Policies policies;
324 # ifdef BOOST_MSVC
325 # pragma pack(pop)
326 # endif
328 template <class P, class T>
329 struct default_pointer
331 typedef P type;
334 template <class T>
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)
344 : policies(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()
354 , policies
357 add_overload(
358 object(from_stack(L, -1))
359 , "__init"
360 , fn
364 Policies policies;
367 template <class T>
368 struct reference_result
369 : mpl::if_<
370 mpl::or_<boost::is_pointer<T>, is_primitive<T> >
372 , typename boost::add_reference<T>::type
376 template <class T>
377 struct reference_argument
378 : mpl::if_<
379 mpl::or_<boost::is_pointer<T>, is_primitive<T> >
381 , typename boost::add_reference<
382 typename boost::add_const<T>::type
383 >::type
387 template <class T, class Policies>
388 struct inject_dependency_policy
389 : mpl::if_<
390 is_primitive<T>
391 , Policies
392 , policy_cons<dependency_policy<0, 1>, Policies>
396 template <
397 class Class
398 , class Get, class GetPolicies
399 , class Set = null_type, class SetPolicies = null_type
401 struct property_registration : registration
403 property_registration(
404 char const* name
405 , Get const& get
406 , GetPolicies const& get_policies
407 , Set const& set = Set()
408 , SetPolicies const& set_policies = SetPolicies()
410 : name(name)
411 , get(get)
412 , get_policies(get_policies)
413 , set(set)
414 , set_policies(set_policies)
417 void register_(lua_State* L) const
419 object context(from_stack(L, -1));
420 register_aux(
422 , context
423 , make_get(L, get, boost::is_member_object_pointer<Get>())
424 , set
428 template <class F>
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&>()
446 , policies()
450 template <class F>
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>()
466 , set_policies
470 template <class S>
471 void register_aux(
472 lua_State* L, object const& context
473 , object const& get_, S const&) const
475 context[name] = property(
476 get_
477 , make_set(L, set, boost::is_member_object_pointer<Set>())
481 void register_aux(
482 lua_State*, object const& context
483 , object const& get_, null_type) const
485 context[name] = property(get_);
488 char const* name;
489 Get get;
490 GetPolicies get_policies;
491 Set set;
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;
503 private:
505 template<class A, class B, class C, class D>
506 class_(const class_<A,B,C,D>&);
508 public:
510 typedef boost::mpl::vector4<X1, X2, X3, detail::unspecified> parameters_type;
512 // WrappedType MUST inherit from T
513 typedef typename detail::extract_parameter<
514 parameters_type
515 , boost::is_base_and_derived<T, boost::mpl::_>
516 , detail::null_type
517 >::type WrappedType;
519 typedef typename detail::extract_parameter<
520 parameters_type
521 , boost::mpl::not_<
522 boost::mpl::or_<
523 detail::is_bases<boost::mpl::_>
524 , boost::is_base_and_derived<boost::mpl::_, T>
525 , boost::is_base_and_derived<T, boost::mpl::_>
528 , detail::null_type
529 >::type HeldType;
531 template <class Src, class Target>
532 void add_downcast(Src*, Target*, boost::mpl::true_)
534 add_cast(
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
548 template<class To>
549 void gen_base_info(detail::type_<To>)
551 add_base(typeid(To), detail::static_cast_<T, To>::execute);
552 add_cast(
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)
576 #ifndef NDEBUG
577 detail::check_link_compatibility();
578 #endif
579 init();
582 template<class F>
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_());
590 // virtual functions
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(
604 name, fn, default_
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)
623 this->add_member(
624 new detail::property_registration<T, Getter, detail::null_type>(
625 name, g, detail::null_type()));
626 return *this;
629 template <class Getter, class MaybeSetter>
630 class_& property(const char* name, Getter g, MaybeSetter s)
632 return property_impl(
633 name, g, s
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
643 > registration_type;
645 this->add_member(
646 new registration_type(name, g, get_policies, s));
647 return *this;
650 template<class Getter, class Setter, class GetPolicies, class SetPolicies>
651 class_& property(
652 const char* name
653 , Getter g, Setter s
654 , GetPolicies const& get_policies
655 , SetPolicies const& set_policies)
657 typedef detail::property_registration<
658 T, Getter, GetPolicies, Setter, SetPolicies
659 > registration_type;
661 this->add_member(
662 new registration_type(name, g, get_policies, s, set_policies));
663 return *this;
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>
670 registration_type;
672 this->add_member(
673 new registration_type(name, mem_ptr, detail::null_type()));
674 return *this;
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>
681 registration_type;
683 this->add_member(
684 new registration_type(name, mem_ptr, policies));
685 return *this;
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::*
693 > registration_type;
695 this->add_member(
696 new registration_type(
697 name, mem_ptr, detail::null_type(), mem_ptr));
698 return *this;
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::*
707 > registration_type;
709 this->add_member(
710 new registration_type(
711 name, mem_ptr, get_policies, mem_ptr));
712 return *this;
715 template <class C, class D, class GetPolicies, class SetPolicies>
716 class_& def_readwrite(
717 const char* name
718 , D C::*mem_ptr
719 , GetPolicies const& get_policies
720 , SetPolicies const& set_policies
723 typedef detail::property_registration<
724 T, D C::*, GetPolicies, D C::*, SetPolicies
725 > registration_type;
727 this->add_member(
728 new registration_type(
729 name, mem_ptr, get_policies, mem_ptr, set_policies));
730 return *this;
733 template<class Derived, class Policies>
734 class_& def(detail::operator_<Derived>, Policies const& policies)
736 return this->def(
737 Derived::name()
738 , &Derived::template apply<T, Policies>::execute
739 , policies
743 template<class Derived>
744 class_& def(detail::operator_<Derived>)
746 return this->def(
747 Derived::name()
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;
759 private:
760 void operator=(class_ const&);
762 void add_wrapper_cast(detail::null_type*)
765 template <class U>
766 void add_wrapper_cast(U*)
768 add_cast(
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>());
777 void init()
779 typedef typename detail::extract_parameter<
780 parameters_type
781 , boost::mpl::or_<
782 detail::is_bases<boost::mpl::_>
783 , boost::is_base_and_derived<boost::mpl::_, T>
785 , no_bases
786 >::type bases_t;
788 typedef typename
789 boost::mpl::if_<detail::is_bases<bases_t>
790 , bases_t
791 , bases<bases_t>
792 >::type Base;
794 class_base::init(
795 typeid(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,
808 Getter g,
809 GetPolicies policies,
810 boost::mpl::bool_<true>)
812 this->add_member(
813 new detail::property_registration<T, Getter, GetPolicies>(
814 name, g, policies));
815 return *this;
818 template<class Getter, class Setter>
819 class_& property_impl(const char* name,
820 Getter g,
821 Setter s,
822 boost::mpl::bool_<false>)
824 typedef detail::property_registration<
825 T, Getter, detail::null_type, Setter, detail::null_type
826 > registration_type;
828 this->add_member(
829 new registration_type(name, g, detail::null_type(), s));
830 return *this;
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_)
838 this->add_member(
839 new detail::memfun_registration<T, F, Policies>(
840 name, fn, Policies()));
841 return *this;
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_)
848 this->add_member(
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()));
856 return *this;
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>
867 , WrappedType
868 >::type construct_type;
870 this->add_member(
871 new detail::constructor_registration<
872 construct_type, HeldType, signature, Policies>(
873 Policies()));
875 this->add_default_member(
876 new detail::constructor_registration<
877 construct_type, HeldType, signature, Policies>(
878 Policies()));
880 return *this;
886 #ifdef _MSC_VER
887 #pragma warning(pop)
888 #endif
890 #endif // LUABIND_CLASS_HPP_INCLUDED