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_pushvalue(L
, -2); // copy key
363 crep
->set_type(base
->type());
368 static int stage1(lua_State
* L
)
371 #ifndef LUABIND_NO_ERROR_CHECKING
373 if (lua_gettop(L
) != 1 || lua_type(L
, 1) != LUA_TSTRING
|| lua_isnumber(L
, 1))
375 lua_pushstring(L
, "invalid construct, expected class name");
381 const char* name
= lua_tostring(L
, 1);
383 void* c
= lua_newuserdata(L
, sizeof(class_rep
));
384 new(c
) class_rep(L
, name
);
386 // make the class globally available
387 lua_pushstring(L
, name
);
388 lua_pushvalue(L
, -2);
389 lua_settable(L
, LUA_GLOBALSINDEX
);
391 // also add it to the closure as return value
392 lua_pushcclosure(L
, &stage2
, 1);
399 struct register_wrapped_type
401 template<class Signature
, class Policies
>
402 static void apply(detail::construct_rep::overload_t
& o
, const Signature
*, const Policies
*)
404 o
.set_wrapped_constructor(
405 &detail::construct_wrapped_class
<Type
, Policies
, Signature
>::apply
411 struct register_wrapped_type
<detail::null_type
>
413 template<class Signature
, class Policies
>
414 static void apply(detail::construct_rep::overload_t
&, const Signature
*, const Policies
*) {}
418 // if the class is held by a smart pointer, we need to be able to
419 // implicitly dereference the pointer when needed.
421 template<class UnderlyingT
, class HeldT
>
422 struct extract_underlying_type
424 static void* extract(void* ptr
)
426 HeldT
& held_obj
= *reinterpret_cast<HeldT
*>(ptr
);
427 UnderlyingT
* underlying_ptr
= get_pointer(held_obj
);
428 return underlying_ptr
;
433 template<class HeldType
>
434 struct internal_held_type_extractor
436 typedef void*(*extractor_fun
)(void*);
439 static extractor_fun
apply(detail::type
<T
>)
441 return detail::extract_underlying_type
<T
, HeldType
>::extract
;
446 struct internal_held_type_extractor
<detail::null_type
>
448 typedef void*(*extractor_fun
)(void*);
451 static extractor_fun
apply(detail::type
<T
>)
457 template<class HeldType
>
458 struct internal_held_type
460 static LUABIND_TYPE_INFO
apply()
462 return LUABIND_TYPEID(HeldType
);
467 struct internal_held_type
<detail::null_type
>
469 static LUABIND_TYPE_INFO
apply()
471 return LUABIND_INVALID_TYPE_INFO
;
490 struct class_base
: detail::scoped_object
496 LUABIND_TYPE_INFO type
;
508 std::map
<const char*, detail::method_rep
, detail::ltstr
> m_methods
;
510 // datamembers, some members may be readonly, and
511 // only have a getter function
512 std::map
<const char*, detail::class_rep::callback
, detail::ltstr
> m_getters
;
513 std::map
<const char*, detail::class_rep::callback
, detail::ltstr
> m_setters
;
515 // the operators in lua
516 std::vector
<detail::class_rep::operator_callback
> m_operators
[detail::number_of_operators
];
517 std::map
<const char*, int, detail::ltstr
> m_static_constants
;
519 std::vector
<base_desc
> m_bases
;
520 detail::construct_rep m_constructor
;
522 void(*m_destructor
)(void*);
523 void*(*m_extractor
)(void*);
525 LUABIND_TYPE_INFO m_type
;
526 LUABIND_TYPE_INFO m_held_type
;
528 #ifndef LUABIND_DONT_COPY_STRINGS
529 // the maps that contains char pointers points into
530 // this vector of strings.
531 std::vector
<char*> m_strings
;
536 void set_type(LUABIND_TYPE_INFO t
) { m_type
= t
; }
537 void set_held_type(LUABIND_TYPE_INFO t
) { m_held_type
= t
; }
538 void set_extractor(void*(*f
)(void*)) { m_extractor
= f
; }
539 void set_destructor(void(*f
)(void*)) { m_destructor
= f
; }
541 inline void add_getter(const char* name
, const boost::function2
<int, lua_State
*, int>& g
)
543 detail::class_rep::callback c
;
545 c
.pointer_offset
= 0;
546 #ifndef LUABIND_DONT_COPY_STRINGS
547 m_strings
.push_back(detail::dup_string(name
));
548 m_getters
[m_strings
.back()] = c
;
554 inline void add_setter(const char* name
, const boost::function2
<int, lua_State
*, int>& s
)
556 detail::class_rep::callback c
;
558 c
.pointer_offset
= 0;
559 #ifndef LUABIND_DONT_COPY_STRINGS
560 m_strings
.push_back(detail::dup_string(name
));
561 m_setters
[m_strings
.back()] = c
;
567 void add_base(const base_desc
& b
)
569 m_bases
.push_back(b
);
574 void add_constructor(const detail::construct_rep::overload_t
& o
)
576 m_constructor
.overloads
.push_back(o
);
579 void add_method(const char* name
, const detail::overload_rep
& o
)
581 #ifdef LUABIND_DONT_COPY_STRINGS
582 detail::method_rep
& method
= m_methods
[name
];
585 m_strings
.push_back(detail::dup_string(name
));
586 detail::method_rep
& method
= m_methods
[m_strings
.back()];
587 method
.name
= m_strings
.back();
589 method
.add_overload(o
);
593 #ifndef LUABIND_NO_ERROR_CHECKING
594 inline void add_operator(int op_id
, int(*func
)(lua_State
*), int(*matcher
)(lua_State
*), void(*sig
)(lua_State
*, std::string
&), int arity
)
596 inline void add_operator(int op_id
, int(*func
)(lua_State
*), int(*matcher
)(lua_State
*), int arity
)
599 detail::class_rep::operator_callback o
;
601 o
.set_match_fun(matcher
);
604 #ifndef LUABIND_NO_ERROR_CHECKING
609 m_operators
[op_id
].push_back(o
);
618 const char* name() const { return m_name
; }
620 class_base(const char* name
): m_name(name
)
627 virtual ~class_base()
629 // if we are copying strings, we have to destroy them too
630 #ifndef LUABIND_DONT_COPY_STRINGS
631 for (std::vector
<char*>::iterator i
= m_strings
.begin(); i
!= m_strings
.end(); ++i
)
636 // pushes the class_rep on the lua stack
637 virtual void commit(lua_State
* L
)
639 detail::class_rep
* crep
;
641 detail::class_registry
* r
= detail::class_registry::get_registry(L
);
642 // create a class_rep structure for this class.
643 // allocate it within lua to let lua collect it on
644 // lua_close(). This is better than allocating it
645 // as a static, since it will then be destructed
646 // when the program exits instead.
647 // warning: we assume that lua will not
648 // move the userdata memory.
649 lua_newuserdata(L
, sizeof(detail::class_rep
));
650 crep
= reinterpret_cast<detail::class_rep
*>(lua_touserdata(L
, -1));
652 const char* n
= lua_typename(L
, lua_type(L
, -1));
654 new(crep
) detail::class_rep(m_type
, m_name
, L
, m_destructor
, m_held_type
, m_extractor
);
656 const char* b
= lua_typename(L
, lua_type(L
, -1));
658 // register this new type in the class registry
659 r
->add_class(m_type
, crep
);
662 for (std::map
<const char*, detail::method_rep
, detail::ltstr
>::iterator i
= m_methods
.begin();
663 i
!= m_methods
.end();
666 i
->second
.crep
= crep
;
668 std::swap(crep
->m_methods
, m_methods
);
671 m_constructor
.swap(crep
->m_constructor
);
673 #ifndef LUABIND_DONT_COPY_STRINGS
674 std::swap(crep
->m_strings
, m_strings
);
677 std::swap(crep
->m_getters
, m_getters
);
678 std::swap(crep
->m_setters
, m_setters
);
680 for(int i
= 0; i
< detail::number_of_operators
; ++i
)
681 std::swap(crep
->m_operators
[i
], m_operators
[i
]);
683 std::swap(crep
->m_static_constants
, m_static_constants
);
685 for (std::vector
<base_desc
>::iterator i
= m_bases
.begin();
689 detail::class_registry
* r
= detail::class_registry::get_registry(L
);
691 // the baseclass' class_rep structure
692 detail::class_rep
* bcrep
= r
->find_class(i
->type
);
694 detail::class_rep::base_info base
;
695 base
.pointer_offset
= i
->ptr_offset
;
698 crep
->add_base_class(base
);
703 virtual luabind::detail::scoped_object
* clone()
705 assert(m_cloned
== false);
711 class_base
* ret
= new class_base(m_name
);
713 std::swap(ret
->m_getters
, m_getters
);
714 std::swap(ret
->m_setters
, m_setters
);
716 for(int i
= 0; i
< detail::number_of_operators
; ++i
)
717 std::swap(ret
->m_operators
[i
], m_operators
[i
]);
719 std::swap(ret
->m_static_constants
, m_static_constants
);
720 ret
->m_destructor
= m_destructor
;
722 std::swap(ret
->m_bases
, m_bases
);
723 std::swap(ret
->m_methods
, m_methods
);
724 m_constructor
.swap(ret
->m_constructor
);
726 #ifndef LUABIND_DONT_COPY_STRINGS
727 std::swap(ret
->m_strings
, m_strings
);
745 // registers a class in the lua environment
746 template<class T
, class X1
, class X2
, class X3
>
747 struct class_
: class_base
749 typedef class_
<T
, X1
, X2
, X3
> self_t
;
755 template<class A
, class B
, class C
, class D
>
756 class_(const class_
<A
,B
,C
,D
>&);
760 // WrappedType MUST inherit from T
761 typedef typename
detail::extract_parameter
<
762 boost::mpl::vector3
<X1
,X2
,X3
>
763 , boost::is_base_and_derived
<T
, boost::mpl::_
>
764 /* , boost::mpl::not_<
766 detail::is_bases<boost::mpl::_>
767 , boost::is_base_and_derived<boost::mpl::_, T>
773 typedef typename
detail::extract_parameter
<
774 boost::mpl::vector3
<X1
,X2
,X3
>
778 detail::is_bases
<boost::mpl::_
>
779 , boost::is_base_and_derived
<boost::mpl::_
, T
>
781 , boost::is_base_and_derived
<T
, boost::mpl::_
>
787 // this function generates conversion information
788 // in the given class_rep structure. It will be able
789 // to implicitly cast to the given template type
791 void gen_base_info(detail::type
<To
>)
793 // fist, make sure the given base class is registered.
794 // if it's not registered we can't push it's lua table onto
795 // the stack because it doesn't have a table
797 // try to cast this type to the base type and remember
798 // the pointer offset. For multiple inheritance the pointer
799 // may change when casting. Since we need to be able to
800 // cast we need this pointer offset.
801 // store the information in this class' base class-vector
803 base
.type
= LUABIND_TYPEID(To
);
804 base
.ptr_offset
= detail::ptr_offset(detail::type
<T
>(), detail::type
<To
>());
808 void gen_base_info(detail::type
<detail::null_type
>)
811 #define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type<B##n>());
813 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES
, class B
)>
814 void generate_baseclass_list(detail::type
<bases
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES
, B
)> >)
816 BOOST_PP_REPEAT(LUABIND_MAX_BASES
, LUABIND_GEN_BASE_INFO
, _
)
819 #undef LUABIND_GEN_BASE_INFO
821 // this is the internal version of def() it is run from both overloads
822 // of def. It has two versions, one where a contstructor is registered
823 // and one where a function is registered
824 template<class Policies
>
825 struct internal_def_s
828 static void apply(const char* name
, F f
, class_base
* c
)
830 // std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";
832 detail::overload_rep
o(f
, static_cast<Policies
*>(0));
834 typedef LUABIND_MSVC_TYPENAME
detail::function_callback_s
<HeldType
,T
,F
,Policies
>::type call_t
;
836 o
.set_match_fun(&detail::match_function_callback_s
<T
,F
,Policies
>::apply
);
837 o
.call_fun
= boost::bind
<int>(call_t(f
), _1
, _2
);
839 #ifndef LUABIND_NO_ERROR_CHECKING
841 o
.set_sig_fun(&detail::get_member_signature
<F
>::apply
);
845 c
->add_method(name
, o
);
848 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, class A
)>
849 static void apply(constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)>, class_base
* c
)
851 // std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";
853 detail::construct_rep::overload_t o
;
856 &detail::construct_class
<
859 ,constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)>
863 // if we have a WrappedType, we have to register it's constructor
864 // but if it's null_type (no WrappedType) we should not register it
865 detail::register_wrapped_type
<WrappedType
>::apply(o
,
866 static_cast<const constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)>*>(0),
867 static_cast<const Policies
*>(0));
871 &detail::constructor_match
<
872 constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)>
877 #ifndef LUABIND_NO_ERROR_CHECKING
879 o
.set_sig_fun(&detail::get_signature
<constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> >::apply
);
883 typedef constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> con_t
;
885 o
.set_arity(detail::calc_arity
<con_t::arity
>::apply(con_t(), static_cast<Policies
*>(0)));
887 c
->add_constructor(o
);
892 class_(lua_State
* L_
, const char* name
): class_base(name
), m_L(L_
) { init(); }
893 class_(const char* name
): class_base(name
), m_L(0) { init(); }
895 // TODO: we sould probably commit the object someplace else
900 lua_pushstring(m_L
, name());
902 const char* n
= lua_typename(m_L
, lua_type(m_L
, -1));
903 lua_settable(m_L
, LUA_GLOBALSINDEX
);
908 class_
& def(const char* name
, F f
)
910 internal_def_s
<detail::null_type
>::apply(name
, f
, this);
914 template<class F
, class Policies
>
915 class_
& def(const char* name
, F f
, const Policies
&)
917 internal_def_s
<Policies
>::apply(name
, f
, this);
921 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, class A
)>
922 class_
& def(constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> sig
)
924 internal_def_s
<detail::null_type
>::apply(sig
, this);
928 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, class A
), class Policies
>
929 class_
& def(constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> sig
, const Policies
& policies
)
931 internal_def_s
<Policies
>::apply(sig
, this);
935 template<class Getter
>
936 class_
& property(const char* name
, Getter g
)
938 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
, Getter
, detail::null_type
>(), _1
, _2
, g
));
942 template<class Getter
, class MaybeSetter
>
943 class_
& property(const char* name
, Getter g
, MaybeSetter s
)
945 return property_impl(name
, g
, s
, boost::mpl::bool_
<detail::is_policy_cons
<MaybeSetter
>::value
>());
948 template<class Getter
, class Setter
, class GetPolicies
>
949 class_
& property(const char* name
, Getter g
, Setter s
, const GetPolicies
& get_policies
)
951 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
, Getter
, GetPolicies
>(get_policies
), _1
, _2
, g
));
952 add_setter(name
, boost::bind
<int>(detail::set_caller
<T
, Setter
, detail::null_type
>(), _1
, _2
, s
));
956 template<class Getter
, class Setter
, class GetPolicies
, class SetPolicies
>
957 class_
& property(const char* name
959 , const GetPolicies
& get_policies
960 , const SetPolicies
& set_policies
)
962 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
, Getter
, GetPolicies
>(get_policies
), _1
, _2
, g
));
963 add_setter(name
, boost::bind
<int>(detail::set_caller
<T
, Setter
, GetPolicies
>(set_policies
), _1
, _2
, s
));
968 class_
& def_readonly(const char* name
, D
T::*member_ptr
)
970 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
974 template<class D
, class Policies
>
975 class_
& def_readonly(const char* name
, D
T::*member_ptr
, const Policies
& policies
)
977 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,Policies
>(policies
), _1
, _2
, member_ptr
));
982 class_
& def_readwrite(const char* name
, D
T::*member_ptr
)
984 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
985 add_setter(name
, boost::bind
<int>(detail::auto_set
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
989 template<class D
, class GetPolicies
>
990 class_
& def_readwrite(const char* name
, D
T::*member_ptr
, const GetPolicies
& get_policies
)
992 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,GetPolicies
>(get_policies
), _1
, _2
, member_ptr
));
993 add_setter(name
, boost::bind
<int>(detail::auto_set
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
997 template<class D
, class GetPolicies
, class SetPolicies
>
998 class_
& def_readwrite(const char* name
, D
T::*member_ptr
, const GetPolicies
& get_policies
, const SetPolicies
& set_policies
)
1000 add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,GetPolicies
>(get_policies
), _1
, _2
, member_ptr
));
1001 add_setter(name
, boost::bind
<int>(detail::auto_set
<T
,D
,SetPolicies
>(set_policies
), _1
, _2
, member_ptr
));
1005 template<class op_id
, class Left
, class Right
, class Policies
>
1006 class_
& def(detail::operator_
<op_id
, Left
, Right
>, const Policies
& policies
)
1008 typedef typename
detail::operator_unwrapper
<Policies
, op_id
, T
, Left
, Right
> op_type
;
1009 #ifndef LUABIND_NO_ERROR_CHECKING
1010 add_operator(op_type::get_id()
1013 , &detail::get_signature
<constructor
<typename
op_type::left_t
, typename
op_type::right_t
> >::apply
1014 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1016 add_operator(op_type::get_id()
1019 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1024 template<class op_id
, class Left
, class Right
>
1025 class_
& def(detail::operator_
<op_id
, Left
, Right
>)
1027 typedef typename
detail::operator_unwrapper
<detail::null_type
, 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
<LUABIND_MSVC_TYPENAME
op_type::left_t
, LUABIND_MSVC_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 Signature
, bool Constant
>
1045 class_
& def(detail::application_operator
<Signature
, Constant
>*)
1047 typedef detail::application_operator
<Signature
, Constant
, detail::null_type
> op_t
;
1049 int arity
= detail::calc_arity
<Signature::arity
>::apply(Signature(), static_cast<detail::null_type
*>(0));
1051 #ifndef LUABIND_NO_ERROR_CHECKING
1052 add_operator(detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, &detail::get_signature
<Signature
>::apply
, arity
+ 1);
1054 add_operator(detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, arity
+ 1);
1060 template<class Signature
, bool Constant
, class Policies
>
1061 class_
& def(detail::application_operator
<Signature
, Constant
>*, const Policies
& policies
)
1063 typedef detail::application_operator
<Signature
, Constant
, Policies
> op_t
;
1065 int arity
= detail::calc_arity
<Signature::arity
>::apply(Signature(), static_cast<Policies
*>(0));
1067 #ifndef LUABIND_NO_ERROR_CHECKING
1068 add_operator(detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, &detail::get_signature
<Signature
>::apply
, arity
+ 1);
1070 add_operator(detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, arity
+ 1);
1076 detail::enum_maker
<self_t
> enum_(const char*)
1078 return detail::enum_maker
<self_t
>(*this);
1085 typedef typename
detail::extract_parameter
<
1086 boost::mpl::vector3
<X1
,X2
,X3
>
1088 detail::is_bases
<boost::mpl::_
>
1089 , boost::is_base_and_derived
<boost::mpl::_
, T
>
1095 boost::mpl::if_
<detail::is_bases
<bases_t
>
1100 set_type(LUABIND_TYPEID(T
));
1101 set_held_type(detail::internal_held_type
<HeldType
>::apply());
1102 set_extractor(detail::internal_held_type_extractor
<HeldType
>::apply(detail::type
<T
>()));
1103 set_destructor(detail::destructor_s
<T
>::apply
);
1105 generate_baseclass_list(detail::type
<Base
>());
1108 template<class Getter
, class GetPolicies
>
1109 class_
& property_impl(const char* name
,
1111 GetPolicies policies
,
1112 boost::mpl::bool_
<true>)
1114 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
,Getter
,GetPolicies
>(policies
), _1
, _2
, g
));
1118 template<class Getter
, class Setter
>
1119 class_
& property_impl(const char* name
,
1122 boost::mpl::bool_
<false>)
1124 add_getter(name
, boost::bind
<int>(detail::get_caller
<T
,Getter
,detail::null_type
>(), _1
, _2
, g
));
1125 add_setter(name
, boost::bind
<int>(detail::set_caller
<T
,Setter
,detail::null_type
>(), _1
, _2
, s
));
1132 #endif // LUABIND_CLASS_HPP_INCLUDED