mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-15 08:21:28 +00:00
1023 lines
22 KiB
C++
1023 lines
22 KiB
C++
// Copyright (c) 2003 Daniel Wallin and Arvid Norberg
|
|
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
// copy of this software and associated documentation files (the "Software"),
|
|
// to deal in the Software without restriction, including without limitation
|
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
// and/or sell copies of the Software, and to permit persons to whom the
|
|
// Software is furnished to do so, subject to the following conditions:
|
|
|
|
// The above copyright notice and this permission notice shall be included
|
|
// in all copies or substantial portions of the Software.
|
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
|
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
|
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
|
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
|
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
|
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
|
// OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
|
|
#ifndef LUABIND_POLICY_HPP_INCLUDED
|
|
#define LUABIND_POLICY_HPP_INCLUDED
|
|
|
|
#include <luabind/config.hpp>
|
|
|
|
#include <typeinfo>
|
|
#include <string>
|
|
#include <memory>
|
|
|
|
#include <boost/type_traits/is_enum.hpp>
|
|
#include <boost/type_traits/is_array.hpp>
|
|
#include <boost/mpl/bool.hpp>
|
|
#include <boost/mpl/integral_c.hpp>
|
|
#include <boost/mpl/equal_to.hpp>
|
|
#include <boost/mpl/eval_if.hpp>
|
|
#include <boost/mpl/or.hpp>
|
|
#include <boost/type_traits/add_reference.hpp>
|
|
#include <boost/type_traits/remove_reference.hpp>
|
|
#include <boost/type_traits/is_pointer.hpp>
|
|
#include <boost/type_traits/is_base_and_derived.hpp>
|
|
#include <boost/bind/arg.hpp>
|
|
#include <boost/limits.hpp>
|
|
#include <boost/tuple/tuple.hpp>
|
|
#include <boost/version.hpp>
|
|
|
|
#include <luabind/detail/class_registry.hpp>
|
|
#include <luabind/detail/primitives.hpp>
|
|
#include <luabind/detail/object_rep.hpp>
|
|
#include <luabind/detail/typetraits.hpp>
|
|
#include <luabind/detail/class_cache.hpp>
|
|
#include <luabind/detail/debug.hpp>
|
|
#include <luabind/detail/class_rep.hpp>
|
|
#include <luabind/detail/has_get_pointer.hpp>
|
|
#include <luabind/detail/make_instance.hpp>
|
|
|
|
#include <boost/type_traits/add_reference.hpp>
|
|
|
|
#include <luabind/detail/decorate_type.hpp>
|
|
#include <luabind/weak_ref.hpp>
|
|
#include <luabind/back_reference_fwd.hpp>
|
|
|
|
#include <luabind/value_wrapper.hpp>
|
|
#include <luabind/from_stack.hpp>
|
|
#include <luabind/typeid.hpp>
|
|
#include <luabind/lua502.hpp>
|
|
|
|
namespace luabind
|
|
{
|
|
namespace detail
|
|
{
|
|
struct conversion_policy_base {};
|
|
}
|
|
|
|
template<int N, bool HasArg = true>
|
|
struct conversion_policy : detail::conversion_policy_base
|
|
{
|
|
BOOST_STATIC_CONSTANT(int, index = N);
|
|
BOOST_STATIC_CONSTANT(bool, has_arg = HasArg);
|
|
};
|
|
|
|
class index_map
|
|
{
|
|
public:
|
|
index_map(const int* m): m_map(m) {}
|
|
|
|
int operator[](int index) const
|
|
{
|
|
return m_map[index];
|
|
}
|
|
|
|
private:
|
|
const int* m_map;
|
|
};
|
|
|
|
// template<class T> class functor;
|
|
class weak_ref;
|
|
}
|
|
|
|
namespace luabind { namespace detail
|
|
{
|
|
template<class H, class T>
|
|
struct policy_cons
|
|
{
|
|
typedef H head;
|
|
typedef T tail;
|
|
|
|
template<class U>
|
|
policy_cons<U, policy_cons<H,T> > operator,(policy_cons<U,detail::null_type>)
|
|
{
|
|
return policy_cons<U, policy_cons<H,T> >();
|
|
}
|
|
|
|
template<class U>
|
|
policy_cons<U, policy_cons<H,T> > operator+(policy_cons<U,detail::null_type>)
|
|
{
|
|
return policy_cons<U, policy_cons<H,T> >();
|
|
}
|
|
|
|
template<class U>
|
|
policy_cons<U, policy_cons<H,T> > operator|(policy_cons<U,detail::null_type>)
|
|
{
|
|
return policy_cons<U, policy_cons<H,T> >();
|
|
}
|
|
};
|
|
|
|
struct indirection_layer
|
|
{
|
|
template<class T>
|
|
indirection_layer(const T&);
|
|
};
|
|
|
|
yes_t is_policy_cons_test(const null_type&);
|
|
template<class H, class T>
|
|
yes_t is_policy_cons_test(const policy_cons<H,T>&);
|
|
no_t is_policy_cons_test(...);
|
|
|
|
template<class T>
|
|
struct is_policy_cons
|
|
{
|
|
static const T& t;
|
|
|
|
BOOST_STATIC_CONSTANT(bool, value =
|
|
sizeof(is_policy_cons_test(t)) == sizeof(yes_t));
|
|
|
|
typedef boost::mpl::bool_<value> type;
|
|
};
|
|
|
|
template<bool>
|
|
struct is_string_literal
|
|
{
|
|
static no_t helper(indirection_layer);
|
|
static yes_t helper(const char*);
|
|
};
|
|
|
|
template<>
|
|
struct is_string_literal<false>
|
|
{
|
|
static no_t helper(indirection_layer);
|
|
};
|
|
|
|
|
|
namespace mpl = boost::mpl;
|
|
|
|
template <class T, class Clone>
|
|
void make_pointee_instance(lua_State* L, T& x, mpl::true_, Clone)
|
|
{
|
|
if (get_pointer(x))
|
|
{
|
|
make_instance(L, x);
|
|
}
|
|
else
|
|
{
|
|
lua_pushnil(L);
|
|
}
|
|
}
|
|
|
|
template <class T>
|
|
void make_pointee_instance(lua_State* L, T& x, mpl::false_, mpl::true_)
|
|
{
|
|
std::auto_ptr<T> ptr(new T(x));
|
|
make_instance(L, ptr);
|
|
}
|
|
|
|
template <class T>
|
|
void make_pointee_instance(lua_State* L, T& x, mpl::false_, mpl::false_)
|
|
{
|
|
make_instance(L, &x);
|
|
}
|
|
|
|
template <class T, class Clone>
|
|
void make_pointee_instance(lua_State* L, T& x, Clone)
|
|
{
|
|
make_pointee_instance(L, x, has_get_pointer<T>(), Clone());
|
|
}
|
|
|
|
// ********** pointer converter ***********
|
|
|
|
struct pointer_converter
|
|
{
|
|
typedef pointer_converter type;
|
|
typedef mpl::false_ is_native;
|
|
|
|
pointer_converter()
|
|
: result(0)
|
|
{}
|
|
|
|
void* result;
|
|
|
|
int const consumed_args(...)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
template<class T>
|
|
void apply(lua_State* L, T* ptr)
|
|
{
|
|
if (ptr == 0)
|
|
{
|
|
lua_pushnil(L);
|
|
return;
|
|
}
|
|
|
|
if (luabind::get_back_reference(L, ptr))
|
|
return;
|
|
|
|
make_instance(L, ptr);
|
|
}
|
|
|
|
template<class T>
|
|
T* apply(lua_State*, by_pointer<T>, int)
|
|
{
|
|
return static_cast<T*>(result);
|
|
}
|
|
|
|
template<class T>
|
|
int match(lua_State* L, by_pointer<T>, int index)
|
|
{
|
|
if (lua_isnil(L, index)) return 0;
|
|
object_rep* obj = get_instance(L, index);
|
|
if (obj == 0) return -1;
|
|
|
|
if (obj->is_const())
|
|
return -1;
|
|
|
|
std::pair<void*, int> s = obj->get_instance(registered_class<T>::id);
|
|
result = s.first;
|
|
return s.second;
|
|
}
|
|
|
|
template<class T>
|
|
void converter_postcall(lua_State*, by_pointer<T>, int)
|
|
{}
|
|
};
|
|
|
|
// ******* value converter *******
|
|
|
|
struct value_converter
|
|
{
|
|
typedef value_converter type;
|
|
typedef mpl::false_ is_native;
|
|
|
|
int const consumed_args(...)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
value_converter()
|
|
: result(0)
|
|
{}
|
|
|
|
void* result;
|
|
|
|
template<class T>
|
|
void apply(lua_State* L, T x)
|
|
{
|
|
if (luabind::get_back_reference(L, x))
|
|
return;
|
|
|
|
make_pointee_instance(L, x, mpl::true_());
|
|
}
|
|
|
|
template<class T>
|
|
T apply(lua_State*, by_value<T>, int)
|
|
{
|
|
return *static_cast<T*>(result);
|
|
}
|
|
|
|
template<class T>
|
|
int match(lua_State* L, by_value<T>, int index)
|
|
{
|
|
// special case if we get nil in, try to match the holder type
|
|
if (lua_isnil(L, index))
|
|
return -1;
|
|
|
|
object_rep* obj = get_instance(L, index);
|
|
if (obj == 0) return -1;
|
|
|
|
std::pair<void*, int> s = obj->get_instance(registered_class<T>::id);
|
|
result = s.first;
|
|
return s.second;
|
|
}
|
|
|
|
template<class T>
|
|
void converter_postcall(lua_State*, T, int) {}
|
|
};
|
|
|
|
// ******* const pointer converter *******
|
|
|
|
struct const_pointer_converter
|
|
{
|
|
typedef const_pointer_converter type;
|
|
typedef mpl::false_ is_native;
|
|
|
|
int const consumed_args(...)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
const_pointer_converter()
|
|
: result(0)
|
|
{}
|
|
|
|
void* result;
|
|
|
|
template<class T>
|
|
void apply(lua_State* L, const T* ptr)
|
|
{
|
|
if (ptr == 0)
|
|
{
|
|
lua_pushnil(L);
|
|
return;
|
|
}
|
|
|
|
if (luabind::get_back_reference(L, ptr))
|
|
return;
|
|
|
|
make_instance(L, ptr);
|
|
}
|
|
|
|
template<class T>
|
|
T const* apply(lua_State*, by_const_pointer<T>, int)
|
|
{
|
|
return static_cast<T const*>(result);
|
|
}
|
|
|
|
template<class T>
|
|
int match(lua_State* L, by_const_pointer<T>, int index)
|
|
{
|
|
if (lua_isnil(L, index)) return 0;
|
|
object_rep* obj = get_instance(L, index);
|
|
if (obj == 0) return -1; // if the type is not one of our own registered types, classify it as a non-match
|
|
std::pair<void*, int> s = obj->get_instance(registered_class<T>::id);
|
|
if (s.second >= 0 && !obj->is_const())
|
|
s.second += 10;
|
|
result = s.first;
|
|
return s.second;
|
|
}
|
|
|
|
template<class T>
|
|
void converter_postcall(lua_State*, T, int) {}
|
|
};
|
|
|
|
// ******* reference converter *******
|
|
|
|
struct ref_converter : pointer_converter
|
|
{
|
|
typedef ref_converter type;
|
|
typedef mpl::false_ is_native;
|
|
|
|
int const consumed_args(...)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
template<class T>
|
|
void apply(lua_State* L, T& ref)
|
|
{
|
|
if (luabind::get_back_reference(L, ref))
|
|
return;
|
|
|
|
make_pointee_instance(L, ref, mpl::false_());
|
|
}
|
|
|
|
template<class T>
|
|
T& apply(lua_State* L, by_reference<T>, int index)
|
|
{
|
|
assert(!lua_isnil(L, index));
|
|
return *pointer_converter::apply(L, by_pointer<T>(), index);
|
|
}
|
|
|
|
template<class T>
|
|
int match(lua_State* L, by_reference<T>, int index)
|
|
{
|
|
object_rep* obj = get_instance(L, index);
|
|
if (obj == 0) return -1;
|
|
|
|
if (obj->is_const())
|
|
return -1;
|
|
|
|
std::pair<void*, int> s = obj->get_instance(registered_class<T>::id);
|
|
result = s.first;
|
|
return s.second;
|
|
}
|
|
|
|
template<class T>
|
|
void converter_postcall(lua_State*, T, int) {}
|
|
};
|
|
|
|
// ******** const reference converter *********
|
|
|
|
struct const_ref_converter
|
|
{
|
|
typedef const_ref_converter type;
|
|
typedef mpl::false_ is_native;
|
|
|
|
int const consumed_args(...)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
const_ref_converter()
|
|
: result(0)
|
|
{}
|
|
|
|
void* result;
|
|
|
|
template<class T>
|
|
void apply(lua_State* L, T const& ref)
|
|
{
|
|
if (luabind::get_back_reference(L, ref))
|
|
return;
|
|
|
|
make_pointee_instance(L, ref, mpl::false_());
|
|
}
|
|
|
|
template<class T>
|
|
T const& apply(lua_State*, by_const_reference<T>, int)
|
|
{
|
|
return *static_cast<T*>(result);
|
|
}
|
|
|
|
template<class T>
|
|
int match(lua_State* L, by_const_reference<T>, int index)
|
|
{
|
|
object_rep* obj = get_instance(L, index);
|
|
if (obj == 0) return -1; // if the type is not one of our own registered types, classify it as a non-match
|
|
|
|
std::pair<void*, int> s = obj->get_instance(registered_class<T>::id);
|
|
if (s.second >= 0 && !obj->is_const())
|
|
s.second += 10;
|
|
result = s.first;
|
|
return s.second;
|
|
}
|
|
|
|
template<class T>
|
|
void converter_postcall(lua_State*, by_const_reference<T>, int)
|
|
{
|
|
}
|
|
};
|
|
|
|
// ****** enum converter ********
|
|
|
|
struct enum_converter
|
|
{
|
|
typedef enum_converter type;
|
|
typedef mpl::true_ is_native;
|
|
|
|
int const consumed_args(...)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
void apply(lua_State* L, int val)
|
|
{
|
|
lua_pushnumber(L, val);
|
|
}
|
|
|
|
template<class T>
|
|
T apply(lua_State* L, by_value<T>, int index)
|
|
{
|
|
return static_cast<T>(static_cast<int>(lua_tonumber(L, index)));
|
|
}
|
|
|
|
template<class T>
|
|
static int match(lua_State* L, by_value<T>, int index)
|
|
{
|
|
if (lua_isnumber(L, index)) return 0; else return -1;
|
|
}
|
|
|
|
template<class T>
|
|
T apply(lua_State* L, by_const_reference<T>, int index)
|
|
{
|
|
return static_cast<T>(static_cast<int>(lua_tonumber(L, index)));
|
|
}
|
|
|
|
template<class T>
|
|
static int match(lua_State* L, by_const_reference<T>, int index)
|
|
{
|
|
if (lua_isnumber(L, index)) return 0; else return -1;
|
|
}
|
|
|
|
template<class T>
|
|
void converter_postcall(lua_State*, T, int) {}
|
|
};
|
|
|
|
template <class U>
|
|
struct value_wrapper_converter
|
|
{
|
|
typedef value_wrapper_converter<U> type;
|
|
typedef mpl::true_ is_native;
|
|
|
|
int const consumed_args(...)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
template<class T>
|
|
T apply(lua_State* L, by_const_reference<T>, int index)
|
|
{
|
|
return T(from_stack(L, index));
|
|
}
|
|
|
|
template<class T>
|
|
T apply(lua_State* L, by_value<T>, int index)
|
|
{
|
|
return apply(L, by_const_reference<T>(), index);
|
|
}
|
|
|
|
template<class T>
|
|
static int match(lua_State* L, by_const_reference<T>, int index)
|
|
{
|
|
return value_wrapper_traits<T>::check(L, index)
|
|
? (std::numeric_limits<int>::max)() / LUABIND_MAX_ARITY
|
|
: -1;
|
|
}
|
|
|
|
template<class T>
|
|
static int match(lua_State* L, by_value<T>, int index)
|
|
{
|
|
return match(L, by_const_reference<T>(), index);
|
|
}
|
|
|
|
void converter_postcall(...) {}
|
|
|
|
template<class T>
|
|
void apply(lua_State* interpreter, T const& value_wrapper)
|
|
{
|
|
value_wrapper_traits<T>::unwrap(interpreter, value_wrapper);
|
|
}
|
|
};
|
|
|
|
template <class T>
|
|
struct default_converter_generator
|
|
: mpl::eval_if<
|
|
is_value_wrapper_arg<T>
|
|
, value_wrapper_converter<T>
|
|
, mpl::eval_if<
|
|
boost::is_enum<typename boost::remove_reference<T>::type>
|
|
, enum_converter
|
|
, mpl::eval_if<
|
|
is_nonconst_pointer<T>
|
|
, pointer_converter
|
|
, mpl::eval_if<
|
|
is_const_pointer<T>
|
|
, const_pointer_converter
|
|
, mpl::eval_if<
|
|
is_nonconst_reference<T>
|
|
, ref_converter
|
|
, mpl::eval_if<
|
|
is_const_reference<T>
|
|
, const_ref_converter
|
|
, value_converter
|
|
>
|
|
>
|
|
>
|
|
>
|
|
>
|
|
>
|
|
{};
|
|
|
|
} // namespace detail
|
|
|
|
// *********** default_policy *****************
|
|
|
|
template <class T>
|
|
struct default_converter
|
|
: detail::default_converter_generator<T>::type
|
|
{};
|
|
|
|
template <class T, class Derived = default_converter<T> >
|
|
struct native_converter_base
|
|
{
|
|
typedef boost::mpl::true_ is_native;
|
|
|
|
int const consumed_args(...)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
template <class U>
|
|
void converter_postcall(lua_State*, U const&, int)
|
|
{}
|
|
|
|
int match(lua_State* L, detail::by_value<T>, int index)
|
|
{
|
|
return derived().compute_score(L, index);
|
|
}
|
|
|
|
int match(lua_State* L, detail::by_value<T const>, int index)
|
|
{
|
|
return derived().compute_score(L, index);
|
|
}
|
|
|
|
int match(lua_State* L, detail::by_const_reference<T>, int index)
|
|
{
|
|
return derived().compute_score(L, index);
|
|
}
|
|
|
|
T apply(lua_State* L, detail::by_value<T>, int index)
|
|
{
|
|
return derived().from(L, index);
|
|
}
|
|
|
|
T apply(lua_State* L, detail::by_value<T const>, int index)
|
|
{
|
|
return derived().from(L, index);
|
|
}
|
|
|
|
T apply(lua_State* L, detail::by_const_reference<T>, int index)
|
|
{
|
|
return derived().from(L, index);
|
|
}
|
|
|
|
void apply(lua_State* L, T const& value)
|
|
{
|
|
derived().to(L, value);
|
|
}
|
|
|
|
Derived& derived()
|
|
{
|
|
return static_cast<Derived&>(*this);
|
|
}
|
|
};
|
|
|
|
template <class T>
|
|
lua_Integer as_lua_integer(T v)
|
|
{
|
|
return static_cast<lua_Integer>(v);
|
|
}
|
|
|
|
template <class T>
|
|
lua_Number as_lua_number(T v)
|
|
{
|
|
return static_cast<lua_Number>(v);
|
|
}
|
|
|
|
# define LUABIND_NUMBER_CONVERTER(type, kind) \
|
|
template <> \
|
|
struct default_converter<type> \
|
|
: native_converter_base<type> \
|
|
{ \
|
|
int compute_score(lua_State* L, int index) \
|
|
{ \
|
|
return lua_type(L, index) == LUA_TNUMBER ? 0 : -1; \
|
|
}; \
|
|
\
|
|
type from(lua_State* L, int index) \
|
|
{ \
|
|
return static_cast<type>(BOOST_PP_CAT(lua_to, kind)(L, index)); \
|
|
} \
|
|
\
|
|
void to(lua_State* L, type const& value) \
|
|
{ \
|
|
BOOST_PP_CAT(lua_push, kind)(L, BOOST_PP_CAT(as_lua_, kind)(value)); \
|
|
} \
|
|
}; \
|
|
\
|
|
template <> \
|
|
struct default_converter<type const> \
|
|
: default_converter<type> \
|
|
{}; \
|
|
\
|
|
template <> \
|
|
struct default_converter<type const&> \
|
|
: default_converter<type> \
|
|
{};
|
|
|
|
LUABIND_NUMBER_CONVERTER(char, integer)
|
|
LUABIND_NUMBER_CONVERTER(signed char, integer)
|
|
LUABIND_NUMBER_CONVERTER(unsigned char, integer)
|
|
LUABIND_NUMBER_CONVERTER(signed short, integer)
|
|
LUABIND_NUMBER_CONVERTER(unsigned short, integer)
|
|
LUABIND_NUMBER_CONVERTER(signed int, integer)
|
|
|
|
LUABIND_NUMBER_CONVERTER(unsigned int, number)
|
|
LUABIND_NUMBER_CONVERTER(unsigned long, number)
|
|
|
|
LUABIND_NUMBER_CONVERTER(signed long, integer)
|
|
LUABIND_NUMBER_CONVERTER(float, number)
|
|
LUABIND_NUMBER_CONVERTER(double, number)
|
|
LUABIND_NUMBER_CONVERTER(long double, number)
|
|
|
|
# undef LUABIND_NUMBER_CONVERTER
|
|
|
|
template <>
|
|
struct default_converter<bool>
|
|
: native_converter_base<bool>
|
|
{
|
|
static int compute_score(lua_State* L, int index)
|
|
{
|
|
return lua_type(L, index) == LUA_TBOOLEAN ? 0 : -1;
|
|
}
|
|
|
|
bool from(lua_State* L, int index)
|
|
{
|
|
return lua_toboolean(L, index) == 1;
|
|
}
|
|
|
|
void to(lua_State* L, bool value)
|
|
{
|
|
lua_pushboolean(L, value);
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct default_converter<bool const>
|
|
: default_converter<bool>
|
|
{};
|
|
|
|
template <>
|
|
struct default_converter<bool const&>
|
|
: default_converter<bool>
|
|
{};
|
|
|
|
template <>
|
|
struct default_converter<std::string>
|
|
: native_converter_base<std::string>
|
|
{
|
|
static int compute_score(lua_State* L, int index)
|
|
{
|
|
return lua_type(L, index) == LUA_TSTRING ? 0 : -1;
|
|
}
|
|
|
|
std::string from(lua_State* L, int index)
|
|
{
|
|
return std::string(lua_tostring(L, index), lua_strlen(L, index));
|
|
}
|
|
|
|
void to(lua_State* L, std::string const& value)
|
|
{
|
|
lua_pushlstring(L, value.data(), value.size());
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct default_converter<std::string const>
|
|
: default_converter<std::string>
|
|
{};
|
|
|
|
template <>
|
|
struct default_converter<std::string const&>
|
|
: default_converter<std::string>
|
|
{};
|
|
|
|
template <>
|
|
struct default_converter<char const*>
|
|
{
|
|
typedef boost::mpl::true_ is_native;
|
|
|
|
int const consumed_args(...)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
template <class U>
|
|
static int match(lua_State* L, U, int index)
|
|
{
|
|
int type = lua_type(L, index);
|
|
return (type == LUA_TSTRING || type == LUA_TNIL) ? 0 : -1;
|
|
}
|
|
|
|
template <class U>
|
|
char const* apply(lua_State* L, U, int index)
|
|
{
|
|
return lua_tostring(L, index);
|
|
}
|
|
|
|
void apply(lua_State* L, char const* str)
|
|
{
|
|
lua_pushstring(L, str);
|
|
}
|
|
|
|
template <class U>
|
|
void converter_postcall(lua_State*, U, int)
|
|
{}
|
|
};
|
|
|
|
template <>
|
|
struct default_converter<const char* const>
|
|
: default_converter<char const*>
|
|
{};
|
|
|
|
template <>
|
|
struct default_converter<char*>
|
|
: default_converter<char const*>
|
|
{};
|
|
|
|
template <std::size_t N>
|
|
struct default_converter<char const[N]>
|
|
: default_converter<char const*>
|
|
{};
|
|
|
|
template <std::size_t N>
|
|
struct default_converter<char[N]>
|
|
: default_converter<char const*>
|
|
{};
|
|
|
|
template <>
|
|
struct default_converter<lua_State*>
|
|
{
|
|
int const consumed_args(...)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
template <class U>
|
|
lua_State* apply(lua_State* L, U, int)
|
|
{
|
|
return L;
|
|
}
|
|
|
|
template <class U>
|
|
static int match(lua_State*, U, int)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
template <class U>
|
|
void converter_postcall(lua_State*, U, int) {}
|
|
};
|
|
|
|
namespace detail
|
|
{
|
|
|
|
struct default_policy : converter_policy_tag
|
|
{
|
|
BOOST_STATIC_CONSTANT(bool, has_arg = true);
|
|
|
|
template<class T>
|
|
static void precall(lua_State*, T, int) {}
|
|
|
|
template<class T, class Direction>
|
|
struct apply
|
|
{
|
|
typedef default_converter<T> type;
|
|
};
|
|
};
|
|
|
|
template<class T>
|
|
struct is_primitive
|
|
: default_converter<T>::is_native
|
|
{};
|
|
|
|
// ============== new policy system =================
|
|
|
|
template<int, class> struct find_conversion_policy;
|
|
|
|
template<bool IsConverter = false>
|
|
struct find_conversion_impl
|
|
{
|
|
template<int N, class Policies>
|
|
struct apply
|
|
{
|
|
typedef typename find_conversion_policy<N, typename Policies::tail>::type type;
|
|
};
|
|
};
|
|
|
|
template<>
|
|
struct find_conversion_impl<true>
|
|
{
|
|
template<int N, class Policies>
|
|
struct apply
|
|
{
|
|
typedef typename Policies::head head;
|
|
typedef typename Policies::tail tail;
|
|
|
|
BOOST_STATIC_CONSTANT(bool, found = (N == head::index));
|
|
|
|
typedef typename
|
|
boost::mpl::if_c<found
|
|
, head
|
|
, typename find_conversion_policy<N, tail>::type
|
|
>::type type;
|
|
};
|
|
};
|
|
|
|
template<class Policies>
|
|
struct find_conversion_impl2
|
|
{
|
|
template<int N>
|
|
struct apply
|
|
: find_conversion_impl<
|
|
boost::is_base_and_derived<conversion_policy_base, typename Policies::head>::value
|
|
>::template apply<N, Policies>
|
|
{
|
|
};
|
|
};
|
|
|
|
template<>
|
|
struct find_conversion_impl2<detail::null_type>
|
|
{
|
|
template<int N>
|
|
struct apply
|
|
{
|
|
typedef default_policy type;
|
|
};
|
|
};
|
|
|
|
template<int N, class Policies>
|
|
struct find_conversion_policy : find_conversion_impl2<Policies>::template apply<N>
|
|
{
|
|
};
|
|
|
|
template<class List>
|
|
struct policy_list_postcall
|
|
{
|
|
typedef typename List::head head;
|
|
typedef typename List::tail tail;
|
|
|
|
static void apply(lua_State* L, const index_map& i)
|
|
{
|
|
head::postcall(L, i);
|
|
policy_list_postcall<tail>::apply(L, i);
|
|
}
|
|
};
|
|
|
|
template<>
|
|
struct policy_list_postcall<detail::null_type>
|
|
{
|
|
static void apply(lua_State*, const index_map&) {}
|
|
};
|
|
|
|
// ==================================================
|
|
|
|
// ************** precall and postcall on policy_cons *********************
|
|
|
|
|
|
template<class List>
|
|
struct policy_precall
|
|
{
|
|
typedef typename List::head head;
|
|
typedef typename List::tail tail;
|
|
|
|
static void apply(lua_State* L, int index)
|
|
{
|
|
head::precall(L, index);
|
|
policy_precall<tail>::apply(L, index);
|
|
}
|
|
};
|
|
|
|
template<>
|
|
struct policy_precall<detail::null_type>
|
|
{
|
|
static void apply(lua_State*, int) {}
|
|
};
|
|
|
|
template<class List>
|
|
struct policy_postcall
|
|
{
|
|
typedef typename List::head head;
|
|
typedef typename List::tail tail;
|
|
|
|
static void apply(lua_State* L, int index)
|
|
{
|
|
head::postcall(L, index);
|
|
policy_postcall<tail>::apply(L, index);
|
|
}
|
|
};
|
|
|
|
template<>
|
|
struct policy_postcall<detail::null_type>
|
|
{
|
|
static void apply(lua_State*, int) {}
|
|
};
|
|
|
|
}} // namespace luabind::detail
|
|
|
|
|
|
namespace luabind { namespace
|
|
{
|
|
#if defined(__GNUC__) && ( \
|
|
(BOOST_VERSION < 103500) \
|
|
|| (BOOST_VERSION < 103900 && (__GNUC__ * 100 + __GNUC_MINOR__ <= 400)) \
|
|
|| (__GNUC__ * 100 + __GNUC_MINOR__ < 400))
|
|
static inline boost::arg<0> return_value()
|
|
{
|
|
return boost::arg<0>();
|
|
}
|
|
|
|
static inline boost::arg<0> result()
|
|
{
|
|
return boost::arg<0>();
|
|
}
|
|
# define LUABIND_PLACEHOLDER_ARG(N) boost::arg<N>(*)()
|
|
#elif defined(BOOST_MSVC) || defined(__MWERKS__) \
|
|
|| (BOOST_VERSION >= 103900 && defined(__GNUC__) \
|
|
&& (__GNUC__ * 100 + __GNUC_MINOR__ == 400))
|
|
static boost::arg<0> return_value;
|
|
static boost::arg<0> result;
|
|
# define LUABIND_PLACEHOLDER_ARG(N) boost::arg<N>
|
|
#else
|
|
boost::arg<0> return_value;
|
|
boost::arg<0> result;
|
|
# define LUABIND_PLACEHOLDER_ARG(N) boost::arg<N>
|
|
#endif
|
|
}}
|
|
|
|
#endif // LUABIND_POLICY_HPP_INCLUDED
|
|
|