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
);
216 T
* ptr
= static_cast<T
*>(luabind::get_pointer(held_obj
));
218 return call(f
, ptr
, L
, static_cast<Policies
*>(this));
223 template<class T
, class F
, class Policies
>
224 struct function_callback_null_type
: Policies
226 function_callback_null_type(F f_
): f(f_
) {}
227 inline int operator()(lua_State
* L
, void* obj_ptr
)
229 // std::cout << "HeldType: null_type\n";
230 T
* ptr
= static_cast<T
*>(obj_ptr
);
231 return call(f
, ptr
, L
, static_cast<Policies
*>(this));
236 template<class HeldType
, class T
, class F
, class Policies
>
237 struct function_callback_s
240 boost::mpl::if_
<boost::is_same
<HeldType
,detail::null_type
>
241 , function_callback_null_type
<T
,F
,Policies
>
242 , function_callback_non_null
<HeldType
,T
,F
,Policies
>
246 template<class T
, class F
, class Policies
>
247 struct match_function_callback_s
249 static inline int apply(lua_State
* L
)
251 object_rep
* obj
= static_cast<object_rep
*>(lua_touserdata(L
, 1));
253 return match(fptr
, L
, obj
->flags() & object_rep::constant
, static_cast<Policies
*>(0));
257 // prints the types of the values on the stack, in the
258 // range [start_index, lua_gettop()]
260 LUABIND_API
std::string
stack_content_by_name(lua_State
* L
, int start_index
);
262 struct LUABIND_API create_class
264 static int stage1(lua_State
* L
);
265 static int stage2(lua_State
* L
);
269 struct register_wrapped_type
271 template<class Signature
, class Policies
>
272 static void apply(detail::construct_rep::overload_t
& o
, const Signature
*, const Policies
*)
274 o
.set_wrapped_constructor(
275 &detail::construct_wrapped_class
<Type
, Policies
, Signature
>::apply
281 struct register_wrapped_type
<detail::null_type
>
283 template<class Signature
, class Policies
>
284 static void apply(detail::construct_rep::overload_t
&, const Signature
*, const Policies
*) {}
288 // if the class is held by a smart pointer, we need to be able to
289 // implicitly dereference the pointer when needed.
291 template<class UnderlyingT
, class HeldT
>
292 struct extract_underlying_type
294 static void* extract(void* ptr
)
296 HeldT
& held_obj
= *reinterpret_cast<HeldT
*>(ptr
);
297 UnderlyingT
* underlying_ptr
= static_cast<UnderlyingT
*>(get_pointer(held_obj
));
298 return underlying_ptr
;
302 template<class UnderlyingT
, class HeldT
>
303 struct extract_underlying_const_type
305 static const void* extract(void* ptr
)
307 HeldT
& held_obj
= *reinterpret_cast<HeldT
*>(ptr
);
308 const UnderlyingT
* underlying_ptr
= static_cast<const UnderlyingT
*>(get_pointer(held_obj
));
309 return underlying_ptr
;
313 template<class HeldType
>
314 struct internal_holder_extractor
316 typedef void*(*extractor_fun
)(void*);
319 static extractor_fun
apply(detail::type
<T
>)
321 return &detail::extract_underlying_type
<T
, HeldType
>::extract
;
326 struct internal_holder_extractor
<detail::null_type
>
328 typedef void*(*extractor_fun
)(void*);
331 static extractor_fun
apply(detail::type
<T
>)
338 template<class HeldType
, class ConstHolderType
>
339 struct convert_holder
341 static void apply(void* holder
, void* target
)
343 new(target
) ConstHolderType(*reinterpret_cast<HeldType
*>(holder
));
348 template<class HeldType
>
349 struct const_converter
351 typedef void(*converter_fun
)(void*, void*);
353 template<class ConstHolderType
>
354 static converter_fun
apply(ConstHolderType
*)
356 return &detail::convert_holder
<HeldType
, ConstHolderType
>::apply
;
361 struct const_converter
<detail::null_type
>
363 typedef void(*converter_fun
)(void*, void*);
366 static converter_fun
apply(T
*)
375 template<class HeldType
>
376 struct internal_const_holder_extractor
378 typedef const void*(*extractor_fun
)(void*);
381 static extractor_fun
apply(detail::type
<T
>)
383 return get_extractor(detail::type
<T
>(), luabind::get_const_holder(static_cast<HeldType
*>(0)));
386 template<class T
, class ConstHolderType
>
387 static extractor_fun
get_extractor(detail::type
<T
>, ConstHolderType
*)
389 return &detail::extract_underlying_const_type
<T
, ConstHolderType
>::extract
;
394 struct internal_const_holder_extractor
<detail::null_type
>
396 typedef const void*(*extractor_fun
)(void*);
399 static extractor_fun
apply(detail::type
<T
>)
407 // this is simply a selector that returns the type_info
408 // of the held type, or invalid_type_info if we don't have
410 template<class HeldType
>
411 struct internal_holder_type
413 static LUABIND_TYPE_INFO
apply()
415 return LUABIND_TYPEID(HeldType
);
420 struct internal_holder_type
<detail::null_type
>
422 static LUABIND_TYPE_INFO
apply()
424 return LUABIND_INVALID_TYPE_INFO
;
429 // this is the actual held_type constructor
430 template<class HeldType
, class T
>
431 struct internal_construct_holder
433 static void apply(void* target
, void* raw_pointer
)
435 new(target
) HeldType(static_cast<T
*>(raw_pointer
));
439 // the following two functions are the ones that returns
440 // a pointer to a held_type_constructor, or 0 if there
442 template<class HeldType
>
443 struct holder_constructor
445 typedef void(*constructor
)(void*,void*);
447 static constructor
apply(detail::type
<T
>)
449 return &internal_construct_holder
<HeldType
, T
>::apply
;
454 struct holder_constructor
<detail::null_type
>
456 typedef void(*constructor
)(void*,void*);
458 static constructor
apply(detail::type
<T
>)
464 // the following two functions are the ones that returns
465 // a pointer to a const_held_type_constructor, or 0 if there
467 template<class HolderType
>
468 struct const_holder_constructor
470 typedef void(*constructor
)(void*,void*);
472 static constructor
apply(detail::type
<T
>)
474 return get_const_holder_constructor(detail::type
<T
>(), luabind::get_const_holder(static_cast<HolderType
*>(0)));
479 template<class T
, class ConstHolderType
>
480 static constructor
get_const_holder_constructor(detail::type
<T
>, ConstHolderType
*)
482 return &internal_construct_holder
<ConstHolderType
, T
>::apply
;
487 struct const_holder_constructor
<detail::null_type
>
489 typedef void(*constructor
)(void*,void*);
491 static constructor
apply(detail::type
<T
>)
499 // this is a selector that returns the size of the held_type
500 // or 0 if we don't have a held_type
501 template <class HolderType
>
502 struct internal_holder_size
504 static int apply() { return get_internal_holder_size(luabind::get_const_holder(static_cast<HolderType
*>(0))); }
506 template<class ConstHolderType
>
507 static int get_internal_holder_size(ConstHolderType
*)
509 return max
<sizeof(HolderType
), sizeof(ConstHolderType
)>::value
;
514 struct internal_holder_size
<detail::null_type
>
516 static int apply() { return 0; }
520 // if we have a held type, return the destructor to it
521 // note the difference. The held_type should only be destructed (not deleted)
522 // since it's constructed in the lua userdata
523 template<class HeldType
>
524 struct internal_holder_destructor
526 typedef void(*destructor_t
)(void*);
528 static destructor_t
apply(detail::type
<T
>)
530 return &detail::destruct_only_s
<HeldType
>::apply
;
534 // if we don't have a held type, return the destructor of the raw type
536 struct internal_holder_destructor
<detail::null_type
>
538 typedef void(*destructor_t
)(void*);
540 static destructor_t
apply(detail::type
<T
>)
542 return &detail::delete_s
<T
>::apply
;
547 // if we have a held type, return the destructor to it's const version
548 template<class HolderType
>
549 struct internal_const_holder_destructor
551 typedef void(*destructor_t
)(void*);
553 static destructor_t
apply(detail::type
<T
>)
555 return const_holder_type_destructor(luabind::get_const_holder(static_cast<HolderType
*>(0)));
560 template<class ConstHolderType
>
561 static destructor_t
const_holder_type_destructor(ConstHolderType
*)
563 return &detail::destruct_only_s
<ConstHolderType
>::apply
;
568 // if we don't have a held type, return the destructor of the raw type
570 struct internal_const_holder_destructor
<detail::null_type
>
572 typedef void(*destructor_t
)(void*);
574 static destructor_t
apply(detail::type
<T
>)
583 template<class HolderType
>
584 struct get_holder_alignment
588 return internal_alignment(luabind::get_const_holder(static_cast<HolderType
*>(0)));
593 template<class ConstHolderType
>
594 static int internal_alignment(ConstHolderType
*)
596 return detail::max
<boost::alignment_of
<HolderType
>::value
597 , boost::alignment_of
<ConstHolderType
>::value
>::value
;
602 struct get_holder_alignment
<detail::null_type
>
626 struct class_base
: detail::scoped_object
632 LUABIND_TYPE_INFO type
;
644 std::map
<const char*, detail::method_rep
, detail::ltstr
> m_methods
;
646 // datamembers, some members may be readonly, and
647 // only have a getter function
648 std::map
<const char*, detail::class_rep::callback
, detail::ltstr
> m_getters
;
649 std::map
<const char*, detail::class_rep::callback
, detail::ltstr
> m_setters
;
651 // the operators in lua
652 std::vector
<detail::class_rep::operator_callback
> m_operators
[detail::number_of_operators
];
653 std::map
<const char*, int, detail::ltstr
> m_static_constants
;
655 std::vector
<base_desc
> m_bases
;
656 detail::construct_rep m_constructor
;
658 void(*m_destructor
)(void*);
659 void(*m_const_holder_destructor
)(void*);
661 void*(*m_extractor
)(void*);
662 const void*(*m_const_extractor
)(void*);
664 void(*m_const_converter
)(void*,void*);
666 void(*m_construct_holder
)(void*, void*);
667 void(*m_construct_const_holder
)(void*, void*);
670 int m_holder_alignment
;
672 LUABIND_TYPE_INFO m_type
;
673 LUABIND_TYPE_INFO m_holder_type
;
674 LUABIND_TYPE_INFO m_const_holder_type
;
676 #ifndef LUABIND_DONT_COPY_STRINGS
677 // the maps that contains char pointers points into
678 // this vector of strings.
679 std::vector
<char*> m_strings
;
684 // public 'cause of enum_maker, FIX
685 void add_static_constant(const char* name
, int val
)
687 m_static_constants
[name
] = val
;
692 void init(LUABIND_TYPE_INFO type
693 , LUABIND_TYPE_INFO holder_type
694 , void*(*extractor
)(void*)
695 , const void*(*const_extractor
)(void*)
696 , void(*const_converter
)(void*,void*)
697 , void(*holder_constructor
)(void*,void*)
698 , void(*const_holder_constructor
)(void*,void*)
699 , void(*destructor
)(void*)
700 , void(*const_holder_destructor
)(void*)
702 , int holder_alignment
)
705 m_holder_type
= holder_type
;
706 m_extractor
= extractor
;
707 m_const_extractor
= const_extractor
;
708 m_const_converter
= const_converter
;
709 m_construct_holder
= holder_constructor
;
710 m_construct_const_holder
= const_holder_constructor
;
711 m_destructor
= destructor
;
712 m_const_holder_destructor
= const_holder_destructor
;
713 m_holder_size
= holder_size
;
714 m_holder_alignment
= holder_alignment
;
718 void set_const_holder_type(T
*)
720 m_const_holder_type
= LUABIND_TYPEID(T
);
723 inline void add_getter(const char* name
, const boost::function2
<int, lua_State
*, int>& g
)
725 detail::class_rep::callback c
;
727 c
.pointer_offset
= 0;
728 #ifndef LUABIND_DONT_COPY_STRINGS
729 m_strings
.push_back(detail::dup_string(name
));
730 m_getters
[m_strings
.back()] = c
;
736 inline void add_setter(const char* name
, const boost::function2
<int, lua_State
*, int>& s
)
738 detail::class_rep::callback c
;
740 c
.pointer_offset
= 0;
741 #ifndef LUABIND_DONT_COPY_STRINGS
742 m_strings
.push_back(detail::dup_string(name
));
743 m_setters
[m_strings
.back()] = c
;
749 void add_base(const base_desc
& b
)
751 m_bases
.push_back(b
);
756 void add_constructor(const detail::construct_rep::overload_t
& o
)
758 m_constructor
.overloads
.push_back(o
);
761 void add_method(const char* name
, const detail::overload_rep
& o
)
763 #ifdef LUABIND_DONT_COPY_STRINGS
764 detail::method_rep
& method
= m_methods
[name
];
767 m_strings
.push_back(detail::dup_string(name
));
768 detail::method_rep
& method
= m_methods
[m_strings
.back()];
769 method
.name
= m_strings
.back();
771 method
.add_overload(o
);
775 #ifndef LUABIND_NO_ERROR_CHECKING
776 inline void add_operator(int op_id
, int(*func
)(lua_State
*), int(*matcher
)(lua_State
*), void(*sig
)(lua_State
*, std::string
&), int arity
)
778 inline void add_operator(int op_id
, int(*func
)(lua_State
*), int(*matcher
)(lua_State
*), int arity
)
781 detail::class_rep::operator_callback o
;
783 o
.set_match_fun(matcher
);
786 #ifndef LUABIND_NO_ERROR_CHECKING
791 m_operators
[op_id
].push_back(o
);
800 const char* name() const { return m_name
; }
802 class_base(const char* name
)
804 #ifndef LUABIND_DONT_COPY_STRINGS
805 m_strings
.push_back(detail::dup_string(name
));
806 m_name
= m_strings
.back();
816 virtual ~class_base()
818 // if we are copying strings, we have to destroy them too
819 #ifndef LUABIND_DONT_COPY_STRINGS
820 for (std::vector
<char*>::iterator i
= m_strings
.begin(); i
!= m_strings
.end(); ++i
)
825 // pushes the class_rep on the lua stack
826 virtual void commit(lua_State
* L
)
828 assert(!m_cloned
&& "class already commited");
830 detail::getref(L
, scope_stack::top(L
));
831 lua_pushstring(L
, m_name
);
833 detail::class_rep
* crep
;
835 detail::class_registry
* r
= detail::class_registry::get_registry(L
);
836 // create a class_rep structure for this class.
837 // allocate it within lua to let lua collect it on
838 // lua_close(). This is better than allocating it
839 // as a static, since it will then be destructed
840 // when the program exits instead.
841 // warning: we assume that lua will not
842 // move the userdata memory.
843 lua_newuserdata(L
, sizeof(detail::class_rep
));
844 crep
= reinterpret_cast<detail::class_rep
*>(lua_touserdata(L
, -1));
846 new(crep
) detail::class_rep( m_type
850 , m_const_holder_destructor
852 , m_const_holder_type
857 , m_construct_const_holder
859 , m_holder_alignment
);
861 // register this new type in the class registry
862 r
->add_class(m_type
, crep
);
863 if (!(LUABIND_TYPE_INFO_EQUAL(m_holder_type
, LUABIND_INVALID_TYPE_INFO
)))
865 // if we have a held type
866 // we have to register it in the class-table
867 // but only for the base class, if it already
868 // exists, we don't have to register it
869 detail::class_rep
* c
= r
->find_class(m_holder_type
);
872 r
->add_class(m_holder_type
, crep
);
873 r
->add_class(m_const_holder_type
, crep
);
878 for (std::map
<const char*, detail::method_rep
, detail::ltstr
>::iterator i
= m_methods
.begin();
879 i
!= m_methods
.end();
882 i
->second
.crep
= crep
;
884 std::swap(crep
->m_methods
, m_methods
);
887 m_constructor
.swap(crep
->m_constructor
);
889 #ifndef LUABIND_DONT_COPY_STRINGS
890 assert(crep
->m_strings
.empty() && "Internal error");
891 std::swap(crep
->m_strings
, m_strings
);
894 std::swap(crep
->m_getters
, m_getters
);
895 std::swap(crep
->m_setters
, m_setters
);
897 for(int i
= 0; i
< detail::number_of_operators
; ++i
)
898 std::swap(crep
->m_operators
[i
], m_operators
[i
]);
900 std::swap(crep
->m_static_constants
, m_static_constants
);
902 for (std::vector
<base_desc
>::iterator i
= m_bases
.begin();
906 detail::class_registry
* r
= detail::class_registry::get_registry(L
);
908 // the baseclass' class_rep structure
909 detail::class_rep
* bcrep
= r
->find_class(i
->type
);
911 detail::class_rep::base_info base
;
912 base
.pointer_offset
= i
->ptr_offset
;
915 crep
->add_base_class(base
);
924 virtual luabind::detail::scoped_object
* clone()
926 assert(m_cloned
== false);
932 class_base
* ret
= new class_base(m_name
);
934 std::swap(ret
->m_getters
, m_getters
);
935 std::swap(ret
->m_setters
, m_setters
);
937 for(int i
= 0; i
< detail::number_of_operators
; ++i
)
938 std::swap(ret
->m_operators
[i
], m_operators
[i
]);
940 std::swap(ret
->m_static_constants
, m_static_constants
);
948 , m_construct_const_holder
950 , m_const_holder_destructor
952 , m_holder_alignment
);
954 ret
->m_const_holder_type
= m_const_holder_type
;
956 std::swap(ret
->m_bases
, m_bases
);
957 std::swap(ret
->m_methods
, m_methods
);
958 m_constructor
.swap(ret
->m_constructor
);
960 ret
->m_name
= m_name
;
962 #ifndef LUABIND_DONT_COPY_STRINGS
963 std::swap(ret
->m_strings
, m_strings
);
981 // registers a class in the lua environment
982 template<class T
, class X1
, class X2
, class X3
>
983 struct class_
: class_base
985 typedef class_
<T
, X1
, X2
, X3
> self_t
;
991 template<class A
, class B
, class C
, class D
>
992 class_(const class_
<A
,B
,C
,D
>&);
996 // WrappedType MUST inherit from T
997 typedef typename
detail::extract_parameter
<
998 boost::mpl::vector3
<X1
,X2
,X3
>
999 , boost::is_base_and_derived
<T
, boost::mpl::_
>
1000 /* , boost::mpl::not_<
1002 detail::is_bases<boost::mpl::_>
1003 , boost::is_base_and_derived<boost::mpl::_, T>
1007 >::type WrappedType
;
1009 typedef typename
detail::extract_parameter
<
1010 boost::mpl::list3
<X1
,X2
,X3
>
1014 detail::is_bases
<boost::mpl::_
>
1015 , boost::is_base_and_derived
<boost::mpl::_
, T
>
1017 , boost::is_base_and_derived
<T
, boost::mpl::_
>
1023 // this function generates conversion information
1024 // in the given class_rep structure. It will be able
1025 // to implicitly cast to the given template type
1027 void gen_base_info(detail::type
<To
>)
1029 // fist, make sure the given base class is registered.
1030 // if it's not registered we can't push it's lua table onto
1031 // the stack because it doesn't have a table
1033 // try to cast this type to the base type and remember
1034 // the pointer offset. For multiple inheritance the pointer
1035 // may change when casting. Since we need to be able to
1036 // cast we need this pointer offset.
1037 // store the information in this class' base class-vector
1039 base
.type
= LUABIND_TYPEID(To
);
1040 base
.ptr_offset
= detail::ptr_offset(detail::type
<T
>(), detail::type
<To
>());
1044 void gen_base_info(detail::type
<detail::null_type
>)
1047 #define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type<B##n>());
1049 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES
, class B
)>
1050 void generate_baseclass_list(detail::type
<bases
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES
, B
)> >)
1052 BOOST_PP_REPEAT(LUABIND_MAX_BASES
, LUABIND_GEN_BASE_INFO
, _
)
1055 #undef LUABIND_GEN_BASE_INFO
1057 // this is the internal version of def() it is run from both overloads
1058 // of def. It has two versions, one where a contstructor is registered
1059 // and one where a function is registered
1060 template<class Policies
>
1061 struct internal_def_s
1064 static void apply(const char* name
, F f
, class_base
* c
)
1066 // std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";
1068 detail::overload_rep
o(f
, static_cast<Policies
*>(0));
1070 typedef LUABIND_MSVC_TYPENAME
detail::function_callback_s
<HeldType
,T
,F
,Policies
>::type call_t
;
1072 o
.set_match_fun(&detail::match_function_callback_s
<T
,F
,Policies
>::apply
);
1073 o
.call_fun
= boost::bind
<int>(call_t(f
), _1
, _2
);
1075 #ifndef LUABIND_NO_ERROR_CHECKING
1077 o
.set_sig_fun(&detail::get_member_signature
<F
>::apply
);
1081 c
->add_method(name
, o
);
1084 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, class A
)>
1085 static void apply(constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)>, class_base
* c
)
1087 // std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";
1089 detail::construct_rep::overload_t o
;
1092 &detail::construct_class
<
1095 ,constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)>
1099 // if we have a WrappedType, we have to register it's constructor
1100 // but if it's null_type (no WrappedType) we should not register it
1101 detail::register_wrapped_type
<WrappedType
>::apply(o
,
1102 static_cast<const constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)>*>(0),
1103 static_cast<const Policies
*>(0));
1107 &detail::constructor_match
<
1108 constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)>
1113 #ifndef LUABIND_NO_ERROR_CHECKING
1115 o
.set_sig_fun(&detail::get_signature
<constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> >::apply
);
1119 typedef constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> con_t
;
1121 o
.set_arity(detail::calc_arity
<con_t::arity
>::apply(con_t(), static_cast<Policies
*>(0)));
1123 c
->add_constructor(o
);
1127 class_(lua_State
* L
, const char* name
): class_base(name
), m_L(L
) { init(); }
1128 class_(const char* name
): class_base(name
), m_L(0) { init(); }
1135 lua_pushvalue(m_L
, LUA_GLOBALSINDEX
);
1136 scope_stack::push(m_L
);
1138 scope_stack::pop(m_L
);
1143 class_
& def(const char* name
, F f
)
1145 internal_def_s
<detail::null_type
>::apply(name
, f
, this);
1149 template<class F
, class Policies
>
1150 class_
& def(const char* name
, F f
, const Policies
&)
1152 internal_def_s
<Policies
>::apply(name
, f
, this);
1156 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, class A
)>
1157 class_
& def(constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> sig
)
1159 internal_def_s
<detail::null_type
>::apply(sig
, this);
1163 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, class A
), class Policies
>
1164 class_
& def(constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> sig
, const Policies
& policies
)
1166 internal_def_s
<Policies
>::apply(sig
, this);
1170 template<class Getter
>
1171 class_
& property(const char* name
, Getter g
)
1173 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
, Getter
, detail::null_type
>(), _1
, _2
, g
));
1177 template<class Getter
, class MaybeSetter
>
1178 class_
& property(const char* name
, Getter g
, MaybeSetter s
)
1180 return property_impl(name
, g
, s
, boost::mpl::bool_
<detail::is_policy_cons
<MaybeSetter
>::value
>());
1183 template<class Getter
, class Setter
, class GetPolicies
>
1184 class_
& property(const char* name
, Getter g
, Setter s
, const GetPolicies
& get_policies
)
1186 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
, Getter
, GetPolicies
>(get_policies
), _1
, _2
, g
));
1187 add_setter(name
, boost::bind
<int>(detail::set_caller
<T
, Setter
, detail::null_type
>(), _1
, _2
, s
));
1191 template<class Getter
, class Setter
, class GetPolicies
, class SetPolicies
>
1192 class_
& property(const char* name
1193 , Getter g
, Setter s
1194 , const GetPolicies
& get_policies
1195 , const SetPolicies
& set_policies
)
1197 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
, Getter
, GetPolicies
>(get_policies
), _1
, _2
, g
));
1198 add_setter(name
, boost::bind
<int>(detail::set_caller
<T
, Setter
, GetPolicies
>(set_policies
), _1
, _2
, s
));
1203 class_
& def_readonly(const char* name
, D
T::*member_ptr
)
1205 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
1209 template<class D
, class Policies
>
1210 class_
& def_readonly(const char* name
, D
T::*member_ptr
, const Policies
& policies
)
1212 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,Policies
>(policies
), _1
, _2
, member_ptr
));
1217 class_
& def_readwrite(const char* name
, D
T::*member_ptr
)
1219 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
1220 add_setter(name
, boost::bind
<int>(detail::auto_set
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
1224 template<class D
, class GetPolicies
>
1225 class_
& def_readwrite(const char* name
, D
T::*member_ptr
, const GetPolicies
& get_policies
)
1227 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,GetPolicies
>(get_policies
), _1
, _2
, member_ptr
));
1228 add_setter(name
, boost::bind
<int>(detail::auto_set
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
1232 template<class D
, class GetPolicies
, class SetPolicies
>
1233 class_
& def_readwrite(const char* name
, D
T::*member_ptr
, const GetPolicies
& get_policies
, const SetPolicies
& set_policies
)
1235 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,GetPolicies
>(get_policies
), _1
, _2
, member_ptr
));
1236 add_setter(name
, boost::bind
<int>(detail::auto_set
<T
,D
,SetPolicies
>(set_policies
), _1
, _2
, member_ptr
));
1240 template<class op_id
, class Left
, class Right
, class Policies
>
1241 class_
& def(detail::operator_
<op_id
, Left
, Right
>, const Policies
& policies
)
1243 typedef typename
detail::operator_unwrapper
<Policies
, op_id
, T
, Left
, Right
> op_type
;
1244 #ifndef LUABIND_NO_ERROR_CHECKING
1245 add_operator(op_type::get_id()
1248 , &detail::get_signature
<constructor
<typename
op_type::left_t
, typename
op_type::right_t
> >::apply
1249 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1251 add_operator(op_type::get_id()
1254 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1259 template<class op_id
, class Left
, class Right
>
1260 class_
& def(detail::operator_
<op_id
, Left
, Right
>)
1262 typedef typename
detail::operator_unwrapper
<detail::null_type
, op_id
, T
, Left
, Right
> op_type
;
1264 #ifndef LUABIND_NO_ERROR_CHECKING
1265 add_operator(op_type::get_id()
1268 , &detail::get_signature
<constructor
<LUABIND_MSVC_TYPENAME
op_type::left_t
, LUABIND_MSVC_TYPENAME
op_type::right_t
> >::apply
1269 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1271 add_operator(op_type::get_id()
1274 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1279 template<class Signature
, bool Constant
>
1280 class_
& def(detail::application_operator
<Signature
, Constant
>*)
1282 typedef detail::application_operator
<Signature
, Constant
, detail::null_type
> op_t
;
1284 int arity
= detail::calc_arity
<Signature::arity
>::apply(Signature(), static_cast<detail::null_type
*>(0));
1286 #ifndef LUABIND_NO_ERROR_CHECKING
1287 add_operator(detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, &detail::get_signature
<Signature
>::apply
, arity
+ 1);
1289 add_operator(detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, arity
+ 1);
1295 template<class Signature
, bool Constant
, class Policies
>
1296 class_
& def(detail::application_operator
<Signature
, Constant
>*, const Policies
& policies
)
1298 typedef detail::application_operator
<Signature
, Constant
, Policies
> op_t
;
1300 int arity
= detail::calc_arity
<Signature::arity
>::apply(Signature(), static_cast<Policies
*>(0));
1302 #ifndef LUABIND_NO_ERROR_CHECKING
1303 add_operator(detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, &detail::get_signature
<Signature
>::apply
, arity
+ 1);
1305 add_operator(detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, arity
+ 1);
1311 detail::enum_maker
<self_t
> enum_(const char*)
1313 return detail::enum_maker
<self_t
>(*this);
1320 typedef typename
detail::extract_parameter
<
1321 boost::mpl::list3
<X1
,X2
,X3
>
1323 detail::is_bases
<boost::mpl::_
>
1324 , boost::is_base_and_derived
<boost::mpl::_
, T
>
1330 boost::mpl::if_
<detail::is_bases
<bases_t
>
1337 class_base::init(LUABIND_TYPEID(T
)
1338 , detail::internal_holder_type
<HeldType
>::apply()
1339 , detail::internal_holder_extractor
<HeldType
>::apply(detail::type
<T
>())
1340 , detail::internal_const_holder_extractor
<HeldType
>::apply(detail::type
<T
>())
1341 , detail::const_converter
<HeldType
>::apply(luabind::get_const_holder(crap
))
1342 , detail::holder_constructor
<HeldType
>::apply(detail::type
<T
>())
1343 , detail::const_holder_constructor
<HeldType
>::apply(detail::type
<T
>())
1344 , detail::internal_holder_destructor
<HeldType
>::apply(detail::type
<T
>())
1345 , detail::internal_const_holder_destructor
<HeldType
>::apply(detail::type
<T
>())
1346 , detail::internal_holder_size
<HeldType
>::apply()
1347 , detail::get_holder_alignment
<HeldType
>::apply());
1349 set_const_holder_type(luabind::get_const_holder(static_cast<HeldType
*>(0)));
1351 generate_baseclass_list(detail::type
<Base
>());
1354 template<class Getter
, class GetPolicies
>
1355 class_
& property_impl(const char* name
,
1357 GetPolicies policies
,
1358 boost::mpl::bool_
<true>)
1360 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
,Getter
,GetPolicies
>(policies
), _1
, _2
, g
));
1364 template<class Getter
, class Setter
>
1365 class_
& property_impl(const char* name
,
1368 boost::mpl::bool_
<false>)
1370 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
,Getter
,detail::null_type
>(), _1
, _2
, g
));
1371 add_setter(name
, boost::bind
<int>(detail::set_caller
<T
,Setter
,detail::null_type
>(), _1
, _2
, s
));
1378 #endif // LUABIND_CLASS_HPP_INCLUDED