1 // Copyright (c) 2003 Daniel Wallin and Arvid Norberg
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the "Software"),
5 // to deal in the Software without restriction, including without limitation
6 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 // and/or sell copies of the Software, and to permit persons to whom the
8 // Software is furnished to do so, subject to the following conditions:
10 // The above copyright notice and this permission notice shall be included
11 // in all copies or substantial portions of the Software.
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
14 // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
15 // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
16 // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
17 // SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
18 // ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
21 // OR OTHER DEALINGS IN THE SOFTWARE.
24 #ifndef LUABIND_CLASS_HPP_INCLUDED
25 #define LUABIND_CLASS_HPP_INCLUDED
29 ------------------------------------------------------
31 * solved for member functions, not application operator *
32 if we have a base class that defines a function a derived class must be able to
33 override that function (not just overload). Right now we just add the other overload
34 to the overloads list and will probably get an ambiguity. If we want to support this
35 each method_rep must include a vector of type_info pointers for each parameter.
36 Operators do not have this problem, since operators always have to have
37 it's own type as one of the arguments, no ambiguity can occur. Application
38 operator, on the other hand, would have this problem.
39 Properties cannot be overloaded, so they should always be overridden.
40 If this is to work for application operator, we really need to specify if an application
41 operator is const or not.
43 If one class registers two functions with the same name and the same
44 signature, there's currently no error. The last registered function will
45 be the one that's used.
46 How do we know which class registered the function? If the function was
47 defined by the base class, it is a legal operation, to override it.
48 we cannot look at the pointer offset, since it always will be zero for one of the bases.
53 ------------------------------------------------------
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
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 cache finalizers in the class_rep. For lua classes
70 we currently do a lookup each time we need to know if a lua class
73 static functions, this could be implemented by letting classes contain
74 other declarations (classes or functions)
76 document custom policies, custom converters
78 store the instance object for policies.
80 support the __concat metamethod. This is a bit tricky, since it cannot be
81 treated as a normal operator. It is a binary operator but we want to use the
82 __tostring implementation for both arguments.
86 #include <luabind/config.hpp>
93 #include <boost/static_assert.hpp>
94 #include <boost/type_traits.hpp>
95 #include <boost/bind.hpp>
96 #include <boost/function.hpp>
97 #include <boost/preprocessor/repetition/enum_params.hpp>
98 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
99 #include <boost/preprocessor/repetition/repeat.hpp>
100 #include <boost/type_traits/is_same.hpp>
101 #include <boost/mpl/list.hpp>
102 #include <boost/mpl/apply.hpp>
103 #include <boost/mpl/lambda.hpp>
104 #include <boost/mpl/logical.hpp>
105 #include <boost/mpl/find_if.hpp>
106 #include <boost/mpl/apply_if.hpp>
107 #include <boost/mpl/logical.hpp>
109 #include <luabind/config.hpp>
110 #include <luabind/scope.hpp>
111 #include <luabind/detail/constructor.hpp>
112 #include <luabind/detail/call.hpp>
113 #include <luabind/detail/signature_match.hpp>
114 #include <luabind/detail/primitives.hpp>
115 #include <luabind/detail/property.hpp>
116 #include <luabind/detail/typetraits.hpp>
117 #include <luabind/detail/class_rep.hpp>
118 #include <luabind/detail/method_rep.hpp>
119 #include <luabind/detail/construct_rep.hpp>
120 #include <luabind/detail/object_rep.hpp>
121 #include <luabind/detail/operators.hpp>
122 #include <luabind/detail/calc_arity.hpp>
123 #include <luabind/detail/call_member.hpp>
124 #include <luabind/detail/enum_maker.hpp>
125 #include <luabind/detail/get_signature.hpp>
126 #include <luabind/detail/implicit_cast.hpp>
127 #include <luabind/detail/operator_id.hpp>
128 #include <luabind/detail/pointee_typeid.hpp>
130 //#include <boost/langbinding/inheritance.hpp>
136 struct unspecified
{};
141 template<class T
, class X1
= detail::unspecified
, class X2
= detail::unspecified
, class X3
= detail::unspecified
>
144 // TODO: this function will only be invoked if the user hasn't defined a correct overload
145 // maybe we should have a static assert in here?
146 inline detail::null_type
* get_const_holder(...)
153 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES
, class A
)>
154 double is_bases_helper(const bases
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES
, A
)>&);
158 char is_bases_helper(const T
&);
160 char is_bases_helper(...);
168 BOOST_STATIC_CONSTANT(bool, value
= sizeof(is_bases_helper(t
)) == sizeof(double));
169 typedef boost::mpl::bool_
<value
> type
;
170 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_bases
,(T
))
173 double is_not_unspecified_helper(const unspecified
*);
174 char is_not_unspecified_helper(...);
177 struct is_not_unspecified
179 BOOST_STATIC_CONSTANT(bool, value
= sizeof(is_not_unspecified_helper(static_cast<T
*>(0))) == sizeof(char));
180 typedef boost::mpl::bool_
<value
> type
;
181 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_not_unspecified
,(T
))
184 template<class Predicate
>
187 typedef typename
boost::mpl::and_
<
189 , is_not_unspecified
<boost::mpl::_1
>
193 template<class Parameters
, class Predicate
, class DefaultValue
>
194 struct extract_parameter
196 typedef typename get_predicate
<Predicate
>::type pred
;
197 typedef typename
boost::mpl::find_if
<Parameters
, pred
>::type iterator
;
198 typedef typename
boost::mpl::apply_if
<boost::is_same
<iterator
, typename
boost::mpl::end
<Parameters
>::type
>
199 , boost::mpl::identity
<DefaultValue
>
204 // TODO: is this detail::class_rep::function_dispatcher or detail::free_functions::function_dispatcher?
205 // LUABIND_API int function_dispatcher(lua_State* L);
207 // this should know about the smart pointer type.
208 // and should really do:
209 // get_pointer(*static_cast<SmartPointer*>(obj_ptr))
210 // to extract the held pointer.
211 template<class HeldType
, class T
, class F
, class Policies
>
212 struct function_callback_non_null
: Policies
214 function_callback_non_null(F f_
): f(f_
) {}
215 inline int operator()(lua_State
* L
, void* obj_ptr
)
217 // HeldType& held_obj = *static_cast<HeldType*>(obj_ptr);
218 // T* ptr = static_cast<T*>(luabind::get_pointer(held_obj));
220 T
* ptr
= static_cast<T
*>(obj_ptr
);
222 return call(f
, ptr
, L
, static_cast<Policies
*>(this));
227 template<class T
, class F
, class Policies
>
228 struct function_callback_null_type
: Policies
230 function_callback_null_type(F f_
): f(f_
) {}
231 inline int operator()(lua_State
* L
, void* obj_ptr
)
233 // std::cout << "HeldType: null_type\n";
234 T
* ptr
= static_cast<T
*>(obj_ptr
);
235 return call(f
, ptr
, L
, static_cast<Policies
*>(this));
240 template<class HeldType
, class T
, class F
, class Policies
>
241 struct function_callback_s
244 boost::mpl::if_
<boost::is_same
<HeldType
,detail::null_type
>
245 , function_callback_null_type
<T
,F
,Policies
>
246 , function_callback_non_null
<HeldType
,T
,F
,Policies
>
250 template<class T
, class F
, class Policies
>
251 struct match_function_callback_s
253 static inline int apply(lua_State
* L
)
255 object_rep
* obj
= static_cast<object_rep
*>(lua_touserdata(L
, 1));
257 return match(fptr
, L
, obj
->flags() & object_rep::constant
, static_cast<Policies
*>(0));
261 // prints the types of the values on the stack, in the
262 // range [start_index, lua_gettop()]
264 LUABIND_API
std::string
stack_content_by_name(lua_State
* L
, int start_index
);
266 struct LUABIND_API create_class
268 static int stage1(lua_State
* L
);
269 static int stage2(lua_State
* L
);
273 struct register_wrapped_type
275 template<class Signature
, class Policies
>
276 static void apply(detail::construct_rep::overload_t
& o
, const Signature
*, const Policies
*)
278 o
.set_wrapped_constructor(
279 &detail::construct_wrapped_class
<Type
, Policies
, Signature
>::apply
285 struct register_wrapped_type
<detail::null_type
>
287 template<class Signature
, class Policies
>
288 static void apply(detail::construct_rep::overload_t
&, const Signature
*, const Policies
*) {}
292 // if the class is held by a smart pointer, we need to be able to
293 // implicitly dereference the pointer when needed.
295 template<class UnderlyingT
, class HeldT
>
296 struct extract_underlying_type
298 static void* extract(void* ptr
)
300 HeldT
& held_obj
= *reinterpret_cast<HeldT
*>(ptr
);
301 UnderlyingT
* underlying_ptr
= static_cast<UnderlyingT
*>(get_pointer(held_obj
));
302 return underlying_ptr
;
306 template<class UnderlyingT
, class HeldT
>
307 struct extract_underlying_const_type
309 static const void* extract(void* ptr
)
311 HeldT
& held_obj
= *reinterpret_cast<HeldT
*>(ptr
);
312 const UnderlyingT
* underlying_ptr
= static_cast<const UnderlyingT
*>(get_pointer(held_obj
));
313 return underlying_ptr
;
317 template<class HeldType
>
318 struct internal_holder_extractor
320 typedef void*(*extractor_fun
)(void*);
323 static extractor_fun
apply(detail::type
<T
>)
325 return &detail::extract_underlying_type
<T
, HeldType
>::extract
;
330 struct internal_holder_extractor
<detail::null_type
>
332 typedef void*(*extractor_fun
)(void*);
335 static extractor_fun
apply(detail::type
<T
>)
342 template<class HeldType
, class ConstHolderType
>
343 struct convert_holder
345 static void apply(void* holder
, void* target
)
347 new(target
) ConstHolderType(*reinterpret_cast<HeldType
*>(holder
));
352 template<class HeldType
>
353 struct const_converter
355 typedef void(*converter_fun
)(void*, void*);
357 template<class ConstHolderType
>
358 static converter_fun
apply(ConstHolderType
*)
360 return &detail::convert_holder
<HeldType
, ConstHolderType
>::apply
;
365 struct const_converter
<detail::null_type
>
367 typedef void(*converter_fun
)(void*, void*);
370 static converter_fun
apply(T
*)
379 template<class HeldType
>
380 struct internal_const_holder_extractor
382 typedef const void*(*extractor_fun
)(void*);
385 static extractor_fun
apply(detail::type
<T
>)
387 return get_extractor(detail::type
<T
>(), luabind::get_const_holder(static_cast<HeldType
*>(0)));
390 template<class T
, class ConstHolderType
>
391 static extractor_fun
get_extractor(detail::type
<T
>, ConstHolderType
*)
393 return &detail::extract_underlying_const_type
<T
, ConstHolderType
>::extract
;
398 struct internal_const_holder_extractor
<detail::null_type
>
400 typedef const void*(*extractor_fun
)(void*);
403 static extractor_fun
apply(detail::type
<T
>)
411 // this is simply a selector that returns the type_info
412 // of the held type, or invalid_type_info if we don't have
414 template<class HeldType
>
415 struct internal_holder_type
417 static LUABIND_TYPE_INFO
apply()
419 return LUABIND_TYPEID(HeldType
);
424 struct internal_holder_type
<detail::null_type
>
426 static LUABIND_TYPE_INFO
apply()
428 return LUABIND_INVALID_TYPE_INFO
;
433 // this is the actual held_type constructor
434 template<class HeldType
, class T
>
435 struct internal_construct_holder
437 static void apply(void* target
, void* raw_pointer
)
439 new(target
) HeldType(static_cast<T
*>(raw_pointer
));
443 // the following two functions are the ones that returns
444 // a pointer to a held_type_constructor, or 0 if there
446 template<class HeldType
>
447 struct holder_constructor
449 typedef void(*constructor
)(void*,void*);
451 static constructor
apply(detail::type
<T
>)
453 return &internal_construct_holder
<HeldType
, T
>::apply
;
458 struct holder_constructor
<detail::null_type
>
460 typedef void(*constructor
)(void*,void*);
462 static constructor
apply(detail::type
<T
>)
468 // the following two functions are the ones that returns
469 // a pointer to a const_held_type_constructor, or 0 if there
471 template<class HolderType
>
472 struct const_holder_constructor
474 typedef void(*constructor
)(void*,void*);
476 static constructor
apply(detail::type
<T
>)
478 return get_const_holder_constructor(detail::type
<T
>(), luabind::get_const_holder(static_cast<HolderType
*>(0)));
483 template<class T
, class ConstHolderType
>
484 static constructor
get_const_holder_constructor(detail::type
<T
>, ConstHolderType
*)
486 return &internal_construct_holder
<ConstHolderType
, T
>::apply
;
491 struct const_holder_constructor
<detail::null_type
>
493 typedef void(*constructor
)(void*,void*);
495 static constructor
apply(detail::type
<T
>)
503 // this is a selector that returns the size of the held_type
504 // or 0 if we don't have a held_type
505 template <class HolderType
>
506 struct internal_holder_size
508 static int apply() { return get_internal_holder_size(luabind::get_const_holder(static_cast<HolderType
*>(0))); }
510 template<class ConstHolderType
>
511 static int get_internal_holder_size(ConstHolderType
*)
513 return max_c
<sizeof(HolderType
), sizeof(ConstHolderType
)>::value
;
518 struct internal_holder_size
<detail::null_type
>
520 static int apply() { return 0; }
524 // if we have a held type, return the destructor to it
525 // note the difference. The held_type should only be destructed (not deleted)
526 // since it's constructed in the lua userdata
527 template<class HeldType
>
528 struct internal_holder_destructor
530 typedef void(*destructor_t
)(void*);
532 static destructor_t
apply(detail::type
<T
>)
534 return &detail::destruct_only_s
<HeldType
>::apply
;
538 // if we don't have a held type, return the destructor of the raw type
540 struct internal_holder_destructor
<detail::null_type
>
542 typedef void(*destructor_t
)(void*);
544 static destructor_t
apply(detail::type
<T
>)
546 return &detail::delete_s
<T
>::apply
;
551 // if we have a held type, return the destructor to it's const version
552 template<class HolderType
>
553 struct internal_const_holder_destructor
555 typedef void(*destructor_t
)(void*);
557 static destructor_t
apply(detail::type
<T
>)
559 return const_holder_type_destructor(luabind::get_const_holder(static_cast<HolderType
*>(0)));
564 template<class ConstHolderType
>
565 static destructor_t
const_holder_type_destructor(ConstHolderType
*)
567 return &detail::destruct_only_s
<ConstHolderType
>::apply
;
572 // if we don't have a held type, return the destructor of the raw type
574 struct internal_const_holder_destructor
<detail::null_type
>
576 typedef void(*destructor_t
)(void*);
578 static destructor_t
apply(detail::type
<T
>)
587 template<class HolderType
>
588 struct get_holder_alignment
592 return internal_alignment(luabind::get_const_holder(static_cast<HolderType
*>(0)));
597 template<class ConstHolderType
>
598 static int internal_alignment(ConstHolderType
*)
600 return detail::max_c
<boost::alignment_of
<HolderType
>::value
601 , boost::alignment_of
<ConstHolderType
>::value
>::value
;
606 struct get_holder_alignment
<detail::null_type
>
630 struct class_base: detail::scoped_object
636 LUABIND_TYPE_INFO type;
648 std::map<const char*, detail::method_rep, detail::ltstr> m_methods;
650 // datamembers, some members may be readonly, and
651 // only have a getter function
652 std::map<const char*, detail::class_rep::callback, detail::ltstr> m_getters;
653 std::map<const char*, detail::class_rep::callback, detail::ltstr> m_setters;
655 // the operators in lua
656 std::vector<detail::class_rep::operator_callback> m_operators[detail::number_of_operators];
657 std::map<const char*, int, detail::ltstr> m_static_constants;
659 std::vector<base_desc> m_bases;
660 detail::construct_rep m_constructor;
662 void(*m_destructor)(void*);
663 void(*m_const_holder_destructor)(void*);
665 void*(*m_extractor)(void*);
666 const void*(*m_const_extractor)(void*);
668 void(*m_const_converter)(void*,void*);
670 void(*m_construct_holder)(void*, void*);
671 void(*m_construct_const_holder)(void*, void*);
674 int m_holder_alignment;
676 LUABIND_TYPE_INFO m_type;
677 LUABIND_TYPE_INFO m_holder_type;
678 LUABIND_TYPE_INFO m_const_holder_type;
680 #ifndef LUABIND_DONT_COPY_STRINGS
681 // the maps that contains char pointers points into
682 // this vector of strings.
683 std::vector<char*> m_strings;
689 // public 'cause of enum_maker, FIX
690 void add_static_constant(const char* name, int val)
692 m_static_constants[name] = val;
697 mutable std::vector<detail::scoped_object*> m_children;
699 void init(LUABIND_TYPE_INFO type
700 , LUABIND_TYPE_INFO holder_type
701 , void*(*extractor)(void*)
702 , const void*(*const_extractor)(void*)
703 , void(*const_converter)(void*,void*)
704 , void(*holder_constructor)(void*,void*)
705 , void(*const_holder_constructor)(void*,void*)
706 , void(*destructor)(void*)
707 , void(*const_holder_destructor)(void*)
709 , int holder_alignment)
712 m_holder_type = holder_type;
713 m_extractor = extractor;
714 m_const_extractor = const_extractor;
715 m_const_converter = const_converter;
716 m_construct_holder = holder_constructor;
717 m_construct_const_holder = const_holder_constructor;
718 m_destructor = destructor;
719 m_const_holder_destructor = const_holder_destructor;
720 m_holder_size = holder_size;
721 m_holder_alignment = holder_alignment;
725 void set_const_holder_type(T*)
727 m_const_holder_type = LUABIND_TYPEID(T);
730 inline void add_getter(const char* name, const boost::function2<int, lua_State*, int>& g)
732 detail::class_rep::callback c;
734 c.pointer_offset = 0;
735 #ifndef LUABIND_DONT_COPY_STRINGS
736 m_strings.push_back(detail::dup_string(name));
737 m_getters[m_strings.back()] = c;
743 inline void add_setter(const char* name, const boost::function2<int, lua_State*, int>& s)
745 detail::class_rep::callback c;
747 c.pointer_offset = 0;
748 #ifndef LUABIND_DONT_COPY_STRINGS
749 m_strings.push_back(detail::dup_string(name));
750 m_setters[m_strings.back()] = c;
756 void add_base(const base_desc& b)
758 m_bases.push_back(b);
763 void add_constructor(const detail::construct_rep::overload_t& o)
765 m_constructor.overloads.push_back(o);
768 void add_method(const char* name, const detail::overload_rep& o)
770 #ifdef LUABIND_DONT_COPY_STRINGS
771 detail::method_rep& method = m_methods[name];
774 m_strings.push_back(detail::dup_string(name));
775 detail::method_rep& method = m_methods[m_strings.back()];
776 method.name = m_strings.back();
778 method.add_overload(o);
782 #ifndef LUABIND_NO_ERROR_CHECKING
783 inline void add_operator(int op_id, int(*func)(lua_State*), int(*matcher)(lua_State*), void(*sig)(lua_State*, std::string&), int arity)
785 inline void add_operator(int op_id, int(*func)(lua_State*), int(*matcher)(lua_State*), int arity)
788 detail::class_rep::operator_callback o;
790 o.set_match_fun(matcher);
793 #ifndef LUABIND_NO_ERROR_CHECKING
798 m_operators[op_id].push_back(o);
807 const char* name() const { return m_name; }
809 class_base(const char* name)
811 #ifndef LUABIND_DONT_COPY_STRINGS
812 m_strings.push_back(detail::dup_string(name));
813 m_name = m_strings.back();
823 virtual ~class_base()
825 for (std::vector<detail::scoped_object*>::iterator
826 i = m_children.begin(); i != m_children.end(); ++i)
829 // if we are copying strings, we have to destroy them too
830 #ifndef LUABIND_DONT_COPY_STRINGS
831 for (std::vector<char*>::iterator i = m_strings.begin(); i != m_strings.end(); ++i)
836 // pushes the class_rep on the lua stack
837 virtual void commit(lua_State* L)
839 assert(!m_cloned && "class already commited");
841 detail::getref(L, scope_stack::top(L));
842 lua_pushstring(L, m_name);
844 detail::class_rep* crep;
846 detail::class_registry* r = detail::class_registry::get_registry(L);
847 // create a class_rep structure for this class.
848 // allocate it within lua to let lua collect it on
849 // lua_close(). This is better than allocating it
850 // as a static, since it will then be destructed
851 // when the program exits instead.
852 // warning: we assume that lua will not
853 // move the userdata memory.
854 lua_newuserdata(L, sizeof(detail::class_rep));
855 crep = reinterpret_cast<detail::class_rep*>(lua_touserdata(L, -1));
857 new(crep) detail::class_rep( m_type
861 , m_const_holder_destructor
863 , m_const_holder_type
868 , m_construct_const_holder
870 , m_holder_alignment);
872 // register this new type in the class registry
873 r->add_class(m_type, crep);
874 if (!(LUABIND_TYPE_INFO_EQUAL(m_holder_type, LUABIND_INVALID_TYPE_INFO)))
876 // if we have a held type
877 // we have to register it in the class-table
878 // but only for the base class, if it already
879 // exists, we don't have to register it
880 detail::class_rep* c = r->find_class(m_holder_type);
883 r->add_class(m_holder_type, crep);
884 r->add_class(m_const_holder_type, crep);
889 m_constructor.swap(crep->m_constructor);
891 #ifndef LUABIND_DONT_COPY_STRINGS
892 assert(crep->m_strings.empty() && "Internal error");
893 std::swap(crep->m_strings, m_strings);
896 std::swap(crep->m_getters, m_getters);
897 std::swap(crep->m_setters, m_setters);
899 for(int i = 0; i < detail::number_of_operators; ++i)
900 std::swap(crep->m_operators[i], m_operators[i]);
902 std::swap(crep->m_static_constants, m_static_constants);
905 // crep->m_methods = m_methods;
907 for (std::vector<base_desc>::iterator i = m_bases.begin();
911 detail::class_registry* r = detail::class_registry::get_registry(L);
913 // the baseclass' class_rep structure
914 detail::class_rep* bcrep = r->find_class(i->type);
916 detail::class_rep::base_info base;
917 base.pointer_offset = i->ptr_offset;
920 crep->add_base_class(base);
922 typedef std::map<const char*, detail::method_rep, detail::ltstr> methods_t;
924 for (methods_t::const_iterator i
925 = bcrep->m_methods.begin()
926 ; i != bcrep->m_methods.end()
929 detail::method_rep& m = m_methods[i->first];
931 typedef std::vector<detail::overload_rep> overloads_t;
933 for (overloads_t::const_iterator j
934 = i->second.overloads().begin()
935 ; j != i->second.overloads().end()
938 detail::overload_rep o = *j;
939 o.add_offset(base.pointer_offset);
944 // copy base class table
945 detail::getref(L, crep->table_ref());
946 detail::getref(L, bcrep->table_ref());
949 while (lua_next(L, -2))
951 lua_pushvalue(L, -2); // copy key
959 crep->m_methods = m_methods;
961 for (std::map<const char*, detail::method_rep, detail::ltstr>::iterator i
962 = crep->m_methods.begin(); i != crep->m_methods.end(); ++i)
964 i->second.crep = crep;
968 for (std::map<const char*, detail::method_rep, detail::ltstr>::iterator i
969 = m_methods.begin(); i != m_methods.end(); ++i)
971 detail::getref(L, crep->table_ref());
972 lua_pushstring(L, i->first);
977 crep->add_method(L, i->first, crep->m_methods[i->first]);
978 i->second.crep = crep;
989 virtual luabind::detail::scoped_object* clone()
991 assert(m_cloned == false);
997 class_base* ret = new class_base(m_name);
999 std::swap(ret->m_getters, m_getters);
1000 std::swap(ret->m_setters, m_setters);
1002 for(int i = 0; i < detail::number_of_operators; ++i)
1003 std::swap(ret->m_operators[i], m_operators[i]);
1005 std::swap(ret->m_static_constants, m_static_constants);
1012 , m_construct_holder
1013 , m_construct_const_holder
1015 , m_const_holder_destructor
1017 , m_holder_alignment);
1019 ret->m_const_holder_type = m_const_holder_type;
1021 ret->m_bases.swap(m_bases);
1022 ret->m_methods.swap(m_methods);
1023 m_constructor.swap(ret->m_constructor);
1025 ret->m_name = m_name;
1027 #ifndef LUABIND_DONT_COPY_STRINGS
1028 std::swap(ret->m_strings, m_strings);
1031 m_children.swap(ret->m_children);
1039 struct class_registration
;
1041 struct class_base
: detail::scope
1044 class_base(char const* name
);
1048 LUABIND_TYPE_INFO type
;
1053 LUABIND_TYPE_INFO type
1054 , LUABIND_TYPE_INFO holder_type
1055 , LUABIND_TYPE_INFO const_holder_type
1056 , void*(*extractor
)(void*)
1057 , const void*(*const_extractor
)(void*)
1058 , void(*const_converter
)(void*,void*)
1059 , void(*holder_constructor
)(void*,void*)
1060 , void(*const_holder_constructor
)(void*,void*)
1061 , void(*destructor
)(void*)
1062 , void(*const_holder_destructor
)(void*)
1064 , int holder_alignment
);
1068 , const boost::function2
<int, lua_State
*, int>& g
);
1072 , const boost::function2
<int, lua_State
*, int>& s
);
1074 void add_base(const base_desc
& b
);
1075 void add_constructor(const detail::construct_rep::overload_t
& o
);
1076 void add_method(const char* name
, const detail::overload_rep
& o
);
1078 #ifndef LUABIND_NO_ERROR_CHECKING
1081 , int(*func
)(lua_State
*)
1082 , int(*matcher
)(lua_State
*)
1083 , void(*sig
)(lua_State
*
1089 , int(*func
)(lua_State
*)
1090 , int(*matcher
)(lua_State
*)
1094 const char* name() const;
1096 void add_static_constant(const char* name
, int val
);
1099 class_registration
* m_registration
;
1102 } // namespace detail
1104 // registers a class in the lua environment
1105 template<class T
, class X1
, class X2
, class X3
>
1106 struct class_
: detail::class_base
1108 typedef class_
<T
, X1
, X2
, X3
> self_t
;
1114 template<class A
, class B
, class C
, class D
>
1115 class_(const class_
<A
,B
,C
,D
>&);
1119 // WrappedType MUST inherit from T
1120 typedef typename
detail::extract_parameter
<
1121 boost::mpl::vector3
<X1
,X2
,X3
>
1122 , boost::is_base_and_derived
<T
, boost::mpl::_
>
1123 /* , boost::mpl::not_<
1125 detail::is_bases<boost::mpl::_>
1126 , boost::is_base_and_derived<boost::mpl::_, T>
1130 >::type WrappedType
;
1132 typedef typename
detail::extract_parameter
<
1133 boost::mpl::list3
<X1
,X2
,X3
>
1137 detail::is_bases
<boost::mpl::_
>
1138 , boost::is_base_and_derived
<boost::mpl::_
, T
>
1140 , boost::is_base_and_derived
<T
, boost::mpl::_
>
1147 void register_downcast(boost::mpl::true_, detail::type<To>* = 0)
1148 { boost::langbinding::register_conversion<To, T>(true); }
1151 void register_downcast(boost::mpl::false_, detail::type<To>* = 0)
1154 // this function generates conversion information
1155 // in the given class_rep structure. It will be able
1156 // to implicitly cast to the given template type
1158 void gen_base_info(detail::type
<To
>)
1160 // boost::langbinding::register_dynamic_id<To>();
1161 // boost::langbinding::register_conversion<T, To>(false);
1163 // register_downcast<To>(boost::mpl::bool_<boost::is_polymorphic<To>::value>());
1165 // fist, make sure the given base class is registered.
1166 // if it's not registered we can't push it's lua table onto
1167 // the stack because it doesn't have a table
1169 // try to cast this type to the base type and remember
1170 // the pointer offset. For multiple inheritance the pointer
1171 // may change when casting. Since we need to be able to
1172 // cast we need this pointer offset.
1173 // store the information in this class' base class-vector
1175 base
.type
= LUABIND_TYPEID(To
);
1176 base
.ptr_offset
= detail::ptr_offset(detail::type
<T
>(), detail::type
<To
>());
1180 void gen_base_info(detail::type
<detail::null_type
>)
1183 #define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type<B##n>());
1185 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES
, class B
)>
1186 void generate_baseclass_list(detail::type
<bases
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES
, B
)> >)
1188 BOOST_PP_REPEAT(LUABIND_MAX_BASES
, LUABIND_GEN_BASE_INFO
, _
)
1191 #undef LUABIND_GEN_BASE_INFO
1193 // this is the internal version of def() it is run from both overloads
1194 // of def. It has two versions, one where a contstructor is registered
1195 // and one where a function is registered
1196 template<class Policies
>
1197 struct internal_def_s
1200 static void apply(const char* name
, F f
, detail::class_base
* c
)
1202 // std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";
1204 detail::overload_rep
o(f
, static_cast<Policies
*>(0));
1206 typedef LUABIND_MSVC_TYPENAME
detail::function_callback_s
<HeldType
,T
,F
,Policies
>::type call_t
;
1208 o
.set_match_fun(&detail::match_function_callback_s
<T
,F
,Policies
>::apply
);
1209 o
.call_fun
= boost::bind
<int>(call_t(f
), _1
, _2
);
1211 #ifndef LUABIND_NO_ERROR_CHECKING
1213 o
.set_sig_fun(&detail::get_member_signature
<F
>::apply
);
1217 c
->add_method(name
, o
);
1220 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, class A
)>
1221 static void apply(constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)>, detail::class_base
* c
)
1223 // std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";
1225 detail::construct_rep::overload_t o
;
1228 &detail::construct_class
<
1231 ,constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)>
1235 // if we have a WrappedType, we have to register it's constructor
1236 // but if it's null_type (no WrappedType) we should not register it
1237 detail::register_wrapped_type
<WrappedType
>::apply(o
,
1238 static_cast<const constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)>*>(0),
1239 static_cast<const Policies
*>(0));
1243 &detail::constructor_match
<
1244 constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)>
1249 #ifndef LUABIND_NO_ERROR_CHECKING
1251 o
.set_sig_fun(&detail::get_signature
<constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> >::apply
);
1255 typedef constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> con_t
;
1257 o
.set_arity(detail::calc_arity
<con_t::arity
>::apply(con_t(), static_cast<Policies
*>(0)));
1259 c
->add_constructor(o
);
1263 class_(lua_State
* L
, const char* name
): class_base(name
), m_L(L
) { init(); }
1264 class_(const char* name
): class_base(name
), m_L(0) { init(); }
1271 lua_pushvalue(m_L, LUA_GLOBALSINDEX);
1272 scope_stack::push(m_L);
1274 scope_stack::pop(m_L);
1279 class_
& def(const char* name
, F f
)
1281 internal_def_s
<detail::null_type
>::apply(name
, f
, this);
1285 template<class F
, class Policies
>
1286 class_
& def(const char* name
, F f
, const Policies
&)
1288 internal_def_s
<Policies
>::apply(name
, f
, this);
1292 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, class A
)>
1293 class_
& def(constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> sig
)
1295 internal_def_s
<detail::null_type
>::apply(sig
, this);
1299 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, class A
), class Policies
>
1300 class_
& def(constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> sig
, const Policies
& policies
)
1302 internal_def_s
<Policies
>::apply(sig
, this);
1306 template<class Getter
>
1307 class_
& property(const char* name
, Getter g
)
1309 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
, Getter
, detail::null_type
>(), _1
, _2
, g
));
1313 template<class Getter
, class MaybeSetter
>
1314 class_
& property(const char* name
, Getter g
, MaybeSetter s
)
1316 return property_impl(name
, g
, s
, boost::mpl::bool_
<detail::is_policy_cons
<MaybeSetter
>::value
>());
1319 template<class Getter
, class Setter
, class GetPolicies
>
1320 class_
& property(const char* name
, Getter g
, Setter s
, const GetPolicies
& get_policies
)
1322 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
, Getter
, GetPolicies
>(get_policies
), _1
, _2
, g
));
1323 add_setter(name
, boost::bind
<int>(detail::set_caller
<T
, Setter
, detail::null_type
>(), _1
, _2
, s
));
1327 template<class Getter
, class Setter
, class GetPolicies
, class SetPolicies
>
1328 class_
& property(const char* name
1329 , Getter g
, Setter s
1330 , const GetPolicies
& get_policies
1331 , const SetPolicies
& set_policies
)
1333 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
, Getter
, GetPolicies
>(get_policies
), _1
, _2
, g
));
1334 add_setter(name
, boost::bind
<int>(detail::set_caller
<T
, Setter
, GetPolicies
>(set_policies
), _1
, _2
, s
));
1339 class_
& def_readonly(const char* name
, D
T::*member_ptr
)
1341 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
1345 template<class D
, class Policies
>
1346 class_
& def_readonly(const char* name
, D
T::*member_ptr
, const Policies
& policies
)
1348 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,Policies
>(policies
), _1
, _2
, member_ptr
));
1353 class_
& def_readwrite(const char* name
, D
T::*member_ptr
)
1355 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
1356 add_setter(name
, boost::bind
<int>(detail::auto_set
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
1360 template<class D
, class GetPolicies
>
1361 class_
& def_readwrite(const char* name
, D
T::*member_ptr
, const GetPolicies
& get_policies
)
1363 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,GetPolicies
>(get_policies
), _1
, _2
, member_ptr
));
1364 add_setter(name
, boost::bind
<int>(detail::auto_set
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
1368 template<class D
, class GetPolicies
, class SetPolicies
>
1369 class_
& def_readwrite(const char* name
, D
T::*member_ptr
, const GetPolicies
& get_policies
, const SetPolicies
& set_policies
)
1371 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,GetPolicies
>(get_policies
), _1
, _2
, member_ptr
));
1372 add_setter(name
, boost::bind
<int>(detail::auto_set
<T
,D
,SetPolicies
>(set_policies
), _1
, _2
, member_ptr
));
1376 template<class op_id
, class Left
, class Right
, class Policies
>
1377 class_
& def(detail::operator_
<op_id
, Left
, Right
>, const Policies
& policies
)
1379 typedef typename
detail::operator_unwrapper
<Policies
, op_id
, T
, Left
, Right
> op_type
;
1380 #ifndef LUABIND_NO_ERROR_CHECKING
1381 add_operator(op_type::get_id()
1384 , &detail::get_signature
<constructor
<typename
op_type::left_t
, typename
op_type::right_t
> >::apply
1385 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1387 add_operator(op_type::get_id()
1390 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1395 template<class op_id
, class Left
, class Right
>
1396 class_
& def(detail::operator_
<op_id
, Left
, Right
>)
1398 typedef typename
detail::operator_unwrapper
<detail::null_type
, op_id
, T
, Left
, Right
> op_type
;
1400 #ifndef LUABIND_NO_ERROR_CHECKING
1401 add_operator(op_type::get_id()
1404 , &detail::get_signature
<constructor
<LUABIND_MSVC_TYPENAME
op_type::left_t
, LUABIND_MSVC_TYPENAME
op_type::right_t
> >::apply
1405 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1407 add_operator(op_type::get_id()
1410 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1415 template<class Signature
, bool Constant
>
1416 class_
& def(detail::application_operator
<Signature
, Constant
>*)
1418 typedef detail::application_operator
<Signature
, Constant
, detail::null_type
> op_t
;
1420 int arity
= detail::calc_arity
<Signature::arity
>::apply(Signature(), static_cast<detail::null_type
*>(0));
1422 #ifndef LUABIND_NO_ERROR_CHECKING
1423 add_operator(detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, &detail::get_signature
<Signature
>::apply
, arity
+ 1);
1425 add_operator(detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, arity
+ 1);
1431 template<class Signature
, bool Constant
, class Policies
>
1432 class_
& def(detail::application_operator
<Signature
, Constant
>*, const Policies
& policies
)
1434 typedef detail::application_operator
<Signature
, Constant
, Policies
> op_t
;
1436 int arity
= detail::calc_arity
<Signature::arity
>::apply(Signature(), static_cast<Policies
*>(0));
1438 #ifndef LUABIND_NO_ERROR_CHECKING
1439 add_operator(detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, &detail::get_signature
<Signature
>::apply
, arity
+ 1);
1441 add_operator(detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, arity
+ 1);
1447 detail::enum_maker
<self_t
> enum_(const char*)
1449 return detail::enum_maker
<self_t
>(*this);
1456 typedef typename
detail::extract_parameter
<
1457 boost::mpl::list3
<X1
,X2
,X3
>
1459 detail::is_bases
<boost::mpl::_
>
1460 , boost::is_base_and_derived
<boost::mpl::_
, T
>
1466 boost::mpl::if_
<detail::is_bases
<bases_t
>
1471 class_base::init(LUABIND_TYPEID(T
)
1472 , detail::internal_holder_type
<HeldType
>::apply()
1473 , detail::pointee_typeid(
1474 get_const_holder(static_cast<HeldType
*>(0)))
1475 , detail::internal_holder_extractor
<HeldType
>::apply(detail::type
<T
>())
1476 , detail::internal_const_holder_extractor
<HeldType
>::apply(detail::type
<T
>())
1477 , detail::const_converter
<HeldType
>::apply(
1478 luabind::get_const_holder((HeldType
*)0))
1479 , detail::holder_constructor
<HeldType
>::apply(detail::type
<T
>())
1480 , detail::const_holder_constructor
<HeldType
>::apply(detail::type
<T
>())
1481 , detail::internal_holder_destructor
<HeldType
>::apply(detail::type
<T
>())
1482 , detail::internal_const_holder_destructor
<HeldType
>::apply(detail::type
<T
>())
1483 , detail::internal_holder_size
<HeldType
>::apply()
1484 , detail::get_holder_alignment
<HeldType
>::apply());
1486 generate_baseclass_list(detail::type
<Base
>());
1489 template<class Getter
, class GetPolicies
>
1490 class_
& property_impl(const char* name
,
1492 GetPolicies policies
,
1493 boost::mpl::bool_
<true>)
1495 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
,Getter
,GetPolicies
>(policies
), _1
, _2
, g
));
1499 template<class Getter
, class Setter
>
1500 class_
& property_impl(const char* name
,
1503 boost::mpl::bool_
<false>)
1505 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
,Getter
,detail::null_type
>(), _1
, _2
, g
));
1506 add_setter(name
, boost::bind
<int>(detail::set_caller
<T
,Setter
,detail::null_type
>(), _1
, _2
, s
));
1513 #endif // LUABIND_CLASS_HPP_INCLUDED