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 name.
58 finish smart pointer support
59 * holder_type<const A> should be constructed as it's correct class, not constructed
60 as holder_type<A> and then reinterpret_casted. We will need another constructor
61 function and another extractor function.
62 * the adopt policy should not be able to adopt pointers to held_types. This
64 * name_of_type must recognize holder_types and not return "custom"
66 document the new yield-policy
68 chache operators and finalizers in the class_rep. For lua classes
69 we currently do a lookup each time we need to know if a lua class
70 has a finalizer or an operator.
72 static functions, this could be implemented by letting classes contain
73 other declarations (classes or functions)
75 document custom policies, custom converters
77 store the instance object for policies.
79 support the __concat metamethod. This is a bit tricky, since it cannot be
80 treated as a normal operator. It is a binary operator but we want to use the
81 __tostring implementation for both arguments.
85 #include <luabind/config.hpp>
92 #include <boost/static_assert.hpp>
93 #include <boost/type_traits.hpp>
94 #include <boost/bind.hpp>
95 #include <boost/function.hpp>
96 #include <boost/preprocessor/repetition/enum_params.hpp>
97 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
98 #include <boost/preprocessor/repetition/repeat.hpp>
99 #include <boost/type_traits/is_same.hpp>
100 #include <boost/mpl/list.hpp>
101 #include <boost/mpl/apply.hpp>
102 #include <boost/mpl/lambda.hpp>
103 #include <boost/mpl/logical.hpp>
104 #include <boost/mpl/find_if.hpp>
105 #include <boost/mpl/apply_if.hpp>
106 #include <boost/mpl/logical.hpp>
108 #include <luabind/config.hpp>
109 #include <luabind/scope.hpp>
110 #include <luabind/detail/constructor.hpp>
111 #include <luabind/detail/call.hpp>
112 #include <luabind/detail/signature_match.hpp>
113 #include <luabind/detail/primitives.hpp>
114 #include <luabind/detail/property.hpp>
115 #include <luabind/detail/typetraits.hpp>
116 #include <luabind/detail/class_rep.hpp>
117 #include <luabind/detail/method_rep.hpp>
118 #include <luabind/detail/construct_rep.hpp>
119 #include <luabind/detail/object_rep.hpp>
120 #include <luabind/detail/operators.hpp>
121 #include <luabind/detail/calc_arity.hpp>
122 #include <luabind/detail/call_member.hpp>
123 #include <luabind/detail/enum_maker.hpp>
124 #include <luabind/detail/get_signature.hpp>
125 #include <luabind/detail/implicit_cast.hpp>
126 #include <luabind/detail/operator_id.hpp>
132 struct unspecified
{};
137 template<class T
, class X1
= detail::unspecified
, class X2
= detail::unspecified
, class X3
= detail::unspecified
>
140 inline type
<detail::null_type
> get_const_holder(...)
142 return type
<detail::null_type
>();
147 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES
, class A
)>
148 double is_bases_helper(const bases
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES
, A
)>&);
152 char is_bases_helper(const T
&);
154 char is_bases_helper(...);
162 BOOST_STATIC_CONSTANT(bool, value
= sizeof(is_bases_helper(t
)) == sizeof(double));
163 typedef boost::mpl::bool_
<value
> type
;
164 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_bases
,(T
))
167 double is_not_unspecified_helper(const unspecified
*);
168 char is_not_unspecified_helper(...);
171 struct is_not_unspecified
173 BOOST_STATIC_CONSTANT(bool, value
= sizeof(is_not_unspecified_helper(static_cast<T
*>(0))) == sizeof(char));
174 typedef boost::mpl::bool_
<value
> type
;
175 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_not_unspecified
,(T
))
178 template<class Predicate
>
181 typedef typename
boost::mpl::and_
<
183 , is_not_unspecified
<boost::mpl::_1
>
187 template<class Parameters
, class Predicate
, class DefaultValue
>
188 struct extract_parameter
190 typedef typename get_predicate
<Predicate
>::type pred
;
191 typedef typename
boost::mpl::find_if
<Parameters
, pred
>::type iterator
;
192 typedef typename
boost::mpl::apply_if
<boost::is_same
<iterator
, typename
boost::mpl::end
<Parameters
>::type
>
193 , boost::mpl::identity
<DefaultValue
>
198 int function_dispatcher(lua_State
* L
);
200 // this should know about the smart pointer type.
201 // and should really do:
202 // get_pointer(*static_cast<SmartPointer*>(obj_ptr))
203 // to extract the held pointer.
204 template<class HeldType
, class T
, class F
, class Policies
>
205 struct function_callback_non_null
: Policies
207 function_callback_non_null(F f_
): f(f_
) {}
208 inline int operator()(lua_State
* L
, void* obj_ptr
)
210 HeldType
& held_obj
= *static_cast<HeldType
*>(obj_ptr
);
212 T
* ptr
= static_cast<T
*>(luabind::get_pointer(held_obj
));
214 return call(f
, ptr
, L
, static_cast<Policies
*>(this));
219 template<class T
, class F
, class Policies
>
220 struct function_callback_null_type
: Policies
222 function_callback_null_type(F f_
): f(f_
) {}
223 inline int operator()(lua_State
* L
, void* obj_ptr
)
225 // std::cout << "HeldType: null_type\n";
226 T
* ptr
= static_cast<T
*>(obj_ptr
);
227 return call(f
, ptr
, L
, static_cast<Policies
*>(this));
232 template<class HeldType
, class T
, class F
, class Policies
>
233 struct function_callback_s
236 boost::mpl::if_
<boost::is_same
<HeldType
,detail::null_type
>
237 , function_callback_null_type
<T
,F
,Policies
>
238 , function_callback_non_null
<HeldType
,T
,F
,Policies
>
242 template<class T
, class F
, class Policies
>
243 struct match_function_callback_s
245 static inline int apply(lua_State
* L
)
247 object_rep
* obj
= static_cast<object_rep
*>(lua_touserdata(L
, 1));
249 return match(fptr
, L
, obj
->flags() & object_rep::constant
, static_cast<Policies
*>(0));
253 // prints the types of the values on the stack, in the
254 // range [start_index, lua_gettop()]
256 std::string
stack_content_by_name(lua_State
* L
, int start_index
);
260 static int stage1(lua_State
* L
);
261 static int stage2(lua_State
* L
);
265 struct register_wrapped_type
267 template<class Signature
, class Policies
>
268 static void apply(detail::construct_rep::overload_t
& o
, const Signature
*, const Policies
*)
270 o
.set_wrapped_constructor(
271 &detail::construct_wrapped_class
<Type
, Policies
, Signature
>::apply
277 struct register_wrapped_type
<detail::null_type
>
279 template<class Signature
, class Policies
>
280 static void apply(detail::construct_rep::overload_t
&, const Signature
*, const Policies
*) {}
284 // if the class is held by a smart pointer, we need to be able to
285 // implicitly dereference the pointer when needed.
287 template<class UnderlyingT
, class HeldT
>
288 struct extract_underlying_type
290 static void* extract(void* ptr
)
292 HeldT
& held_obj
= *reinterpret_cast<HeldT
*>(ptr
);
293 UnderlyingT
* underlying_ptr
= static_cast<UnderlyingT
*>(get_pointer(held_obj
));
294 return underlying_ptr
;
299 template<class HeldType
>
300 struct internal_held_type_extractor
302 typedef void*(*extractor_fun
)(void*);
305 static extractor_fun
apply(detail::type
<T
>)
307 return detail::extract_underlying_type
<T
, HeldType
>::extract
;
312 struct internal_held_type_extractor
<detail::null_type
>
314 typedef void*(*extractor_fun
)(void*);
317 static extractor_fun
apply(detail::type
<T
>)
324 // this is simply a selector that returns the type_info
325 // of the held type, or invalid_type_info if we don't have
327 template<class HeldType
>
328 struct internal_held_type
330 static LUABIND_TYPE_INFO
apply()
332 return LUABIND_TYPEID(HeldType
);
337 struct internal_held_type
<detail::null_type
>
339 static LUABIND_TYPE_INFO
apply()
341 return LUABIND_INVALID_TYPE_INFO
;
346 // this is the actual held_type constructor
347 template<class HeldType
, class T
>
348 struct internal_construct_held_type
350 static void apply(void* target
, void* raw_pointer
)
352 new(target
) HeldType(static_cast<T
*>(raw_pointer
));
356 // the followinf two functions are the ones that returns
357 // a pointer to a held_type_constructor, or 0 if there
359 template<class HeldType
>
360 struct internal_held_type_constructor
362 typedef void(*constructor
)(void*,void*);
364 static constructor
apply(detail::type
<T
>)
366 return &internal_construct_held_type
<HeldType
, T
>::apply
;
371 struct internal_held_type_constructor
<detail::null_type
>
373 typedef void(*constructor
)(void*,void*);
375 static constructor
apply(detail::type
<T
>)
382 // this is a selector that returns the size of the held_type
383 // or 0 if we don't have a held_type
384 template <class HeldType
>
385 struct internal_held_type_size
387 static int apply() { return sizeof(HeldType
); }
391 struct internal_held_type_size
<detail::null_type
>
393 static int apply() { return 0; }
397 // if we have a held type, return the destructor to it
398 // note the difference. The held_type should only be destructed (not deleted)
399 // since it's constructed in the lua userdata
400 template<class HeldType
>
401 struct internal_held_type_destructor
403 typedef void(*destructor_t
)(void*);
405 static destructor_t
apply(detail::type
<T
>)
407 return &detail::destruct_only_s
<HeldType
>::apply
;
411 // if we don't have a held type, return the destructor of the raw type
413 struct internal_held_type_destructor
<detail::null_type
>
415 typedef void(*destructor_t
)(void*);
417 static destructor_t
apply(detail::type
<T
>)
419 return &detail::delete_s
<T
>::apply
;
424 struct get_holder_alignment
428 return boost::alignment_of
<T
>::value
;
433 struct get_holder_alignment
<detail::null_type
>
457 struct class_base
: detail::scoped_object
463 LUABIND_TYPE_INFO type
;
475 std::map
<const char*, detail::method_rep
, detail::ltstr
> m_methods
;
477 // datamembers, some members may be readonly, and
478 // only have a getter function
479 std::map
<const char*, detail::class_rep::callback
, detail::ltstr
> m_getters
;
480 std::map
<const char*, detail::class_rep::callback
, detail::ltstr
> m_setters
;
482 // the operators in lua
483 std::vector
<detail::class_rep::operator_callback
> m_operators
[detail::number_of_operators
];
484 std::map
<const char*, int, detail::ltstr
> m_static_constants
;
486 std::vector
<base_desc
> m_bases
;
487 detail::construct_rep m_constructor
;
489 void(*m_destructor
)(void*);
490 void*(*m_extractor
)(void*);
491 void(*m_construct_held_type
)(void*, void*);
492 int m_held_type_size
;
493 int m_held_type_alignment
;
495 LUABIND_TYPE_INFO m_type
;
496 LUABIND_TYPE_INFO m_held_type
;
497 LUABIND_TYPE_INFO m_const_holder_type
;
499 #ifndef LUABIND_DONT_COPY_STRINGS
500 // the maps that contains char pointers points into
501 // this vector of strings.
502 std::vector
<char*> m_strings
;
507 // public 'cause of enum_maker, FIX
508 void add_static_constant(const char* name
, int val
)
510 m_static_constants
[name
] = val
;
515 void set_type(LUABIND_TYPE_INFO t
) { m_type
= t
; }
516 void set_held_type(LUABIND_TYPE_INFO t
) { m_held_type
= t
; }
519 void set_const_holder_type(type
<T
>)
521 m_const_holder_type
= LUABIND_TYPEID(T
);
524 void set_extractor(void*(*f
)(void*)) { m_extractor
= f
; }
525 void set_held_type_constructor(void(*f
)(void*,void*)) { m_construct_held_type
= f
; }
526 void set_destructor(void(*f
)(void*)) { m_destructor
= f
; }
527 void set_held_type_size(int s
) { m_held_type_size
= s
; }
528 void set_held_type_alignment(int n
) { m_held_type_alignment
= n
; }
530 inline void add_getter(const char* name
, const boost::function2
<int, lua_State
*, int>& g
)
532 detail::class_rep::callback c
;
534 c
.pointer_offset
= 0;
535 #ifndef LUABIND_DONT_COPY_STRINGS
536 m_strings
.push_back(detail::dup_string(name
));
537 m_getters
[m_strings
.back()] = c
;
543 inline void add_setter(const char* name
, const boost::function2
<int, lua_State
*, int>& s
)
545 detail::class_rep::callback c
;
547 c
.pointer_offset
= 0;
548 #ifndef LUABIND_DONT_COPY_STRINGS
549 m_strings
.push_back(detail::dup_string(name
));
550 m_setters
[m_strings
.back()] = c
;
556 void add_base(const base_desc
& b
)
558 m_bases
.push_back(b
);
563 void add_constructor(const detail::construct_rep::overload_t
& o
)
565 m_constructor
.overloads
.push_back(o
);
568 void add_method(const char* name
, const detail::overload_rep
& o
)
570 #ifdef LUABIND_DONT_COPY_STRINGS
571 detail::method_rep
& method
= m_methods
[name
];
574 m_strings
.push_back(detail::dup_string(name
));
575 detail::method_rep
& method
= m_methods
[m_strings
.back()];
576 method
.name
= m_strings
.back();
578 method
.add_overload(o
);
582 #ifndef LUABIND_NO_ERROR_CHECKING
583 inline void add_operator(int op_id
, int(*func
)(lua_State
*), int(*matcher
)(lua_State
*), void(*sig
)(lua_State
*, std::string
&), int arity
)
585 inline void add_operator(int op_id
, int(*func
)(lua_State
*), int(*matcher
)(lua_State
*), int arity
)
588 detail::class_rep::operator_callback o
;
590 o
.set_match_fun(matcher
);
593 #ifndef LUABIND_NO_ERROR_CHECKING
598 m_operators
[op_id
].push_back(o
);
607 const char* name() const { return m_name
; }
609 class_base(const char* name
)
611 #ifndef LUABIND_DONT_COPY_STRINGS
612 m_strings
.push_back(detail::dup_string(name
));
613 m_name
= m_strings
.back();
623 virtual ~class_base()
625 // if we are copying strings, we have to destroy them too
626 #ifndef LUABIND_DONT_COPY_STRINGS
627 for (std::vector
<char*>::iterator i
= m_strings
.begin(); i
!= m_strings
.end(); ++i
)
632 // pushes the class_rep on the lua stack
633 virtual void commit(lua_State
* L
)
635 assert(!m_cloned
&& "class already commited");
637 detail::getref(L
, scope_stack::top(L
));
638 lua_pushstring(L
, m_name
);
640 detail::class_rep
* crep
;
642 detail::class_registry
* r
= detail::class_registry::get_registry(L
);
643 // create a class_rep structure for this class.
644 // allocate it within lua to let lua collect it on
645 // lua_close(). This is better than allocating it
646 // as a static, since it will then be destructed
647 // when the program exits instead.
648 // warning: we assume that lua will not
649 // move the userdata memory.
650 lua_newuserdata(L
, sizeof(detail::class_rep
));
651 crep
= reinterpret_cast<detail::class_rep
*>(lua_touserdata(L
, -1));
653 new(crep
) detail::class_rep(m_type
, m_name
, L
, m_destructor
, m_held_type
, m_const_holder_type
, m_extractor
, m_construct_held_type
, m_held_type_size
, m_held_type_alignment
);
655 // register this new type in the class registry
656 r
->add_class(m_type
, crep
);
657 if (!(LUABIND_TYPE_INFO_EQUAL(m_held_type
, LUABIND_INVALID_TYPE_INFO
)))
659 // if we have a held type
660 // we have to register it in the class-table
661 // but only for the base class, if it already
662 // exists, we don't have to register it
663 detail::class_rep
* c
= r
->find_class(m_held_type
);
666 r
->add_class(m_held_type
, crep
);
667 r
->add_class(m_const_holder_type
, crep
);
672 for (std::map
<const char*, detail::method_rep
, detail::ltstr
>::iterator i
= m_methods
.begin();
673 i
!= m_methods
.end();
676 i
->second
.crep
= crep
;
678 std::swap(crep
->m_methods
, m_methods
);
681 m_constructor
.swap(crep
->m_constructor
);
683 #ifndef LUABIND_DONT_COPY_STRINGS
684 assert(crep
->m_strings
.empty() && "Internal error");
685 std::swap(crep
->m_strings
, m_strings
);
688 std::swap(crep
->m_getters
, m_getters
);
689 std::swap(crep
->m_setters
, m_setters
);
691 for(int i
= 0; i
< detail::number_of_operators
; ++i
)
692 std::swap(crep
->m_operators
[i
], m_operators
[i
]);
694 std::swap(crep
->m_static_constants
, m_static_constants
);
696 for (std::vector
<base_desc
>::iterator i
= m_bases
.begin();
700 detail::class_registry
* r
= detail::class_registry::get_registry(L
);
702 // the baseclass' class_rep structure
703 detail::class_rep
* bcrep
= r
->find_class(i
->type
);
705 detail::class_rep::base_info base
;
706 base
.pointer_offset
= i
->ptr_offset
;
709 crep
->add_base_class(base
);
718 virtual luabind::detail::scoped_object
* clone()
720 assert(m_cloned
== false);
726 class_base
* ret
= new class_base(m_name
);
728 std::swap(ret
->m_getters
, m_getters
);
729 std::swap(ret
->m_setters
, m_setters
);
731 for(int i
= 0; i
< detail::number_of_operators
; ++i
)
732 std::swap(ret
->m_operators
[i
], m_operators
[i
]);
734 std::swap(ret
->m_static_constants
, m_static_constants
);
735 ret
->m_destructor
= m_destructor
;
736 ret
->m_extractor
= m_extractor
;
737 ret
->m_construct_held_type
= m_construct_held_type
;
738 ret
->m_held_type_size
= m_held_type_size
;
739 ret
->m_held_type_alignment
= m_held_type_alignment
;
741 std::swap(ret
->m_bases
, m_bases
);
742 std::swap(ret
->m_methods
, m_methods
);
743 m_constructor
.swap(ret
->m_constructor
);
745 ret
->m_name
= m_name
;
747 ret
->m_type
= m_type
;
748 ret
->m_held_type
= m_held_type
;
749 ret
->m_const_holder_type
= m_const_holder_type
;
751 #ifndef LUABIND_DONT_COPY_STRINGS
752 std::swap(ret
->m_strings
, m_strings
);
770 // registers a class in the lua environment
771 template<class T
, class X1
, class X2
, class X3
>
772 struct class_
: class_base
774 typedef class_
<T
, X1
, X2
, X3
> self_t
;
780 template<class A
, class B
, class C
, class D
>
781 class_(const class_
<A
,B
,C
,D
>&);
785 // WrappedType MUST inherit from T
786 typedef typename
detail::extract_parameter
<
787 boost::mpl::vector3
<X1
,X2
,X3
>
788 , boost::is_base_and_derived
<T
, boost::mpl::_
>
789 /* , boost::mpl::not_<
791 detail::is_bases<boost::mpl::_>
792 , boost::is_base_and_derived<boost::mpl::_, T>
798 typedef typename
detail::extract_parameter
<
799 boost::mpl::list3
<X1
,X2
,X3
>
803 detail::is_bases
<boost::mpl::_
>
804 , boost::is_base_and_derived
<boost::mpl::_
, T
>
806 , boost::is_base_and_derived
<T
, boost::mpl::_
>
812 // this function generates conversion information
813 // in the given class_rep structure. It will be able
814 // to implicitly cast to the given template type
816 void gen_base_info(detail::type
<To
>)
818 // fist, make sure the given base class is registered.
819 // if it's not registered we can't push it's lua table onto
820 // the stack because it doesn't have a table
822 // try to cast this type to the base type and remember
823 // the pointer offset. For multiple inheritance the pointer
824 // may change when casting. Since we need to be able to
825 // cast we need this pointer offset.
826 // store the information in this class' base class-vector
828 base
.type
= LUABIND_TYPEID(To
);
829 base
.ptr_offset
= detail::ptr_offset(detail::type
<T
>(), detail::type
<To
>());
833 void gen_base_info(detail::type
<detail::null_type
>)
836 #define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type<B##n>());
838 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES
, class B
)>
839 void generate_baseclass_list(detail::type
<bases
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES
, B
)> >)
841 BOOST_PP_REPEAT(LUABIND_MAX_BASES
, LUABIND_GEN_BASE_INFO
, _
)
844 #undef LUABIND_GEN_BASE_INFO
846 // this is the internal version of def() it is run from both overloads
847 // of def. It has two versions, one where a contstructor is registered
848 // and one where a function is registered
849 template<class Policies
>
850 struct internal_def_s
853 static void apply(const char* name
, F f
, class_base
* c
)
855 // std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";
857 detail::overload_rep
o(f
, static_cast<Policies
*>(0));
859 typedef LUABIND_MSVC_TYPENAME
detail::function_callback_s
<HeldType
,T
,F
,Policies
>::type call_t
;
861 o
.set_match_fun(&detail::match_function_callback_s
<T
,F
,Policies
>::apply
);
862 o
.call_fun
= boost::bind
<int>(call_t(f
), _1
, _2
);
864 #ifndef LUABIND_NO_ERROR_CHECKING
866 o
.set_sig_fun(&detail::get_member_signature
<F
>::apply
);
870 c
->add_method(name
, o
);
873 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, class A
)>
874 static void apply(constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)>, class_base
* c
)
876 // std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";
878 detail::construct_rep::overload_t o
;
881 &detail::construct_class
<
884 ,constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)>
888 // if we have a WrappedType, we have to register it's constructor
889 // but if it's null_type (no WrappedType) we should not register it
890 detail::register_wrapped_type
<WrappedType
>::apply(o
,
891 static_cast<const constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)>*>(0),
892 static_cast<const Policies
*>(0));
896 &detail::constructor_match
<
897 constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)>
902 #ifndef LUABIND_NO_ERROR_CHECKING
904 o
.set_sig_fun(&detail::get_signature
<constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> >::apply
);
908 typedef constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> con_t
;
910 o
.set_arity(detail::calc_arity
<con_t::arity
>::apply(con_t(), static_cast<Policies
*>(0)));
912 c
->add_constructor(o
);
916 class_(lua_State
* L
, const char* name
): class_base(name
), m_L(L
) { init(); }
917 class_(const char* name
): class_base(name
), m_L(0) { init(); }
924 lua_pushvalue(m_L
, LUA_GLOBALSINDEX
);
925 scope_stack::push(m_L
);
927 scope_stack::pop(m_L
);
932 class_
& def(const char* name
, F f
)
934 internal_def_s
<detail::null_type
>::apply(name
, f
, this);
938 template<class F
, class Policies
>
939 class_
& def(const char* name
, F f
, const Policies
&)
941 internal_def_s
<Policies
>::apply(name
, f
, this);
945 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, class A
)>
946 class_
& def(constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> sig
)
948 internal_def_s
<detail::null_type
>::apply(sig
, this);
952 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, class A
), class Policies
>
953 class_
& def(constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> sig
, const Policies
& policies
)
955 internal_def_s
<Policies
>::apply(sig
, this);
959 template<class Getter
>
960 class_
& property(const char* name
, Getter g
)
962 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
, Getter
, detail::null_type
>(), _1
, _2
, g
));
966 template<class Getter
, class MaybeSetter
>
967 class_
& property(const char* name
, Getter g
, MaybeSetter s
)
969 return property_impl(name
, g
, s
, boost::mpl::bool_
<detail::is_policy_cons
<MaybeSetter
>::value
>());
972 template<class Getter
, class Setter
, class GetPolicies
>
973 class_
& property(const char* name
, Getter g
, Setter s
, const GetPolicies
& get_policies
)
975 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
, Getter
, GetPolicies
>(get_policies
), _1
, _2
, g
));
976 add_setter(name
, boost::bind
<int>(detail::set_caller
<T
, Setter
, detail::null_type
>(), _1
, _2
, s
));
980 template<class Getter
, class Setter
, class GetPolicies
, class SetPolicies
>
981 class_
& property(const char* name
983 , const GetPolicies
& get_policies
984 , const SetPolicies
& set_policies
)
986 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
, Getter
, GetPolicies
>(get_policies
), _1
, _2
, g
));
987 add_setter(name
, boost::bind
<int>(detail::set_caller
<T
, Setter
, GetPolicies
>(set_policies
), _1
, _2
, s
));
992 class_
& def_readonly(const char* name
, D
T::*member_ptr
)
994 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
998 template<class D
, class Policies
>
999 class_
& def_readonly(const char* name
, D
T::*member_ptr
, const Policies
& policies
)
1001 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,Policies
>(policies
), _1
, _2
, member_ptr
));
1006 class_
& def_readwrite(const char* name
, D
T::*member_ptr
)
1008 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
1009 add_setter(name
, boost::bind
<int>(detail::auto_set
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
1013 template<class D
, class GetPolicies
>
1014 class_
& def_readwrite(const char* name
, D
T::*member_ptr
, const GetPolicies
& get_policies
)
1016 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,GetPolicies
>(get_policies
), _1
, _2
, member_ptr
));
1017 add_setter(name
, boost::bind
<int>(detail::auto_set
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
1021 template<class D
, class GetPolicies
, class SetPolicies
>
1022 class_
& def_readwrite(const char* name
, D
T::*member_ptr
, const GetPolicies
& get_policies
, const SetPolicies
& set_policies
)
1024 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,GetPolicies
>(get_policies
), _1
, _2
, member_ptr
));
1025 add_setter(name
, boost::bind
<int>(detail::auto_set
<T
,D
,SetPolicies
>(set_policies
), _1
, _2
, member_ptr
));
1029 template<class op_id
, class Left
, class Right
, class Policies
>
1030 class_
& def(detail::operator_
<op_id
, Left
, Right
>, const Policies
& policies
)
1032 typedef typename
detail::operator_unwrapper
<Policies
, op_id
, T
, Left
, Right
> op_type
;
1033 #ifndef LUABIND_NO_ERROR_CHECKING
1034 add_operator(op_type::get_id()
1037 , &detail::get_signature
<constructor
<typename
op_type::left_t
, typename
op_type::right_t
> >::apply
1038 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1040 add_operator(op_type::get_id()
1043 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1048 template<class op_id
, class Left
, class Right
>
1049 class_
& def(detail::operator_
<op_id
, Left
, Right
>)
1051 typedef typename
detail::operator_unwrapper
<detail::null_type
, op_id
, T
, Left
, Right
> op_type
;
1053 #ifndef LUABIND_NO_ERROR_CHECKING
1054 add_operator(op_type::get_id()
1057 , &detail::get_signature
<constructor
<LUABIND_MSVC_TYPENAME
op_type::left_t
, LUABIND_MSVC_TYPENAME
op_type::right_t
> >::apply
1058 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1060 add_operator(op_type::get_id()
1063 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1068 template<class Signature
, bool Constant
>
1069 class_
& def(detail::application_operator
<Signature
, Constant
>*)
1071 typedef detail::application_operator
<Signature
, Constant
, detail::null_type
> op_t
;
1073 int arity
= detail::calc_arity
<Signature::arity
>::apply(Signature(), static_cast<detail::null_type
*>(0));
1075 #ifndef LUABIND_NO_ERROR_CHECKING
1076 add_operator(detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, &detail::get_signature
<Signature
>::apply
, arity
+ 1);
1078 add_operator(detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, arity
+ 1);
1084 template<class Signature
, bool Constant
, class Policies
>
1085 class_
& def(detail::application_operator
<Signature
, Constant
>*, const Policies
& policies
)
1087 typedef detail::application_operator
<Signature
, Constant
, Policies
> op_t
;
1089 int arity
= detail::calc_arity
<Signature::arity
>::apply(Signature(), static_cast<Policies
*>(0));
1091 #ifndef LUABIND_NO_ERROR_CHECKING
1092 add_operator(detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, &detail::get_signature
<Signature
>::apply
, arity
+ 1);
1094 add_operator(detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, arity
+ 1);
1100 detail::enum_maker
<self_t
> enum_(const char*)
1102 return detail::enum_maker
<self_t
>(*this);
1109 typedef typename
detail::extract_parameter
<
1110 boost::mpl::list3
<X1
,X2
,X3
>
1112 detail::is_bases
<boost::mpl::_
>
1113 , boost::is_base_and_derived
<boost::mpl::_
, T
>
1119 boost::mpl::if_
<detail::is_bases
<bases_t
>
1124 set_type(LUABIND_TYPEID(T
));
1125 set_held_type(detail::internal_held_type
<HeldType
>::apply());
1126 set_const_holder_type(get_const_holder(detail::type
<HeldType
>()));
1127 set_extractor(detail::internal_held_type_extractor
<HeldType
>::apply(detail::type
<T
>()));
1128 set_held_type_constructor(detail::internal_held_type_constructor
<HeldType
>::apply(detail::type
<T
>()));
1129 set_held_type_size(detail::internal_held_type_size
<HeldType
>::apply());
1130 set_destructor(detail::internal_held_type_destructor
<HeldType
>::apply(detail::type
<T
>()));
1132 set_held_type_alignment(detail::get_holder_alignment
<HeldType
>::apply());
1134 generate_baseclass_list(detail::type
<Base
>());
1137 template<class Getter
, class GetPolicies
>
1138 class_
& property_impl(const char* name
,
1140 GetPolicies policies
,
1141 boost::mpl::bool_
<true>)
1143 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
,Getter
,GetPolicies
>(policies
), _1
, _2
, g
));
1147 template<class Getter
, class Setter
>
1148 class_
& property_impl(const char* name
,
1151 boost::mpl::bool_
<false>)
1153 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
,Getter
,detail::null_type
>(), _1
, _2
, g
));
1154 add_setter(name
, boost::bind
<int>(detail::set_caller
<T
,Setter
,detail::null_type
>(), _1
, _2
, s
));
1161 #endif // LUABIND_CLASS_HPP_INCLUDED