Store dependency refs directly in the registry.
[luabind.git] / luabind / class.hpp
blobd1cd360ebb5beec2122433061ea3601cb82cf84e
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/compute_score.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/call.hpp>
105 #include <luabind/detail/object_rep.hpp>
106 #include <luabind/detail/calc_arity.hpp>
107 #include <luabind/detail/call_member.hpp>
108 #include <luabind/detail/enum_maker.hpp>
109 #include <luabind/detail/get_signature.hpp>
110 #include <luabind/detail/implicit_cast.hpp>
111 #include <luabind/detail/operator_id.hpp>
112 #include <luabind/detail/pointee_typeid.hpp>
113 #include <luabind/detail/link_compatibility.hpp>
114 #include <luabind/typeid.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
122 namespace boost
125 template <class T> class shared_ptr;
127 } // namespace boost
129 namespace luabind
131 namespace detail
133 struct unspecified {};
135 template<class Derived> struct operator_;
137 struct you_need_to_define_a_get_const_holder_function_for_your_smart_ptr {};
140 template<class T, class X1 = detail::unspecified, class X2 = detail::unspecified, class X3 = detail::unspecified>
141 struct class_;
143 // TODO: this function will only be invoked if the user hasn't defined a correct overload
144 // maybe we should have a static assert in here?
145 inline detail::you_need_to_define_a_get_const_holder_function_for_your_smart_ptr*
146 get_const_holder(...)
148 return 0;
151 template <class T>
152 boost::shared_ptr<T const>* get_const_holder(boost::shared_ptr<T>*)
154 return 0;
157 template <
158 BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
159 LUABIND_MAX_BASES, class A, detail::null_type)
161 struct bases
164 typedef bases<detail::null_type> no_bases;
166 namespace detail
168 template <class T>
169 struct is_bases
170 : mpl::false_
173 template <BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class A)>
174 struct is_bases<bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, A)> >
175 : mpl::true_
178 template <class T, class P>
179 struct is_unspecified
180 : mpl::apply1<P, T>
183 template <class P>
184 struct is_unspecified<unspecified, P>
185 : mpl::true_
188 template <class P>
189 struct is_unspecified_mfn
191 template <class T>
192 struct apply
193 : is_unspecified<T, P>
197 template<class Predicate>
198 struct get_predicate
200 typedef mpl::protect<is_unspecified_mfn<Predicate> > type;
203 template <class Result, class Default>
204 struct result_or_default
206 typedef Result type;
209 template <class Default>
210 struct result_or_default<unspecified, Default>
212 typedef Default type;
215 template<class Parameters, class Predicate, class DefaultValue>
216 struct extract_parameter
218 typedef typename get_predicate<Predicate>::type pred;
219 typedef typename boost::mpl::find_if<Parameters, pred>::type iterator;
220 typedef typename result_or_default<
221 typename iterator::type, DefaultValue
222 >::type type;
225 // prints the types of the values on the stack, in the
226 // range [start_index, lua_gettop()]
228 LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index);
230 struct LUABIND_API create_class
232 static int stage1(lua_State* L);
233 static int stage2(lua_State* L);
236 } // detail
238 namespace detail {
240 template<class T>
241 struct static_scope
243 static_scope(T& self_) : self(self_)
247 T& operator[](scope s) const
249 self.add_inner_scope(s);
250 return self;
253 private:
254 template<class U> void operator,(U const&) const;
255 void operator=(static_scope const&);
257 T& self;
260 struct class_registration;
262 struct LUABIND_API class_base : scope
264 public:
265 class_base(char const* name);
267 struct base_desc
269 type_id type;
270 int ptr_offset;
273 void init(type_id const& type);
275 void add_base(const base_desc& b);
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 private:
286 class_registration* m_registration;
289 template <class Class, class F, class Policies>
290 struct memfun_registration : registration
292 memfun_registration(char const* name, F f, Policies const& policies)
293 : name(name)
294 , f(f)
295 , policies(policies)
298 void register_(lua_State* L) const
300 object fn = make_function(
301 L, f, deduce_signature(f, (Class*)0), policies);
303 add_overload(
304 object(from_stack(L, -1))
305 , name
306 , fn
310 char const* name;
311 F f;
312 Policies policies;
315 template <class P, class T>
316 struct default_pointer
318 typedef P type;
321 template <class T>
322 struct default_pointer<null_type, T>
324 typedef std::auto_ptr<T> type;
327 template <class Class, class Pointer, class Signature, class Policies>
328 struct constructor_registration : registration
330 constructor_registration(Policies const& policies)
331 : policies(policies)
334 void register_(lua_State* L) const
336 typedef typename default_pointer<Pointer, Class>::type pointer;
338 object fn = make_function(
340 , construct<Class, pointer, Signature>(), Signature()
341 , policies
344 add_overload(
345 object(from_stack(L, -1))
346 , "__init"
347 , fn
351 Policies policies;
354 template <class T>
355 struct reference_result
356 : mpl::if_<
357 mpl::or_<boost::is_pointer<T>, is_primitive<T> >
359 , typename boost::add_reference<T>::type
363 template <class T, class Policies>
364 struct inject_dependency_policy
365 : mpl::if_<
366 is_primitive<T>
367 , Policies
368 , policy_cons<dependency_policy<0, 1>, Policies>
372 template <
373 class Class
374 , class Get, class GetPolicies
375 , class Set = null_type, class SetPolicies = null_type
377 struct property_registration : registration
379 property_registration(
380 char const* name
381 , Get const& get
382 , GetPolicies const& get_policies
383 , Set const& set = Set()
384 , SetPolicies const& set_policies = SetPolicies()
386 : name(name)
387 , get(get)
388 , get_policies(get_policies)
389 , set(set)
390 , set_policies(set_policies)
393 void register_(lua_State* L) const
395 object context(from_stack(L, -1));
396 register_aux(
398 , context
399 , make_get(L, get, boost::is_member_object_pointer<Get>())
400 , set
404 template <class F>
405 object make_get(lua_State* L, F const& f, mpl::false_) const
407 return make_function(
408 L, f, deduce_signature(f, (Class*)0), get_policies);
411 template <class T, class D>
412 object make_get(lua_State* L, D T::* mem_ptr, mpl::true_) const
414 typedef typename reference_result<D>::type result_type;
415 typedef typename inject_dependency_policy<
416 D, GetPolicies>::type policies;
418 return make_function(
420 , access_member_ptr<T, D, result_type>(mem_ptr)
421 , mpl::vector2<result_type, Class const&>()
422 , policies()
426 template <class F>
427 object make_set(lua_State* L, F const& f, mpl::false_) const
429 return make_function(
430 L, f, deduce_signature(f, (Class*)0), set_policies);
433 template <class T, class D>
434 object make_set(lua_State* L, D T::* mem_ptr, mpl::true_) const
436 return make_function(
438 , access_member_ptr<T, D>(mem_ptr)
439 , mpl::vector3<void, Class&, D const&>()
440 , set_policies
444 template <class S>
445 void register_aux(
446 lua_State* L, object const& context
447 , object const& get_, S const&) const
449 context[name] = property(
450 get_
451 , make_set(L, set, boost::is_member_object_pointer<Set>())
455 void register_aux(
456 lua_State* L, object const& context
457 , object const& get_, null_type) const
459 context[name] = property(get_);
462 char const* name;
463 Get get;
464 GetPolicies get_policies;
465 Set set;
466 SetPolicies set_policies;
469 } // namespace detail
471 // registers a class in the lua environment
472 template<class T, class X1, class X2, class X3>
473 struct class_: detail::class_base
475 typedef class_<T, X1, X2, X3> self_t;
477 private:
479 template<class A, class B, class C, class D>
480 class_(const class_<A,B,C,D>&);
482 public:
484 typedef boost::mpl::vector4<X1, X2, X3, detail::unspecified> parameters_type;
486 // WrappedType MUST inherit from T
487 typedef typename detail::extract_parameter<
488 parameters_type
489 , boost::is_base_and_derived<T, boost::mpl::_>
490 , detail::null_type
491 >::type WrappedType;
493 typedef typename detail::extract_parameter<
494 parameters_type
495 , boost::mpl::not_<
496 boost::mpl::or_<
497 detail::is_bases<boost::mpl::_>
498 , boost::is_base_and_derived<boost::mpl::_, T>
499 , boost::is_base_and_derived<T, boost::mpl::_>
502 , detail::null_type
503 >::type HeldType;
505 // this function generates conversion information
506 // in the given class_rep structure. It will be able
507 // to implicitly cast to the given template type
508 template<class To>
509 void gen_base_info(detail::type_<To>)
511 // fist, make sure the given base class is registered.
512 // if it's not registered we can't push it's lua table onto
513 // the stack because it doesn't have a table
515 // try to cast this type to the base type and remember
516 // the pointer offset. For multiple inheritance the pointer
517 // may change when casting. Since we need to be able to
518 // cast we need this pointer offset.
519 // store the information in this class' base class-vector
520 base_desc base;
521 base.type = typeid(To);
522 base.ptr_offset = detail::ptr_offset(detail::type_<T>(), detail::type_<To>());
523 add_base(base);
526 void gen_base_info(detail::type_<detail::null_type>)
529 #define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type_<B##n>());
531 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class B)>
532 void generate_baseclass_list(detail::type_<bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, B)> >)
534 BOOST_PP_REPEAT(LUABIND_MAX_BASES, LUABIND_GEN_BASE_INFO, _)
537 #undef LUABIND_GEN_BASE_INFO
539 class_(const char* name): class_base(name), scope(*this)
541 #ifndef NDEBUG
542 detail::check_link_compatibility();
543 #endif
544 init();
547 template<class F>
548 class_& def(const char* name, F f)
550 return this->virtual_def(
551 name, f, detail::null_type()
552 , detail::null_type(), boost::mpl::true_());
555 // virtual functions
556 template<class F, class DefaultOrPolicies>
557 class_& def(char const* name, F fn, DefaultOrPolicies default_or_policies)
559 return this->virtual_def(
560 name, fn, default_or_policies, detail::null_type()
561 , LUABIND_MSVC_TYPENAME detail::is_policy_cons<DefaultOrPolicies>::type());
564 template<class F, class Default, class Policies>
565 class_& def(char const* name, F fn
566 , Default default_, Policies const& policies)
568 return this->virtual_def(
569 name, fn, default_
570 , policies, boost::mpl::false_());
573 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)>
574 class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig)
576 return this->def_constructor(&sig, detail::null_type());
579 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A), class Policies>
580 class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig, const Policies& policies)
582 return this->def_constructor(&sig, policies);
585 template <class Getter>
586 class_& property(const char* name, Getter g)
588 this->add_member(
589 new detail::property_registration<T, Getter, detail::null_type>(
590 name, g, detail::null_type()));
591 return *this;
594 template <class Getter, class MaybeSetter>
595 class_& property(const char* name, Getter g, MaybeSetter s)
597 return property_impl(
598 name, g, s
599 , boost::mpl::bool_<detail::is_policy_cons<MaybeSetter>::value>()
603 template<class Getter, class Setter, class GetPolicies>
604 class_& property(const char* name, Getter g, Setter s, const GetPolicies& get_policies)
606 typedef detail::property_registration<
607 T, Getter, GetPolicies, Setter, detail::null_type
608 > registration_type;
610 this->add_member(
611 new registration_type(name, g, get_policies, s));
612 return *this;
615 template<class Getter, class Setter, class GetPolicies, class SetPolicies>
616 class_& property(
617 const char* name
618 , Getter g, Setter s
619 , GetPolicies const& get_policies
620 , SetPolicies const& set_policies)
622 typedef detail::property_registration<
623 T, Getter, GetPolicies, Setter, SetPolicies
624 > registration_type;
626 this->add_member(
627 new registration_type(name, g, get_policies, s, set_policies));
628 return *this;
631 template <class C, class D>
632 class_& def_readonly(const char* name, D C::*mem_ptr)
634 typedef detail::property_registration<T, D C::*, detail::null_type>
635 registration_type;
637 this->add_member(
638 new registration_type(name, mem_ptr, detail::null_type()));
639 return *this;
642 template <class C, class D, class Policies>
643 class_& def_readonly(const char* name, D C::*mem_ptr, Policies const& policies)
645 typedef detail::property_registration<T, D C::*, Policies>
646 registration_type;
648 this->add_member(
649 new registration_type(name, mem_ptr, policies));
650 return *this;
653 template <class C, class D>
654 class_& def_readwrite(const char* name, D C::*mem_ptr)
656 typedef detail::property_registration<
657 T, D C::*, detail::null_type, D C::*
658 > registration_type;
660 this->add_member(
661 new registration_type(
662 name, mem_ptr, detail::null_type(), mem_ptr));
663 return *this;
666 template <class C, class D, class GetPolicies>
667 class_& def_readwrite(
668 const char* name, D C::*mem_ptr, GetPolicies const& get_policies)
670 typedef detail::property_registration<
671 T, D C::*, GetPolicies, D C::*
672 > registration_type;
674 this->add_member(
675 new registration_type(
676 name, mem_ptr, get_policies, mem_ptr));
677 return *this;
680 template <class C, class D, class GetPolicies, class SetPolicies>
681 class_& def_readwrite(
682 const char* name
683 , D C::*mem_ptr
684 , GetPolicies const& get_policies
685 , SetPolicies const& set_policies
688 typedef detail::property_registration<
689 T, D C::*, GetPolicies, D C::*, SetPolicies
690 > registration_type;
692 this->add_member(
693 new registration_type(
694 name, mem_ptr, get_policies, mem_ptr, set_policies));
695 return *this;
698 template<class Derived, class Policies>
699 class_& def(detail::operator_<Derived>, Policies const& policies)
701 return this->def(
702 Derived::name()
703 , &Derived::template apply<T, Policies>::execute
704 , policies
708 template<class Derived>
709 class_& def(detail::operator_<Derived>)
711 return this->def(
712 Derived::name()
713 , &Derived::template apply<T, detail::null_type>::execute
717 detail::enum_maker<self_t> enum_(const char*)
719 return detail::enum_maker<self_t>(*this);
722 detail::static_scope<self_t> scope;
724 private:
725 void operator=(class_ const&);
727 void init()
729 typedef typename detail::extract_parameter<
730 parameters_type
731 , boost::mpl::or_<
732 detail::is_bases<boost::mpl::_>
733 , boost::is_base_and_derived<boost::mpl::_, T>
735 , no_bases
736 >::type bases_t;
738 typedef typename
739 boost::mpl::if_<detail::is_bases<bases_t>
740 , bases_t
741 , bases<bases_t>
742 >::type Base;
744 class_base::init(typeid(T));
746 generate_baseclass_list(detail::type_<Base>());
749 template<class Getter, class GetPolicies>
750 class_& property_impl(const char* name,
751 Getter g,
752 GetPolicies policies,
753 boost::mpl::bool_<true>)
755 this->add_member(
756 new detail::property_registration<T, Getter, GetPolicies>(
757 name, g, policies));
758 return *this;
761 template<class Getter, class Setter>
762 class_& property_impl(const char* name,
763 Getter g,
764 Setter s,
765 boost::mpl::bool_<false>)
767 typedef detail::property_registration<
768 T, Getter, detail::null_type, Setter, detail::null_type
769 > registration_type;
771 this->add_member(
772 new registration_type(name, g, detail::null_type(), s));
773 return *this;
776 // these handle default implementation of virtual functions
777 template<class F, class Policies>
778 class_& virtual_def(char const* name, F const& fn
779 , Policies const&, detail::null_type, boost::mpl::true_)
781 this->add_member(
782 new detail::memfun_registration<T, F, Policies>(
783 name, fn, Policies()));
784 return *this;
787 template<class F, class Default, class Policies>
788 class_& virtual_def(char const* name, F const& fn
789 , Default const& default_, Policies const&, boost::mpl::false_)
791 this->add_member(
792 new detail::memfun_registration<T, F, Policies>(
793 name, fn, Policies()));
795 this->add_default_member(
796 new detail::memfun_registration<T, Default, Policies>(
797 name, default_, Policies()));
799 return *this;
802 template<class Signature, class Policies>
803 class_& def_constructor(Signature*, Policies const&)
805 typedef typename Signature::signature signature;
807 typedef typename boost::mpl::if_<
808 boost::is_same<WrappedType, detail::null_type>
810 , WrappedType
811 >::type construct_type;
813 this->add_member(
814 new detail::constructor_registration<
815 construct_type, HeldType, signature, Policies>(
816 Policies()));
818 this->add_default_member(
819 new detail::constructor_registration<
820 construct_type, HeldType, signature, Policies>(
821 Policies()));
823 return *this;
829 #ifdef _MSC_VER
830 #pragma warning(pop)
831 #endif
833 #endif // LUABIND_CLASS_HPP_INCLUDED