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 ------------------------------------------------------
55 add access to the keys on iterators
57 finish scopes (and document)
59 finish smart pointer support
60 * we need a special case in the value_converter matcher to know that smart
61 pointers can be implicitly cast to base types.
62 * holder_type<const A> must be supported by the converters
63 * the adopt policy should not be able to adopt pointers to held_types. This
65 * name_of_type must recognize holder_types and not return "custom"
66 * maybe it's better to avoid LUABIND_TYPEID() etc. in user code. get_const_holder
69 document the new yield-policy
71 chache operators and finalizers in the class_rep. For lua classes
72 we currently do a lookup each time we need to know if a lua class
73 has a finalizer or an operator.
75 instead of registering the name of free functions and make a lookup in
76 the register to see if we are overloading, look in the actual namespace
77 where we are registering the function to see if there already is a function
78 with the same name there, and in that case, add an overload to it.
80 static functions, this could be implemented by letting classes contain
81 other declarations (classes or functions)
83 document custom policies, custom converters
85 store the instance object for policies.
87 support the __concat metamethod. This is a bit tricky, since it cannot be
88 treated as a normal operator. It is a binary operator but we want to use the
89 __tostring implementation for both arguments.
93 #include <luabind/config.hpp>
100 #include <boost/static_assert.hpp>
101 #include <boost/type_traits.hpp>
102 #include <boost/bind.hpp>
103 #include <boost/function.hpp>
104 #include <boost/preprocessor/repetition/enum_params.hpp>
105 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
106 #include <boost/preprocessor/repetition/repeat.hpp>
107 #include <boost/type_traits/is_same.hpp>
108 #include <boost/mpl/list.hpp>
109 #include <boost/mpl/apply.hpp>
110 #include <boost/mpl/lambda.hpp>
111 #include <boost/mpl/logical.hpp>
112 #include <boost/mpl/find_if.hpp>
113 #include <boost/mpl/apply_if.hpp>
114 #include <boost/mpl/logical.hpp>
116 #include <luabind/config.hpp>
117 #include <luabind/scope.hpp>
118 #include <luabind/detail/constructor.hpp>
119 #include <luabind/detail/call.hpp>
120 #include <luabind/detail/signature_match.hpp>
121 #include <luabind/detail/primitives.hpp>
122 #include <luabind/detail/property.hpp>
123 #include <luabind/detail/typetraits.hpp>
124 #include <luabind/detail/class_rep.hpp>
125 #include <luabind/detail/method_rep.hpp>
126 #include <luabind/detail/construct_rep.hpp>
127 #include <luabind/detail/object_rep.hpp>
128 #include <luabind/detail/operators.hpp>
129 #include <luabind/detail/calc_arity.hpp>
130 #include <luabind/detail/call_member.hpp>
131 #include <luabind/detail/enum_maker.hpp>
132 #include <luabind/detail/get_signature.hpp>
133 #include <luabind/detail/implicit_cast.hpp>
134 #include <luabind/detail/operator_id.hpp>
140 struct unspecified
{};
143 template<class T
, class X1
= detail::unspecified
, class X2
= detail::unspecified
, class X3
= detail::unspecified
>
146 inline LUABIND_TYPE_INFO
get_const_holder(...)
148 return LUABIND_INVALID_TYPE_INFO
;
153 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES
, class A
)>
154 double is_bases_helper(const bases
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES
, A
)>&);
158 char is_bases_helper(const T
&);
160 char is_bases_helper(...);
168 BOOST_STATIC_CONSTANT(bool, value
= sizeof(is_bases_helper(t
)) == sizeof(double));
169 typedef boost::mpl::bool_
<value
> type
;
170 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_bases
,(T
))
173 double is_not_unspecified_helper(const unspecified
*);
174 char is_not_unspecified_helper(...);
177 struct is_not_unspecified
179 BOOST_STATIC_CONSTANT(bool, value
= sizeof(is_not_unspecified_helper(static_cast<T
*>(0))) == sizeof(char));
180 typedef boost::mpl::bool_
<value
> type
;
181 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_not_unspecified
,(T
))
184 template<class Predicate
>
187 typedef typename
boost::mpl::and_
<
189 , is_not_unspecified
<boost::mpl::_1
>
193 template<class Parameters
, class Predicate
, class DefaultValue
>
194 struct extract_parameter
196 typedef typename get_predicate
<Predicate
>::type pred
;
197 typedef typename
boost::mpl::find_if
<Parameters
, pred
>::type iterator
;
198 typedef typename
boost::mpl::apply_if
<boost::is_same
<iterator
, typename
boost::mpl::end
<Parameters
>::type
>
199 , boost::mpl::identity
<DefaultValue
>
204 int function_dispatcher(lua_State
* L
);
206 // this should know about the smart pointer type.
207 // and should really do:
208 // get_pointer(*static_cast<SmartPointer*>(obj_ptr))
209 // to extract the held pointer.
210 template<class HeldType
, class T
, class F
, class Policies
>
211 struct function_callback_non_null
: Policies
213 function_callback_non_null(F f_
): f(f_
) {}
214 inline int operator()(lua_State
* L
, void* obj_ptr
)
216 HeldType
& held_obj
= *static_cast<HeldType
*>(obj_ptr
);
218 T
* ptr
= static_cast<T
*>(get_pointer(held_obj
));
220 return call(f
, ptr
, L
, static_cast<Policies
*>(this));
225 template<class T
, class F
, class Policies
>
226 struct function_callback_null_type
: Policies
228 function_callback_null_type(F f_
): f(f_
) {}
229 inline int operator()(lua_State
* L
, void* obj_ptr
)
231 // std::cout << "HeldType: null_type\n";
232 T
* ptr
= static_cast<T
*>(obj_ptr
);
233 return call(f
, ptr
, L
, static_cast<Policies
*>(this));
238 template<class HeldType
, class T
, class F
, class Policies
>
239 struct function_callback_s
242 boost::mpl::if_
<boost::is_same
<HeldType
,detail::null_type
>
243 , function_callback_null_type
<T
,F
,Policies
>
244 , function_callback_non_null
<HeldType
,T
,F
,Policies
>
248 template<class T
, class F
, class Policies
>
249 struct match_function_callback_s
251 static inline int apply(lua_State
* L
)
253 object_rep
* obj
= static_cast<object_rep
*>(lua_touserdata(L
, 1));
255 return match(fptr
, L
, obj
->flags() & object_rep::constant
, static_cast<Policies
*>(0));
259 // prints the types of the values on the stack, in the
260 // range [start_index, lua_gettop()]
262 std::string
stack_content_by_name(lua_State
* L
, int start_index
);
266 static int stage1(lua_State
* L
);
267 static int stage2(lua_State
* L
);
271 struct register_wrapped_type
273 template<class Signature
, class Policies
>
274 static void apply(detail::construct_rep::overload_t
& o
, const Signature
*, const Policies
*)
276 o
.set_wrapped_constructor(
277 &detail::construct_wrapped_class
<Type
, Policies
, Signature
>::apply
283 struct register_wrapped_type
<detail::null_type
>
285 template<class Signature
, class Policies
>
286 static void apply(detail::construct_rep::overload_t
&, const Signature
*, const Policies
*) {}
290 // if the class is held by a smart pointer, we need to be able to
291 // implicitly dereference the pointer when needed.
293 template<class UnderlyingT
, class HeldT
>
294 struct extract_underlying_type
296 static void* extract(void* ptr
)
298 HeldT
& held_obj
= *reinterpret_cast<HeldT
*>(ptr
);
299 UnderlyingT
* underlying_ptr
= static_cast<UnderlyingT
*>(get_pointer(held_obj
));
300 return underlying_ptr
;
305 template<class HeldType
>
306 struct internal_held_type_extractor
308 typedef void*(*extractor_fun
)(void*);
311 static extractor_fun
apply(detail::type
<T
>)
313 return detail::extract_underlying_type
<T
, HeldType
>::extract
;
318 struct internal_held_type_extractor
<detail::null_type
>
320 typedef void*(*extractor_fun
)(void*);
323 static extractor_fun
apply(detail::type
<T
>)
330 // this is simply a selector that returns the type_info
331 // of the held type, or invalid_type_info if we don't have
333 template<class HeldType
>
334 struct internal_held_type
336 static LUABIND_TYPE_INFO
apply()
338 return LUABIND_TYPEID(HeldType
);
343 struct internal_held_type
<detail::null_type
>
345 static LUABIND_TYPE_INFO
apply()
347 return LUABIND_INVALID_TYPE_INFO
;
352 // this is the actual held_type constructor
353 template<class HeldType
, class T
>
354 struct internal_construct_held_type
356 static void apply(void* target
, void* raw_pointer
)
358 new(target
) HeldType(static_cast<T
*>(raw_pointer
));
362 // the followinf two functions are the ones that returns
363 // a pointer to a held_type_constructor, or 0 if there
365 template<class HeldType
>
366 struct internal_held_type_constructor
368 typedef void(*constructor
)(void*,void*);
370 static constructor
apply(detail::type
<T
>)
372 return &internal_construct_held_type
<HeldType
, T
>::apply
;
377 struct internal_held_type_constructor
<detail::null_type
>
379 typedef void(*constructor
)(void*,void*);
381 static constructor
apply(detail::type
<T
>)
388 // this is a selector that returns the size of the held_type
389 // or 0 if we don't have a held_type
390 template <class HeldType
>
391 struct internal_held_type_size
393 static int apply() { return sizeof(HeldType
); }
397 struct internal_held_type_size
<detail::null_type
>
399 static int apply() { return 0; }
403 // if we have a held type, return the destructor to it
404 // note the difference. The held_type should only be destructed (not deleted)
405 // since it's constructed in the lua userdata
406 template<class HeldType
>
407 struct internal_held_type_destructor
409 typedef void(*destructor_t
)(void*);
411 static destructor_t
apply(detail::type
<T
>)
413 return &detail::destruct_only_s
<HeldType
>::apply
;
417 // if we don't have a held type, return the destructor of the raw type
419 struct internal_held_type_destructor
<detail::null_type
>
421 typedef void(*destructor_t
)(void*);
423 static destructor_t
apply(detail::type
<T
>)
425 return &detail::delete_s
<T
>::apply
;
430 struct get_holder_alignment
434 return boost::alignment_of
<T
>::value
;
439 struct get_holder_alignment
<detail::null_type
>
463 struct class_base
: detail::scoped_object
469 LUABIND_TYPE_INFO type
;
481 std::map
<const char*, detail::method_rep
, detail::ltstr
> m_methods
;
483 // datamembers, some members may be readonly, and
484 // only have a getter function
485 std::map
<const char*, detail::class_rep::callback
, detail::ltstr
> m_getters
;
486 std::map
<const char*, detail::class_rep::callback
, detail::ltstr
> m_setters
;
488 // the operators in lua
489 std::vector
<detail::class_rep::operator_callback
> m_operators
[detail::number_of_operators
];
490 std::map
<const char*, int, detail::ltstr
> m_static_constants
;
492 std::vector
<base_desc
> m_bases
;
493 detail::construct_rep m_constructor
;
495 void(*m_destructor
)(void*);
496 void*(*m_extractor
)(void*);
497 void(*m_construct_held_type
)(void*, void*);
498 int m_held_type_size
;
499 int m_held_type_alignment
;
501 LUABIND_TYPE_INFO m_type
;
502 LUABIND_TYPE_INFO m_held_type
;
503 LUABIND_TYPE_INFO m_const_holder_type
;
505 #ifndef LUABIND_DONT_COPY_STRINGS
506 // the maps that contains char pointers points into
507 // this vector of strings.
508 std::vector
<char*> m_strings
;
513 // public 'cause of enum_maker, FIX
514 void add_static_constant(const char* name
, int val
)
516 m_static_constants
[name
] = val
;
521 void set_type(LUABIND_TYPE_INFO t
) { m_type
= t
; }
522 void set_held_type(LUABIND_TYPE_INFO t
) { m_held_type
= t
; }
524 void set_const_holder_type(LUABIND_TYPE_INFO t
)
526 m_const_holder_type
= t
;
529 void set_extractor(void*(*f
)(void*)) { m_extractor
= f
; }
530 void set_held_type_constructor(void(*f
)(void*,void*)) { m_construct_held_type
= f
; }
531 void set_destructor(void(*f
)(void*)) { m_destructor
= f
; }
532 void set_held_type_size(int s
) { m_held_type_size
= s
; }
533 void set_held_type_alignment(int n
) { m_held_type_alignment
= n
; }
535 inline void add_getter(const char* name
, const boost::function2
<int, lua_State
*, int>& g
)
537 detail::class_rep::callback c
;
539 c
.pointer_offset
= 0;
540 #ifndef LUABIND_DONT_COPY_STRINGS
541 m_strings
.push_back(detail::dup_string(name
));
542 m_getters
[m_strings
.back()] = c
;
548 inline void add_setter(const char* name
, const boost::function2
<int, lua_State
*, int>& s
)
550 detail::class_rep::callback c
;
552 c
.pointer_offset
= 0;
553 #ifndef LUABIND_DONT_COPY_STRINGS
554 m_strings
.push_back(detail::dup_string(name
));
555 m_setters
[m_strings
.back()] = c
;
561 void add_base(const base_desc
& b
)
563 m_bases
.push_back(b
);
568 void add_constructor(const detail::construct_rep::overload_t
& o
)
570 m_constructor
.overloads
.push_back(o
);
573 void add_method(const char* name
, const detail::overload_rep
& o
)
575 #ifdef LUABIND_DONT_COPY_STRINGS
576 detail::method_rep
& method
= m_methods
[name
];
579 m_strings
.push_back(detail::dup_string(name
));
580 detail::method_rep
& method
= m_methods
[m_strings
.back()];
581 method
.name
= m_strings
.back();
583 method
.add_overload(o
);
587 #ifndef LUABIND_NO_ERROR_CHECKING
588 inline void add_operator(int op_id
, int(*func
)(lua_State
*), int(*matcher
)(lua_State
*), void(*sig
)(lua_State
*, std::string
&), int arity
)
590 inline void add_operator(int op_id
, int(*func
)(lua_State
*), int(*matcher
)(lua_State
*), int arity
)
593 detail::class_rep::operator_callback o
;
595 o
.set_match_fun(matcher
);
598 #ifndef LUABIND_NO_ERROR_CHECKING
603 m_operators
[op_id
].push_back(o
);
612 const char* name() const { return m_name
; }
614 class_base(const char* name
)
616 #ifndef LUABIND_DONT_COPY_STRINGS
617 m_strings
.push_back(detail::dup_string(name
));
618 m_name
= m_strings
.back();
628 virtual ~class_base()
630 // if we are copying strings, we have to destroy them too
631 #ifndef LUABIND_DONT_COPY_STRINGS
632 for (std::vector
<char*>::iterator i
= m_strings
.begin(); i
!= m_strings
.end(); ++i
)
637 // pushes the class_rep on the lua stack
638 virtual void commit(lua_State
* L
)
640 assert(!m_cloned
&& "class already commited");
644 detail::getref(L
, scope_stack::top(L
));
645 lua_pushstring(L
, m_name
);
647 detail::class_rep
* crep
;
649 detail::class_registry
* r
= detail::class_registry::get_registry(L
);
650 // create a class_rep structure for this class.
651 // allocate it within lua to let lua collect it on
652 // lua_close(). This is better than allocating it
653 // as a static, since it will then be destructed
654 // when the program exits instead.
655 // warning: we assume that lua will not
656 // move the userdata memory.
657 lua_newuserdata(L
, sizeof(detail::class_rep
));
658 crep
= reinterpret_cast<detail::class_rep
*>(lua_touserdata(L
, -1));
660 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
);
662 // register this new type in the class registry
663 r
->add_class(m_type
, crep
);
664 if (!(LUABIND_TYPE_INFO_EQUAL(m_held_type
, LUABIND_INVALID_TYPE_INFO
)))
666 // if we have a held type
667 // we have to register it in the class-table
668 // but only for the base class, if it already
669 // exists, we don't have to register it
670 detail::class_rep
* c
= r
->find_class(m_held_type
);
671 if (c
== 0) r
->add_class(m_held_type
, crep
);
675 for (std::map
<const char*, detail::method_rep
, detail::ltstr
>::iterator i
= m_methods
.begin();
676 i
!= m_methods
.end();
679 i
->second
.crep
= crep
;
681 std::swap(crep
->m_methods
, m_methods
);
684 m_constructor
.swap(crep
->m_constructor
);
686 #ifndef LUABIND_DONT_COPY_STRINGS
687 assert(crep
->m_strings
.empty() && "Internal error");
688 std::swap(crep
->m_strings
, m_strings
);
691 std::swap(crep
->m_getters
, m_getters
);
692 std::swap(crep
->m_setters
, m_setters
);
694 for(int i
= 0; i
< detail::number_of_operators
; ++i
)
695 std::swap(crep
->m_operators
[i
], m_operators
[i
]);
697 std::swap(crep
->m_static_constants
, m_static_constants
);
699 for (std::vector
<base_desc
>::iterator i
= m_bases
.begin();
703 detail::class_registry
* r
= detail::class_registry::get_registry(L
);
705 // the baseclass' class_rep structure
706 detail::class_rep
* bcrep
= r
->find_class(i
->type
);
708 detail::class_rep::base_info base
;
709 base
.pointer_offset
= i
->ptr_offset
;
712 crep
->add_base_class(base
);
721 virtual luabind::detail::scoped_object
* clone()
723 assert(m_cloned
== false);
729 class_base
* ret
= new class_base(m_name
);
731 std::swap(ret
->m_getters
, m_getters
);
732 std::swap(ret
->m_setters
, m_setters
);
734 for(int i
= 0; i
< detail::number_of_operators
; ++i
)
735 std::swap(ret
->m_operators
[i
], m_operators
[i
]);
737 std::swap(ret
->m_static_constants
, m_static_constants
);
738 ret
->m_destructor
= m_destructor
;
739 ret
->m_extractor
= m_extractor
;
740 ret
->m_construct_held_type
= m_construct_held_type
;
741 ret
->m_held_type_size
= m_held_type_size
;
743 std::swap(ret
->m_bases
, m_bases
);
744 std::swap(ret
->m_methods
, m_methods
);
745 m_constructor
.swap(ret
->m_constructor
);
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::vector3
<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(); }
928 class_
& def(const char* name
, F f
)
930 internal_def_s
<detail::null_type
>::apply(name
, f
, this);
934 template<class F
, class Policies
>
935 class_
& def(const char* name
, F f
, const Policies
&)
937 internal_def_s
<Policies
>::apply(name
, f
, this);
941 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, class A
)>
942 class_
& def(constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> sig
)
944 internal_def_s
<detail::null_type
>::apply(sig
, this);
948 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, class A
), class Policies
>
949 class_
& def(constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> sig
, const Policies
& policies
)
951 internal_def_s
<Policies
>::apply(sig
, this);
955 template<class Getter
>
956 class_
& property(const char* name
, Getter g
)
958 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
, Getter
, detail::null_type
>(), _1
, _2
, g
));
962 template<class Getter
, class MaybeSetter
>
963 class_
& property(const char* name
, Getter g
, MaybeSetter s
)
965 return property_impl(name
, g
, s
, boost::mpl::bool_
<detail::is_policy_cons
<MaybeSetter
>::value
>());
968 template<class Getter
, class Setter
, class GetPolicies
>
969 class_
& property(const char* name
, Getter g
, Setter s
, const GetPolicies
& get_policies
)
971 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
, Getter
, GetPolicies
>(get_policies
), _1
, _2
, g
));
972 add_setter(name
, boost::bind
<int>(detail::set_caller
<T
, Setter
, detail::null_type
>(), _1
, _2
, s
));
976 template<class Getter
, class Setter
, class GetPolicies
, class SetPolicies
>
977 class_
& property(const char* name
979 , const GetPolicies
& get_policies
980 , const SetPolicies
& set_policies
)
982 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
, Getter
, GetPolicies
>(get_policies
), _1
, _2
, g
));
983 add_setter(name
, boost::bind
<int>(detail::set_caller
<T
, Setter
, GetPolicies
>(set_policies
), _1
, _2
, s
));
988 class_
& def_readonly(const char* name
, D
T::*member_ptr
)
990 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
994 template<class D
, class Policies
>
995 class_
& def_readonly(const char* name
, D
T::*member_ptr
, const Policies
& policies
)
997 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,Policies
>(policies
), _1
, _2
, member_ptr
));
1002 class_
& def_readwrite(const char* name
, D
T::*member_ptr
)
1004 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
1005 add_setter(name
, boost::bind
<int>(detail::auto_set
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
1009 template<class D
, class GetPolicies
>
1010 class_
& def_readwrite(const char* name
, D
T::*member_ptr
, const GetPolicies
& get_policies
)
1012 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,GetPolicies
>(get_policies
), _1
, _2
, member_ptr
));
1013 add_setter(name
, boost::bind
<int>(detail::auto_set
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
1017 template<class D
, class GetPolicies
, class SetPolicies
>
1018 class_
& def_readwrite(const char* name
, D
T::*member_ptr
, const GetPolicies
& get_policies
, const SetPolicies
& set_policies
)
1020 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,GetPolicies
>(get_policies
), _1
, _2
, member_ptr
));
1021 add_setter(name
, boost::bind
<int>(detail::auto_set
<T
,D
,SetPolicies
>(set_policies
), _1
, _2
, member_ptr
));
1025 template<class op_id
, class Left
, class Right
, class Policies
>
1026 class_
& def(detail::operator_
<op_id
, Left
, Right
>, const Policies
& policies
)
1028 typedef typename
detail::operator_unwrapper
<Policies
, op_id
, T
, Left
, Right
> op_type
;
1029 #ifndef LUABIND_NO_ERROR_CHECKING
1030 add_operator(op_type::get_id()
1033 , &detail::get_signature
<constructor
<typename
op_type::left_t
, typename
op_type::right_t
> >::apply
1034 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1036 add_operator(op_type::get_id()
1039 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1044 template<class op_id
, class Left
, class Right
>
1045 class_
& def(detail::operator_
<op_id
, Left
, Right
>)
1047 typedef typename
detail::operator_unwrapper
<detail::null_type
, op_id
, T
, Left
, Right
> op_type
;
1049 #ifndef LUABIND_NO_ERROR_CHECKING
1050 add_operator(op_type::get_id()
1053 , &detail::get_signature
<constructor
<LUABIND_MSVC_TYPENAME
op_type::left_t
, LUABIND_MSVC_TYPENAME
op_type::right_t
> >::apply
1054 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1056 add_operator(op_type::get_id()
1059 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1064 template<class Signature
, bool Constant
>
1065 class_
& def(detail::application_operator
<Signature
, Constant
>*)
1067 typedef detail::application_operator
<Signature
, Constant
, detail::null_type
> op_t
;
1069 int arity
= detail::calc_arity
<Signature::arity
>::apply(Signature(), static_cast<detail::null_type
*>(0));
1071 #ifndef LUABIND_NO_ERROR_CHECKING
1072 add_operator(detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, &detail::get_signature
<Signature
>::apply
, arity
+ 1);
1074 add_operator(detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, arity
+ 1);
1080 template<class Signature
, bool Constant
, class Policies
>
1081 class_
& def(detail::application_operator
<Signature
, Constant
>*, const Policies
& policies
)
1083 typedef detail::application_operator
<Signature
, Constant
, Policies
> op_t
;
1085 int arity
= detail::calc_arity
<Signature::arity
>::apply(Signature(), static_cast<Policies
*>(0));
1087 #ifndef LUABIND_NO_ERROR_CHECKING
1088 add_operator(detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, &detail::get_signature
<Signature
>::apply
, arity
+ 1);
1090 add_operator(detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, arity
+ 1);
1096 detail::enum_maker
<self_t
> enum_(const char*)
1098 return detail::enum_maker
<self_t
>(*this);
1105 typedef typename
detail::extract_parameter
<
1106 boost::mpl::vector3
<X1
,X2
,X3
>
1108 detail::is_bases
<boost::mpl::_
>
1109 , boost::is_base_and_derived
<boost::mpl::_
, T
>
1115 boost::mpl::if_
<detail::is_bases
<bases_t
>
1120 set_type(LUABIND_TYPEID(T
));
1121 set_held_type(detail::internal_held_type
<HeldType
>::apply());
1122 set_const_holder_type(get_const_holder(detail::type
<HeldType
>()));
1123 set_extractor(detail::internal_held_type_extractor
<HeldType
>::apply(detail::type
<T
>()));
1124 set_held_type_constructor(detail::internal_held_type_constructor
<HeldType
>::apply(detail::type
<T
>()));
1125 set_held_type_size(detail::internal_held_type_size
<HeldType
>::apply());
1126 set_destructor(detail::internal_held_type_destructor
<HeldType
>::apply(detail::type
<T
>()));
1128 set_held_type_alignment(detail::get_holder_alignment
<HeldType
>::apply());
1130 generate_baseclass_list(detail::type
<Base
>());
1133 template<class Getter
, class GetPolicies
>
1134 class_
& property_impl(const char* name
,
1136 GetPolicies policies
,
1137 boost::mpl::bool_
<true>)
1139 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
,Getter
,GetPolicies
>(policies
), _1
, _2
, g
));
1143 template<class Getter
, class Setter
>
1144 class_
& property_impl(const char* name
,
1147 boost::mpl::bool_
<false>)
1149 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
,Getter
,detail::null_type
>(), _1
, _2
, g
));
1150 add_setter(name
, boost::bind
<int>(detail::set_caller
<T
,Setter
,detail::null_type
>(), _1
, _2
, s
));
1157 #endif // LUABIND_CLASS_HPP_INCLUDED