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>
133 struct unspecified
{};
138 template<class T
, class X1
= detail::unspecified
, class X2
= detail::unspecified
, class X3
= detail::unspecified
>
141 // TODO: this function will only be invoked if the user hasn't defined a correct overload
142 // maybe we should have a static assert in here?
143 inline detail::null_type
* get_const_holder(...)
150 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES
, class A
)>
151 double is_bases_helper(const bases
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES
, A
)>&);
155 char is_bases_helper(const T
&);
157 char is_bases_helper(...);
165 BOOST_STATIC_CONSTANT(bool, value
= sizeof(is_bases_helper(t
)) == sizeof(double));
166 typedef boost::mpl::bool_
<value
> type
;
167 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_bases
,(T
))
170 double is_not_unspecified_helper(const unspecified
*);
171 char is_not_unspecified_helper(...);
174 struct is_not_unspecified
176 BOOST_STATIC_CONSTANT(bool, value
= sizeof(is_not_unspecified_helper(static_cast<T
*>(0))) == sizeof(char));
177 typedef boost::mpl::bool_
<value
> type
;
178 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_not_unspecified
,(T
))
181 template<class Predicate
>
184 typedef typename
boost::mpl::and_
<
186 , is_not_unspecified
<boost::mpl::_1
>
190 template<class Parameters
, class Predicate
, class DefaultValue
>
191 struct extract_parameter
193 typedef typename get_predicate
<Predicate
>::type pred
;
194 typedef typename
boost::mpl::find_if
<Parameters
, pred
>::type iterator
;
195 typedef typename
boost::mpl::apply_if
<boost::is_same
<iterator
, typename
boost::mpl::end
<Parameters
>::type
>
196 , boost::mpl::identity
<DefaultValue
>
201 // TODO: is this detail::class_rep::function_dispatcher or detail::free_functions::function_dispatcher?
202 // LUABIND_API int function_dispatcher(lua_State* L);
204 // this should know about the smart pointer type.
205 // and should really do:
206 // get_pointer(*static_cast<SmartPointer*>(obj_ptr))
207 // to extract the held pointer.
208 template<class HeldType
, class T
, class F
, class Policies
>
209 struct function_callback_non_null
: Policies
211 function_callback_non_null(F f_
): f(f_
) {}
212 inline int operator()(lua_State
* L
, void* obj_ptr
)
214 // HeldType& held_obj = *static_cast<HeldType*>(obj_ptr);
215 // T* ptr = static_cast<T*>(luabind::get_pointer(held_obj));
217 T
* ptr
= static_cast<T
*>(obj_ptr
);
219 return call(f
, ptr
, L
, static_cast<Policies
*>(this));
224 template<class T
, class F
, class Policies
>
225 struct function_callback_null_type
: Policies
227 function_callback_null_type(F f_
): f(f_
) {}
228 inline int operator()(lua_State
* L
, void* obj_ptr
)
230 // std::cout << "HeldType: null_type\n";
231 T
* ptr
= static_cast<T
*>(obj_ptr
);
232 return call(f
, ptr
, L
, static_cast<Policies
*>(this));
237 template<class HeldType
, class T
, class F
, class Policies
>
238 struct function_callback_s
241 boost::mpl::if_
<boost::is_same
<HeldType
,detail::null_type
>
242 , function_callback_null_type
<T
,F
,Policies
>
243 , function_callback_non_null
<HeldType
,T
,F
,Policies
>
247 template<class T
, class F
, class Policies
>
248 struct match_function_callback_s
250 static inline int apply(lua_State
* L
)
252 object_rep
* obj
= static_cast<object_rep
*>(lua_touserdata(L
, 1));
254 return match(fptr
, L
, obj
->flags() & object_rep::constant
, static_cast<Policies
*>(0));
258 // prints the types of the values on the stack, in the
259 // range [start_index, lua_gettop()]
261 LUABIND_API
std::string
stack_content_by_name(lua_State
* L
, int start_index
);
263 struct LUABIND_API create_class
265 static int stage1(lua_State
* L
);
266 static int stage2(lua_State
* L
);
270 struct register_wrapped_type
272 template<class Signature
, class Policies
>
273 static void apply(detail::construct_rep::overload_t
& o
, const Signature
*, const Policies
*)
275 o
.set_wrapped_constructor(
276 &detail::construct_wrapped_class
<Type
, Policies
, Signature
>::apply
282 struct register_wrapped_type
<detail::null_type
>
284 template<class Signature
, class Policies
>
285 static void apply(detail::construct_rep::overload_t
&, const Signature
*, const Policies
*) {}
289 // if the class is held by a smart pointer, we need to be able to
290 // implicitly dereference the pointer when needed.
292 template<class UnderlyingT
, class HeldT
>
293 struct extract_underlying_type
295 static void* extract(void* ptr
)
297 HeldT
& held_obj
= *reinterpret_cast<HeldT
*>(ptr
);
298 UnderlyingT
* underlying_ptr
= static_cast<UnderlyingT
*>(get_pointer(held_obj
));
299 return underlying_ptr
;
303 template<class UnderlyingT
, class HeldT
>
304 struct extract_underlying_const_type
306 static const void* extract(void* ptr
)
308 HeldT
& held_obj
= *reinterpret_cast<HeldT
*>(ptr
);
309 const UnderlyingT
* underlying_ptr
= static_cast<const UnderlyingT
*>(get_pointer(held_obj
));
310 return underlying_ptr
;
314 template<class HeldType
>
315 struct internal_holder_extractor
317 typedef void*(*extractor_fun
)(void*);
320 static extractor_fun
apply(detail::type
<T
>)
322 return &detail::extract_underlying_type
<T
, HeldType
>::extract
;
327 struct internal_holder_extractor
<detail::null_type
>
329 typedef void*(*extractor_fun
)(void*);
332 static extractor_fun
apply(detail::type
<T
>)
339 template<class HeldType
, class ConstHolderType
>
340 struct convert_holder
342 static void apply(void* holder
, void* target
)
344 new(target
) ConstHolderType(*reinterpret_cast<HeldType
*>(holder
));
349 template<class HeldType
>
350 struct const_converter
352 typedef void(*converter_fun
)(void*, void*);
354 template<class ConstHolderType
>
355 static converter_fun
apply(ConstHolderType
*)
357 return &detail::convert_holder
<HeldType
, ConstHolderType
>::apply
;
362 struct const_converter
<detail::null_type
>
364 typedef void(*converter_fun
)(void*, void*);
367 static converter_fun
apply(T
*)
376 template<class HeldType
>
377 struct internal_const_holder_extractor
379 typedef const void*(*extractor_fun
)(void*);
382 static extractor_fun
apply(detail::type
<T
>)
384 return get_extractor(detail::type
<T
>(), luabind::get_const_holder(static_cast<HeldType
*>(0)));
387 template<class T
, class ConstHolderType
>
388 static extractor_fun
get_extractor(detail::type
<T
>, ConstHolderType
*)
390 return &detail::extract_underlying_const_type
<T
, ConstHolderType
>::extract
;
395 struct internal_const_holder_extractor
<detail::null_type
>
397 typedef const void*(*extractor_fun
)(void*);
400 static extractor_fun
apply(detail::type
<T
>)
408 // this is simply a selector that returns the type_info
409 // of the held type, or invalid_type_info if we don't have
411 template<class HeldType
>
412 struct internal_holder_type
414 static LUABIND_TYPE_INFO
apply()
416 return LUABIND_TYPEID(HeldType
);
421 struct internal_holder_type
<detail::null_type
>
423 static LUABIND_TYPE_INFO
apply()
425 return LUABIND_INVALID_TYPE_INFO
;
430 // this is the actual held_type constructor
431 template<class HeldType
, class T
>
432 struct internal_construct_holder
434 static void apply(void* target
, void* raw_pointer
)
436 new(target
) HeldType(static_cast<T
*>(raw_pointer
));
440 // the following two functions are the ones that returns
441 // a pointer to a held_type_constructor, or 0 if there
443 template<class HeldType
>
444 struct holder_constructor
446 typedef void(*constructor
)(void*,void*);
448 static constructor
apply(detail::type
<T
>)
450 return &internal_construct_holder
<HeldType
, T
>::apply
;
455 struct holder_constructor
<detail::null_type
>
457 typedef void(*constructor
)(void*,void*);
459 static constructor
apply(detail::type
<T
>)
465 // the following two functions are the ones that returns
466 // a pointer to a const_held_type_constructor, or 0 if there
468 template<class HolderType
>
469 struct const_holder_constructor
471 typedef void(*constructor
)(void*,void*);
473 static constructor
apply(detail::type
<T
>)
475 return get_const_holder_constructor(detail::type
<T
>(), luabind::get_const_holder(static_cast<HolderType
*>(0)));
480 template<class T
, class ConstHolderType
>
481 static constructor
get_const_holder_constructor(detail::type
<T
>, ConstHolderType
*)
483 return &internal_construct_holder
<ConstHolderType
, T
>::apply
;
488 struct const_holder_constructor
<detail::null_type
>
490 typedef void(*constructor
)(void*,void*);
492 static constructor
apply(detail::type
<T
>)
500 // this is a selector that returns the size of the held_type
501 // or 0 if we don't have a held_type
502 template <class HolderType
>
503 struct internal_holder_size
505 static int apply() { return get_internal_holder_size(luabind::get_const_holder(static_cast<HolderType
*>(0))); }
507 template<class ConstHolderType
>
508 static int get_internal_holder_size(ConstHolderType
*)
510 return max_c
<sizeof(HolderType
), sizeof(ConstHolderType
)>::value
;
515 struct internal_holder_size
<detail::null_type
>
517 static int apply() { return 0; }
521 // if we have a held type, return the destructor to it
522 // note the difference. The held_type should only be destructed (not deleted)
523 // since it's constructed in the lua userdata
524 template<class HeldType
>
525 struct internal_holder_destructor
527 typedef void(*destructor_t
)(void*);
529 static destructor_t
apply(detail::type
<T
>)
531 return &detail::destruct_only_s
<HeldType
>::apply
;
535 // if we don't have a held type, return the destructor of the raw type
537 struct internal_holder_destructor
<detail::null_type
>
539 typedef void(*destructor_t
)(void*);
541 static destructor_t
apply(detail::type
<T
>)
543 return &detail::delete_s
<T
>::apply
;
548 // if we have a held type, return the destructor to it's const version
549 template<class HolderType
>
550 struct internal_const_holder_destructor
552 typedef void(*destructor_t
)(void*);
554 static destructor_t
apply(detail::type
<T
>)
556 return const_holder_type_destructor(luabind::get_const_holder(static_cast<HolderType
*>(0)));
561 template<class ConstHolderType
>
562 static destructor_t
const_holder_type_destructor(ConstHolderType
*)
564 return &detail::destruct_only_s
<ConstHolderType
>::apply
;
569 // if we don't have a held type, return the destructor of the raw type
571 struct internal_const_holder_destructor
<detail::null_type
>
573 typedef void(*destructor_t
)(void*);
575 static destructor_t
apply(detail::type
<T
>)
584 template<class HolderType
>
585 struct get_holder_alignment
589 return internal_alignment(luabind::get_const_holder(static_cast<HolderType
*>(0)));
594 template<class ConstHolderType
>
595 static int internal_alignment(ConstHolderType
*)
597 return detail::max_c
<boost::alignment_of
<HolderType
>::value
598 , boost::alignment_of
<ConstHolderType
>::value
>::value
;
603 struct get_holder_alignment
<detail::null_type
>
627 struct class_base
: detail::scoped_object
633 LUABIND_TYPE_INFO type
;
645 std::map
<const char*, detail::method_rep
, detail::ltstr
> m_methods
;
647 // datamembers, some members may be readonly, and
648 // only have a getter function
649 std::map
<const char*, detail::class_rep::callback
, detail::ltstr
> m_getters
;
650 std::map
<const char*, detail::class_rep::callback
, detail::ltstr
> m_setters
;
652 // the operators in lua
653 std::vector
<detail::class_rep::operator_callback
> m_operators
[detail::number_of_operators
];
654 std::map
<const char*, int, detail::ltstr
> m_static_constants
;
656 std::vector
<base_desc
> m_bases
;
657 detail::construct_rep m_constructor
;
659 void(*m_destructor
)(void*);
660 void(*m_const_holder_destructor
)(void*);
662 void*(*m_extractor
)(void*);
663 const void*(*m_const_extractor
)(void*);
665 void(*m_const_converter
)(void*,void*);
667 void(*m_construct_holder
)(void*, void*);
668 void(*m_construct_const_holder
)(void*, void*);
671 int m_holder_alignment
;
673 LUABIND_TYPE_INFO m_type
;
674 LUABIND_TYPE_INFO m_holder_type
;
675 LUABIND_TYPE_INFO m_const_holder_type
;
677 #ifndef LUABIND_DONT_COPY_STRINGS
678 // the maps that contains char pointers points into
679 // this vector of strings.
680 std::vector
<char*> m_strings
;
686 // public 'cause of enum_maker, FIX
687 void add_static_constant(const char* name
, int val
)
689 m_static_constants
[name
] = val
;
694 mutable std::vector
<detail::scoped_object
*> m_children
;
696 void init(LUABIND_TYPE_INFO type
697 , LUABIND_TYPE_INFO holder_type
698 , void*(*extractor
)(void*)
699 , const void*(*const_extractor
)(void*)
700 , void(*const_converter
)(void*,void*)
701 , void(*holder_constructor
)(void*,void*)
702 , void(*const_holder_constructor
)(void*,void*)
703 , void(*destructor
)(void*)
704 , void(*const_holder_destructor
)(void*)
706 , int holder_alignment
)
709 m_holder_type
= holder_type
;
710 m_extractor
= extractor
;
711 m_const_extractor
= const_extractor
;
712 m_const_converter
= const_converter
;
713 m_construct_holder
= holder_constructor
;
714 m_construct_const_holder
= const_holder_constructor
;
715 m_destructor
= destructor
;
716 m_const_holder_destructor
= const_holder_destructor
;
717 m_holder_size
= holder_size
;
718 m_holder_alignment
= holder_alignment
;
722 void set_const_holder_type(T
*)
724 m_const_holder_type
= LUABIND_TYPEID(T
);
727 inline void add_getter(const char* name
, const boost::function2
<int, lua_State
*, int>& g
)
729 detail::class_rep::callback c
;
731 c
.pointer_offset
= 0;
732 #ifndef LUABIND_DONT_COPY_STRINGS
733 m_strings
.push_back(detail::dup_string(name
));
734 m_getters
[m_strings
.back()] = c
;
740 inline void add_setter(const char* name
, const boost::function2
<int, lua_State
*, int>& s
)
742 detail::class_rep::callback c
;
744 c
.pointer_offset
= 0;
745 #ifndef LUABIND_DONT_COPY_STRINGS
746 m_strings
.push_back(detail::dup_string(name
));
747 m_setters
[m_strings
.back()] = c
;
753 void add_base(const base_desc
& b
)
755 m_bases
.push_back(b
);
760 void add_constructor(const detail::construct_rep::overload_t
& o
)
762 m_constructor
.overloads
.push_back(o
);
765 void add_method(const char* name
, const detail::overload_rep
& o
)
767 #ifdef LUABIND_DONT_COPY_STRINGS
768 detail::method_rep
& method
= m_methods
[name
];
771 m_strings
.push_back(detail::dup_string(name
));
772 detail::method_rep
& method
= m_methods
[m_strings
.back()];
773 method
.name
= m_strings
.back();
775 method
.add_overload(o
);
779 #ifndef LUABIND_NO_ERROR_CHECKING
780 inline void add_operator(int op_id
, int(*func
)(lua_State
*), int(*matcher
)(lua_State
*), void(*sig
)(lua_State
*, std::string
&), int arity
)
782 inline void add_operator(int op_id
, int(*func
)(lua_State
*), int(*matcher
)(lua_State
*), int arity
)
785 detail::class_rep::operator_callback o
;
787 o
.set_match_fun(matcher
);
790 #ifndef LUABIND_NO_ERROR_CHECKING
795 m_operators
[op_id
].push_back(o
);
804 const char* name() const { return m_name
; }
806 class_base(const char* name
)
808 #ifndef LUABIND_DONT_COPY_STRINGS
809 m_strings
.push_back(detail::dup_string(name
));
810 m_name
= m_strings
.back();
820 virtual ~class_base()
822 for (std::vector
<detail::scoped_object
*>::iterator
823 i
= m_children
.begin(); i
!= m_children
.end(); ++i
)
826 // if we are copying strings, we have to destroy them too
827 #ifndef LUABIND_DONT_COPY_STRINGS
828 for (std::vector
<char*>::iterator i
= m_strings
.begin(); i
!= m_strings
.end(); ++i
)
833 // pushes the class_rep on the lua stack
834 virtual void commit(lua_State
* L
)
836 assert(!m_cloned
&& "class already commited");
838 detail::getref(L
, scope_stack::top(L
));
839 lua_pushstring(L
, m_name
);
841 detail::class_rep
* crep
;
843 detail::class_registry
* r
= detail::class_registry::get_registry(L
);
844 // create a class_rep structure for this class.
845 // allocate it within lua to let lua collect it on
846 // lua_close(). This is better than allocating it
847 // as a static, since it will then be destructed
848 // when the program exits instead.
849 // warning: we assume that lua will not
850 // move the userdata memory.
851 lua_newuserdata(L
, sizeof(detail::class_rep
));
852 crep
= reinterpret_cast<detail::class_rep
*>(lua_touserdata(L
, -1));
854 new(crep
) detail::class_rep( m_type
858 , m_const_holder_destructor
860 , m_const_holder_type
865 , m_construct_const_holder
867 , m_holder_alignment
);
869 // register this new type in the class registry
870 r
->add_class(m_type
, crep
);
871 if (!(LUABIND_TYPE_INFO_EQUAL(m_holder_type
, LUABIND_INVALID_TYPE_INFO
)))
873 // if we have a held type
874 // we have to register it in the class-table
875 // but only for the base class, if it already
876 // exists, we don't have to register it
877 detail::class_rep
* c
= r
->find_class(m_holder_type
);
880 r
->add_class(m_holder_type
, crep
);
881 r
->add_class(m_const_holder_type
, crep
);
886 m_constructor
.swap(crep
->m_constructor
);
888 #ifndef LUABIND_DONT_COPY_STRINGS
889 assert(crep
->m_strings
.empty() && "Internal error");
890 std::swap(crep
->m_strings
, m_strings
);
893 std::swap(crep
->m_getters
, m_getters
);
894 std::swap(crep
->m_setters
, m_setters
);
896 for(int i
= 0; i
< detail::number_of_operators
; ++i
)
897 std::swap(crep
->m_operators
[i
], m_operators
[i
]);
899 std::swap(crep
->m_static_constants
, m_static_constants
);
901 for (std::vector
<base_desc
>::iterator i
= m_bases
.begin();
905 detail::class_registry
* r
= detail::class_registry::get_registry(L
);
907 // the baseclass' class_rep structure
908 detail::class_rep
* bcrep
= r
->find_class(i
->type
);
910 detail::class_rep::base_info base
;
911 base
.pointer_offset
= i
->ptr_offset
;
914 crep
->add_base_class(base
);
916 // copy base class table
917 detail::getref(L
, crep
->table_ref());
918 detail::getref(L
, bcrep
->table_ref());
921 while (lua_next(L
, -2))
923 lua_pushvalue(L
, -2); // copy key
931 crep
->m_methods
= m_methods
;
933 for (std::map
<const char*, detail::method_rep
, detail::ltstr
>::iterator i
934 = crep
->m_methods
.begin(); i
!= crep
->m_methods
.end(); ++i
)
936 i
->second
.crep
= crep
;
940 for (std::map
<const char*, detail::method_rep
, detail::ltstr
>::iterator i
941 = m_methods
.begin(); i
!= m_methods
.end(); ++i
)
943 crep
->add_method(L
, i
->first
, crep
->m_methods
[i
->first
]);
944 i
->second
.crep
= crep
;
955 virtual luabind::detail::scoped_object
* clone()
957 assert(m_cloned
== false);
963 class_base
* ret
= new class_base(m_name
);
965 std::swap(ret
->m_getters
, m_getters
);
966 std::swap(ret
->m_setters
, m_setters
);
968 for(int i
= 0; i
< detail::number_of_operators
; ++i
)
969 std::swap(ret
->m_operators
[i
], m_operators
[i
]);
971 std::swap(ret
->m_static_constants
, m_static_constants
);
979 , m_construct_const_holder
981 , m_const_holder_destructor
983 , m_holder_alignment
);
985 ret
->m_const_holder_type
= m_const_holder_type
;
987 ret
->m_bases
.swap(m_bases
);
988 ret
->m_methods
.swap(m_methods
);
989 m_constructor
.swap(ret
->m_constructor
);
991 ret
->m_name
= m_name
;
993 #ifndef LUABIND_DONT_COPY_STRINGS
994 std::swap(ret
->m_strings
, m_strings
);
997 m_children
.swap(ret
->m_children
);
1013 // registers a class in the lua environment
1014 template<class T
, class X1
, class X2
, class X3
>
1015 struct class_
: class_base
1017 typedef class_
<T
, X1
, X2
, X3
> self_t
;
1023 template<class A
, class B
, class C
, class D
>
1024 class_(const class_
<A
,B
,C
,D
>&);
1028 // WrappedType MUST inherit from T
1029 typedef typename
detail::extract_parameter
<
1030 boost::mpl::vector3
<X1
,X2
,X3
>
1031 , boost::is_base_and_derived
<T
, boost::mpl::_
>
1032 /* , boost::mpl::not_<
1034 detail::is_bases<boost::mpl::_>
1035 , boost::is_base_and_derived<boost::mpl::_, T>
1039 >::type WrappedType
;
1041 typedef typename
detail::extract_parameter
<
1042 boost::mpl::list3
<X1
,X2
,X3
>
1046 detail::is_bases
<boost::mpl::_
>
1047 , boost::is_base_and_derived
<boost::mpl::_
, T
>
1049 , boost::is_base_and_derived
<T
, boost::mpl::_
>
1055 // this function generates conversion information
1056 // in the given class_rep structure. It will be able
1057 // to implicitly cast to the given template type
1059 void gen_base_info(detail::type
<To
>)
1061 // fist, make sure the given base class is registered.
1062 // if it's not registered we can't push it's lua table onto
1063 // the stack because it doesn't have a table
1065 // try to cast this type to the base type and remember
1066 // the pointer offset. For multiple inheritance the pointer
1067 // may change when casting. Since we need to be able to
1068 // cast we need this pointer offset.
1069 // store the information in this class' base class-vector
1071 base
.type
= LUABIND_TYPEID(To
);
1072 base
.ptr_offset
= detail::ptr_offset(detail::type
<T
>(), detail::type
<To
>());
1076 void gen_base_info(detail::type
<detail::null_type
>)
1079 #define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type<B##n>());
1081 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES
, class B
)>
1082 void generate_baseclass_list(detail::type
<bases
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES
, B
)> >)
1084 BOOST_PP_REPEAT(LUABIND_MAX_BASES
, LUABIND_GEN_BASE_INFO
, _
)
1087 #undef LUABIND_GEN_BASE_INFO
1089 // this is the internal version of def() it is run from both overloads
1090 // of def. It has two versions, one where a contstructor is registered
1091 // and one where a function is registered
1092 template<class Policies
>
1093 struct internal_def_s
1096 static void apply(const char* name
, F f
, class_base
* c
)
1098 // std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";
1100 detail::overload_rep
o(f
, static_cast<Policies
*>(0));
1102 typedef LUABIND_MSVC_TYPENAME
detail::function_callback_s
<HeldType
,T
,F
,Policies
>::type call_t
;
1104 o
.set_match_fun(&detail::match_function_callback_s
<T
,F
,Policies
>::apply
);
1105 o
.call_fun
= boost::bind
<int>(call_t(f
), _1
, _2
);
1107 #ifndef LUABIND_NO_ERROR_CHECKING
1109 o
.set_sig_fun(&detail::get_member_signature
<F
>::apply
);
1113 c
->add_method(name
, o
);
1116 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, class A
)>
1117 static void apply(constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)>, class_base
* c
)
1119 // std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";
1121 detail::construct_rep::overload_t o
;
1124 &detail::construct_class
<
1127 ,constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)>
1131 // if we have a WrappedType, we have to register it's constructor
1132 // but if it's null_type (no WrappedType) we should not register it
1133 detail::register_wrapped_type
<WrappedType
>::apply(o
,
1134 static_cast<const constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)>*>(0),
1135 static_cast<const Policies
*>(0));
1139 &detail::constructor_match
<
1140 constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)>
1145 #ifndef LUABIND_NO_ERROR_CHECKING
1147 o
.set_sig_fun(&detail::get_signature
<constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> >::apply
);
1151 typedef constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> con_t
;
1153 o
.set_arity(detail::calc_arity
<con_t::arity
>::apply(con_t(), static_cast<Policies
*>(0)));
1155 c
->add_constructor(o
);
1159 class_(lua_State
* L
, const char* name
): class_base(name
), m_L(L
) { init(); }
1160 class_(const char* name
): class_base(name
), m_L(0) { init(); }
1167 lua_pushvalue(m_L
, LUA_GLOBALSINDEX
);
1168 scope_stack::push(m_L
);
1170 scope_stack::pop(m_L
);
1175 class_
& def(const char* name
, F f
)
1177 internal_def_s
<detail::null_type
>::apply(name
, f
, this);
1181 template<class F
, class Policies
>
1182 class_
& def(const char* name
, F f
, const Policies
&)
1184 internal_def_s
<Policies
>::apply(name
, f
, this);
1188 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, class A
)>
1189 class_
& def(constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> sig
)
1191 internal_def_s
<detail::null_type
>::apply(sig
, this);
1195 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, class A
), class Policies
>
1196 class_
& def(constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> sig
, const Policies
& policies
)
1198 internal_def_s
<Policies
>::apply(sig
, this);
1202 template<class Getter
>
1203 class_
& property(const char* name
, Getter g
)
1205 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
, Getter
, detail::null_type
>(), _1
, _2
, g
));
1209 template<class Getter
, class MaybeSetter
>
1210 class_
& property(const char* name
, Getter g
, MaybeSetter s
)
1212 return property_impl(name
, g
, s
, boost::mpl::bool_
<detail::is_policy_cons
<MaybeSetter
>::value
>());
1215 template<class Getter
, class Setter
, class GetPolicies
>
1216 class_
& property(const char* name
, Getter g
, Setter s
, const GetPolicies
& get_policies
)
1218 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
, Getter
, GetPolicies
>(get_policies
), _1
, _2
, g
));
1219 add_setter(name
, boost::bind
<int>(detail::set_caller
<T
, Setter
, detail::null_type
>(), _1
, _2
, s
));
1223 template<class Getter
, class Setter
, class GetPolicies
, class SetPolicies
>
1224 class_
& property(const char* name
1225 , Getter g
, Setter s
1226 , const GetPolicies
& get_policies
1227 , const SetPolicies
& set_policies
)
1229 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
, Getter
, GetPolicies
>(get_policies
), _1
, _2
, g
));
1230 add_setter(name
, boost::bind
<int>(detail::set_caller
<T
, Setter
, GetPolicies
>(set_policies
), _1
, _2
, s
));
1235 class_
& def_readonly(const char* name
, D
T::*member_ptr
)
1237 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
1241 template<class D
, class Policies
>
1242 class_
& def_readonly(const char* name
, D
T::*member_ptr
, const Policies
& policies
)
1244 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,Policies
>(policies
), _1
, _2
, member_ptr
));
1249 class_
& def_readwrite(const char* name
, D
T::*member_ptr
)
1251 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
1252 add_setter(name
, boost::bind
<int>(detail::auto_set
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
1256 template<class D
, class GetPolicies
>
1257 class_
& def_readwrite(const char* name
, D
T::*member_ptr
, const GetPolicies
& get_policies
)
1259 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,GetPolicies
>(get_policies
), _1
, _2
, member_ptr
));
1260 add_setter(name
, boost::bind
<int>(detail::auto_set
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
1264 template<class D
, class GetPolicies
, class SetPolicies
>
1265 class_
& def_readwrite(const char* name
, D
T::*member_ptr
, const GetPolicies
& get_policies
, const SetPolicies
& set_policies
)
1267 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,GetPolicies
>(get_policies
), _1
, _2
, member_ptr
));
1268 add_setter(name
, boost::bind
<int>(detail::auto_set
<T
,D
,SetPolicies
>(set_policies
), _1
, _2
, member_ptr
));
1272 template<class op_id
, class Left
, class Right
, class Policies
>
1273 class_
& def(detail::operator_
<op_id
, Left
, Right
>, const Policies
& policies
)
1275 typedef typename
detail::operator_unwrapper
<Policies
, op_id
, T
, Left
, Right
> op_type
;
1276 #ifndef LUABIND_NO_ERROR_CHECKING
1277 add_operator(op_type::get_id()
1280 , &detail::get_signature
<constructor
<typename
op_type::left_t
, typename
op_type::right_t
> >::apply
1281 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1283 add_operator(op_type::get_id()
1286 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1291 template<class op_id
, class Left
, class Right
>
1292 class_
& def(detail::operator_
<op_id
, Left
, Right
>)
1294 typedef typename
detail::operator_unwrapper
<detail::null_type
, op_id
, T
, Left
, Right
> op_type
;
1296 #ifndef LUABIND_NO_ERROR_CHECKING
1297 add_operator(op_type::get_id()
1300 , &detail::get_signature
<constructor
<LUABIND_MSVC_TYPENAME
op_type::left_t
, LUABIND_MSVC_TYPENAME
op_type::right_t
> >::apply
1301 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1303 add_operator(op_type::get_id()
1306 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1311 template<class Signature
, bool Constant
>
1312 class_
& def(detail::application_operator
<Signature
, Constant
>*)
1314 typedef detail::application_operator
<Signature
, Constant
, detail::null_type
> op_t
;
1316 int arity
= detail::calc_arity
<Signature::arity
>::apply(Signature(), static_cast<detail::null_type
*>(0));
1318 #ifndef LUABIND_NO_ERROR_CHECKING
1319 add_operator(detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, &detail::get_signature
<Signature
>::apply
, arity
+ 1);
1321 add_operator(detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, arity
+ 1);
1327 template<class Signature
, bool Constant
, class Policies
>
1328 class_
& def(detail::application_operator
<Signature
, Constant
>*, const Policies
& policies
)
1330 typedef detail::application_operator
<Signature
, Constant
, Policies
> op_t
;
1332 int arity
= detail::calc_arity
<Signature::arity
>::apply(Signature(), static_cast<Policies
*>(0));
1334 #ifndef LUABIND_NO_ERROR_CHECKING
1335 add_operator(detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, &detail::get_signature
<Signature
>::apply
, arity
+ 1);
1337 add_operator(detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, arity
+ 1);
1343 detail::enum_maker
<self_t
> enum_(const char*)
1345 return detail::enum_maker
<self_t
>(*this);
1348 class_
& operator[](const detail::scoped_object
& x
)
1350 detail::scoped_object
* ptr
= &const_cast<detail::scoped_object
&>(x
);
1351 m_children
.push_back(ptr
->clone());
1359 typedef typename
detail::extract_parameter
<
1360 boost::mpl::list3
<X1
,X2
,X3
>
1362 detail::is_bases
<boost::mpl::_
>
1363 , boost::is_base_and_derived
<boost::mpl::_
, T
>
1369 boost::mpl::if_
<detail::is_bases
<bases_t
>
1376 class_base::init(LUABIND_TYPEID(T
)
1377 , detail::internal_holder_type
<HeldType
>::apply()
1378 , detail::internal_holder_extractor
<HeldType
>::apply(detail::type
<T
>())
1379 , detail::internal_const_holder_extractor
<HeldType
>::apply(detail::type
<T
>())
1380 , detail::const_converter
<HeldType
>::apply(luabind::get_const_holder(crap
))
1381 , detail::holder_constructor
<HeldType
>::apply(detail::type
<T
>())
1382 , detail::const_holder_constructor
<HeldType
>::apply(detail::type
<T
>())
1383 , detail::internal_holder_destructor
<HeldType
>::apply(detail::type
<T
>())
1384 , detail::internal_const_holder_destructor
<HeldType
>::apply(detail::type
<T
>())
1385 , detail::internal_holder_size
<HeldType
>::apply()
1386 , detail::get_holder_alignment
<HeldType
>::apply());
1388 set_const_holder_type(luabind::get_const_holder(static_cast<HeldType
*>(0)));
1390 generate_baseclass_list(detail::type
<Base
>());
1393 template<class Getter
, class GetPolicies
>
1394 class_
& property_impl(const char* name
,
1396 GetPolicies policies
,
1397 boost::mpl::bool_
<true>)
1399 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
,Getter
,GetPolicies
>(policies
), _1
, _2
, g
));
1403 template<class Getter
, class Setter
>
1404 class_
& property_impl(const char* name
,
1407 boost::mpl::bool_
<false>)
1409 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
,Getter
,detail::null_type
>(), _1
, _2
, g
));
1410 add_setter(name
, boost::bind
<int>(detail::set_caller
<T
,Setter
,detail::null_type
>(), _1
, _2
, s
));
1417 #endif // LUABIND_CLASS_HPP_INCLUDED