fixed filesystem example
[luabind.git] / luabind / class.hpp
bloba6b0f0e6193982fc501ffeb04cef2b4bbe940b2f
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 scopes
56 classes with the same name in different scopes will have the same (fully qualified) name.
57 functions that are renamed will still have the same name in error-messages
59 finish smart pointer support
60 * make sure there are no bugs in the conversion from holder to const_holder
61 * the adopt policy should not be able to adopt pointers to held_types. This
62 must be prohibited.
63 * name_of_type must recognize holder_types and not return "custom"
65 support calling functions on lua threads (i.e. use lua_resume() instead of lua_pcall()).
67 document the new yield-policy more
69 document custom policies, custom converters
71 store the instance object for policies.
73 support the __concat metamethod. This is a bit tricky, since it cannot be
74 treated as a normal operator. It is a binary operator but we want to use the
75 __tostring implementation for both arguments.
79 #include <luabind/prefix.hpp>
80 #include <luabind/config.hpp>
82 #include <string>
83 #include <map>
84 #include <vector>
85 #include <cassert>
87 #include <boost/static_assert.hpp>
88 #include <boost/type_traits.hpp>
89 #include <boost/bind.hpp>
90 #include <boost/function.hpp>
91 #include <boost/preprocessor/repetition/enum_params.hpp>
92 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
93 #include <boost/preprocessor/repetition/repeat.hpp>
94 #include <boost/type_traits/is_same.hpp>
95 #include <boost/mpl/list.hpp>
96 #include <boost/mpl/apply.hpp>
97 #include <boost/mpl/lambda.hpp>
98 #include <boost/mpl/logical.hpp>
99 #include <boost/mpl/find_if.hpp>
100 #include <boost/mpl/apply_if.hpp>
101 #include <boost/mpl/logical.hpp>
103 #include <luabind/config.hpp>
104 #include <luabind/scope.hpp>
105 #include <luabind/detail/constructor.hpp>
106 #include <luabind/detail/call.hpp>
107 #include <luabind/detail/signature_match.hpp>
108 #include <luabind/detail/primitives.hpp>
109 #include <luabind/detail/property.hpp>
110 #include <luabind/detail/typetraits.hpp>
111 #include <luabind/detail/class_rep.hpp>
112 #include <luabind/detail/method_rep.hpp>
113 #include <luabind/detail/construct_rep.hpp>
114 #include <luabind/detail/object_rep.hpp>
115 #include <luabind/detail/operators.hpp>
116 #include <luabind/detail/calc_arity.hpp>
117 #include <luabind/detail/call_member.hpp>
118 #include <luabind/detail/enum_maker.hpp>
119 #include <luabind/detail/get_signature.hpp>
120 #include <luabind/detail/implicit_cast.hpp>
121 #include <luabind/detail/operator_id.hpp>
122 #include <luabind/detail/pointee_typeid.hpp>
123 #include <luabind/detail/link_compatibility.hpp>
125 //#include <boost/langbinding/inheritance.hpp>
127 namespace luabind
129 namespace detail
131 struct unspecified {};
134 using detail::type;
136 template<class T, class X1 = detail::unspecified, class X2 = detail::unspecified, class X3 = detail::unspecified>
137 struct class_;
139 // TODO: this function will only be invoked if the user hasn't defined a correct overload
140 // maybe we should have a static assert in here?
141 inline detail::null_type* get_const_holder(...)
143 return 0;
146 namespace detail
148 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class A)>
149 double is_bases_helper(const bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, A)>&);
151 #ifndef BOOST_MSVC
152 template<class T>
153 char is_bases_helper(const T&);
154 #else
155 char is_bases_helper(...);
156 #endif
158 template<class T>
159 struct is_bases
161 static const T& t;
163 BOOST_STATIC_CONSTANT(bool, value = sizeof(is_bases_helper(t)) == sizeof(double));
164 typedef boost::mpl::bool_<value> type;
165 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_bases,(T))
168 double is_not_unspecified_helper(const unspecified*);
169 char is_not_unspecified_helper(...);
171 template<class T>
172 struct is_not_unspecified
174 BOOST_STATIC_CONSTANT(bool, value = sizeof(is_not_unspecified_helper(static_cast<T*>(0))) == sizeof(char));
175 typedef boost::mpl::bool_<value> type;
176 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_not_unspecified,(T))
179 template<class Predicate>
180 struct get_predicate
182 typedef typename boost::mpl::and_<
183 Predicate
184 , is_not_unspecified<boost::mpl::_1>
185 > type;
188 template<class Parameters, class Predicate, class DefaultValue>
189 struct extract_parameter
191 typedef typename get_predicate<Predicate>::type pred;
192 typedef typename boost::mpl::find_if<Parameters, pred>::type iterator;
193 typedef typename boost::mpl::apply_if<boost::is_same<iterator, typename boost::mpl::end<Parameters>::type>
194 , boost::mpl::identity<DefaultValue>
195 , iterator
196 >::type type;
199 // this should know about the smart pointer type.
200 // and should really do:
201 // get_pointer(*static_cast<SmartPointer*>(obj_ptr))
202 // to extract the held pointer.
203 template<class HeldType, class T, class F, class Policies>
204 struct function_callback_non_null : Policies
206 function_callback_non_null(F f_): f(f_) {}
207 inline int operator()(lua_State* L, void* obj_ptr)
209 // HeldType& held_obj = *static_cast<HeldType*>(obj_ptr);
210 // T* ptr = static_cast<T*>(luabind::get_pointer(held_obj));
211 // is this correct?
212 T* ptr = static_cast<T*>(obj_ptr);
214 return call(f, ptr, L, static_cast<Policies*>(this));
216 F f;
219 template<class T, class F, class Policies>
220 struct function_callback_null_type : Policies
222 function_callback_null_type(F f_): f(f_) {}
223 inline int operator()(lua_State* L, void* obj_ptr)
225 // std::cout << "HeldType: null_type\n";
226 T* ptr = static_cast<T*>(obj_ptr);
227 return call(f, ptr, L, static_cast<Policies*>(this));
229 F f;
232 template<class HeldType, class T, class F, class Policies>
233 struct function_callback_s
235 typedef typename
236 boost::mpl::if_<boost::is_same<HeldType,detail::null_type>
237 , function_callback_null_type<T,F,Policies>
238 , function_callback_non_null<HeldType,T,F,Policies>
239 >::type type;
242 template<class T, class F, class Policies>
243 struct match_function_callback_s
245 static inline int apply(lua_State* L)
247 object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, 1));
248 F fptr = 0;
249 return match(fptr, L, obj->flags() & object_rep::constant, static_cast<Policies*>(0));
253 // prints the types of the values on the stack, in the
254 // range [start_index, lua_gettop()]
256 LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index);
258 struct LUABIND_API create_class
260 static int stage1(lua_State* L);
261 static int stage2(lua_State* L);
264 template<class Type>
265 struct register_wrapped_type
267 template<class Signature, class Policies>
268 static void apply(detail::construct_rep::overload_t& o, const Signature*, const Policies*)
270 o.set_wrapped_constructor(
271 &detail::construct_wrapped_class<Type, Policies, Signature>::apply
276 template<>
277 struct register_wrapped_type<detail::null_type>
279 template<class Signature, class Policies>
280 static void apply(detail::construct_rep::overload_t&, const Signature*, const Policies*) {}
284 // if the class is held by a smart pointer, we need to be able to
285 // implicitly dereference the pointer when needed.
287 template<class UnderlyingT, class HeldT>
288 struct extract_underlying_type
290 static void* extract(void* ptr)
292 HeldT& held_obj = *reinterpret_cast<HeldT*>(ptr);
293 UnderlyingT* underlying_ptr = static_cast<UnderlyingT*>(get_pointer(held_obj));
294 return underlying_ptr;
298 template<class UnderlyingT, class HeldT>
299 struct extract_underlying_const_type
301 static const void* extract(void* ptr)
303 HeldT& held_obj = *reinterpret_cast<HeldT*>(ptr);
304 const UnderlyingT* underlying_ptr = static_cast<const UnderlyingT*>(get_pointer(held_obj));
305 return underlying_ptr;
309 template<class HeldType>
310 struct internal_holder_extractor
312 typedef void*(*extractor_fun)(void*);
314 template<class T>
315 static extractor_fun apply(detail::type<T>)
317 return &detail::extract_underlying_type<T, HeldType>::extract;
321 template<>
322 struct internal_holder_extractor<detail::null_type>
324 typedef void*(*extractor_fun)(void*);
326 template<class T>
327 static extractor_fun apply(detail::type<T>)
329 return 0;
334 template<class HeldType, class ConstHolderType>
335 struct convert_holder
337 static void apply(void* holder, void* target)
339 new(target) ConstHolderType(*reinterpret_cast<HeldType*>(holder));
344 template<class HeldType>
345 struct const_converter
347 typedef void(*converter_fun)(void*, void*);
349 template<class ConstHolderType>
350 static converter_fun apply(ConstHolderType*)
352 return &detail::convert_holder<HeldType, ConstHolderType>::apply;
356 template<>
357 struct const_converter<detail::null_type>
359 typedef void(*converter_fun)(void*, void*);
361 template<class T>
362 static converter_fun apply(T*)
364 return 0;
371 template<class HeldType>
372 struct internal_const_holder_extractor
374 typedef const void*(*extractor_fun)(void*);
376 template<class T>
377 static extractor_fun apply(detail::type<T>)
379 return get_extractor(detail::type<T>(), luabind::get_const_holder(static_cast<HeldType*>(0)));
381 private:
382 template<class T, class ConstHolderType>
383 static extractor_fun get_extractor(detail::type<T>, ConstHolderType*)
385 return &detail::extract_underlying_const_type<T, ConstHolderType>::extract;
389 template<>
390 struct internal_const_holder_extractor<detail::null_type>
392 typedef const void*(*extractor_fun)(void*);
394 template<class T>
395 static extractor_fun apply(detail::type<T>)
397 return 0;
403 // this is simply a selector that returns the type_info
404 // of the held type, or invalid_type_info if we don't have
405 // a held_type
406 template<class HeldType>
407 struct internal_holder_type
409 static LUABIND_TYPE_INFO apply()
411 return LUABIND_TYPEID(HeldType);
415 template<>
416 struct internal_holder_type<detail::null_type>
418 static LUABIND_TYPE_INFO apply()
420 return LUABIND_INVALID_TYPE_INFO;
425 // this is the actual held_type constructor
426 template<class HeldType, class T>
427 struct internal_construct_holder
429 static void apply(void* target, void* raw_pointer)
431 new(target) HeldType(static_cast<T*>(raw_pointer));
435 // this is the actual held_type default constructor
436 template<class HeldType, class T>
437 struct internal_default_construct_holder
439 static void apply(void* target)
441 new(target) HeldType();
445 // the following two functions are the ones that returns
446 // a pointer to a held_type_constructor, or 0 if there
447 // is no held_type
448 template<class HeldType>
449 struct holder_constructor
451 typedef void(*constructor)(void*,void*);
452 template<class T>
453 static constructor apply(detail::type<T>)
455 return &internal_construct_holder<HeldType, T>::apply;
459 template<>
460 struct holder_constructor<detail::null_type>
462 typedef void(*constructor)(void*,void*);
463 template<class T>
464 static constructor apply(detail::type<T>)
466 return 0;
470 // the following two functions are the ones that returns
471 // a pointer to a const_held_type_constructor, or 0 if there
472 // is no held_type
473 template<class HolderType>
474 struct const_holder_constructor
476 typedef void(*constructor)(void*,void*);
477 template<class T>
478 static constructor apply(detail::type<T>)
480 return get_const_holder_constructor(detail::type<T>(), luabind::get_const_holder(static_cast<HolderType*>(0)));
483 private:
485 template<class T, class ConstHolderType>
486 static constructor get_const_holder_constructor(detail::type<T>, ConstHolderType*)
488 return &internal_construct_holder<ConstHolderType, T>::apply;
492 template<>
493 struct const_holder_constructor<detail::null_type>
495 typedef void(*constructor)(void*,void*);
496 template<class T>
497 static constructor apply(detail::type<T>)
499 return 0;
504 // the following two functions are the ones that returns
505 // a pointer to a held_type_constructor, or 0 if there
506 // is no held_type. The holder_type is default constructed
507 template<class HeldType>
508 struct holder_default_constructor
510 typedef void(*constructor)(void*);
511 template<class T>
512 static constructor apply(detail::type<T>)
514 return &internal_default_construct_holder<HeldType, T>::apply;
518 template<>
519 struct holder_default_constructor<detail::null_type>
521 typedef void(*constructor)(void*);
522 template<class T>
523 static constructor apply(detail::type<T>)
525 return 0;
530 // the following two functions are the ones that returns
531 // a pointer to a const_held_type_constructor, or 0 if there
532 // is no held_type. The constructed held_type is default
533 // constructed
534 template<class HolderType>
535 struct const_holder_default_constructor
537 typedef void(*constructor)(void*);
538 template<class T>
539 static constructor apply(detail::type<T>)
541 return get_const_holder_default_constructor(detail::type<T>(), luabind::get_const_holder(static_cast<HolderType*>(0)));
544 private:
546 template<class T, class ConstHolderType>
547 static constructor get_const_holder_default_constructor(detail::type<T>, ConstHolderType*)
549 return &internal_default_construct_holder<ConstHolderType, T>::apply;
553 template<>
554 struct const_holder_default_constructor<detail::null_type>
556 typedef void(*constructor)(void*);
557 template<class T>
558 static constructor apply(detail::type<T>)
560 return 0;
567 // this is a selector that returns the size of the held_type
568 // or 0 if we don't have a held_type
569 template <class HolderType>
570 struct internal_holder_size
572 static int apply() { return get_internal_holder_size(luabind::get_const_holder(static_cast<HolderType*>(0))); }
573 private:
574 template<class ConstHolderType>
575 static int get_internal_holder_size(ConstHolderType*)
577 return max_c<sizeof(HolderType), sizeof(ConstHolderType)>::value;
581 template <>
582 struct internal_holder_size<detail::null_type>
584 static int apply() { return 0; }
588 // if we have a held type, return the destructor to it
589 // note the difference. The held_type should only be destructed (not deleted)
590 // since it's constructed in the lua userdata
591 template<class HeldType>
592 struct internal_holder_destructor
594 typedef void(*destructor_t)(void*);
595 template<class T>
596 static destructor_t apply(detail::type<T>)
598 return &detail::destruct_only_s<HeldType>::apply;
602 // if we don't have a held type, return the destructor of the raw type
603 template<>
604 struct internal_holder_destructor<detail::null_type>
606 typedef void(*destructor_t)(void*);
607 template<class T>
608 static destructor_t apply(detail::type<T>)
610 return &detail::delete_s<T>::apply;
615 // if we have a held type, return the destructor to it's const version
616 template<class HolderType>
617 struct internal_const_holder_destructor
619 typedef void(*destructor_t)(void*);
620 template<class T>
621 static destructor_t apply(detail::type<T>)
623 return const_holder_type_destructor(luabind::get_const_holder(static_cast<HolderType*>(0)));
626 private:
628 template<class ConstHolderType>
629 static destructor_t const_holder_type_destructor(ConstHolderType*)
631 return &detail::destruct_only_s<ConstHolderType>::apply;
636 // if we don't have a held type, return the destructor of the raw type
637 template<>
638 struct internal_const_holder_destructor<detail::null_type>
640 typedef void(*destructor_t)(void*);
641 template<class T>
642 static destructor_t apply(detail::type<T>)
644 return 0;
651 template<class HolderType>
652 struct get_holder_alignment
654 static int apply()
656 return internal_alignment(luabind::get_const_holder(static_cast<HolderType*>(0)));
659 private:
661 template<class ConstHolderType>
662 static int internal_alignment(ConstHolderType*)
664 return detail::max_c<boost::alignment_of<HolderType>::value
665 , boost::alignment_of<ConstHolderType>::value>::value;
669 template<>
670 struct get_holder_alignment<detail::null_type>
672 static int apply()
674 return 1;
679 } // detail
681 namespace detail {
683 template<class T>
684 struct static_scope
686 static_scope(T& self_) : self(self_)
690 T& operator[](scope s) const
692 self.add_inner_scope(s);
693 return self;
696 private:
697 template<class U> void operator,(U const&) const;
699 T& self;
702 struct class_registration;
704 struct LUABIND_API class_base : scope
706 public:
707 class_base(char const* name);
709 struct base_desc
711 LUABIND_TYPE_INFO type;
712 int ptr_offset;
715 void init(
716 LUABIND_TYPE_INFO type
717 , LUABIND_TYPE_INFO holder_type
718 , LUABIND_TYPE_INFO const_holder_type
719 , void*(*extractor)(void*)
720 , const void*(*const_extractor)(void*)
721 , void(*const_converter)(void*,void*)
722 , void(*holder_constructor)(void*,void*)
723 , void(*const_holder_constructor)(void*,void*)
724 , void(*holder_default_constructor)(void*)
725 , void(*const_holder_default_constructor)(void*)
726 , void(*destructor)(void*)
727 , void(*const_holder_destructor)(void*)
728 , int holder_size
729 , int holder_alignment);
731 void add_getter(
732 const char* name
733 , const boost::function2<int, lua_State*, int>& g);
735 #ifdef LUABIND_NO_ERROR_CHECKING
736 void class_base::add_setter(
737 const char* name
738 , const boost::function2<int, lua_State*, int>& s);
739 #else
740 void class_base::add_setter(
741 const char* name
742 , const boost::function2<int, lua_State*, int>& s
743 , int (*match)(lua_State*, int)
744 , void (*get_sig_ptr)(lua_State*, std::string&));
745 #endif
747 void add_base(const base_desc& b);
748 void add_constructor(const detail::construct_rep::overload_t& o);
749 void add_method(const char* name, const detail::overload_rep& o);
751 #ifndef LUABIND_NO_ERROR_CHECKING
752 void add_operator(
753 int op_id
754 , int(*func)(lua_State*)
755 , int(*matcher)(lua_State*)
756 , void(*sig)(lua_State*
757 , std::string&)
758 , int arity);
759 #else
760 void add_operator(
761 int op_id
762 , int(*func)(lua_State*)
763 , int(*matcher)(lua_State*)
764 , int arity);
765 #endif
767 const char* name() const;
769 void add_static_constant(const char* name, int val);
770 void add_inner_scope(scope& s);
772 private:
773 class_registration* m_registration;
776 } // namespace detail
778 // registers a class in the lua environment
779 template<class T, class X1, class X2, class X3>
780 struct class_: detail::class_base
782 typedef class_<T, X1, X2, X3> self_t;
784 private:
786 template<class A, class B, class C, class D>
787 class_(const class_<A,B,C,D>&);
789 public:
791 // WrappedType MUST inherit from T
792 typedef typename detail::extract_parameter<
793 boost::mpl::vector3<X1,X2,X3>
794 , boost::is_base_and_derived<T, boost::mpl::_>
795 /* , boost::mpl::not_<
796 boost::mpl::or_<
797 detail::is_bases<boost::mpl::_>
798 , boost::is_base_and_derived<boost::mpl::_, T>
801 , detail::null_type
802 >::type WrappedType;
804 typedef typename detail::extract_parameter<
805 boost::mpl::list3<X1,X2,X3>
806 , boost::mpl::not_<
807 boost::mpl::or_<
808 boost::mpl::or_<
809 detail::is_bases<boost::mpl::_>
810 , boost::is_base_and_derived<boost::mpl::_, T>
812 , boost::is_base_and_derived<T, boost::mpl::_>
815 , detail::null_type
816 >::type HeldType;
818 template<class To>
819 void register_downcast(boost::mpl::true_, detail::type<To>* = 0)
820 { boost::langbinding::register_conversion<To, T>(true); }
822 template<class To>
823 void register_downcast(boost::mpl::false_, detail::type<To>* = 0)
826 // this function generates conversion information
827 // in the given class_rep structure. It will be able
828 // to implicitly cast to the given template type
829 template<class To>
830 void gen_base_info(detail::type<To>)
832 // boost::langbinding::register_dynamic_id<To>();
833 // boost::langbinding::register_conversion<T, To>(false);
835 // register_downcast<To>(boost::mpl::bool_<boost::is_polymorphic<To>::value>());
837 // fist, make sure the given base class is registered.
838 // if it's not registered we can't push it's lua table onto
839 // the stack because it doesn't have a table
841 // try to cast this type to the base type and remember
842 // the pointer offset. For multiple inheritance the pointer
843 // may change when casting. Since we need to be able to
844 // cast we need this pointer offset.
845 // store the information in this class' base class-vector
846 base_desc base;
847 base.type = LUABIND_TYPEID(To);
848 base.ptr_offset = detail::ptr_offset(detail::type<T>(), detail::type<To>());
849 add_base(base);
852 void gen_base_info(detail::type<detail::null_type>)
855 #define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type<B##n>());
857 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class B)>
858 void generate_baseclass_list(detail::type<bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, B)> >)
860 BOOST_PP_REPEAT(LUABIND_MAX_BASES, LUABIND_GEN_BASE_INFO, _)
863 #undef LUABIND_GEN_BASE_INFO
865 // this is the internal version of def() it is run from both overloads
866 // of def. It has two versions, one where a contstructor is registered
867 // and one where a function is registered
868 template<class Policies>
869 struct internal_def_s
871 template<class F>
872 static void apply(const char* name, F f, detail::class_base* c)
874 // std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";
876 detail::overload_rep o(f, static_cast<Policies*>(0));
878 typedef LUABIND_MSVC_TYPENAME detail::function_callback_s<HeldType,T,F,Policies>::type call_t;
880 o.set_match_fun(&detail::match_function_callback_s<T,F,Policies>::apply);
881 o.call_fun = boost::bind<int>(call_t(f), _1, _2);
883 #ifndef LUABIND_NO_ERROR_CHECKING
885 o.set_sig_fun(&detail::get_member_signature<F>::apply);
887 #endif
889 c->add_method(name, o);
892 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)>
893 static void apply(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>, detail::class_base* c)
895 // std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";
897 detail::construct_rep::overload_t o;
899 o.set_constructor(
900 &detail::construct_class<
902 ,Policies
903 ,constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>
904 >::apply
907 // if we have a WrappedType, we have to register it's constructor
908 // but if it's null_type (no WrappedType) we should not register it
909 detail::register_wrapped_type<WrappedType>::apply(o,
910 static_cast<const constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>*>(0),
911 static_cast<const Policies*>(0));
914 o.set_match_fun(
915 &detail::constructor_match<
916 constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>
918 ,Policies
919 >::apply);
921 #ifndef LUABIND_NO_ERROR_CHECKING
923 o.set_sig_fun(&detail::get_signature<constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> >::apply);
925 #endif
927 typedef constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> con_t;
929 o.set_arity(detail::calc_arity<con_t::arity>::apply(con_t(), static_cast<Policies*>(0)));
931 c->add_constructor(o);
935 class_(const char* name): class_base(name), static_(*this)
937 #ifndef NDEBUG
938 detail::check_link_compatibility();
939 #endif
940 init();
943 template<class F>
944 class_& def(const char* name, F f)
946 internal_def_s<detail::null_type>::apply(name, f, this);
947 return *this;
950 template<class F, class Policies>
951 class_& def(const char* name, F f, const Policies&)
953 internal_def_s<Policies>::apply(name, f, this);
954 return *this;
957 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)>
958 class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig)
960 internal_def_s<detail::null_type>::apply(sig, this);
961 return *this;
964 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A), class Policies>
965 class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig, const Policies& policies)
967 internal_def_s<Policies>::apply(sig, this);
968 return *this;
971 template<class Getter>
972 class_& property(const char* name, Getter g)
974 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, detail::null_type>(), _1, _2, g));
975 return *this;
978 template<class Getter, class MaybeSetter>
979 class_& property(const char* name, Getter g, MaybeSetter s)
981 return property_impl(name, g, s, boost::mpl::bool_<detail::is_policy_cons<MaybeSetter>::value>());
984 template<class Getter, class Setter, class GetPolicies>
985 class_& property(const char* name, Getter g, Setter s, const GetPolicies& get_policies)
987 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, GetPolicies>(get_policies), _1, _2, g));
988 #ifndef LUABIND_NO_ERROR_CHECKING
989 add_setter(
990 name
991 , boost::bind<int>(detail::set_caller<T, Setter, detail::null_type>(), _1, _2, s)
992 , detail::gen_set_matcher((Setter)0, (detail::null_type*)0)
993 , &detail::get_member_signature<Setter>::apply);
994 #else
995 add_setter(
996 name
997 , boost::bind<int>(detail::set_caller<T, Setter, detail::null_type>(), _1, _2, s));
998 #endif
999 return *this;
1002 template<class Getter, class Setter, class GetPolicies, class SetPolicies>
1003 class_& property(const char* name
1004 , Getter g, Setter s
1005 , const GetPolicies& get_policies
1006 , const SetPolicies& set_policies)
1008 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, GetPolicies>(get_policies), _1, _2, g));
1009 #ifndef LUABIND_NO_ERROR_CHECKING
1010 add_setter(
1011 name
1012 , boost::bind<int>(detail::set_caller<T, Setter, SetPolicies>(), _1, _2, s)
1013 , detail::gen_set_matcher((Setter)0, (SetPolicies*)0)
1014 , &detail::get_member_signature<Setter>::apply);
1015 #else
1016 add_setter(name, boost::bind<int>(detail::set_caller<T, Setter, SetPolicies>(set_policies), _1, _2, s));
1017 #endif
1018 return *this;
1021 template<class D>
1022 class_& def_readonly(const char* name, D T::*member_ptr)
1024 add_getter(name, boost::bind<int>(detail::auto_get<T,D,detail::null_type>(), _1, _2, member_ptr));
1025 return *this;
1028 template<class D, class Policies>
1029 class_& def_readonly(const char* name, D T::*member_ptr, const Policies& policies)
1031 add_getter(name, boost::bind<int>(detail::auto_get<T,D,Policies>(policies), _1, _2, member_ptr));
1032 return *this;
1035 template<class D>
1036 class_& def_readwrite(const char* name, D T::*member_ptr)
1038 add_getter(name, boost::bind<int>(detail::auto_get<T,D,detail::null_type>(), _1, _2, member_ptr));
1039 #ifndef LUABIND_NO_ERROR_CHECKING
1040 add_setter(
1041 name
1042 , boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr)
1043 , &detail::set_matcher<D, detail::null_type>::apply
1044 , &detail::get_setter_signature<D>::apply);
1045 #else
1046 add_setter(name, boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr));
1047 #endif
1048 return *this;
1051 template<class D, class GetPolicies>
1052 class_& def_readwrite(const char* name, D T::*member_ptr, const GetPolicies& get_policies)
1054 add_getter(name, boost::bind<int>(detail::auto_get<T,D,GetPolicies>(get_policies), _1, _2, member_ptr));
1055 #ifndef LUABIND_NO_ERROR_CHECKING
1056 add_setter(
1057 name
1058 , boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr)
1059 , &detail::set_matcher<D, detail::null_type>::apply
1060 , &detail::get_setter_signature<D>::apply);
1061 #else
1062 add_setter(name, boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr));
1063 #endif
1064 return *this;
1067 template<class D, class GetPolicies, class SetPolicies>
1068 class_& def_readwrite(const char* name, D T::*member_ptr, const GetPolicies& get_policies, const SetPolicies& set_policies)
1070 add_getter(name, boost::bind<int>(detail::auto_get<T,D,GetPolicies>(get_policies), _1, _2, member_ptr));
1071 #ifndef LUABIND_NO_ERROR_CHECKING
1072 add_setter(
1073 name
1074 , boost::bind<int>(detail::auto_set<T,D,SetPolicies>(), _1, _2, member_ptr)
1075 , &detail::set_matcher<D, SetPolicies>::apply
1076 , &detail::get_setter_signature<D>::apply);
1077 #else
1078 add_setter(name, boost::bind<int>(detail::auto_set<T,D,SetPolicies>(set_policies), _1, _2, member_ptr));
1079 #endif
1080 return *this;
1083 template<class op_id, class Left, class Right, class Policies>
1084 class_& def(detail::operator_<op_id, Left, Right>, const Policies& policies)
1086 typedef typename detail::operator_unwrapper<Policies, op_id, T, Left, Right> op_type;
1087 #ifndef LUABIND_NO_ERROR_CHECKING
1088 add_operator(op_type::get_id()
1089 , &op_type::execute
1090 , &op_type::match
1091 , &detail::get_signature<constructor<typename op_type::left_t, typename op_type::right_t> >::apply
1092 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1093 #else
1094 add_operator(op_type::get_id()
1095 , &op_type::execute
1096 , &op_type::match
1097 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1098 #endif
1099 return *this;
1102 template<class op_id, class Left, class Right>
1103 class_& def(detail::operator_<op_id, Left, Right>)
1105 typedef typename detail::operator_unwrapper<detail::null_type, op_id, T, Left, Right> op_type;
1107 #ifndef LUABIND_NO_ERROR_CHECKING
1108 add_operator(op_type::get_id()
1109 , &op_type::execute
1110 , &op_type::match
1111 , &detail::get_signature<constructor<LUABIND_MSVC_TYPENAME op_type::left_t, LUABIND_MSVC_TYPENAME op_type::right_t> >::apply
1112 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1113 #else
1114 add_operator(op_type::get_id()
1115 , &op_type::execute
1116 , &op_type::match
1117 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1118 #endif
1119 return *this;
1122 template<class Signature, bool Constant>
1123 class_& def(detail::application_operator<Signature, Constant>*)
1125 typedef detail::application_operator<Signature, Constant, detail::null_type> op_t;
1127 int arity = detail::calc_arity<Signature::arity>::apply(Signature(), static_cast<detail::null_type*>(0));
1129 #ifndef LUABIND_NO_ERROR_CHECKING
1130 add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, &detail::get_signature<Signature>::apply, arity + 1);
1131 #else
1132 add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, arity + 1);
1133 #endif
1135 return *this;
1138 template<class Signature, bool Constant, class Policies>
1139 class_& def(detail::application_operator<Signature, Constant>*, const Policies& policies)
1141 typedef detail::application_operator<Signature, Constant, Policies> op_t;
1143 int arity = detail::calc_arity<Signature::arity>::apply(Signature(), static_cast<Policies*>(0));
1145 #ifndef LUABIND_NO_ERROR_CHECKING
1146 add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, &detail::get_signature<Signature>::apply, arity + 1);
1147 #else
1148 add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, arity + 1);
1149 #endif
1151 return *this;
1154 detail::enum_maker<self_t> enum_(const char*)
1156 return detail::enum_maker<self_t>(*this);
1159 detail::static_scope<self_t> scope;
1161 private:
1163 void init()
1165 typedef typename detail::extract_parameter<
1166 boost::mpl::list3<X1,X2,X3>
1167 , boost::mpl::or_<
1168 detail::is_bases<boost::mpl::_>
1169 , boost::is_base_and_derived<boost::mpl::_, T>
1171 , no_bases
1172 >::type bases_t;
1174 typedef typename
1175 boost::mpl::if_<detail::is_bases<bases_t>
1176 , bases_t
1177 , bases<bases_t>
1178 >::type Base;
1180 class_base::init(LUABIND_TYPEID(T)
1181 , detail::internal_holder_type<HeldType>::apply()
1182 , detail::pointee_typeid(
1183 get_const_holder(static_cast<HeldType*>(0)))
1184 , detail::internal_holder_extractor<HeldType>::apply(detail::type<T>())
1185 , detail::internal_const_holder_extractor<HeldType>::apply(detail::type<T>())
1186 , detail::const_converter<HeldType>::apply(
1187 luabind::get_const_holder((HeldType*)0))
1188 , detail::holder_constructor<HeldType>::apply(detail::type<T>())
1189 , detail::const_holder_constructor<HeldType>::apply(detail::type<T>())
1190 , detail::holder_default_constructor<HeldType>::apply(detail::type<T>())
1191 , detail::const_holder_default_constructor<HeldType>::apply(detail::type<T>())
1192 , detail::internal_holder_destructor<HeldType>::apply(detail::type<T>())
1193 , detail::internal_const_holder_destructor<HeldType>::apply(detail::type<T>())
1194 , detail::internal_holder_size<HeldType>::apply()
1195 , detail::get_holder_alignment<HeldType>::apply());
1197 generate_baseclass_list(detail::type<Base>());
1200 template<class Getter, class GetPolicies>
1201 class_& property_impl(const char* name,
1202 Getter g,
1203 GetPolicies policies,
1204 boost::mpl::bool_<true>)
1206 add_getter(name, boost::bind<int>(detail::get_caller<T,Getter,GetPolicies>(policies), _1, _2, g));
1207 return *this;
1210 template<class Getter, class Setter>
1211 class_& property_impl(const char* name,
1212 Getter g,
1213 Setter s,
1214 boost::mpl::bool_<false>)
1216 add_getter(name, boost::bind<int>(detail::get_caller<T,Getter,detail::null_type>(), _1, _2, g));
1217 #ifndef LUABIND_NO_ERROR_CHECKING
1218 add_setter(
1219 name
1220 , boost::bind<int>(detail::set_caller<T, Setter, detail::null_type>(), _1, _2, s)
1221 , detail::gen_set_matcher((Setter)0, (detail::null_type*)0)
1222 , &detail::get_member_signature<Setter>::apply);
1223 #else
1224 add_setter(name, boost::bind<int>(detail::set_caller<T,Setter,detail::null_type>(), _1, _2, s));
1225 #endif
1226 return *this;
1232 #endif // LUABIND_CLASS_HPP_INCLUDED