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 make all proxy_callers one policy based class
117 make all proxy_objects one policy based class
123 #include <luabind/config.hpp>
130 #include <boost/static_assert.hpp>
131 #include <boost/type_traits.hpp>
132 #include <boost/bind.hpp>
133 #include <boost/function.hpp>
134 #include <boost/preprocessor/repetition/enum_params.hpp>
135 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
136 #include <boost/preprocessor/repetition/repeat.hpp>
137 #include <boost/type_traits/is_same.hpp>
138 #include <boost/mpl/list.hpp>
139 #include <boost/mpl/apply.hpp>
140 #include <boost/mpl/lambda.hpp>
141 #include <boost/mpl/logical.hpp>
142 #include <boost/mpl/find_if.hpp>
143 #include <boost/mpl/apply_if.hpp>
144 #include <boost/mpl/logical.hpp>
146 #include <luabind/config.hpp>
147 #include <luabind/detail/constructor.hpp>
148 #include <luabind/detail/call.hpp>
149 #include <luabind/detail/signature_match.hpp>
150 #include <luabind/detail/primitives.hpp>
151 #include <luabind/detail/property.hpp>
152 #include <luabind/detail/typetraits.hpp>
153 #include <luabind/detail/class_rep.hpp>
154 #include <luabind/detail/method_rep.hpp>
155 #include <luabind/detail/construct_rep.hpp>
156 #include <luabind/detail/object_rep.hpp>
157 #include <luabind/detail/operators.hpp>
158 #include <luabind/detail/call_member.hpp>
159 #include <luabind/detail/enum_maker.hpp>
160 #include <luabind/detail/get_signature.hpp>
161 #include <luabind/detail/implicit_cast.hpp>
162 #include <luabind/detail/calc_arity.hpp>
168 struct unspecified
{};
171 template<class T
, class X1
= detail::unspecified
, class X2
= detail::unspecified
, class X3
= detail::unspecified
>
176 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES
, class A
)>
177 double is_bases_helper(const bases
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES
, A
)>&);
181 char is_bases_helper(const T
&);
183 char is_bases_helper(...);
191 BOOST_STATIC_CONSTANT(bool, value
= sizeof(is_bases_helper(t
)) == sizeof(double));
192 typedef boost::mpl::bool_
<value
> type
;
193 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_bases
,(T
))
196 double is_not_unspecified_helper(const unspecified
*);
197 char is_not_unspecified_helper(...);
200 struct is_not_unspecified
202 BOOST_STATIC_CONSTANT(bool, value
= sizeof(is_not_unspecified_helper(static_cast<T
*>(0))) == sizeof(char));
203 typedef boost::mpl::bool_
<value
> type
;
204 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_not_unspecified
,(T
))
207 template<class Predicate
>
210 typedef typename
boost::mpl::and_
<
212 , is_not_unspecified
<boost::mpl::_1
>
216 template<class Parameters
, class Predicate
, class DefaultValue
>
217 struct extract_parameter
219 typedef typename get_predicate
<Predicate
>::type pred
;
220 typedef typename
boost::mpl::find_if
<Parameters
, pred
>::type iterator
;
221 typedef typename
boost::mpl::apply_if
<boost::is_same
<iterator
, typename
boost::mpl::end
<Parameters
>::type
>
222 , boost::mpl::identity
<DefaultValue
>
227 int function_dispatcher(lua_State
* L
);
229 // this should know about the smart pointer type.
230 // and should really do:
231 // get_pointer(*static_cast<SmartPointer*>(obj_ptr))
232 // to extract the held pointer.
233 template<class HeldType
, class T
, class F
, class Policies
>
234 struct function_callback_non_null
236 function_callback_non_null(F f_
): f(f_
) {}
237 inline int operator()(lua_State
* L
, void* obj_ptr
)
239 HeldType
& held_obj
= *static_cast<HeldType
*>(obj_ptr
);
241 T
* ptr
= get_pointer(held_obj
);
242 // BOOST_STATIC_ASSERT((boost::is_same<HeldType, detail::null_type>::value == false));
244 // std::cout << "HeldType: " << typeid(HeldType).name() << "\n";
246 return call(f
, ptr
, L
, static_cast<Policies
*>(this));
251 template<class T
, class F
, class Policies
>
252 struct function_callback_null_type
: Policies
254 function_callback_null_type(F f_
): f(f_
) {}
255 inline int operator()(lua_State
* L
, void* obj_ptr
)
257 // std::cout << "HeldType: null_type\n";
258 T
* ptr
= static_cast<T
*>(obj_ptr
);
259 return call(f
, ptr
, L
, static_cast<Policies
*>(this));
264 template<class HeldType
, class T
, class F
, class Policies
>
265 struct function_callback_s
268 boost::mpl::if_
<boost::is_same
<HeldType
,detail::null_type
>
269 , function_callback_null_type
<T
,F
,Policies
>
270 , function_callback_non_null
<HeldType
,T
,F
,Policies
>
274 template<class T
, class F
, class Policies
>
275 struct match_function_callback_s
277 static inline int apply(lua_State
* L
)
279 object_rep
* obj
= static_cast<object_rep
*>(lua_touserdata(L
, 1));
281 return match(fptr
, L
, obj
->flags() & object_rep::constant
, static_cast<Policies
*>(0));
285 // prints the types of the values on the stack, in the
286 // range [start_index, lua_gettop()]
287 inline std::string
stack_content_by_name(lua_State
* L
, int start_index
)
290 int top
= lua_gettop(L
);
291 for (int i
= start_index
; i
<= top
; ++i
)
293 object_rep
* obj
= is_class_object(L
, i
);
294 class_rep
* crep
= is_class_rep(L
, i
)?(class_rep
*)lua_touserdata(L
, i
):0;
295 if (obj
== 0 && crep
== 0)
297 int type
= lua_type(L
, i
);
298 ret
+= lua_typename(L
, type
);
302 if (obj
->flags() & object_rep::constant
) ret
+= "const ";
303 ret
+= obj
->crep()->name();
311 if (i
< top
) ret
+= ", ";
318 static int stage2(lua_State
* L
)
321 class_rep
* crep
= static_cast<class_rep
*>(lua_touserdata(L
, lua_upvalueindex(1)));
322 assert((crep
!= 0) && "internal error, please report");
323 assert((is_class_rep(L
, lua_upvalueindex(1))) && "internal error, please report");
325 #ifndef LUABIND_NO_ERROR_CHECKING
327 if (!is_class_rep(L
, 1))
329 lua_pushstring(L
, "expected class to derive from or a newline");
335 class_rep
* base
= static_cast<class_rep
*>(lua_touserdata(L
, 1));
337 class_rep::base_info binfo
;
339 binfo
.pointer_offset
= 0;
341 crep
->add_base(binfo
);
343 if (base
->get_class_type() == class_rep::lua_class
)
345 // copy base class members
347 detail::getref(L
, crep
->table_ref());
348 detail::getref(L
, base
->table_ref());
351 while (lua_next(L
, -2))
353 lua_pushvalue(L
, -2); // copy key
359 crep
->set_type(base
->type());
364 static int stage1(lua_State
* L
)
367 #ifndef LUABIND_NO_ERROR_CHECKING
369 if (lua_gettop(L
) != 1 || lua_type(L
, 1) != LUA_TSTRING
|| lua_isnumber(L
, 1))
371 lua_pushstring(L
, "invalid construct, expected class name");
377 const char* name
= lua_tostring(L
, 1);
379 void* c
= lua_newuserdata(L
, sizeof(class_rep
));
381 lua_pushvalue(L
, -1);
382 // the global name of the class is registered inside this constructor
383 new(c
) class_rep(L
, name
);
384 lua_pushcclosure(L
, &stage2
, 1);
391 struct register_wrapped_type
393 template<class Signature
, class Policies
>
394 static void apply(detail::construct_rep::overload_t
& o
, const Signature
*, const Policies
*)
396 o
.set_wrapped_constructor(
397 &detail::construct_wrapped_class
<Type
, Policies
, Signature
>::apply
403 struct register_wrapped_type
<detail::null_type
>
405 template<class Signature
, class Policies
>
406 static void apply(detail::construct_rep::overload_t
&, const Signature
*, const Policies
*) {}
410 // if the class is held by a smart pointer, we need to be able to
411 // implicitly dereference the pointer when needed.
413 template<class UnderlyingT
, class HeldT
>
414 struct extract_underlying_type
416 static void* extract(void* ptr
)
418 HeldT
& held_obj
= *reinterpret_cast<HeldT
*>(ptr
);
419 UnderlyingT
* underlying_ptr
= get_pointer(held_obj
);
420 return underlying_ptr
;
424 template<class HeldType
>
425 struct internal_new_crep
428 static void apply(detail::class_rep
* crep
, const char* name
, lua_State
* L
, detail::class_registry
* r
, detail::type
<T
>)
430 new(crep
) detail::class_rep(LUABIND_TYPEID(T
),
433 detail::destructor_s
<T
>::apply
,
434 LUABIND_TYPEID(HeldType
),
435 detail::extract_underlying_type
<
436 T
, HeldType
>::extract
);
438 if (r
->classes
.find(LUABIND_TYPEID(HeldType
)) == r
->classes
.end())
440 r
->classes
[LUABIND_TYPEID(HeldType
)] = crep
;
446 struct internal_new_crep
<detail::null_type
>
449 static void apply(detail::class_rep
* crep
, const char* name
, lua_State
* L
, detail::class_registry
* r
, detail::type
<T
>)
451 new(crep
) detail::class_rep(LUABIND_TYPEID(T
),
454 detail::destructor_s
<T
>::apply
,
455 LUABIND_INVALID_TYPE_INFO
,
462 // registers a class in the lua environment
463 template<class T
, class X1
, class X2
, class X3
>
466 typedef class_
<T
, X1
, X2
, X3
> self_t
;
469 template<class A
, class B
, class C
, class D
>
470 class_(const class_
<A
,B
,C
,D
>&);
473 // WrappedType MUST inherit from T
474 typedef typename
detail::extract_parameter
<
475 boost::mpl::vector3
<X1
,X2
,X3
>
476 , boost::is_base_and_derived
<T
, boost::mpl::_
>
477 /* , boost::mpl::not_<
479 detail::is_bases<boost::mpl::_>
480 , boost::is_base_and_derived<boost::mpl::_, T>
486 typedef typename
detail::extract_parameter
<
487 boost::mpl::vector3
<X1
,X2
,X3
>
491 detail::is_bases
<boost::mpl::_
>
492 , boost::is_base_and_derived
<boost::mpl::_
, T
>
494 , boost::is_base_and_derived
<T
, boost::mpl::_
>
502 detail::class_rep
* m_crep
;
504 // this function generates conversion information
505 // in the given class_rep structure. It will be able
506 // to implicitly cast to the given template type
508 static void gen_base_info(detail::class_rep
* crep
, detail::class_registry
* registry
, detail::type
<To
>)
510 // fist, make sure the given base class is registered.
511 // if it's not registered we can't push it's lua table onto
512 // the stack because it doesn't have a table
514 // If you hit this assert you are deriving from a type that is not registered
515 // in lua. That is, in the class_<> you are giving a baseclass that isn't registered.
516 // Please note that if you don't need to have access to the base class or the
517 // conversion from the derived class to the base class, you don't need
518 // to tell luabind that it derives.
519 assert(registry
->find_class(LUABIND_TYPEID(To
)) && "You cannot derive from an unregistered type");
521 // try to cast this type to the base type and remember
522 // the pointer offset. For multiple inheritance the pointer
523 // may change when casting. Since we need to be able to
524 // cast we need this pointer offset.
525 // store the information in this class' base class-vector
526 detail::class_rep::base_info base
;
527 base
.base
= registry
->find_class(LUABIND_TYPEID(To
));
528 T
* null_pointer
= reinterpret_cast<T
*>(1); // this wont work if the pointer is 0!
529 base
.pointer_offset
= static_cast<int>((reinterpret_cast<char*>(static_cast<To
*>(null_pointer
)) - reinterpret_cast<char*>(null_pointer
)));
530 crep
->add_base(base
);
533 static void gen_base_info(detail::class_rep
*, detail::class_registry
*, detail::type
<detail::null_type
>)
536 #define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(crep, reg, detail::type<B##n>());
538 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES
, class B
)>
539 static void generate_baseclass_list(detail::class_rep
* crep
, detail::class_registry
* reg
, detail::type
<bases
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES
, B
)> >)
541 BOOST_PP_REPEAT(LUABIND_MAX_BASES
, LUABIND_GEN_BASE_INFO
, _
)
544 #undef LUABIND_GEN_BASE_INFO
546 // this is the internal version of def() it is run from both overloads
547 // of def. It has two versions, one where a contstructor is registered
548 // and one where a function is registered
549 template<class Policies
>
550 struct internal_def_s
553 static void apply(const char* name
, F f
, detail::class_rep
* crep
)
555 // std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";
557 detail::overload_rep
o(f
, static_cast<Policies
*>(0));
559 typedef LUABIND_MSVC_TYPENAME
detail::function_callback_s
<HeldType
,T
,F
,Policies
>::type call_t
;
561 o
.set_match_fun(&detail::match_function_callback_s
<T
,F
,Policies
>::apply
);
562 o
.call_fun
= boost::bind
<int>(call_t(f
), _1
, _2
);
564 #ifndef LUABIND_NO_ERROR_CHECKING
566 o
.set_sig_fun(&detail::get_member_signature
<F
>::apply
);
570 crep
->add_function(name
, o
);
573 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, class A
)>
574 static void apply(constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)>, detail::class_rep
* crep
)
576 // std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";
578 detail::construct_rep::overload_t o
;
581 &detail::construct_class
<
584 ,constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)>
588 // if we have a WrappedType, we have to register it's constructor
589 // but if it's null_type (no WrappedType) we should not register it
590 detail::register_wrapped_type
<WrappedType
>::apply(o
,
591 static_cast<const constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)>*>(0),
592 static_cast<const Policies
*>(0));
596 &detail::constructor_match
<
597 constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)>
602 #ifndef LUABIND_NO_ERROR_CHECKING
604 o
.set_sig_fun(&detail::get_signature
<constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> >::apply
);
608 typedef constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> con_t
;
610 o
.set_arity(detail::calc_arity
<con_t::arity
>::apply(con_t(), static_cast<Policies
*>(0)));
612 crep
->add_constructor(o
);
616 class_(lua_State
* L_
, const char* name_
): L(L_
), name(name_
)
619 std::cout << "X1: " << typeid(X1).name() << "\n";
620 std::cout << "X2: " << typeid(X2).name() << "\n";
621 std::cout << "X3: " << typeid(X3).name() << "\n";
622 std::cout << "HeldType1: " << typeid(HeldType).name() << "\n";
624 detail::class_registry
* r
= detail::class_registry::get_registry(L
);
625 // create a class_rep structure for this class.
626 // allocate it within lua to let lua collect it on
627 // lua_close(). This is better than allocating it
628 // as a static, since it will then be destructed
629 // when the program exits instead.
630 // warning: we assume that lua will not
631 // move the userdata memory.
632 lua_newuserdata(L
, sizeof(detail::class_rep
));
633 m_crep
= reinterpret_cast<detail::class_rep
*>(lua_touserdata(L
, -1));
635 detail::internal_new_crep
<HeldType
>::apply(m_crep
, name
, L
, r
, detail::type
<T
>());
637 typedef typename
detail::extract_parameter
<
638 boost::mpl::vector3
<X1
,X2
,X3
>
640 detail::is_bases
<boost::mpl::_
>
641 , boost::is_base_and_derived
<boost::mpl::_
, T
>
647 boost::mpl::if_
<detail::is_bases
<bases_t
>
652 generate_baseclass_list(m_crep
, r
, detail::type
<Base
>());
654 // register this new type in the class registry
655 r
->add_class(LUABIND_TYPEID(T
), m_crep
);
657 // std::cout << "held type: " << typeid(HeldType).name() << '\n';
661 class_
& def(const char* name
, F f
)
663 internal_def_s
<detail::null_type
>::apply(name
, f
, m_crep
);
667 template<class F
, class Policies
>
668 class_
& def(const char* name
, F f
, const Policies
&)
670 internal_def_s
<Policies
>::apply(name
, f
, m_crep
);
674 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, class A
)>
675 class_
& def(constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> sig
)
677 internal_def_s
<detail::null_type
>::apply(sig
, m_crep
);
681 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, class A
), class Policies
>
682 class_
& def(constructor
<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY
, A
)> sig
, const Policies
& policies
)
684 internal_def_s
<Policies
>::apply(sig
, m_crep
);
690 template<class Getter
, class Head
, class Tail
>
691 class_
& property(const char* name
, Getter g
, const detail::policy_cons
<Head
,Tail
>& policies
)
693 typedef detail::policy_cons
<Head
,Tail
> policies_t
;
695 m_crep
->add_getter(name
, boost::bind
<int>(detail::get_caller
<T
, Getter
, policies_t
>(policies
), _1
, _2
, g
));
701 template<class Getter
, class Setter
>
702 class_
& property(const char* name
, Getter g
, Setter s
)
704 m_crep
->add_getter(name
, boost::bind
<int>(detail::get_caller
<T
, Getter
, detail::null_type
>(), _1
, _2
, g
));
705 m_crep
->add_setter(name
, boost::bind
<int>(detail::set_caller
<T
, Setter
, detail::null_type
>(), _1
, _2
, s
));
709 template<class Getter
, class Setter
, class H1
, class T1
>
710 class_
& property(const char* name
, Getter g
, Setter s
, const detail::policy_cons
<H1
,T1
>& get_policies
)
712 typedef detail::policy_cons
<H1
,T1
> get_policies_t
;
714 m_crep
->add_getter(name
, boost::bind
<int>(detail::get_caller
<T
, Getter
, get_policies_t
>(get_policies
), _1
, _2
, g
));
715 m_crep
->add_setter(name
, boost::bind
<int>(detail::set_caller
<T
, Setter
, detail::null_type
>(), _1
, _2
, s
));
719 template<class Getter
, class Setter
, class H2
, class T2
>
720 class_
& property(const char* name
722 , const detail::null_type
&
723 , const detail::policy_cons
<H2
,T2
>& set_policies
)
725 typedef detail::policy_cons
<H2
,T2
> set_policies_t
;
727 m_crep
->add_getter(name
, boost::bind
<int>(detail::get_caller
<T
, Getter
, detail::null_type
>(), _1
, _2
, g
));
728 m_crep
->add_setter(name
, boost::bind
<int>(detail::set_caller
<T
, Setter
, set_policies_t
>(set_policies
), _1
, _2
, s
));
732 template<class Getter
, class Setter
, class H1
, class T1
, class H2
, class T2
>
733 class_
& property(const char* name
735 , const detail::policy_cons
<H1
,T1
>& get_policies
736 , const detail::policy_cons
<H2
,T2
>& set_policies
)
738 typedef detail::policy_cons
<H1
,T1
> get_policies_t
;
739 typedef detail::policy_cons
<H2
,T2
> set_policies_t
;
741 m_crep
->add_getter(name
, boost::bind
<int>(detail::get_caller
<T
, Getter
, get_policies_t
>(get_policies
), _1
, _2
, g
));
742 m_crep
->add_setter(name
, boost::bind
<int>(detail::set_caller
<T
, Setter
, set_policies_t
>(set_policies
), _1
, _2
, s
));
746 template<class Getter
>
747 class_
& property(const char* name
, Getter g
)
749 m_crep
->add_getter(name
, boost::bind
<int>(detail::get_caller
<T
, Getter
, detail::null_type
>(), _1
, _2
, g
));
754 class_
& def_readonly(const char* name
, D
T::*member_ptr
)
756 m_crep
->add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
760 template<class D
, class Policies
>
761 class_
& def_readonly(const char* name
, D
T::*member_ptr
, const Policies
& policies
)
763 m_crep
->add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,Policies
>(policies
), _1
, _2
, member_ptr
));
768 class_
& def_readwrite(const char* name
, D
T::*member_ptr
)
770 m_crep
->add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
771 m_crep
->add_setter(name
, boost::bind
<int>(detail::auto_set
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
775 template<class D
, class GetPolicies
>
776 class_
& def_readwrite(const char* name
, D
T::*member_ptr
, const GetPolicies
& get_policies
)
778 m_crep
->add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,GetPolicies
>(get_policies
), _1
, _2
, member_ptr
));
779 m_crep
->add_setter(name
, boost::bind
<int>(detail::auto_set
<T
,D
,detail::null_type
>(), _1
, _2
, member_ptr
));
783 template<class D
, class GetPolicies
, class SetPolicies
>
784 class_
& def_readwrite(const char* name
, D
T::*member_ptr
, const GetPolicies
& get_policies
, const SetPolicies
& set_policies
)
786 m_crep
->add_getter(name
, boost::bind
<int>(detail::auto_get
<T
,D
,GetPolicies
>(get_policies
), _1
, _2
, member_ptr
));
787 m_crep
->add_setter(name
, boost::bind
<int>(detail::auto_set
<T
,D
,SetPolicies
>(set_policies
), _1
, _2
, member_ptr
));
791 template<class op_id
, class Left
, class Right
, class Policies
>
792 class_
& def(detail::operator_
<op_id
, Left
, Right
>, const Policies
& policies
)
794 typedef typename
detail::operator_unwrapper
<Policies
, op_id
, T
, Left
, Right
> op_type
;
795 #ifndef LUABIND_NO_ERROR_CHECKING
796 m_crep
->add_operator(L
800 , &detail::get_signature
<constructor
<typename
op_type::left_t
, typename
op_type::right_t
> >::apply
801 , detail::is_unary(op_type::get_id()) ? 1 : 2);
803 m_crep
->add_operator(L
807 , detail::is_unary(op_type::get_id()) ? 1 : 2);
812 template<class op_id
, class Left
, class Right
>
813 class_
& def(detail::operator_
<op_id
, Left
, Right
>)
815 typedef typename
detail::operator_unwrapper
<detail::null_type
, op_id
, T
, Left
, Right
> op_type
;
817 #ifndef LUABIND_NO_ERROR_CHECKING
818 m_crep
->add_operator(L
822 , &detail::get_signature
<constructor
<LUABIND_MSVC_TYPENAME
op_type::left_t
, LUABIND_MSVC_TYPENAME
op_type::right_t
> >::apply
823 , detail::is_unary(op_type::get_id()) ? 1 : 2);
825 m_crep
->add_operator(L
829 , detail::is_unary(op_type::get_id()) ? 1 : 2);
834 template<class Signature
, bool Constant
>
835 class_
& def(detail::application_operator
<Signature
, Constant
>*)
837 typedef detail::application_operator
<Signature
, Constant
, detail::null_type
> op_t
;
839 int arity
= detail::calc_arity
<Signature::arity
>::apply(Signature(), static_cast<detail::null_type
*>(0));
841 #ifndef LUABIND_NO_ERROR_CHECKING
842 m_crep
->add_operator(L
, detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, &detail::get_signature
<Signature
>::apply
, arity
+ 1);
844 m_crep
->add_operator(L
, detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, arity
+ 1);
850 template<class Signature
, bool Constant
, class Policies
>
851 class_
& def(detail::application_operator
<Signature
, Constant
>*, const Policies
& policies
)
853 typedef detail::application_operator
<Signature
, Constant
, Policies
> op_t
;
855 int arity
= detail::calc_arity
<Signature::arity
>::apply(Signature(), static_cast<Policies
*>(0));
857 #ifndef LUABIND_NO_ERROR_CHECKING
859 m_crep
->add_operator(L
, detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, &detail::get_signature
<Signature
>::apply
, arity
+ 1);
861 m_crep
->add_operator(L
, detail::op_call
, &op_t::template apply
<T
>::execute
, &op_t::match
, arity
+ 1);
867 detail::enum_maker
<self_t
> enum_(const char*)
869 return detail::enum_maker
<self_t
>(*this);
875 #endif // LUABIND_CLASS_HPP_INCLUDED