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
31 move all exceptions to the exception.hpp header
34 Since functions can be overridden, the constness of the member functions
35 must be taken into account.
37 * solved for member functions, not application operator *
38 if we have a base class that defines a function a derived class must be able to
39 override that function (not just overload). Right now we just add the other overload
40 to the overloads list and will probably get an ambiguity. If we want to support this
41 each method_rep must include a vector of type_info pointers for each parameter.
42 Operators do not have this problem, since operators always have to have
43 it's own type as one of the arguments, no ambiguity can occur. Application
44 operator, on the other hand, would have this problem.
45 Properties cannot be overloaded, so they should always be overridden.
46 If this is to work for application operator, we really need to specify if an application
47 operator is const or not.
49 If one class registers two functions with the same name and the same
50 signature, there's currently no error. The last registered function will
51 be the one that's used.
52 How do we know which class registered the function? If the function was
53 defined by the base class, it is a legal operation, to override it.
54 we cannot look at the pointer offset, since it always will be zero for one of the bases.
57 We do not currently run unwrap_other<> on the parameters given to the application
58 operators when we register them.
61 if the first matched binary operator does not match the parameters we have to manually
62 check if the right parameter has a matching operator.
64 * I think this is resolved *
65 There is currently a restriction that operators must take their parameters as const references
66 or as copies. This could be solved by specifying special wrapper types for const references and
67 non-const references. Binary operators shouldn't implicitly convert it's parameters to const&.
70 The application operator do not currently work on const objects. Again, to solve this we need
71 some kind of wrapper to say that the self object is const.
73 Make sure we don't have any memory leaks when we use lua_error()
75 We should avoid names that begins with lua_ (in our own scopes) since the lua distribution
76 have plenty of defines with that prefix.
78 Optimize by calling lua_rawset/get instead of lua_settable/gettable
81 use ordinary function pointers instead of boost::function.
82 the boost::function is only used on member functions now, We have to use it in order
83 to support free functions as member functions.
86 when we register classes we should import all methods and properties
87 from the base classes into the class. We will then need to offset the object pointer
88 on a per method/property basis. This will allow methods from the base class to be
89 overloaded without shadowing the base class. The method lookup will also be
92 remove methods from methodtable of classrep when overloading them in lua
95 we currently set uninitialized references to -1, they should be set to LUA_NOREF!
98 the error exception class should avoid heap allocations
103 document custom policies, custom converters
105 store the instance object for policies.
107 support the __concat metamethod. This is a bit tricky, since it cannot be
108 treated as a normal operator. It is a binary operator but we want to use the
109 __tostring implementation for both arguments.
111 smart pointer support
115 __finalize function on lua classes
117 make all proxy_callers one policy based class
119 make all proxy_objects one policy based class
125 #include <luabind/config.hpp>
132 #include <boost/static_assert.hpp>
133 #include <boost/type_traits.hpp>
134 #include <boost/bind.hpp>
135 #include <boost/function.hpp>
136 #include <boost/preprocessor/repetition/enum_params.hpp>
137 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
138 #include <boost/preprocessor/repetition/repeat.hpp>
139 #include <boost/type_traits/is_same.hpp>
140 #include <boost/mpl/list.hpp>
141 #include <boost/mpl/apply.hpp>
142 #include <boost/mpl/lambda.hpp>
143 #include <boost/mpl/logical.hpp>
144 #include <boost/mpl/find_if.hpp>
145 #include <boost/mpl/apply_if.hpp>
146 #include <boost/mpl/logical.hpp>
148 #include <luabind/config.hpp>
149 #include <luabind/scope.hpp>
150 #include <luabind/detail/constructor.hpp>
151 #include <luabind/detail/call.hpp>
152 #include <luabind/detail/signature_match.hpp>
153 #include <luabind/detail/primitives.hpp>
154 #include <luabind/detail/property.hpp>
155 #include <luabind/detail/typetraits.hpp>
156 #include <luabind/detail/class_rep.hpp>
157 #include <luabind/detail/method_rep.hpp>
158 #include <luabind/detail/construct_rep.hpp>
159 #include <luabind/detail/object_rep.hpp>
160 #include <luabind/detail/operators.hpp>
161 #include <luabind/detail/calc_arity.hpp>
162 #include <luabind/detail/call_member.hpp>
163 #include <luabind/detail/enum_maker.hpp>
164 #include <luabind/detail/get_signature.hpp>
165 #include <luabind/detail/implicit_cast.hpp>
166 #include <luabind/detail/operator_id.hpp>
172 struct unspecified
{};
175 template<class T
, class X1
= detail::unspecified
, class X2
= detail::unspecified
, class X3
= detail::unspecified
>
180 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES
, class A
)>
181 double is_bases_helper(const bases
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES
, A
)>&);
185 char is_bases_helper(const T
&);
187 char is_bases_helper(...);
195 BOOST_STATIC_CONSTANT(bool, value
= sizeof(is_bases_helper(t
)) == sizeof(double));
196 typedef boost::mpl::bool_
<value
> type
;
197 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_bases
,(T
))
200 double is_not_unspecified_helper(const unspecified
*);
201 char is_not_unspecified_helper(...);
204 struct is_not_unspecified
206 BOOST_STATIC_CONSTANT(bool, value
= sizeof(is_not_unspecified_helper(static_cast<T
*>(0))) == sizeof(char));
207 typedef boost::mpl::bool_
<value
> type
;
208 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_not_unspecified
,(T
))
211 template<class Predicate
>
214 typedef typename
boost::mpl::and_
<
216 , is_not_unspecified
<boost::mpl::_1
>
220 template<class Parameters
, class Predicate
, class DefaultValue
>
221 struct extract_parameter
223 typedef typename get_predicate
<Predicate
>::type pred
;
224 typedef typename
boost::mpl::find_if
<Parameters
, pred
>::type iterator
;
225 typedef typename
boost::mpl::apply_if
<boost::is_same
<iterator
, typename
boost::mpl::end
<Parameters
>::type
>
226 , boost::mpl::identity
<DefaultValue
>
231 int function_dispatcher(lua_State
* L
);
233 // this should know about the smart pointer type.
234 // and should really do:
235 // get_pointer(*static_cast<SmartPointer*>(obj_ptr))
236 // to extract the held pointer.
237 template<class HeldType
, class T
, class F
, class Policies
>
238 struct function_callback_non_null
240 function_callback_non_null(F f_
): f(f_
) {}
241 inline int operator()(lua_State
* L
, void* obj_ptr
)
243 HeldType
& held_obj
= *static_cast<HeldType
*>(obj_ptr
);
245 T
* ptr
= get_pointer(held_obj
);
246 // BOOST_STATIC_ASSERT((boost::is_same<HeldType, detail::null_type>::value == false));
248 // std::cout << "HeldType: " << typeid(HeldType).name() << "\n";
250 return call(f
, ptr
, L
, static_cast<Policies
*>(this));
255 template<class T
, class F
, class Policies
>
256 struct function_callback_null_type
: Policies
258 function_callback_null_type(F f_
): f(f_
) {}
259 inline int operator()(lua_State
* L
, void* obj_ptr
)
261 // std::cout << "HeldType: null_type\n";
262 T
* ptr
= static_cast<T
*>(obj_ptr
);
263 return call(f
, ptr
, L
, static_cast<Policies
*>(this));
268 template<class HeldType
, class T
, class F
, class Policies
>
269 struct function_callback_s
272 boost::mpl::if_
<boost::is_same
<HeldType
,detail::null_type
>
273 , function_callback_null_type
<T
,F
,Policies
>
274 , function_callback_non_null
<HeldType
,T
,F
,Policies
>
278 template<class T
, class F
, class Policies
>
279 struct match_function_callback_s
281 static inline int apply(lua_State
* L
)
283 object_rep
* obj
= static_cast<object_rep
*>(lua_touserdata(L
, 1));
285 return match(fptr
, L
, obj
->flags() & object_rep::constant
, static_cast<Policies
*>(0));
289 // prints the types of the values on the stack, in the
290 // range [start_index, lua_gettop()]
291 inline std::string
stack_content_by_name(lua_State
* L
, int start_index
)
294 int top
= lua_gettop(L
);
295 for (int i
= start_index
; i
<= top
; ++i
)
297 object_rep
* obj
= is_class_object(L
, i
);
298 class_rep
* crep
= is_class_rep(L
, i
)?(class_rep
*)lua_touserdata(L
, i
):0;
299 if (obj
== 0 && crep
== 0)
301 int type
= lua_type(L
, i
);
302 ret
+= lua_typename(L
, type
);
306 if (obj
->flags() & object_rep::constant
) ret
+= "const ";
307 ret
+= obj
->crep()->name();
315 if (i
< top
) ret
+= ", ";
322 static int stage2(lua_State
* L
)
325 class_rep
* crep
= static_cast<class_rep
*>(lua_touserdata(L
, lua_upvalueindex(1)));
326 assert((crep
!= 0) && "internal error, please report");
327 assert((is_class_rep(L
, lua_upvalueindex(1))) && "internal error, please report");
329 #ifndef LUABIND_NO_ERROR_CHECKING
331 if (!is_class_rep(L
, 1))
333 lua_pushstring(L
, "expected class to derive from or a newline");
339 class_rep
* base
= static_cast<class_rep
*>(lua_touserdata(L
, 1));
341 class_rep::base_info binfo
;
343 binfo
.pointer_offset
= 0;
345 crep
->add_base_class(binfo
);
347 if (base
->get_class_type() == class_rep::lua_class
)
349 // copy base class members
351 detail::getref(L
, crep
->table_ref());
352 detail::getref(L
, base
->table_ref());
355 while (lua_next(L
, -2))
357 lua_pushstring(L
, "__init");
358 if (lua_equal(L
, -1, -3))
364 lua_pushstring(L
, "__finalize");
365 if (lua_equal(L
, -1, -3))
371 lua_pushvalue(L
, -2); // copy key
377 crep
->set_type(base
->type());
382 static int stage1(lua_State
* L
)
385 #ifndef LUABIND_NO_ERROR_CHECKING
387 if (lua_gettop(L
) != 1 || lua_type(L
, 1) != LUA_TSTRING
|| lua_isnumber(L
, 1))
389 lua_pushstring(L
, "invalid construct, expected class name");
395 const char* name
= lua_tostring(L
, 1);
397 void* c
= lua_newuserdata(L
, sizeof(class_rep
));
398 new(c
) class_rep(L
, name
);
400 // make the class globally available
401 lua_pushstring(L
, name
);
402 lua_pushvalue(L
, -2);
403 lua_settable(L
, LUA_GLOBALSINDEX
);
405 // also add it to the closure as return value
406 lua_pushcclosure(L
, &stage2
, 1);
413 struct register_wrapped_type
415 template<class Signature
, class Policies
>
416 static void apply(detail::construct_rep::overload_t
& o
, const Signature
*, const Policies
*)
418 o
.set_wrapped_constructor(
419 &detail::construct_wrapped_class
<Type
, Policies
, Signature
>::apply
425 struct register_wrapped_type
<detail::null_type
>
427 template<class Signature
, class Policies
>
428 static void apply(detail::construct_rep::overload_t
&, const Signature
*, const Policies
*) {}
432 // if the class is held by a smart pointer, we need to be able to
433 // implicitly dereference the pointer when needed.
435 template<class UnderlyingT
, class HeldT
>
436 struct extract_underlying_type
438 static void* extract(void* ptr
)
440 HeldT
& held_obj
= *reinterpret_cast<HeldT
*>(ptr
);
441 UnderlyingT
* underlying_ptr
= get_pointer(held_obj
);
442 return underlying_ptr
;
447 template<class HeldType
>
448 struct internal_held_type_extractor
450 typedef void*(*extractor_fun
)(void*);
453 static extractor_fun
apply(detail::type
<T
>)
455 return detail::extract_underlying_type
<T
, HeldType
>::extract
;
460 struct internal_held_type_extractor
<detail::null_type
>
462 typedef void*(*extractor_fun
)(void*);
465 static extractor_fun
apply(detail::type
<T
>)
471 template<class HeldType
>
472 struct internal_held_type
474 static LUABIND_TYPE_INFO
apply()
476 return LUABIND_TYPEID(HeldType
);
481 struct internal_held_type
<detail::null_type
>
483 static LUABIND_TYPE_INFO
apply()
485 return LUABIND_INVALID_TYPE_INFO
;
504 struct class_base
: detail::scoped_object
510 LUABIND_TYPE_INFO type
;
522 std::map
<const char*, detail::method_rep
, detail::ltstr
> m_methods
;
524 // datamembers, some members may be readonly, and
525 // only have a getter function
526 std::map
<const char*, detail::class_rep::callback
, detail::ltstr
> m_getters
;
527 std::map
<const char*, detail::class_rep::callback
, detail::ltstr
> m_setters
;
529 // the operators in lua
530 std::vector
<detail::class_rep::operator_callback
> m_operators
[detail::number_of_operators
];
531 std::map
<const char*, int, detail::ltstr
> m_static_constants
;
533 std::vector
<base_desc
> m_bases
;
534 detail::construct_rep m_constructor
;
536 void(*m_destructor
)(void*);
537 void*(*m_extractor
)(void*);
539 LUABIND_TYPE_INFO m_type
;
540 LUABIND_TYPE_INFO m_held_type
;
542 #ifndef LUABIND_DONT_COPY_STRINGS
543 // the maps that contains char pointers points into
544 // this vector of strings.
545 std::vector
<char*> m_strings
;
550 void set_type(LUABIND_TYPE_INFO t
) { m_type
= t
; }
551 void set_held_type(LUABIND_TYPE_INFO t
) { m_held_type
= t
; }
552 void set_extractor(void*(*f
)(void*)) { m_extractor
= f
; }
553 void set_destructor(void(*f
)(void*)) { m_destructor
= f
; }
555 inline void add_getter(const char* name
, const boost::function2
<int, lua_State
*, int>& g
)
557 detail::class_rep::callback c
;
559 c
.pointer_offset
= 0;
560 #ifndef LUABIND_DONT_COPY_STRINGS
561 m_strings
.push_back(detail::dup_string(name
));
562 m_getters
[m_strings
.back()] = c
;
568 inline void add_setter(const char* name
, const boost::function2
<int, lua_State
*, int>& s
)
570 detail::class_rep::callback c
;
572 c
.pointer_offset
= 0;
573 #ifndef LUABIND_DONT_COPY_STRINGS
574 m_strings
.push_back(detail::dup_string(name
));
575 m_setters
[m_strings
.back()] = c
;
581 void add_base(const base_desc
& b
)
583 m_bases
.push_back(b
);
588 void add_constructor(const detail::construct_rep::overload_t
& o
)
590 m_constructor
.overloads
.push_back(o
);
593 void add_method(const char* name
, const detail::overload_rep
& o
)
595 #ifdef LUABIND_DONT_COPY_STRINGS
596 detail::method_rep
& method
= m_methods
[name
];
599 m_strings
.push_back(detail::dup_string(name
));
600 detail::method_rep
& method
= m_methods
[m_strings
.back()];
601 method
.name
= m_strings
.back();
603 method
.add_overload(o
);
607 #ifndef LUABIND_NO_ERROR_CHECKING
608 inline void add_operator(int op_id
, int(*func
)(lua_State
*), int(*matcher
)(lua_State
*), void(*sig
)(lua_State
*, std::string
&), int arity
)
610 inline void add_operator(int op_id
, int(*func
)(lua_State
*), int(*matcher
)(lua_State
*), int arity
)
613 detail::class_rep::operator_callback o
;
615 o
.set_match_fun(matcher
);
618 #ifndef LUABIND_NO_ERROR_CHECKING
623 m_operators
[op_id
].push_back(o
);
632 const char* name() const { return m_name
; }
634 class_base(const char* name
): m_name(name
)
641 virtual ~class_base()
643 // if we are copying strings, we have to destroy them too
644 #ifndef LUABIND_DONT_COPY_STRINGS
645 for (std::vector
<char*>::iterator i
= m_strings
.begin(); i
!= m_strings
.end(); ++i
)
650 // pushes the class_rep on the lua stack
651 virtual void commit(lua_State
* L
)
653 detail::class_rep
* crep
;
655 detail::class_registry
* r
= detail::class_registry::get_registry(L
);
656 // create a class_rep structure for this class.
657 // allocate it within lua to let lua collect it on
658 // lua_close(). This is better than allocating it
659 // as a static, since it will then be destructed
660 // when the program exits instead.
661 // warning: we assume that lua will not
662 // move the userdata memory.
663 lua_newuserdata(L
, sizeof(detail::class_rep
));
664 crep
= reinterpret_cast<detail::class_rep
*>(lua_touserdata(L
, -1));
666 new(crep
) detail::class_rep(m_type
, m_name
, L
, m_destructor
, m_held_type
, m_extractor
);
668 // register this new type in the class registry
669 r
->add_class(m_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 std::swap(crep
->m_strings
, m_strings
);
687 std::swap(crep
->m_getters
, m_getters
);
688 std::swap(crep
->m_setters
, m_setters
);
690 for(int i
= 0; i
< detail::number_of_operators
; ++i
)
691 std::swap(crep
->m_operators
[i
], m_operators
[i
]);
693 std::swap(crep
->m_static_constants
, m_static_constants
);
695 for (std::vector
<base_desc
>::iterator i
= m_bases
.begin();
699 detail::class_registry
* r
= detail::class_registry::get_registry(L
);
701 // the baseclass' class_rep structure
702 detail::class_rep
* bcrep
= r
->find_class(i
->type
);
704 detail::class_rep::base_info base
;
705 base
.pointer_offset
= i
->ptr_offset
;
708 crep
->add_base_class(base
);
713 virtual luabind::detail::scoped_object
* clone()
715 assert(m_cloned
== false);
721 class_base
* ret
= new class_base(m_name
);
723 std::swap(ret
->m_getters
, m_getters
);
724 std::swap(ret
->m_setters
, m_setters
);
726 for(int i
= 0; i
< detail::number_of_operators
; ++i
)
727 std::swap(ret
->m_operators
[i
], m_operators
[i
]);
729 std::swap(ret
->m_static_constants
, m_static_constants
);
730 ret
->m_destructor
= m_destructor
;
732 std::swap(ret
->m_bases
, m_bases
);
733 std::swap(ret
->m_methods
, m_methods
);
734 m_constructor
.swap(ret
->m_constructor
);
736 #ifndef LUABIND_DONT_COPY_STRINGS
737 std::swap(ret
->m_strings
, m_strings
);
755 // registers a class in the lua environment
756 template<class T
, class X1
, class X2
, class X3
>
757 struct class_
: class_base
759 typedef class_
<T
, X1
, X2
, X3
> self_t
;
765 template<class A
, class B
, class C
, class D
>
766 class_(const class_
<A
,B
,C
,D
>&);
770 // WrappedType MUST inherit from T
771 typedef typename
detail::extract_parameter
<
772 boost::mpl::vector3
<X1
,X2
,X3
>
773 , boost::is_base_and_derived
<T
, boost::mpl::_
>
774 /* , boost::mpl::not_<
776 detail::is_bases<boost::mpl::_>
777 , boost::is_base_and_derived<boost::mpl::_, T>
783 typedef typename
detail::extract_parameter
<
784 boost::mpl::vector3
<X1
,X2
,X3
>
788 detail::is_bases
<boost::mpl::_
>
789 , boost::is_base_and_derived
<boost::mpl::_
, T
>
791 , boost::is_base_and_derived
<T
, boost::mpl::_
>
797 // this function generates conversion information
798 // in the given class_rep structure. It will be able
799 // to implicitly cast to the given template type
801 void gen_base_info(detail::type
<To
>)
803 // fist, make sure the given base class is registered.
804 // if it's not registered we can't push it's lua table onto
805 // the stack because it doesn't have a table
807 // try to cast this type to the base type and remember
808 // the pointer offset. For multiple inheritance the pointer
809 // may change when casting. Since we need to be able to
810 // cast we need this pointer offset.
811 // store the information in this class' base class-vector
813 base
.type
= LUABIND_TYPEID(To
);
814 base
.ptr_offset
= detail::ptr_offset(detail::type
<T
>(), detail::type
<To
>());
818 void gen_base_info(detail::type
<detail::null_type
>)
821 #define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type<B##n>());
823 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES
, class B
)>
824 void generate_baseclass_list(detail::type
<bases
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES
, B
)> >)
826 BOOST_PP_REPEAT(LUABIND_MAX_BASES
, LUABIND_GEN_BASE_INFO
, _
)
829 #undef LUABIND_GEN_BASE_INFO
831 // this is the internal version of def() it is run from both overloads
832 // of def. It has two versions, one where a contstructor is registered
833 // and one where a function is registered
834 template<class Policies
>
835 struct internal_def_s
838 static void apply(const char* name
, F f
, class_base
* c
)
840 // std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";
842 detail::overload_rep
o(f
, static_cast<Policies
*>(0));
844 typedef LUABIND_MSVC_TYPENAME
detail::function_callback_s
<HeldType
,T
,F
,Policies
>::type call_t
;
846 o
.set_match_fun(&detail::match_function_callback_s
<T
,F
,Policies
>::apply
);
847 o
.call_fun
= boost::bind
<int>(call_t(f
), _1
, _2
);
849 #ifndef LUABIND_NO_ERROR_CHECKING
851 o
.set_sig_fun(&detail::get_member_signature
<F
>::apply
);
855 c
->add_method(name
, o
);
858 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, class A
)>
859 static void apply(constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)>, class_base
* c
)
861 // std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";
863 detail::construct_rep::overload_t o
;
866 &detail::construct_class
<
869 ,constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)>
873 // if we have a WrappedType, we have to register it's constructor
874 // but if it's null_type (no WrappedType) we should not register it
875 detail::register_wrapped_type
<WrappedType
>::apply(o
,
876 static_cast<const constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)>*>(0),
877 static_cast<const Policies
*>(0));
881 &detail::constructor_match
<
882 constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)>
887 #ifndef LUABIND_NO_ERROR_CHECKING
889 o
.set_sig_fun(&detail::get_signature
<constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> >::apply
);
893 typedef constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> con_t
;
895 o
.set_arity(detail::calc_arity
<con_t::arity
>::apply(con_t(), static_cast<Policies
*>(0)));
897 c
->add_constructor(o
);
902 class_(lua_State
* L_
, const char* name
): class_base(name
), m_L(L_
) { init(); }
903 class_(const char* name
): class_base(name
), m_L(0) { init(); }
905 // TODO: we sould probably commit the object someplace else
910 lua_pushstring(m_L
, name());
912 lua_settable(m_L
, LUA_GLOBALSINDEX
);
917 class_
& def(const char* name
, F f
)
919 internal_def_s
<detail::null_type
>::apply(name
, f
, this);
923 template<class F
, class Policies
>
924 class_
& def(const char* name
, F f
, const Policies
&)
926 internal_def_s
<Policies
>::apply(name
, f
, this);
930 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, class A
)>
931 class_
& def(constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> sig
)
933 internal_def_s
<detail::null_type
>::apply(sig
, this);
937 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, class A
), class Policies
>
938 class_
& def(constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> sig
, const Policies
& policies
)
940 internal_def_s
<Policies
>::apply(sig
, this);
944 template<class Getter
>
945 class_
& property(const char* name
, Getter g
)
947 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
, Getter
, detail::null_type
>(), _1
, _2
, g
));
951 template<class Getter
, class MaybeSetter
>
952 class_
& property(const char* name
, Getter g
, MaybeSetter s
)
954 return property_impl(name
, g
, s
, boost::mpl::bool_
<detail::is_policy_cons
<MaybeSetter
>::value
>());
957 template<class Getter
, class Setter
, class GetPolicies
>
958 class_
& property(const char* name
, Getter g
, Setter s
, const GetPolicies
& get_policies
)
960 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
, Getter
, GetPolicies
>(get_policies
), _1
, _2
, g
));
961 add_setter(name
, boost::bind
<int>(detail::set_caller
<T
, Setter
, detail::null_type
>(), _1
, _2
, s
));
965 template<class Getter
, class Setter
, class GetPolicies
, class SetPolicies
>
966 class_
& property(const char* name
968 , const GetPolicies
& get_policies
969 , const SetPolicies
& set_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
, GetPolicies
>(set_policies
), _1
, _2
, s
));
977 class_
& def_readonly(const char* name
, D
T::*member_ptr
)
979 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
983 template<class D
, class Policies
>
984 class_
& def_readonly(const char* name
, D
T::*member_ptr
, const Policies
& policies
)
986 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,Policies
>(policies
), _1
, _2
, member_ptr
));
991 class_
& def_readwrite(const char* name
, D
T::*member_ptr
)
993 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
994 add_setter(name
, boost::bind
<int>(detail::auto_set
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
998 template<class D
, class GetPolicies
>
999 class_
& def_readwrite(const char* name
, D
T::*member_ptr
, const GetPolicies
& get_policies
)
1001 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,GetPolicies
>(get_policies
), _1
, _2
, member_ptr
));
1002 add_setter(name
, boost::bind
<int>(detail::auto_set
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
1006 template<class D
, class GetPolicies
, class SetPolicies
>
1007 class_
& def_readwrite(const char* name
, D
T::*member_ptr
, const GetPolicies
& get_policies
, const SetPolicies
& set_policies
)
1009 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,GetPolicies
>(get_policies
), _1
, _2
, member_ptr
));
1010 add_setter(name
, boost::bind
<int>(detail::auto_set
<T
,D
,SetPolicies
>(set_policies
), _1
, _2
, member_ptr
));
1014 template<class op_id
, class Left
, class Right
, class Policies
>
1015 class_
& def(detail::operator_
<op_id
, Left
, Right
>, const Policies
& policies
)
1017 typedef typename
detail::operator_unwrapper
<Policies
, op_id
, T
, Left
, Right
> op_type
;
1018 #ifndef LUABIND_NO_ERROR_CHECKING
1019 add_operator(op_type::get_id()
1022 , &detail::get_signature
<constructor
<typename
op_type::left_t
, typename
op_type::right_t
> >::apply
1023 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1025 add_operator(op_type::get_id()
1028 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1033 template<class op_id
, class Left
, class Right
>
1034 class_
& def(detail::operator_
<op_id
, Left
, Right
>)
1036 typedef typename
detail::operator_unwrapper
<detail::null_type
, op_id
, T
, Left
, Right
> op_type
;
1038 #ifndef LUABIND_NO_ERROR_CHECKING
1039 add_operator(op_type::get_id()
1042 , &detail::get_signature
<constructor
<LUABIND_MSVC_TYPENAME
op_type::left_t
, LUABIND_MSVC_TYPENAME
op_type::right_t
> >::apply
1043 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1045 add_operator(op_type::get_id()
1048 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1053 template<class Signature
, bool Constant
>
1054 class_
& def(detail::application_operator
<Signature
, Constant
>*)
1056 typedef detail::application_operator
<Signature
, Constant
, detail::null_type
> op_t
;
1058 int arity
= detail::calc_arity
<Signature::arity
>::apply(Signature(), static_cast<detail::null_type
*>(0));
1060 #ifndef LUABIND_NO_ERROR_CHECKING
1061 add_operator(detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, &detail::get_signature
<Signature
>::apply
, arity
+ 1);
1063 add_operator(detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, arity
+ 1);
1069 template<class Signature
, bool Constant
, class Policies
>
1070 class_
& def(detail::application_operator
<Signature
, Constant
>*, const Policies
& policies
)
1072 typedef detail::application_operator
<Signature
, Constant
, Policies
> op_t
;
1074 int arity
= detail::calc_arity
<Signature::arity
>::apply(Signature(), static_cast<Policies
*>(0));
1076 #ifndef LUABIND_NO_ERROR_CHECKING
1077 add_operator(detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, &detail::get_signature
<Signature
>::apply
, arity
+ 1);
1079 add_operator(detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, arity
+ 1);
1085 detail::enum_maker
<self_t
> enum_(const char*)
1087 return detail::enum_maker
<self_t
>(*this);
1094 typedef typename
detail::extract_parameter
<
1095 boost::mpl::vector3
<X1
,X2
,X3
>
1097 detail::is_bases
<boost::mpl::_
>
1098 , boost::is_base_and_derived
<boost::mpl::_
, T
>
1104 boost::mpl::if_
<detail::is_bases
<bases_t
>
1109 set_type(LUABIND_TYPEID(T
));
1110 set_held_type(detail::internal_held_type
<HeldType
>::apply());
1111 set_extractor(detail::internal_held_type_extractor
<HeldType
>::apply(detail::type
<T
>()));
1112 set_destructor(detail::destructor_s
<T
>::apply
);
1114 generate_baseclass_list(detail::type
<Base
>());
1117 template<class Getter
, class GetPolicies
>
1118 class_
& property_impl(const char* name
,
1120 GetPolicies policies
,
1121 boost::mpl::bool_
<true>)
1123 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
,Getter
,GetPolicies
>(policies
), _1
, _2
, g
));
1127 template<class Getter
, class Setter
>
1128 class_
& property_impl(const char* name
,
1131 boost::mpl::bool_
<false>)
1133 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
,Getter
,detail::null_type
>(), _1
, _2
, g
));
1134 add_setter(name
, boost::bind
<int>(detail::set_caller
<T
,Setter
,detail::null_type
>(), _1
, _2
, s
));
1141 #endif // LUABIND_CLASS_HPP_INCLUDED