object.hpp
来自「这是整套横扫千军3D版游戏的源码」· HPP 代码 · 共 1,163 行 · 第 1/2 页
HPP
1,163 行
template<class T>
this_type& operator=(T const& value)
{
value_wrapper_traits<Next>::unwrap(m_interpreter, m_next);
detail::stack_pop pop(m_interpreter, 1);
lua_pushvalue(m_interpreter, m_key_index);
detail::push(m_interpreter, value);
lua_settable(m_interpreter, -3);
return *this;
}
template<class T>
index_proxy<this_type> operator[](T const& key)
{
return index_proxy<this_type>(*this, m_interpreter, key);
}
void push(lua_State* interpreter);
lua_State* interpreter() const
{
return m_interpreter;
}
private:
this_type& operator=(index_proxy<Next> const&);
mutable lua_State* m_interpreter;
int m_key_index;
Next const& m_next;
};
} // namespace adl
typedef detail::basic_iterator<detail::basic_access> iterator;
typedef detail::basic_iterator<detail::raw_access> raw_iterator;
#ifndef LUABIND_USE_VALUE_WRAPPER_TAG
template<class T>
struct value_wrapper_traits<adl::index_proxy<T> >
#else
template<>
struct value_wrapper_traits<adl::index_proxy_tag>
#endif
{
typedef boost::mpl::true_ is_specialized;
template<class Next>
static lua_State* interpreter(adl::index_proxy<Next> const& proxy)
{
return proxy.interpreter();
}
template<class Next>
static void unwrap(lua_State* interpreter, adl::index_proxy<Next> const& proxy)
{
const_cast<adl::index_proxy<Next>&>(proxy).push(interpreter);
}
};
#ifndef LUABIND_USE_VALUE_WRAPPER_TAG
template<class AccessPolicy>
struct value_wrapper_traits<adl::iterator_proxy<AccessPolicy> >
#else
template<>
struct value_wrapper_traits<adl::iterator_proxy_tag>
#endif
{
typedef boost::mpl::true_ is_specialized;
template<class Proxy>
static lua_State* interpreter(Proxy const& p)
{
return p.interpreter();
}
template<class Proxy>
static void unwrap(lua_State* interpreter, Proxy const& p)
{
// TODO: Why const_cast?
const_cast<Proxy&>(p).push(interpreter);
}
};
namespace adl
{
class object_init
{
protected:
object_init()
{}
explicit object_init(from_stack const& stack_reference, boost::mpl::true_)
: m_handle(stack_reference.interpreter, stack_reference.index)
{
}
template<class ValueWrapper>
explicit object_init(ValueWrapper const& value_wrapper, boost::mpl::false_)
{
lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
value_wrapper
);
value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value_wrapper);
detail::stack_pop pop(interpreter, 1);
handle(interpreter, -1).swap(m_handle);
}
handle m_handle;
};
// An object holds a reference to a Lua value residing
// in the registry.
class object : public object_interface<object>
{
struct safe_bool_type {};
public:
object()
{}
explicit object(handle const& other)
: m_handle(other)
{}
explicit object(from_stack const& stack_reference)
: m_handle(stack_reference.interpreter, stack_reference.index)
{
}
template<class T>
object(lua_State* interpreter, T const& value)
{
detail::push(interpreter, value);
detail::stack_pop pop(interpreter, 1);
handle(interpreter, -1).swap(m_handle);
}
template<class T, class Policies>
object(lua_State* interpreter, T const& value, Policies const&)
{
detail::push(interpreter, value, Policies());
detail::stack_pop pop(interpreter, 1);
handle(interpreter, -1).swap(m_handle);
}
void push(lua_State* interpreter) const;
lua_State* interpreter() const;
bool is_valid() const;
operator safe_bool_type*() const;
template<class T>
index_proxy<object> operator[](T const& key) const
{
return index_proxy<object>(
*this, m_handle.interpreter(), key
);
}
void swap(object& other)
{
m_handle.swap(other.m_handle);
}
private:
handle m_handle;
};
inline void object::push(lua_State* interpreter) const
{
m_handle.push(interpreter);
}
inline lua_State* object::interpreter() const
{
return m_handle.interpreter();
}
inline bool object::is_valid() const
{
return m_handle.interpreter() != 0;
}
inline object::operator object::safe_bool_type*() const
{
return is_valid()?(safe_bool_type*)1:0;
}
} // namespace adl
using adl::object;
template<>
struct value_wrapper_traits<object>
{
typedef boost::mpl::true_ is_specialized;
static lua_State* interpreter(object const& value)
{
return value.interpreter();
}
static void unwrap(lua_State* interpreter, object const& value)
{
value.push(interpreter);
}
static bool check(...)
{
return true;
}
};
template<class Next>
inline void adl::index_proxy<Next>::push(lua_State* interpreter)
{
assert(interpreter == m_interpreter);
value_wrapper_traits<Next>::unwrap(m_interpreter, m_next);
lua_pushvalue(m_interpreter, m_key_index);
lua_gettable(m_interpreter, -2);
lua_remove(m_interpreter, -2);
}
template<class Next>
inline adl::index_proxy<Next>::operator object()
{
detail::stack_pop pop(m_interpreter, 1);
push(m_interpreter);
return object(from_stack(m_interpreter, -1));
}
template<class AccessPolicy>
adl::iterator_proxy<AccessPolicy>::operator object()
{
lua_pushvalue(m_interpreter, m_key_index);
AccessPolicy::get(m_interpreter, m_table_index);
detail::stack_pop pop(m_interpreter, 1);
return object(from_stack(m_interpreter, -1));
}
template<class AccessPolicy>
object detail::basic_iterator<AccessPolicy>::key() const
{
return object(m_key);
}
namespace detail
{
template<
class T
, class ValueWrapper
, class Policies
, class ErrorPolicy
, class ReturnType
>
ReturnType object_cast_aux(
ValueWrapper const& value_wrapper
, T*
, Policies*
, ErrorPolicy*
, ReturnType*
)
{
lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
value_wrapper
);
#ifndef LUABIND_NO_ERROR_CHECKING
if (!interpreter)
return ErrorPolicy::handle_error(interpreter, LUABIND_TYPEID(void));
#endif
value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value_wrapper);
detail::stack_pop pop(interpreter, 1);
typedef typename detail::find_conversion_policy<
0
, Policies
>::type converter_generator;
typename mpl::apply_wrap2<converter_generator, T, lua_to_cpp>::type cv;
#ifndef LUABIND_NO_ERROR_CHECKING
if (cv.match(interpreter, LUABIND_DECORATE_TYPE(T), -1) < 0)
{
return ErrorPolicy::handle_error(interpreter, LUABIND_TYPEID(T));
}
#endif
return cv.apply(interpreter, LUABIND_DECORATE_TYPE(T), -1);
}
template<class T>
struct throw_error_policy
{
static T handle_error(lua_State* interpreter, LUABIND_TYPE_INFO type_info)
{
#ifndef LUABIND_NO_EXCEPTIONS
throw cast_failed(interpreter, type_info);
#else
cast_failed_callback_fun e = get_cast_failed_callback();
if (e) e(interpreter, type_info);
assert(0 && "object_cast failed. If you want to handle this error use "
"luabind::set_error_callback()");
std::terminate();
#endif
}
};
template<class T>
struct nothrow_error_policy
{
static boost::optional<T> handle_error(lua_State*, LUABIND_TYPE_INFO)
{
return boost::optional<T>();
}
};
} // namespace detail
template<class T, class ValueWrapper>
T object_cast(ValueWrapper const& value_wrapper)
{
return detail::object_cast_aux(
value_wrapper
, (T*)0
, (detail::null_type*)0
, (detail::throw_error_policy<T>*)0
, (T*)0
);
}
template<class T, class ValueWrapper, class Policies>
T object_cast(ValueWrapper const& value_wrapper, Policies const&)
{
return detail::object_cast_aux(
value_wrapper
, (T*)0
, (Policies*)0
, (detail::throw_error_policy<T>*)0
, (T*)0
);
}
template<class T, class ValueWrapper>
boost::optional<T> object_cast_nothrow(ValueWrapper const& value_wrapper)
{
return detail::object_cast_aux(
value_wrapper
, (T*)0
, (detail::null_type*)0
, (detail::nothrow_error_policy<T>*)0
, (boost::optional<T>*)0
);
}
template<class T, class ValueWrapper, class Policies>
boost::optional<T> object_cast_nothrow(ValueWrapper const& value_wrapper, Policies const&)
{
return detail::object_cast_aux(
value_wrapper
, (T*)0
, (Policies*)0
, (detail::nothrow_error_policy<T>*)0
, (boost::optional<T>*)0
);
}
namespace detail
{
template<int Index>
struct push_args_from_tuple
{
template<class H, class T, class Policies>
inline static void apply(lua_State* L, const boost::tuples::cons<H, T>& x, const Policies& p)
{
convert_to_lua_p<Index>(L, *x.get_head(), p);
push_args_from_tuple<Index+1>::apply(L, x.get_tail(), p);
}
template<class H, class T>
inline static void apply(lua_State* L, const boost::tuples::cons<H, T>& x)
{
convert_to_lua(L, *x.get_head());
push_args_from_tuple<Index+1>::apply(L, x.get_tail());
}
template<class Policies>
inline static void apply(lua_State*, const boost::tuples::null_type&, const Policies&) {};
inline static void apply(lua_State*, const boost::tuples::null_type&) {};
};
} // namespace detail
namespace adl
{
template<class ValueWrapper, class Arguments>
struct call_proxy
{
call_proxy(ValueWrapper& value_wrapper, Arguments arguments)
: value_wrapper(&value_wrapper)
, arguments(arguments)
{}
call_proxy(call_proxy const& other)
: value_wrapper(other.value_wrapper)
, arguments(other.arguments)
{
other.value_wrapper = 0;
}
~call_proxy()
{
if (value_wrapper)
call((detail::null_type*)0);
}
operator object()
{
return call((detail::null_type*)0);
}
template<class Policies>
object operator[](Policies const&)
{
return call((Policies*)0);
}
template<class Policies>
object call(Policies*)
{
lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
*value_wrapper
);
value_wrapper_traits<ValueWrapper>::unwrap(
interpreter
, *value_wrapper
);
value_wrapper = 0;
detail::push_args_from_tuple<1>::apply(interpreter, arguments, Policies());
if (detail::pcall(interpreter, boost::tuples::length<Arguments>::value, 1))
{
#ifndef LUABIND_NO_EXCEPTIONS
throw luabind::error(interpreter);
#else
error_callback_fun e = get_error_callback();
if (e) e(interpreter);
assert(0 && "the lua function threw an error and exceptions are disabled."
"if you want to handle this error use luabind::set_error_callback()");
std::terminate();
#endif
}
detail::stack_pop pop(interpreter, 1);
return object(from_stack(interpreter, -1));
}
mutable ValueWrapper* value_wrapper;
Arguments arguments;
};
template<class Derived>
call_proxy<Derived, boost::tuples::tuple<> >
object_interface<Derived>::operator()()
{
return call_proxy<Derived, boost::tuples::tuple<> >(
derived()
, boost::tuples::tuple<>()
);
}
} // namespace adl
inline object newtable(lua_State* interpreter)
{
lua_newtable(interpreter);
detail::stack_pop pop(interpreter, 1);
return object(from_stack(interpreter, -1));
}
inline object globals(lua_State* interpreter)
{
lua_pushvalue(interpreter, LUA_GLOBALSINDEX);
detail::stack_pop pop(interpreter, 1);
return object(from_stack(interpreter, -1));
}
template<class ValueWrapper, class K>
inline object gettable(ValueWrapper const& table, K const& key)
{
lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
table
);
value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
detail::stack_pop pop(interpreter, 2);
detail::push(interpreter, key);
lua_gettable(interpreter, -2);
return object(from_stack(interpreter, -1));
}
template<class ValueWrapper, class K, class T>
inline void settable(ValueWrapper const& table, K const& key, T const& value)
{
lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
table
);
// TODO: Exception safe?
value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
detail::stack_pop pop(interpreter, 1);
detail::push(interpreter, key);
detail::push(interpreter, value);
lua_settable(interpreter, -3);
}
template<class ValueWrapper, class K>
inline object rawget(ValueWrapper const& table, K const& key)
{
lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
table
);
value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
detail::stack_pop pop(interpreter, 2);
detail::push(interpreter, key);
lua_rawget(interpreter, -2);
return object(from_stack(interpreter, -1));
}
template<class ValueWrapper, class K, class T>
inline void rawset(ValueWrapper const& table, K const& key, T const& value)
{
lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
table
);
// TODO: Exception safe?
value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
detail::stack_pop pop(interpreter, 1);
detail::push(interpreter, key);
detail::push(interpreter, value);
lua_rawset(interpreter, -3);
}
template<class ValueWrapper>
inline int type(ValueWrapper const& value)
{
lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
value
);
value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value);
detail::stack_pop pop(interpreter, 1);
return lua_type(interpreter, -1);
}
} // namespace luabind
#endif // LUABIND_OBJECT_050419_HPP
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?