📄 class.hpp
字号:
// destructive copy
virtual luabind::detail::scoped_object* clone()
{
assert(m_cloned == false);
#ifndef NDEBUG
m_cloned = true;
#endif
class_base* ret = new class_base(m_name);
std::swap(ret->m_getters, m_getters);
std::swap(ret->m_setters, m_setters);
for(int i = 0; i < detail::number_of_operators; ++i)
std::swap(ret->m_operators[i], m_operators[i]);
std::swap(ret->m_static_constants, m_static_constants);
ret->init(m_type
, m_holder_type
, m_extractor
, m_const_extractor
, m_const_converter
, m_construct_holder
, m_construct_const_holder
, m_destructor
, m_const_holder_destructor
, m_holder_size
, m_holder_alignment);
ret->m_const_holder_type = m_const_holder_type;
std::swap(ret->m_bases, m_bases);
std::swap(ret->m_methods, m_methods);
m_constructor.swap(ret->m_constructor);
ret->m_name = m_name;
#ifndef LUABIND_DONT_COPY_STRINGS
std::swap(ret->m_strings, m_strings);
#endif
return ret;
}
};
// registers a class in the lua environment
template<class T, class X1, class X2, class X3>
struct class_: class_base
{
typedef class_<T, X1, X2, X3> self_t;
lua_State* m_L;
private:
template<class A, class B, class C, class D>
class_(const class_<A,B,C,D>&);
public:
// WrappedType MUST inherit from T
typedef typename detail::extract_parameter<
boost::mpl::vector3<X1,X2,X3>
, boost::is_base_and_derived<T, boost::mpl::_>
/* , boost::mpl::not_<
boost::mpl::or_<
detail::is_bases<boost::mpl::_>
, boost::is_base_and_derived<boost::mpl::_, T>
>
>*/
, detail::null_type
>::type WrappedType;
typedef typename detail::extract_parameter<
boost::mpl::list3<X1,X2,X3>
, boost::mpl::not_<
boost::mpl::or_<
boost::mpl::or_<
detail::is_bases<boost::mpl::_>
, boost::is_base_and_derived<boost::mpl::_, T>
>
, boost::is_base_and_derived<T, boost::mpl::_>
>
>
, detail::null_type
>::type HeldType;
// this function generates conversion information
// in the given class_rep structure. It will be able
// to implicitly cast to the given template type
template<class To>
void gen_base_info(detail::type<To>)
{
// fist, make sure the given base class is registered.
// if it's not registered we can't push it's lua table onto
// the stack because it doesn't have a table
// try to cast this type to the base type and remember
// the pointer offset. For multiple inheritance the pointer
// may change when casting. Since we need to be able to
// cast we need this pointer offset.
// store the information in this class' base class-vector
base_desc base;
base.type = LUABIND_TYPEID(To);
base.ptr_offset = detail::ptr_offset(detail::type<T>(), detail::type<To>());
add_base(base);
}
void gen_base_info(detail::type<detail::null_type>)
{}
#define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type<B##n>());
template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class B)>
void generate_baseclass_list(detail::type<bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, B)> >)
{
BOOST_PP_REPEAT(LUABIND_MAX_BASES, LUABIND_GEN_BASE_INFO, _)
}
#undef LUABIND_GEN_BASE_INFO
// this is the internal version of def() it is run from both overloads
// of def. It has two versions, one where a contstructor is registered
// and one where a function is registered
template<class Policies>
struct internal_def_s
{
template<class F>
static void apply(const char* name, F f, class_base* c)
{
// std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";
detail::overload_rep o(f, static_cast<Policies*>(0));
typedef LUABIND_MSVC_TYPENAME detail::function_callback_s<HeldType,T,F,Policies>::type call_t;
o.set_match_fun(&detail::match_function_callback_s<T,F,Policies>::apply);
o.call_fun = boost::bind<int>(call_t(f), _1, _2);
#ifndef LUABIND_NO_ERROR_CHECKING
o.set_sig_fun(&detail::get_member_signature<F>::apply);
#endif
c->add_method(name, o);
}
template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)>
static void apply(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>, class_base* c)
{
// std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";
detail::construct_rep::overload_t o;
o.set_constructor(
&detail::construct_class<
T
,Policies
,constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>
>::apply
);
// if we have a WrappedType, we have to register it's constructor
// but if it's null_type (no WrappedType) we should not register it
detail::register_wrapped_type<WrappedType>::apply(o,
static_cast<const constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>*>(0),
static_cast<const Policies*>(0));
o.set_match_fun(
&detail::constructor_match<
constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>
,2
,Policies
>::apply);
#ifndef LUABIND_NO_ERROR_CHECKING
o.set_sig_fun(&detail::get_signature<constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> >::apply);
#endif
typedef constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> con_t;
o.set_arity(detail::calc_arity<con_t::arity>::apply(con_t(), static_cast<Policies*>(0)));
c->add_constructor(o);
}
};
class_(lua_State* L, const char* name): class_base(name), m_L(L) { init(); }
class_(const char* name): class_base(name), m_L(0) { init(); }
~class_()
{
if (m_L != 0)
{
scope::init(m_L);
lua_pushvalue(m_L, LUA_GLOBALSINDEX);
scope_stack::push(m_L);
commit(m_L);
scope_stack::pop(m_L);
}
}
template<class F>
class_& def(const char* name, F f)
{
internal_def_s<detail::null_type>::apply(name, f, this);
return *this;
}
template<class F, class Policies>
class_& def(const char* name, F f, const Policies&)
{
internal_def_s<Policies>::apply(name, f, this);
return *this;
}
template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)>
class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig)
{
internal_def_s<detail::null_type>::apply(sig, this);
return *this;
}
template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A), class Policies>
class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig, const Policies& policies)
{
internal_def_s<Policies>::apply(sig, this);
return *this;
}
template<class Getter>
class_& property(const char* name, Getter g)
{
add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, detail::null_type>(), _1, _2, g));
return *this;
}
template<class Getter, class MaybeSetter>
class_& property(const char* name, Getter g, MaybeSetter s)
{
return property_impl(name, g, s, boost::mpl::bool_<detail::is_policy_cons<MaybeSetter>::value>());
}
template<class Getter, class Setter, class GetPolicies>
class_& property(const char* name, Getter g, Setter s, const GetPolicies& get_policies)
{
add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, GetPolicies>(get_policies), _1, _2, g));
add_setter(name, boost::bind<int>(detail::set_caller<T, Setter, detail::null_type>(), _1, _2, s));
return *this;
}
template<class Getter, class Setter, class GetPolicies, class SetPolicies>
class_& property(const char* name
, Getter g, Setter s
, const GetPolicies& get_policies
, const SetPolicies& set_policies)
{
add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, GetPolicies>(get_policies), _1, _2, g));
add_setter(name, boost::bind<int>(detail::set_caller<T, Setter, GetPolicies>(set_policies), _1, _2, s));
return *this;
}
template<class D>
class_& def_readonly(const char* name, D T::*member_ptr)
{
add_getter(name, boost::bind<int>(detail::auto_get<T,D,detail::null_type>(), _1, _2, member_ptr));
return *this;
}
template<class D, class Policies>
class_& def_readonly(const char* name, D T::*member_ptr, const Policies& policies)
{
add_getter(name, boost::bind<int>(detail::auto_get<T,D,Policies>(policies), _1, _2, member_ptr));
return *this;
}
template<class D>
class_& def_readwrite(const char* name, D T::*member_ptr)
{
add_getter(name, boost::bind<int>(detail::auto_get<T,D,detail::null_type>(), _1, _2, member_ptr));
add_setter(name, boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr));
return *this;
}
template<class D, class GetPolicies>
class_& def_readwrite(const char* name, D T::*member_ptr, const GetPolicies& get_policies)
{
add_getter(name, boost::bind<int>(detail::auto_get<T,D,GetPolicies>(get_policies), _1, _2, member_ptr));
add_setter(name, boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr));
return *this;
}
template<class D, class GetPolicies, class SetPolicies>
class_& def_readwrite(const char* name, D T::*member_ptr, const GetPolicies& get_policies, const SetPolicies& set_policies)
{
add_getter(name, boost::bind<int>(detail::auto_get<T,D,GetPolicies>(get_policies), _1, _2, member_ptr));
add_setter(name, boost::bind<int>(detail::auto_set<T,D,SetPolicies>(set_policies), _1, _2, member_ptr));
return *this;
}
template<class op_id, class Left, class Right, class Policies>
class_& def(detail::operator_<op_id, Left, Right>, const Policies& policies)
{
typedef typename detail::operator_unwrapper<Policies, op_id, T, Left, Right> op_type;
#ifndef LUABIND_NO_ERROR_CHECKING
add_operator(op_type::get_id()
, &op_type::execute
, &op_type::match
, &detail::get_signature<constructor<typename op_type::left_t, typename op_type::right_t> >::apply
, detail::is_unary(op_type::get_id()) ? 1 : 2);
#else
add_operator(op_type::get_id()
, &op_type::execute
, &op_type::match
, detail::is_unary(op_type::get_id()) ? 1 : 2);
#endif
return *this;
}
template<class op_id, class Left, class Right>
class_& def(detail::operator_<op_id, Left, Right>)
{
typedef typename detail::operator_unwrapper<detail::null_type, op_id, T, Left, Right> op_type;
#ifndef LUABIND_NO_ERROR_CHECKING
add_operator(op_type::get_id()
, &op_type::execute
, &op_type::match
, &detail::get_signature<constructor<LUABIND_MSVC_TYPENAME op_type::left_t, LUABIND_MSVC_TYPENAME op_type::right_t> >::apply
, detail::is_unary(op_type::get_id()) ? 1 : 2);
#else
add_operator(op_type::get_id()
, &op_type::execute
, &op_type::match
, detail::is_unary(op_type::get_id()) ? 1 : 2);
#endif
return *this;
}
template<class Signature, bool Constant>
class_& def(detail::application_operator<Signature, Constant>*)
{
typedef detail::application_operator<Signature, Constant, detail::null_type> op_t;
int arity = detail::calc_arity<Signature::arity>::apply(Signature(), static_cast<detail::null_type*>(0));
#ifndef LUABIND_NO_ERROR_CHECKING
add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, &detail::get_signature<Signature>::apply, arity + 1);
#else
add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, arity + 1);
#endif
return *this;
}
template<class Signature, bool Constant, class Policies>
class_& def(detail::application_operator<Signature, Constant>*, const Policies& policies)
{
typedef detail::application_operator<Signature, Constant, Policies> op_t;
int arity = detail::calc_arity<Signature::arity>::apply(Signature(), static_cast<Policies*>(0));
#ifndef LUABIND_NO_ERROR_CHECKING
add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, &detail::get_signature<Signature>::apply, arity + 1);
#else
add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, arity + 1);
#endif
return *this;
}
detail::enum_maker<self_t> enum_(const char*)
{
return detail::enum_maker<self_t>(*this);
}
private:
void init()
{
typedef typename detail::extract_parameter<
boost::mpl::list3<X1,X2,X3>
, boost::mpl::or_<
detail::is_bases<boost::mpl::_>
, boost::is_base_and_derived<boost::mpl::_, T>
>
, no_bases
>::type bases_t;
typedef typename
boost::mpl::if_<detail::is_bases<bases_t>
, bases_t
, bases<bases_t>
>::type Base;
HeldType* crap = 0;
class_base::init(LUABIND_TYPEID(T)
, detail::internal_holder_type<HeldType>::apply()
, detail::internal_holder_extractor<HeldType>::apply(detail::type<T>())
, detail::internal_const_holder_extractor<HeldType>::apply(detail::type<T>())
, detail::const_converter<HeldType>::apply(luabind::get_const_holder(crap))
, detail::holder_constructor<HeldType>::apply(detail::type<T>())
, detail::const_holder_constructor<HeldType>::apply(detail::type<T>())
, detail::internal_holder_destructor<HeldType>::apply(detail::type<T>())
, detail::internal_const_holder_destructor<HeldType>::apply(detail::type<T>())
, detail::internal_holder_size<HeldType>::apply()
, detail::get_holder_alignment<HeldType>::apply());
set_const_holder_type(luabind::get_const_holder(static_cast<HeldType*>(0)));
generate_baseclass_list(detail::type<Base>());
}
template<class Getter, class GetPolicies>
class_& property_impl(const char* name,
Getter g,
GetPolicies policies,
boost::mpl::bool_<true>)
{
add_getter(name, boost::bind<int>(detail::get_caller<T,Getter,GetPolicies>(policies), _1, _2, g));
return *this;
}
template<class Getter, class Setter>
class_& property_impl(const char* name,
Getter g,
Setter s,
boost::mpl::bool_<false>)
{
add_getter(name, boost::bind<int>(detail::get_caller<T,Getter,detail::null_type>(), _1, _2, g));
add_setter(name, boost::bind<int>(detail::set_caller<T,Setter,detail::null_type>(), _1, _2, s));
return *this;
}
};
}
#endif // LUABIND_CLASS_HPP_INCLUDED
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -