mirror of
https://github.com/EQEmu/Server.git
synced 2026-06-22 19:58:24 +00:00
Revert "Build System Updated"
This commit is contained in:
+33
-37
@@ -20,46 +20,42 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
// OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef LUABIND_CALL_SHARED_HPP_INCLUDED
|
||||
#define LUABIND_CALL_SHARED_HPP_INCLUDED
|
||||
#if !BOOST_PP_IS_ITERATING
|
||||
|
||||
namespace luabind {
|
||||
namespace detail {
|
||||
# include <luabind/detail/signature_match.hpp>
|
||||
|
||||
inline void call_error(lua_State* L)
|
||||
#ifndef LUABIND_CALC_ARITY_HPP_INCLUDED
|
||||
#define LUABIND_CALC_ARITY_HPP_INCLUDED
|
||||
|
||||
#define LUABIND_FIND_CONV(z,n,text) typedef typename find_conversion_policy<n + 1, Policies>::type p##n;
|
||||
#define LUABIND_CALC_ARITY(z,n,text) + BOOST_PP_CAT(p,n)::has_arg
|
||||
|
||||
namespace luabind { namespace detail
|
||||
{
|
||||
template<int N> struct calc_arity;
|
||||
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, <luabind/detail/calc_arity.hpp>, 1))
|
||||
#include BOOST_PP_ITERATE()
|
||||
}}
|
||||
|
||||
#undef LUABIND_CALC_ARITY
|
||||
#undef LUABIND_FIND_CONV
|
||||
|
||||
|
||||
#endif // LUABIND_CALC_ARITY_HPP_INCLUDED
|
||||
|
||||
#else // BOOST_PP_ITERATE
|
||||
|
||||
template<>
|
||||
struct calc_arity<BOOST_PP_ITERATION()>
|
||||
{
|
||||
template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A), class Policies>
|
||||
static int apply(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>, Policies*)
|
||||
{
|
||||
#ifndef LUABIND_NO_EXCEPTIONS
|
||||
throw luabind::error(L);
|
||||
#else
|
||||
error_callback_fun e = get_error_callback();
|
||||
if(e) e(L);
|
||||
|
||||
assert(0 && "the lua function threw an error and exceptions are disabled."
|
||||
" If you want to handle the error you can use luabind::set_error_callback()");
|
||||
std::terminate();
|
||||
#endif
|
||||
BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_FIND_CONV, _)
|
||||
return 0 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_CALC_ARITY, _);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void cast_error(lua_State* L)
|
||||
{
|
||||
#ifndef LUABIND_NO_EXCEPTIONS
|
||||
throw cast_failed(L, typeid(T));
|
||||
#else
|
||||
cast_failed_callback_fun e = get_cast_failed_callback();
|
||||
if(e) e(L, typeid(T));
|
||||
|
||||
assert(0 && "the lua function's return value could not be converted."
|
||||
" If you want to handle the error you can use luabind::set_cast_failed_callback()");
|
||||
std::terminate();
|
||||
#endif
|
||||
}
|
||||
|
||||
template< typename... Args >
|
||||
void expand_hack(Args... /*args*/)
|
||||
{}
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,547 +1,323 @@
|
||||
// Copyright Daniel Wallin 208.Use, modification and distribution is
|
||||
// Copyright Daniel Wallin 2008. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef LUABIND_CALL2_080911_HPP
|
||||
#define LUABIND_CALL2_080911_HPP
|
||||
|
||||
#include <luabind/config.hpp>
|
||||
#include <typeinfo>
|
||||
#include <luabind/detail/meta.hpp>
|
||||
#include <luabind/detail/policy.hpp>
|
||||
#include <luabind/yield_policy.hpp>
|
||||
#include <luabind/detail/decorate_type.hpp>
|
||||
#include <luabind/detail/object.hpp>
|
||||
|
||||
#ifdef LUABIND_NO_INTERNAL_TAG_ARGUMENTS
|
||||
#include <tuple>
|
||||
#endif
|
||||
|
||||
namespace luabind {
|
||||
namespace detail {
|
||||
|
||||
struct invoke_context;
|
||||
|
||||
struct LUABIND_API function_object
|
||||
{
|
||||
function_object(lua_CFunction entry)
|
||||
: entry(entry)
|
||||
, next(0)
|
||||
{}
|
||||
|
||||
virtual ~function_object()
|
||||
{}
|
||||
|
||||
virtual int call(lua_State* L, invoke_context& ctx) /* const */ = 0;
|
||||
virtual void format_signature(lua_State* L, char const* function) const = 0;
|
||||
|
||||
lua_CFunction entry;
|
||||
std::string name;
|
||||
function_object* next;
|
||||
object keepalive;
|
||||
};
|
||||
|
||||
struct LUABIND_API invoke_context
|
||||
{
|
||||
invoke_context()
|
||||
: best_score((std::numeric_limits<int>::max)())
|
||||
//This need to avoid static analyzer's treats
|
||||
, candidates{ nullptr,nullptr,nullptr,nullptr,nullptr,
|
||||
nullptr,nullptr,nullptr,nullptr,nullptr }
|
||||
, candidate_index(0)
|
||||
{}
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
return candidate_index == 1;
|
||||
}
|
||||
|
||||
void format_error(lua_State* L, function_object const* overloads) const;
|
||||
|
||||
int best_score;
|
||||
function_object const* candidates[10]; // This looks like it could crash if you provide too many overloads?
|
||||
int candidate_index;
|
||||
};
|
||||
|
||||
namespace call_detail_new {
|
||||
|
||||
/*
|
||||
Compute Stack Indices
|
||||
Given the list of argument converter arities, computes the stack indices that each converter addresses.
|
||||
*/
|
||||
|
||||
template< typename ConsumedList, unsigned int CurrentSum, unsigned int... StackIndices >
|
||||
struct compute_stack_indices;
|
||||
|
||||
template< unsigned int Consumed0, unsigned int... Consumeds, unsigned int CurrentSum, unsigned int... StackIndices >
|
||||
struct compute_stack_indices< meta::index_list< Consumed0, Consumeds... >, CurrentSum, StackIndices... >
|
||||
{
|
||||
using type = typename compute_stack_indices< meta::index_list< Consumeds... >, CurrentSum + Consumed0, StackIndices..., CurrentSum >::type;
|
||||
};
|
||||
|
||||
template< unsigned int CurrentSum, unsigned int... StackIndices >
|
||||
struct compute_stack_indices< meta::index_list< >, CurrentSum, StackIndices... >
|
||||
{
|
||||
using type = meta::index_list< StackIndices... >;
|
||||
};
|
||||
|
||||
template< typename Foo >
|
||||
struct FooFoo { // Foo!
|
||||
enum { consumed_args = Foo::consumed_args };
|
||||
};
|
||||
|
||||
|
||||
template< typename PolicyList, typename StackIndexList >
|
||||
struct policy_list_postcall;
|
||||
|
||||
template< typename Policy0, typename... Policies, typename StackIndexList >
|
||||
struct policy_list_postcall< meta::type_list< call_policy_injector<Policy0>, Policies... >, StackIndexList > {
|
||||
static void postcall(lua_State* L, int results) {
|
||||
Policy0::postcall(L, results, StackIndexList());
|
||||
policy_list_postcall< meta::type_list< Policies... >, StackIndexList >::postcall(L, results);
|
||||
}
|
||||
};
|
||||
|
||||
template< typename ConverterPolicy, typename StackIndexList, bool has_postcall >
|
||||
struct converter_policy_postcall {
|
||||
static void postcall(lua_State* L, int results) {
|
||||
ConverterPolicy::postcall(L, results, StackIndexList());
|
||||
}
|
||||
};
|
||||
|
||||
template< typename ConverterPolicy, typename StackIndexList >
|
||||
struct converter_policy_postcall< ConverterPolicy, StackIndexList, false > {
|
||||
static void postcall(lua_State* /*L*/, int /*results*/) {
|
||||
}
|
||||
};
|
||||
|
||||
template< unsigned int Index, typename Policy, typename... Policies, typename StackIndexList >
|
||||
struct policy_list_postcall< meta::type_list< converter_policy_injector< Index, Policy >, Policies... >, StackIndexList > {
|
||||
static void postcall(lua_State* L, int results) {
|
||||
converter_policy_postcall < Policy, StackIndexList, converter_policy_injector< Index, Policy >::has_postcall >::postcall(L, results);
|
||||
policy_list_postcall< meta::type_list< Policies... >, StackIndexList >::postcall(L, results);
|
||||
}
|
||||
};
|
||||
|
||||
template< typename StackIndexList >
|
||||
struct policy_list_postcall< meta::type_list< >, StackIndexList > {
|
||||
static void postcall(lua_State* /*L*/, int /*results*/) {}
|
||||
};
|
||||
|
||||
#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS
|
||||
template< typename... ArgumentConverters >
|
||||
struct compute_invoke_values {
|
||||
using consumed_list = meta::index_list< FooFoo<ArgumentConverters>::consumed_args... >;
|
||||
using stack_index_list = typename compute_stack_indices< consumed_list, 1 >::type;
|
||||
enum { arity = meta::sum<consumed_list>::value };
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS
|
||||
inline int match_deferred(lua_State* L, meta::index_list<>, meta::type_list<>)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template< unsigned int StackIndex0, unsigned int... StackIndices,
|
||||
typename ArgumentType0, typename... ArgumentTypes,
|
||||
typename ArgumentConverter0, typename... ArgumentConverters >
|
||||
int match_deferred(lua_State* L,
|
||||
meta::index_list< StackIndex0, StackIndices... >,
|
||||
meta::type_list< ArgumentType0, ArgumentTypes... >,
|
||||
ArgumentConverter0& converter0, ArgumentConverters&... converters
|
||||
)
|
||||
{
|
||||
const int this_match = converter0.match(L, decorated_type<ArgumentType0>(), StackIndex0);
|
||||
const int other_match = match_deferred(L, meta::index_list<StackIndices...>(), meta::type_list<ArgumentTypes...>(), converters...);
|
||||
return (this_match >= 0) ? // could also sum them all up unconditionally
|
||||
this_match + match_deferred(L, meta::index_list<StackIndices...>(), meta::type_list<ArgumentTypes...>(), converters...)
|
||||
: no_match;
|
||||
}
|
||||
|
||||
template< typename T, bool isvoid, bool memfun = std::is_member_function_pointer<T>::value > struct do_call_struct;
|
||||
|
||||
template< typename T >
|
||||
struct do_call_struct< T, true, true /*memfun*/> {
|
||||
template< typename F, typename ArgumentType0, typename... ArgumentTypes, unsigned int StackIndex0, unsigned int... StackIndices, typename ReturnConverter, typename Argument0Converter, typename... ArgumentConverters >
|
||||
static void do_call(lua_State* L, F& f,
|
||||
meta::index_list<StackIndex0, StackIndices...>, meta::type_list<ArgumentType0, ArgumentTypes...>,
|
||||
ReturnConverter& result_converter, Argument0Converter& arg0_converter, ArgumentConverters&... arg_converters
|
||||
)
|
||||
{
|
||||
((arg0_converter.to_cpp(L, decorated_type<ArgumentType0>(), StackIndex0)).*f)(
|
||||
arg_converters.to_cpp(L, decorated_type<ArgumentTypes>(), StackIndices)...
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
struct do_call_struct< T, false, true /*memfun*/> {
|
||||
template< typename F, typename ArgumentType0, typename... ArgumentTypes, unsigned int StackIndex0, unsigned int... StackIndices, typename ReturnConverter, typename Argument0Converter, typename... ArgumentConverters >
|
||||
static void do_call(lua_State* L, F& f,
|
||||
meta::index_list<StackIndex0, StackIndices...>, meta::type_list<ArgumentType0, ArgumentTypes...>,
|
||||
ReturnConverter& result_converter, Argument0Converter& arg0_converter, ArgumentConverters&... arg_converters
|
||||
)
|
||||
{
|
||||
result_converter.to_lua(L,
|
||||
((arg0_converter.to_cpp(L, decorated_type<ArgumentType0>(), StackIndex0)).*f)(
|
||||
arg_converters.to_cpp(L, decorated_type<ArgumentTypes>(), StackIndices)...
|
||||
)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template< typename T >
|
||||
struct do_call_struct< T, true, false > {
|
||||
template<
|
||||
typename F,
|
||||
typename... ArgumentTypes, unsigned int... StackIndices,
|
||||
typename ReturnConverter, typename... ArgumentConverters
|
||||
>
|
||||
static void do_call(lua_State* L, F& f,
|
||||
meta::index_list<StackIndices...>, meta::type_list<ArgumentTypes...>,
|
||||
ReturnConverter& result_converter, ArgumentConverters&... arg_converters)
|
||||
{
|
||||
f(arg_converters.to_cpp(L, decorated_type<ArgumentTypes>(), StackIndices)...);
|
||||
}
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
struct do_call_struct< T, false, false > {
|
||||
template<
|
||||
typename F,
|
||||
typename... ArgumentTypes, unsigned int... StackIndices,
|
||||
typename ReturnConverter, typename... ArgumentConverters
|
||||
>
|
||||
static void do_call(lua_State* L, F& f,
|
||||
meta::index_list<StackIndices...>, meta::type_list<ArgumentTypes...>,
|
||||
ReturnConverter& result_converter, ArgumentConverters&... arg_converters)
|
||||
{
|
||||
result_converter.to_lua(L,
|
||||
f(arg_converters.to_cpp(L, decorated_type<ArgumentTypes>(), StackIndices)...)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template< typename F, typename ReturnType, typename... Arguments,
|
||||
typename ReturnConverter, typename... ArgumentConverters,
|
||||
unsigned int Index0, unsigned int... Indices, typename PolicyList
|
||||
>
|
||||
int invoke3(lua_State* L, function_object const& self, invoke_context& ctx, F& f,
|
||||
PolicyList, meta::index_list< Index0, Indices... > index_list, meta::type_list<ReturnType, Arguments...> signature_list,
|
||||
ReturnConverter return_converter, ArgumentConverters... argument_converters)
|
||||
{
|
||||
using invoke_values = typename call_detail_new::compute_invoke_values< ArgumentConverters... >;
|
||||
using argument_list_type = meta::type_list<Arguments...>;
|
||||
using argument_index_list = meta::index_list<Indices...>;
|
||||
|
||||
int const arguments = lua_gettop(L);
|
||||
int score = no_match;
|
||||
|
||||
if(invoke_values::arity == arguments) {
|
||||
score = match_deferred(L, typename invoke_values::stack_index_list(), argument_list_type(), argument_converters...);
|
||||
}
|
||||
|
||||
if(score >= 0 && score < ctx.best_score) {
|
||||
ctx.best_score = score;
|
||||
ctx.candidates[0] = &self;
|
||||
ctx.candidate_index = 1;
|
||||
} else if(score == ctx.best_score) {
|
||||
ctx.candidates[ctx.candidate_index++] = &self;
|
||||
}
|
||||
|
||||
int results = 0;
|
||||
|
||||
if(self.next)
|
||||
{
|
||||
results = self.next->call(L, ctx);
|
||||
}
|
||||
|
||||
if(score == ctx.best_score && ctx.candidate_index == 1)
|
||||
{
|
||||
do_call_struct<F, std::is_void<ReturnType>::value>::do_call(L, f, typename invoke_values::stack_index_list(), argument_list_type(), return_converter, argument_converters...);
|
||||
meta::init_order{ (argument_converters.converter_postcall(L, decorated_type<Arguments>(), meta::get< typename invoke_values::stack_index_list, Indices - 1 >::value), 0)... };
|
||||
|
||||
results = lua_gettop(L) - invoke_values::arity;
|
||||
if(has_call_policy<PolicyList, yield_policy>::value) {
|
||||
results = lua_yield(L, results);
|
||||
}
|
||||
|
||||
// call policiy list postcall
|
||||
call_detail_new::policy_list_postcall < PolicyList, typename meta::push_front< typename invoke_values::stack_index_list, meta::index<invoke_values::arity> >::type >::postcall(L, results);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
template< typename F, typename ReturnType, typename... Arguments, unsigned int Index0, unsigned int... Indices, typename PolicyList >
|
||||
int invoke2(lua_State* L, function_object const& self, invoke_context& ctx, F& f,
|
||||
meta::type_list<ReturnType, Arguments...> signature, meta::index_list<Index0, Indices...>, PolicyList)
|
||||
{
|
||||
using signature_type = meta::type_list<ReturnType, Arguments...>;
|
||||
using return_converter = specialized_converter_policy_n<0, PolicyList, ReturnType, cpp_to_lua>;
|
||||
return invoke3(L, self, ctx, f,
|
||||
PolicyList(), meta::index_list<Index0, Indices...>(), signature,
|
||||
return_converter(), specialized_converter_policy_n<Indices, PolicyList, Arguments, lua_to_cpp>()...
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template <class F, class Signature, typename... PolicyInjectors>
|
||||
// boost::bind's operator() is const, std::bind's is not
|
||||
inline int invoke(lua_State* L, function_object const& self, invoke_context& ctx, F& f, Signature,
|
||||
meta::type_list< PolicyInjectors... > const& injectors)
|
||||
{
|
||||
return invoke2(L, self, ctx, f, Signature(), typename meta::make_index_range<0, meta::size<Signature>::value>::type(), injectors);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LUABIND_NO_INTERNAL_TAG_ARGUMENTS
|
||||
|
||||
// VC2013RC doesn't support expanding a template and its member template in one expression, that's why we have to to incrementally build
|
||||
// the converter list instead of a single combined expansion.
|
||||
template< typename ArgumentList, typename PolicyList, typename CurrentList = meta::type_list<>, unsigned int Counter = 1 >
|
||||
struct compute_argument_converter_list;
|
||||
|
||||
template< typename Argument0, typename... Arguments, typename PolicyList, typename... CurrentConverters, unsigned int Counter >
|
||||
struct compute_argument_converter_list< meta::type_list<Argument0, Arguments... >, PolicyList, meta::type_list<CurrentConverters...>, Counter >
|
||||
{
|
||||
using converter_type = typename policy_detail::get_converter_policy<Counter, PolicyList>::type;
|
||||
using this_specialized = typename converter_type::template specialize<Argument0, lua_to_cpp >::type;
|
||||
using type = typename compute_argument_converter_list<meta::type_list<Arguments...>, PolicyList, meta::type_list<CurrentConverters..., this_specialized>, Counter + 1>::type;
|
||||
};
|
||||
|
||||
template<typename PolicyList, typename... CurrentConverters, unsigned int Counter >
|
||||
struct compute_argument_converter_list< meta::type_list<>, PolicyList, meta::type_list<CurrentConverters...>, Counter >
|
||||
{
|
||||
using type = meta::type_list<CurrentConverters...>;
|
||||
};
|
||||
|
||||
template< typename ConverterList >
|
||||
struct build_consumed_list;
|
||||
|
||||
template< typename... Converters >
|
||||
struct build_consumed_list< meta::type_list< Converters... > > {
|
||||
using consumed_list = meta::index_list< call_detail_new::FooFoo<Converters>::consumed_args... >;
|
||||
};
|
||||
|
||||
template< typename SignatureList, typename PolicyList >
|
||||
struct invoke_traits;
|
||||
|
||||
// Specialization for free functions
|
||||
template< typename ResultType, typename... Arguments, typename PolicyList >
|
||||
struct invoke_traits< meta::type_list<ResultType, Arguments... >, PolicyList >
|
||||
{
|
||||
using signature_list = meta::type_list<ResultType, Arguments...>;
|
||||
using policy_list = PolicyList;
|
||||
using result_type = ResultType;
|
||||
using result_converter = specialized_converter_policy_n<0, PolicyList, result_type, cpp_to_lua >;
|
||||
using argument_list = meta::type_list<Arguments...>;
|
||||
|
||||
using decorated_argument_list = meta::type_list< decorate_type_t<Arguments>... >;
|
||||
// note that this is 0-based, so whenever you want to fetch from the converter list, you need to add 1
|
||||
using argument_index_list = typename meta::make_index_range< 0, sizeof...(Arguments) >::type;
|
||||
using argument_converter_list = typename compute_argument_converter_list<argument_list, PolicyList>::type;
|
||||
using argument_converter_tuple_type = typename meta::make_tuple<argument_converter_list>::type;
|
||||
using consumed_list = typename build_consumed_list<argument_converter_list>::consumed_list;
|
||||
using stack_index_list = typename call_detail_new::compute_stack_indices< consumed_list, 1 >::type;
|
||||
enum { arity = meta::sum<consumed_list>::value };
|
||||
};
|
||||
|
||||
template< typename StackIndexList, typename SignatureList, unsigned int End = meta::size<SignatureList>::value, unsigned int Index = 1 >
|
||||
struct match_struct {
|
||||
template< typename TupleType >
|
||||
static int match(lua_State* L, TupleType& tuple)
|
||||
{
|
||||
const int this_match = std::get<Index - 1>(tuple).match(L, decorate_type_t<typename SignatureList::template at<Index>>(), meta::get<StackIndexList, Index - 1>::value);
|
||||
return this_match >= 0 ? // could also sum them up unconditionally
|
||||
this_match + match_struct<StackIndexList, SignatureList, End, Index + 1>::match(L, tuple)
|
||||
: no_match;
|
||||
}
|
||||
};
|
||||
|
||||
template< typename StackIndexList, typename SignatureList, unsigned int Index >
|
||||
struct match_struct< StackIndexList, SignatureList, Index, Index >
|
||||
{
|
||||
template< typename TupleType >
|
||||
static int match(lua_State* /*L*/, TupleType&) {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
template< typename PolicyList, typename Signature, typename F >
|
||||
struct invoke_struct
|
||||
{
|
||||
using traits = invoke_traits< Signature, PolicyList >;
|
||||
|
||||
template< bool IsMember, bool IsVoid, typename IndexList >
|
||||
struct call_struct;
|
||||
|
||||
template< unsigned int... ArgumentIndices >
|
||||
struct call_struct< false /*member*/, false /*void*/, meta::index_list<ArgumentIndices...> >
|
||||
{
|
||||
static void call(lua_State* L, F& f, typename traits::argument_converter_tuple_type& argument_tuple)
|
||||
{
|
||||
using decorated_list = typename traits::decorated_argument_list;
|
||||
using stack_indices = typename traits::stack_index_list;
|
||||
using result_converter = typename traits::result_converter;
|
||||
|
||||
result_converter().to_lua(L,
|
||||
f((std::get<ArgumentIndices>(argument_tuple).to_cpp(L,
|
||||
typename meta::get<decorated_list, ArgumentIndices>::type(),
|
||||
meta::get<stack_indices, ArgumentIndices>::value))...
|
||||
)
|
||||
);
|
||||
|
||||
meta::init_order{
|
||||
(std::get<ArgumentIndices>(argument_tuple).converter_postcall(L,
|
||||
typename meta::get<typename traits::decorated_argument_list, ArgumentIndices>::type(),
|
||||
meta::get<typename traits::stack_index_list, ArgumentIndices>::value), 0)...
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
template< unsigned int... ArgumentIndices >
|
||||
struct call_struct< false /*member*/, true /*void*/, meta::index_list<ArgumentIndices...> >
|
||||
{
|
||||
static void call(lua_State* L, F& f, typename traits::argument_converter_tuple_type& argument_tuple)
|
||||
{
|
||||
using decorated_list = typename traits::decorated_argument_list;
|
||||
using stack_indices = typename traits::stack_index_list;
|
||||
|
||||
// This prevents unused warnings with empty parameter lists
|
||||
(void)L;
|
||||
|
||||
f(std::get<ArgumentIndices>(argument_tuple).to_cpp(L,
|
||||
typename meta::get<decorated_list, ArgumentIndices>::type(),
|
||||
meta::get<stack_indices, ArgumentIndices>::value)...
|
||||
|
||||
);
|
||||
|
||||
meta::init_order{
|
||||
(std::get<ArgumentIndices>(argument_tuple).converter_postcall(L,
|
||||
typename meta::get<typename traits::decorated_argument_list, ArgumentIndices>::type(),
|
||||
meta::get<typename traits::stack_index_list, ArgumentIndices>::value), 0)...
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
template< unsigned int ClassIndex, unsigned int... ArgumentIndices >
|
||||
struct call_struct< true /*member*/, false /*void*/, meta::index_list<ClassIndex, ArgumentIndices...> >
|
||||
{
|
||||
static void call(lua_State* L, F& f, typename traits::argument_converter_tuple_type& argument_tuple)
|
||||
{
|
||||
using decorated_list = typename traits::decorated_argument_list;
|
||||
using stack_indices = typename traits::stack_index_list;
|
||||
using result_converter = typename traits::result_converter;
|
||||
|
||||
auto& object = std::get<0>(argument_tuple).to_cpp(L,
|
||||
typename meta::get<typename traits::decorated_argument_list, 0>::type(), 1);
|
||||
|
||||
result_converter().to_lua(L,
|
||||
(object.*f)(std::get<ArgumentIndices>(argument_tuple).to_cpp(L,
|
||||
typename meta::get<decorated_list, ArgumentIndices>::type(),
|
||||
meta::get<stack_indices, ArgumentIndices>::value)...
|
||||
)
|
||||
);
|
||||
|
||||
meta::init_order{
|
||||
(std::get<ArgumentIndices>(argument_tuple).converter_postcall(L,
|
||||
typename meta::get<typename traits::decorated_argument_list, ArgumentIndices>::type(),
|
||||
meta::get<typename traits::stack_index_list, ArgumentIndices>::value), 0)...
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
template< unsigned int ClassIndex, unsigned int... ArgumentIndices >
|
||||
struct call_struct< true /*member*/, true /*void*/, meta::index_list<ClassIndex, ArgumentIndices...> >
|
||||
{
|
||||
static void call(lua_State* L, F& f, typename traits::argument_converter_tuple_type& argument_tuple)
|
||||
{
|
||||
using decorated_list = typename traits::decorated_argument_list;
|
||||
using stack_indices = typename traits::stack_index_list;
|
||||
|
||||
auto& object = std::get<0>(argument_tuple).to_cpp(L, typename meta::get<typename traits::decorated_argument_list, 0>::type(), 1);
|
||||
|
||||
(object.*f)(std::get<ArgumentIndices>(argument_tuple).to_cpp(L,
|
||||
typename meta::get<decorated_list, ArgumentIndices>::type(),
|
||||
meta::get<stack_indices, ArgumentIndices>::value)...
|
||||
);
|
||||
|
||||
meta::init_order{
|
||||
(std::get<ArgumentIndices>(argument_tuple).converter_postcall(L,
|
||||
typename meta::get<typename traits::decorated_argument_list, ArgumentIndices>::type(),
|
||||
meta::get<typename traits::stack_index_list, ArgumentIndices>::value), 0)...
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
static int invoke(lua_State* L, function_object const& self, invoke_context& ctx, F& f) {
|
||||
int const arguments = lua_gettop(L);
|
||||
int score = no_match;
|
||||
|
||||
// Even match needs the tuple, since pointer_converters buffer the cast result
|
||||
typename traits::argument_converter_tuple_type converter_tuple;
|
||||
|
||||
if(traits::arity == arguments) {
|
||||
// Things to remember:
|
||||
// 0 is the perfect match. match > 0 means that objects had to be casted, where the value
|
||||
// is the total distance of all arguments to their given types (graph distance).
|
||||
// This is why we can say MaxArguments = 100, MaxDerivationDepth = 100, so no match will be > 100*100=10k and -10k1 absorbs every match.
|
||||
// This gets rid of the awkward checks during converter match traversal.
|
||||
using struct_type = match_struct< typename traits::stack_index_list, typename traits::signature_list >;
|
||||
score = struct_type::match(L, converter_tuple);
|
||||
}
|
||||
|
||||
if(score >= 0 && score < ctx.best_score) {
|
||||
ctx.best_score = score;
|
||||
ctx.candidates[0] = &self;
|
||||
ctx.candidate_index = 1;
|
||||
} else if(score == ctx.best_score) {
|
||||
ctx.candidates[ctx.candidate_index++] = &self;
|
||||
}
|
||||
|
||||
int results = 0;
|
||||
|
||||
if(self.next)
|
||||
{
|
||||
results = self.next->call(L, ctx);
|
||||
}
|
||||
|
||||
if(score == ctx.best_score && ctx.candidate_index == 1)
|
||||
{
|
||||
call_struct<
|
||||
std::is_member_function_pointer<F>::value,
|
||||
std::is_void<typename traits::result_type>::value,
|
||||
typename traits::argument_index_list
|
||||
>::call(L, f, converter_tuple);
|
||||
|
||||
results = lua_gettop(L) - traits::arity;
|
||||
if(has_call_policy<PolicyList, yield_policy>::value) {
|
||||
results = lua_yield(L, results);
|
||||
}
|
||||
|
||||
call_detail_new::policy_list_postcall < PolicyList, typename meta::push_front< typename traits::stack_index_list, meta::index<traits::arity> >::type >::postcall(L, results);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template< typename PolicyList, typename Signature, typename F>
|
||||
inline int invoke(lua_State* L, function_object const& self, invoke_context& ctx, F& f)
|
||||
{
|
||||
return invoke_struct<PolicyList, Signature, F>::invoke(L, self, ctx, f);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
} // namespace luabind::detail
|
||||
#if !BOOST_PP_IS_ITERATING
|
||||
|
||||
# ifndef LUABIND_CALL2_080911_HPP
|
||||
# define LUABIND_CALL2_080911_HPP
|
||||
|
||||
# include <boost/mpl/apply_wrap.hpp>
|
||||
# include <boost/mpl/begin_end.hpp>
|
||||
# include <boost/mpl/deref.hpp>
|
||||
# include <boost/mpl/front.hpp>
|
||||
# include <boost/mpl/long.hpp>
|
||||
# include <boost/mpl/size.hpp>
|
||||
# include <boost/preprocessor/control/if.hpp>
|
||||
# include <boost/preprocessor/iteration/iterate.hpp>
|
||||
# include <boost/preprocessor/iteration/local.hpp>
|
||||
# include <boost/preprocessor/repetition/enum.hpp>
|
||||
# include <boost/preprocessor/repetition/enum_trailing_params.hpp>
|
||||
# include <boost/type_traits/is_void.hpp>
|
||||
|
||||
# include <luabind/config.hpp>
|
||||
# include <luabind/detail/policy.hpp>
|
||||
# include <luabind/yield_policy.hpp>
|
||||
|
||||
namespace luabind { namespace detail {
|
||||
|
||||
struct invoke_context;
|
||||
|
||||
struct LUABIND_API function_object
|
||||
{
|
||||
function_object(lua_CFunction entry)
|
||||
: entry(entry)
|
||||
, next(0)
|
||||
{}
|
||||
|
||||
virtual ~function_object()
|
||||
{}
|
||||
|
||||
virtual int call(
|
||||
lua_State* L, invoke_context& ctx) const = 0;
|
||||
virtual void format_signature(lua_State* L, char const* function) const = 0;
|
||||
|
||||
lua_CFunction entry;
|
||||
std::string name;
|
||||
function_object* next;
|
||||
object keepalive;
|
||||
};
|
||||
|
||||
struct LUABIND_API invoke_context
|
||||
{
|
||||
invoke_context()
|
||||
: best_score((std::numeric_limits<int>::max)())
|
||||
, candidate_index(0)
|
||||
{}
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
return candidate_index == 1;
|
||||
}
|
||||
|
||||
void format_error(lua_State* L, function_object const* overloads) const;
|
||||
|
||||
int best_score;
|
||||
function_object const* candidates[10];
|
||||
int candidate_index;
|
||||
};
|
||||
|
||||
template <class F, class Signature, class Policies, class IsVoid>
|
||||
inline int invoke0(
|
||||
lua_State* L, function_object const& self, invoke_context& ctx
|
||||
, F const& f, Signature, Policies const& policies, IsVoid, mpl::true_)
|
||||
{
|
||||
return invoke_member(
|
||||
L, self, ctx, f, Signature(), policies
|
||||
, mpl::long_<mpl::size<Signature>::value - 1>(), IsVoid()
|
||||
);
|
||||
}
|
||||
|
||||
template <class F, class Signature, class Policies, class IsVoid>
|
||||
inline int invoke0(
|
||||
lua_State* L, function_object const& self, invoke_context& ctx,
|
||||
F const& f, Signature, Policies const& policies, IsVoid, mpl::false_)
|
||||
{
|
||||
return invoke_normal(
|
||||
L, self, ctx, f, Signature(), policies
|
||||
, mpl::long_<mpl::size<Signature>::value - 1>(), IsVoid()
|
||||
);
|
||||
}
|
||||
|
||||
template <class F, class Signature, class Policies>
|
||||
inline int invoke(
|
||||
lua_State* L, function_object const& self, invoke_context& ctx
|
||||
, F const& f, Signature, Policies const& policies)
|
||||
{
|
||||
return invoke0(
|
||||
L, self, ctx, f, Signature(), policies
|
||||
, boost::is_void<typename mpl::front<Signature>::type>()
|
||||
, boost::is_member_function_pointer<F>()
|
||||
);
|
||||
}
|
||||
|
||||
inline int maybe_yield_aux(lua_State*, int results, mpl::false_)
|
||||
{
|
||||
return results;
|
||||
}
|
||||
|
||||
inline int maybe_yield_aux(lua_State* L, int results, mpl::true_)
|
||||
{
|
||||
return lua_yield(L, results);
|
||||
}
|
||||
|
||||
template <class Policies>
|
||||
int maybe_yield(lua_State* L, int results, Policies*)
|
||||
{
|
||||
return maybe_yield_aux(
|
||||
L, results, mpl::bool_<has_yield<Policies>::value>());
|
||||
}
|
||||
|
||||
inline int sum_scores(int const* first, int const* last)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
for (; first != last; ++first)
|
||||
{
|
||||
if (*first < 0)
|
||||
return *first;
|
||||
result += *first;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
# define LUABIND_INVOKE_NEXT_ITER(n) \
|
||||
typename mpl::next< \
|
||||
BOOST_PP_IF( \
|
||||
n, BOOST_PP_CAT(iter,BOOST_PP_DEC(n)), first) \
|
||||
>::type
|
||||
|
||||
# define LUABIND_INVOKE_NEXT_INDEX(n) \
|
||||
BOOST_PP_IF( \
|
||||
n \
|
||||
, BOOST_PP_CAT(index,BOOST_PP_DEC(n)) + \
|
||||
BOOST_PP_CAT(c,BOOST_PP_DEC(n)).consumed_args() \
|
||||
, 1 \
|
||||
)
|
||||
|
||||
# define LUABIND_INVOKE_COMPUTE_ARITY(n) + BOOST_PP_CAT(c,n).consumed_args()
|
||||
|
||||
# define LUABIND_INVOKE_DECLARE_CONVERTER(n) \
|
||||
typedef LUABIND_INVOKE_NEXT_ITER(n) BOOST_PP_CAT(iter,n); \
|
||||
typedef typename mpl::deref<BOOST_PP_CAT(iter,n)>::type \
|
||||
BOOST_PP_CAT(a,n); \
|
||||
typedef typename find_conversion_policy<n + 1, Policies>::type \
|
||||
BOOST_PP_CAT(p,n); \
|
||||
typename mpl::apply_wrap2< \
|
||||
BOOST_PP_CAT(p,n), BOOST_PP_CAT(a,n), lua_to_cpp>::type BOOST_PP_CAT(c,n); \
|
||||
int const BOOST_PP_CAT(index,n) = LUABIND_INVOKE_NEXT_INDEX(n);
|
||||
|
||||
# define LUABIND_INVOKE_COMPUTE_SCORE(n) \
|
||||
, BOOST_PP_CAT(c,n).match( \
|
||||
L, LUABIND_DECORATE_TYPE(BOOST_PP_CAT(a,n)), BOOST_PP_CAT(index,n))
|
||||
|
||||
# define LUABIND_INVOKE_ARG(z, n, base) \
|
||||
BOOST_PP_CAT(c,base(n)).apply( \
|
||||
L, LUABIND_DECORATE_TYPE(BOOST_PP_CAT(a,base(n))), BOOST_PP_CAT(index,base(n)))
|
||||
|
||||
# define LUABIND_INVOKE_CONVERTER_POSTCALL(n) \
|
||||
BOOST_PP_CAT(c,n).converter_postcall( \
|
||||
L, LUABIND_DECORATE_TYPE(BOOST_PP_CAT(a,n)), BOOST_PP_CAT(index,n));
|
||||
|
||||
# define BOOST_PP_ITERATION_PARAMS_1 \
|
||||
(3, (0, LUABIND_MAX_ARITY, <luabind/detail/call.hpp>))
|
||||
# include BOOST_PP_ITERATE()
|
||||
|
||||
# define LUABIND_INVOKE_VOID
|
||||
# define BOOST_PP_ITERATION_PARAMS_1 \
|
||||
(3, (0, LUABIND_MAX_ARITY, <luabind/detail/call.hpp>))
|
||||
# include BOOST_PP_ITERATE()
|
||||
|
||||
# undef LUABIND_INVOKE_VOID
|
||||
# define LUABIND_INVOKE_MEMBER
|
||||
# define BOOST_PP_ITERATION_PARAMS_1 \
|
||||
(3, (0, LUABIND_MAX_ARITY, <luabind/detail/call.hpp>))
|
||||
# include BOOST_PP_ITERATE()
|
||||
|
||||
# define LUABIND_INVOKE_VOID
|
||||
# define BOOST_PP_ITERATION_PARAMS_1 \
|
||||
(3, (0, LUABIND_MAX_ARITY, <luabind/detail/call.hpp>))
|
||||
# include BOOST_PP_ITERATE()
|
||||
|
||||
}} // namespace luabind::detail
|
||||
|
||||
# endif // LUABIND_CALL2_080911_HPP
|
||||
|
||||
#else // BOOST_PP_IS_ITERATING
|
||||
|
||||
# ifdef LUABIND_INVOKE_MEMBER
|
||||
# define N BOOST_PP_INC(BOOST_PP_ITERATION())
|
||||
# else
|
||||
# define N BOOST_PP_ITERATION()
|
||||
# endif
|
||||
|
||||
template <class F, class Signature, class Policies>
|
||||
inline int
|
||||
# ifdef LUABIND_INVOKE_MEMBER
|
||||
invoke_member
|
||||
# else
|
||||
invoke_normal
|
||||
# endif
|
||||
(
|
||||
lua_State* L, function_object const& self, invoke_context& ctx
|
||||
, F const& f, Signature, Policies const&, mpl::long_<N>
|
||||
# ifdef LUABIND_INVOKE_VOID
|
||||
, mpl::true_
|
||||
# else
|
||||
, mpl::false_
|
||||
# endif
|
||||
)
|
||||
{
|
||||
typedef typename mpl::begin<Signature>::type first;
|
||||
# ifndef LUABIND_INVOKE_VOID
|
||||
typedef typename mpl::deref<first>::type result_type;
|
||||
typedef typename find_conversion_policy<0, Policies>::type result_policy;
|
||||
typename mpl::apply_wrap2<
|
||||
result_policy, result_type, cpp_to_lua>::type result_converter;
|
||||
# endif
|
||||
|
||||
# if N > 0
|
||||
# define BOOST_PP_LOCAL_MACRO(n) LUABIND_INVOKE_DECLARE_CONVERTER(n)
|
||||
# define BOOST_PP_LOCAL_LIMITS (0,N-1)
|
||||
# include BOOST_PP_LOCAL_ITERATE()
|
||||
# endif
|
||||
|
||||
int const arity = 0
|
||||
# if N > 0
|
||||
# define BOOST_PP_LOCAL_MACRO(n) LUABIND_INVOKE_COMPUTE_ARITY(n)
|
||||
# define BOOST_PP_LOCAL_LIMITS (0,N-1)
|
||||
# include BOOST_PP_LOCAL_ITERATE()
|
||||
# endif
|
||||
;
|
||||
|
||||
int const arguments = lua_gettop(L);
|
||||
|
||||
int score = -1;
|
||||
|
||||
if (arity == arguments)
|
||||
{
|
||||
int const scores[] = {
|
||||
0
|
||||
# if N > 0
|
||||
# define BOOST_PP_LOCAL_MACRO(n) LUABIND_INVOKE_COMPUTE_SCORE(n)
|
||||
# define BOOST_PP_LOCAL_LIMITS (0,N-1)
|
||||
# include BOOST_PP_LOCAL_ITERATE()
|
||||
# endif
|
||||
};
|
||||
|
||||
score = sum_scores(scores + 1, scores + 1 + N);
|
||||
}
|
||||
|
||||
if (score >= 0 && score < ctx.best_score)
|
||||
{
|
||||
ctx.best_score = score;
|
||||
ctx.candidates[0] = &self;
|
||||
ctx.candidate_index = 1;
|
||||
}
|
||||
else if (score == ctx.best_score)
|
||||
{
|
||||
ctx.candidates[ctx.candidate_index++] = &self;
|
||||
}
|
||||
|
||||
int results = 0;
|
||||
|
||||
if (self.next)
|
||||
{
|
||||
results = self.next->call(L, ctx);
|
||||
}
|
||||
|
||||
if (score == ctx.best_score && ctx.candidate_index == 1)
|
||||
{
|
||||
# ifndef LUABIND_INVOKE_VOID
|
||||
result_converter.apply(
|
||||
L,
|
||||
# endif
|
||||
# ifdef LUABIND_INVOKE_MEMBER
|
||||
(c0.apply(L, LUABIND_DECORATE_TYPE(a0), index0).*f)(
|
||||
BOOST_PP_ENUM(BOOST_PP_DEC(N), LUABIND_INVOKE_ARG, BOOST_PP_INC)
|
||||
)
|
||||
# else
|
||||
# define LUABIND_INVOKE_IDENTITY(x) x
|
||||
f(
|
||||
BOOST_PP_ENUM(N, LUABIND_INVOKE_ARG, LUABIND_INVOKE_IDENTITY)
|
||||
)
|
||||
# undef LUABIND_INVOKE_IDENTITY
|
||||
# endif
|
||||
# ifndef LUABIND_INVOKE_VOID
|
||||
)
|
||||
# endif
|
||||
;
|
||||
|
||||
# if N > 0
|
||||
# define BOOST_PP_LOCAL_MACRO(n) LUABIND_INVOKE_CONVERTER_POSTCALL(n)
|
||||
# define BOOST_PP_LOCAL_LIMITS (0,N-1)
|
||||
# include BOOST_PP_LOCAL_ITERATE()
|
||||
# endif
|
||||
|
||||
results = maybe_yield(L, lua_gettop(L) - arguments, (Policies*)0);
|
||||
|
||||
int const indices[] = {
|
||||
arguments + results BOOST_PP_ENUM_TRAILING_PARAMS(N, index)
|
||||
};
|
||||
|
||||
policy_list_postcall<Policies>::apply(L, indices);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
# undef N
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -20,175 +20,423 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
// OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
#if !BOOST_PP_IS_ITERATING
|
||||
|
||||
#ifndef LUABIND_CALL_FUNCTION_HPP_INCLUDED
|
||||
#define LUABIND_CALL_FUNCTION_HPP_INCLUDED
|
||||
|
||||
#include <luabind/config.hpp>
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
#include <boost/preprocessor/repeat.hpp>
|
||||
#include <boost/preprocessor/iteration/iterate.hpp>
|
||||
#include <boost/preprocessor/repetition/enum.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/punctuation/comma_if.hpp>
|
||||
|
||||
#include <luabind/error.hpp>
|
||||
#include <luabind/detail/push_to_lua.hpp>
|
||||
#include <luabind/detail/convert_to_lua.hpp>
|
||||
#include <luabind/detail/pcall.hpp>
|
||||
#include <luabind/detail/call_shared.hpp>
|
||||
#include <luabind/detail/stack_utils.hpp>
|
||||
|
||||
namespace luabind
|
||||
{
|
||||
namespace adl {
|
||||
class object;
|
||||
}
|
||||
namespace detail
|
||||
{
|
||||
|
||||
using adl::object;
|
||||
// if the proxy_function_caller returns non-void
|
||||
template<class Ret, class Tuple>
|
||||
class proxy_function_caller
|
||||
{
|
||||
// friend class luabind::object;
|
||||
public:
|
||||
|
||||
namespace detail {
|
||||
typedef int(*function_t)(lua_State*, int, int);
|
||||
|
||||
template< typename PolicyList, unsigned int pos >
|
||||
void push_arguments(lua_State* /*L*/) {}
|
||||
proxy_function_caller(
|
||||
lua_State* L
|
||||
, int params
|
||||
, function_t fun
|
||||
, const Tuple args)
|
||||
: m_state(L)
|
||||
, m_params(params)
|
||||
, m_fun(fun)
|
||||
, m_args(args)
|
||||
, m_called(false)
|
||||
{
|
||||
}
|
||||
|
||||
template< typename PolicyList, unsigned int Pos, typename Arg0, typename... Args >
|
||||
void push_arguments(lua_State* L, Arg0&& arg0, Args&&... args)
|
||||
{
|
||||
using converter_type = specialized_converter_policy< fetched_converter_policy<Pos, PolicyList>, Arg0, cpp_to_lua >;
|
||||
converter_type().to_lua(L, unwrapped<Arg0>::get(std::forward<Arg0>(arg0)));
|
||||
push_arguments<PolicyList, Pos + 1>(L, std::forward<Args>(args)...);
|
||||
}
|
||||
proxy_function_caller(const proxy_function_caller& rhs)
|
||||
: m_state(rhs.m_state)
|
||||
, m_params(rhs.m_params)
|
||||
, m_fun(rhs.m_fun)
|
||||
, m_args(rhs.m_args)
|
||||
, m_called(rhs.m_called)
|
||||
{
|
||||
rhs.m_called = true;
|
||||
}
|
||||
|
||||
#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS
|
||||
template<typename Ret, typename PolicyList, typename... Args, unsigned int... Indices, typename Fn>
|
||||
void call_function_impl(lua_State* L, int m_params, Fn fn, std::true_type /* void */, meta::index_list<Indices...>, Args&&... args)
|
||||
{
|
||||
int top = lua_gettop(L);
|
||||
~proxy_function_caller()
|
||||
{
|
||||
if (m_called) return;
|
||||
|
||||
push_arguments<PolicyList, 1>(L, std::forward<Args>(args)...);
|
||||
m_called = true;
|
||||
lua_State* L = m_state;
|
||||
|
||||
if(fn(L, sizeof...(Args), 0)) {
|
||||
assert(lua_gettop(L) == top - m_params + 1);
|
||||
call_error(L);
|
||||
}
|
||||
// pops the return values from the function call
|
||||
stack_pop pop(L, lua_gettop(L) - top + m_params);
|
||||
}
|
||||
int top = lua_gettop(L);
|
||||
|
||||
template<typename Ret, typename PolicyList, typename... Args, unsigned int... Indices, typename Fn>
|
||||
Ret call_function_impl(lua_State* L, int m_params, Fn fn, std::false_type /* void */, meta::index_list<Indices...>, Args&&... args)
|
||||
{
|
||||
int top = lua_gettop(L);
|
||||
|
||||
push_arguments<PolicyList, 1>(L, std::forward<Args>(args)...);
|
||||
|
||||
if(fn(L, sizeof...(Args), 1)) {
|
||||
assert(lua_gettop(L) == top - m_params + 1);
|
||||
call_error(L);
|
||||
}
|
||||
// pops the return values from the function call
|
||||
stack_pop pop(L, lua_gettop(L) - top + m_params);
|
||||
|
||||
specialized_converter_policy_n<0, PolicyList, Ret, lua_to_cpp> converter;
|
||||
if(converter.match(L, decorate_type_t<Ret>(), -1) < 0) {
|
||||
cast_error<Ret>(L);
|
||||
}
|
||||
|
||||
return converter.to_cpp(L, decorate_type_t<Ret>(), -1);
|
||||
}
|
||||
push_args_from_tuple<1>::apply(L, m_args);
|
||||
if (m_fun(L, boost::tuples::length<Tuple>::value, 0))
|
||||
{
|
||||
assert(lua_gettop(L) == top - m_params + 1);
|
||||
#ifndef LUABIND_NO_EXCEPTIONS
|
||||
throw luabind::error(L);
|
||||
#else
|
||||
template<typename Ret, typename PolicyList, typename IndexList, unsigned int NumParams, int(*Function)(lua_State*, int, int), bool IsVoid = std::is_void<Ret>::value>
|
||||
struct call_function_struct;
|
||||
error_callback_fun e = get_error_callback();
|
||||
if (e) e(L);
|
||||
|
||||
template<typename Ret, typename PolicyList, unsigned int NumParams, int(*Function)(lua_State*, int, int), unsigned int... Indices >
|
||||
struct call_function_struct< Ret, PolicyList, meta::index_list<Indices...>, NumParams, Function, true /* void */ >
|
||||
{
|
||||
template< typename... Args >
|
||||
static void call(lua_State* L, Args&&... args) {
|
||||
int top = lua_gettop(L);
|
||||
assert(0 && "the lua function threw an error and exceptions are disabled."
|
||||
" If you want to handle the error you can use luabind::set_error_callback()");
|
||||
std::terminate();
|
||||
|
||||
push_arguments<PolicyList, 1>(L, std::forward<Args>(args)...);
|
||||
|
||||
if(Function(L, sizeof...(Args), 0)) {
|
||||
if(Function == &detail::pcall) {
|
||||
assert(lua_gettop(L) == static_cast<int>(top - NumParams + 1));
|
||||
#endif
|
||||
}
|
||||
call_error(L);
|
||||
|
||||
// pops the return values from the function call
|
||||
stack_pop pop(L, lua_gettop(L) - top + m_params);
|
||||
}
|
||||
// pops the return values from the function call
|
||||
stack_pop pop(L, lua_gettop(L) - top + NumParams);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Ret, typename PolicyList, unsigned int NumParams, int(*Function)(lua_State*, int, int), unsigned int... Indices >
|
||||
struct call_function_struct< Ret, PolicyList, meta::index_list<Indices...>, NumParams, Function, false /* void */ >
|
||||
{
|
||||
template< typename... Args >
|
||||
static Ret call(lua_State* L, Args&&... args) {
|
||||
int top = lua_gettop(L);
|
||||
operator Ret()
|
||||
{
|
||||
typename mpl::apply_wrap2<default_policy,Ret,lua_to_cpp>::type converter;
|
||||
|
||||
push_arguments<PolicyList, 1>(L, std::forward<Args>(args)...);
|
||||
m_called = true;
|
||||
lua_State* L = m_state;
|
||||
|
||||
if(Function(L, sizeof...(Args), 1)) {
|
||||
if(Function == &detail::pcall) {
|
||||
assert(lua_gettop(L) == static_cast<int>(top - NumParams + 1));
|
||||
int top = lua_gettop(L);
|
||||
|
||||
push_args_from_tuple<1>::apply(L, m_args);
|
||||
if (m_fun(L, boost::tuples::length<Tuple>::value, 1))
|
||||
{
|
||||
assert(lua_gettop(L) == top - m_params + 1);
|
||||
#ifndef LUABIND_NO_EXCEPTIONS
|
||||
throw luabind::error(L);
|
||||
#else
|
||||
error_callback_fun e = get_error_callback();
|
||||
if (e) e(L);
|
||||
|
||||
assert(0 && "the lua function threw an error and exceptions are disabled."
|
||||
" If you want to handle the error you can use luabind::set_error_callback()");
|
||||
std::terminate();
|
||||
#endif
|
||||
}
|
||||
call_error(L);
|
||||
}
|
||||
// pops the return values from the function call
|
||||
stack_pop pop(L, lua_gettop(L) - top + NumParams);
|
||||
|
||||
specialized_converter_policy_n<0, PolicyList, Ret, lua_to_cpp> converter;
|
||||
if(converter.match(L, decorate_type_t<Ret>(), -1) < 0) {
|
||||
cast_error<Ret>(L);
|
||||
// pops the return values from the function call
|
||||
stack_pop pop(L, lua_gettop(L) - top + m_params);
|
||||
|
||||
#ifndef LUABIND_NO_ERROR_CHECKING
|
||||
|
||||
if (converter.match(L, LUABIND_DECORATE_TYPE(Ret), -1) < 0)
|
||||
{
|
||||
#ifndef LUABIND_NO_EXCEPTIONS
|
||||
throw cast_failed(L, typeid(Ret));
|
||||
#else
|
||||
cast_failed_callback_fun e = get_cast_failed_callback();
|
||||
if (e) e(L, typeid(Ret));
|
||||
|
||||
assert(0 && "the lua function's return value could not be converted."
|
||||
" If you want to handle the error you can use luabind::set_error_callback()");
|
||||
std::terminate();
|
||||
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
return converter.apply(L, LUABIND_DECORATE_TYPE(Ret), -1);
|
||||
}
|
||||
|
||||
return converter.to_cpp(L, decorate_type_t<Ret>(), -1);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
}
|
||||
template<class Policies>
|
||||
Ret operator[](const Policies& p)
|
||||
{
|
||||
typedef typename detail::find_conversion_policy<0, Policies>::type converter_policy;
|
||||
typename mpl::apply_wrap2<converter_policy,Ret,lua_to_cpp>::type converter;
|
||||
|
||||
template<class R, typename PolicyList = no_policies, typename... Args>
|
||||
R call_pushed_function(lua_State* L, Args&&... args)
|
||||
{
|
||||
#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS
|
||||
return detail::call_function_impl<R, PolicyList>(L, 1, &detail::pcall, std::is_void<R>(), meta::index_range<1, sizeof...(Args)+1>(), std::forward<Args>(args)...);
|
||||
m_called = true;
|
||||
lua_State* L = m_state;
|
||||
|
||||
int top = lua_gettop(L);
|
||||
|
||||
detail::push_args_from_tuple<1>::apply(L, m_args, p);
|
||||
if (m_fun(L, boost::tuples::length<Tuple>::value, 1))
|
||||
{
|
||||
assert(lua_gettop(L) == top - m_params + 1);
|
||||
#ifndef LUABIND_NO_EXCEPTIONS
|
||||
throw error(L);
|
||||
#else
|
||||
return detail::call_function_struct<R, PolicyList, meta::index_range<1, sizeof...(Args)+1>, 1, &detail::pcall >::call(L, std::forward<Args>(args)...);
|
||||
error_callback_fun e = get_error_callback();
|
||||
if (e) e(L);
|
||||
|
||||
assert(0 && "the lua function threw an error and exceptions are disabled."
|
||||
" If you want to handle the error you can use luabind::set_error_callback()");
|
||||
std::terminate();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
template<class R, typename PolicyList = no_policies, typename... Args>
|
||||
R call_function(lua_State* L, const char* name, Args&&... args)
|
||||
{
|
||||
assert(name && "luabind::call_function() expects a function name");
|
||||
lua_getglobal(L, name);
|
||||
return call_pushed_function<R, PolicyList>(L, std::forward<Args>(args)...);
|
||||
}
|
||||
// pops the return values from the function call
|
||||
stack_pop pop(L, lua_gettop(L) - top + m_params);
|
||||
|
||||
template<class R, typename PolicyList = no_policies, typename... Args>
|
||||
R resume_pushed_function(lua_State* L, Args&&... args)
|
||||
{
|
||||
#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS
|
||||
return detail::call_function_impl<R, PolicyList>(L, 1, &detail::resume_impl, std::is_void<R>(), meta::index_range<1, sizeof...(Args)+1>(), std::forward<Args>(args)...);
|
||||
#ifndef LUABIND_NO_ERROR_CHECKING
|
||||
|
||||
if (converter.match(L, LUABIND_DECORATE_TYPE(Ret), -1) < 0)
|
||||
{
|
||||
#ifndef LUABIND_NO_EXCEPTIONS
|
||||
throw cast_failed(L, typeid(Ret));
|
||||
#else
|
||||
return detail::call_function_struct<R, PolicyList, meta::index_range<1, sizeof...(Args)+1>, 1, &detail::resume_impl >::call(L, std::forward<Args>(args)...);
|
||||
cast_failed_callback_fun e = get_cast_failed_callback();
|
||||
if (e) e(L, typeid(Ret));
|
||||
|
||||
assert(0 && "the lua function's return value could not be converted."
|
||||
" If you want to handle the error you can use luabind::set_error_callback()");
|
||||
std::terminate();
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return converter.apply(L, LUABIND_DECORATE_TYPE(Ret), -1);
|
||||
}
|
||||
|
||||
template<class R, typename PolicyList = no_policies, typename... Args>
|
||||
R resume_function(lua_State* L, const char* name, Args&&... args)
|
||||
{
|
||||
assert(name && "luabind::resume_function() expects a function name");
|
||||
lua_getglobal(L, name);
|
||||
return resume_pushed_function<R, PolicyList>(L, std::forward<Args>(args)...);
|
||||
}
|
||||
private:
|
||||
|
||||
template<class R, typename PolicyList = no_policies, typename... Args>
|
||||
R resume(lua_State* L, Args&&... args)
|
||||
{
|
||||
#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS
|
||||
return detail::call_function_impl<R, PolicyList>(L, 0, &detail::resume_impl, std::is_void<R>(), meta::index_range<1, sizeof...(Args)+1>(), std::forward<Args>(args)...);
|
||||
lua_State* m_state;
|
||||
int m_params;
|
||||
function_t m_fun;
|
||||
Tuple m_args;
|
||||
mutable bool m_called;
|
||||
|
||||
};
|
||||
|
||||
// if the proxy_member_caller returns void
|
||||
template<class Tuple>
|
||||
class proxy_function_void_caller
|
||||
{
|
||||
friend class luabind::object;
|
||||
public:
|
||||
|
||||
typedef int(*function_t)(lua_State*, int, int);
|
||||
|
||||
proxy_function_void_caller(
|
||||
lua_State* L
|
||||
, int params
|
||||
, function_t fun
|
||||
, const Tuple args)
|
||||
: m_state(L)
|
||||
, m_params(params)
|
||||
, m_fun(fun)
|
||||
, m_args(args)
|
||||
, m_called(false)
|
||||
{
|
||||
}
|
||||
|
||||
proxy_function_void_caller(const proxy_function_void_caller& rhs)
|
||||
: m_state(rhs.m_state)
|
||||
, m_params(rhs.m_params)
|
||||
, m_fun(rhs.m_fun)
|
||||
, m_args(rhs.m_args)
|
||||
, m_called(rhs.m_called)
|
||||
{
|
||||
rhs.m_called = true;
|
||||
}
|
||||
|
||||
~proxy_function_void_caller()
|
||||
{
|
||||
if (m_called) return;
|
||||
|
||||
m_called = true;
|
||||
lua_State* L = m_state;
|
||||
|
||||
int top = lua_gettop(L);
|
||||
|
||||
push_args_from_tuple<1>::apply(L, m_args);
|
||||
if (m_fun(L, boost::tuples::length<Tuple>::value, 0))
|
||||
{
|
||||
assert(lua_gettop(L) == top - m_params + 1);
|
||||
#ifndef LUABIND_NO_EXCEPTIONS
|
||||
throw luabind::error(L);
|
||||
#else
|
||||
return detail::call_function_struct<R, PolicyList, meta::index_range<1, sizeof...(Args)+1>, 0, &detail::resume_impl >::call(L, std::forward<Args>(args)...);
|
||||
error_callback_fun e = get_error_callback();
|
||||
if (e) e(L);
|
||||
|
||||
assert(0 && "the lua function threw an error and exceptions are disabled."
|
||||
" If you want to handle the error you can use luabind::set_error_callback()");
|
||||
std::terminate();
|
||||
#endif
|
||||
}
|
||||
// pops the return values from the function call
|
||||
stack_pop pop(L, lua_gettop(L) - top + m_params);
|
||||
}
|
||||
|
||||
template<class Policies>
|
||||
void operator[](const Policies& p)
|
||||
{
|
||||
m_called = true;
|
||||
lua_State* L = m_state;
|
||||
|
||||
int top = lua_gettop(L);
|
||||
|
||||
detail::push_args_from_tuple<1>::apply(L, m_args, p);
|
||||
if (m_fun(L, boost::tuples::length<Tuple>::value, 0))
|
||||
{
|
||||
assert(lua_gettop(L) == top - m_params + 1);
|
||||
#ifndef LUABIND_NO_EXCEPTIONS
|
||||
throw error(L);
|
||||
#else
|
||||
error_callback_fun e = get_error_callback();
|
||||
if (e) e(L);
|
||||
|
||||
assert(0 && "the lua function threw an error and exceptions are disabled."
|
||||
" If you want to handle the error you can use luabind::set_error_callback()");
|
||||
std::terminate();
|
||||
#endif
|
||||
}
|
||||
// pops the return values from the function call
|
||||
stack_pop pop(L, lua_gettop(L) - top + m_params);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
lua_State* m_state;
|
||||
int m_params;
|
||||
function_t m_fun;
|
||||
Tuple m_args;
|
||||
mutable bool m_called;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, <luabind/detail/call_function.hpp>, 1))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
}
|
||||
|
||||
#endif // LUABIND_CALL_FUNCTION_HPP_INCLUDED
|
||||
|
||||
#else
|
||||
#if BOOST_PP_ITERATION_FLAGS() == 1
|
||||
|
||||
#define LUABIND_TUPLE_PARAMS(z, n, data) const A##n *
|
||||
#define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n
|
||||
|
||||
|
||||
template<class Ret BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
|
||||
typename boost::mpl::if_<boost::is_void<Ret>
|
||||
, luabind::detail::proxy_function_void_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
|
||||
, luabind::detail::proxy_function_caller<Ret, boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> > >::type
|
||||
call_function(lua_State* L, const char* name BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _) )
|
||||
{
|
||||
assert(name && "luabind::call_function() expects a function name");
|
||||
typedef boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> tuple_t;
|
||||
#if BOOST_PP_ITERATION() == 0
|
||||
tuple_t args;
|
||||
#else
|
||||
tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a));
|
||||
#endif
|
||||
typedef typename boost::mpl::if_<boost::is_void<Ret>
|
||||
, luabind::detail::proxy_function_void_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
|
||||
, luabind::detail::proxy_function_caller<Ret, boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> > >::type proxy_type;
|
||||
|
||||
lua_getglobal(L, name);
|
||||
|
||||
return proxy_type(L, 1, &detail::pcall, args);
|
||||
}
|
||||
|
||||
template<class Ret BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
|
||||
typename boost::mpl::if_<boost::is_void<Ret>
|
||||
, luabind::detail::proxy_function_void_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
|
||||
, luabind::detail::proxy_function_caller<Ret, boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> > >::type
|
||||
call_function(luabind::object const& obj BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _) )
|
||||
{
|
||||
typedef boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> tuple_t;
|
||||
#if BOOST_PP_ITERATION() == 0
|
||||
tuple_t args;
|
||||
#else
|
||||
tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a));
|
||||
#endif
|
||||
typedef typename boost::mpl::if_<boost::is_void<Ret>
|
||||
, luabind::detail::proxy_function_void_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
|
||||
, luabind::detail::proxy_function_caller<Ret, boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> > >::type proxy_type;
|
||||
|
||||
obj.push(obj.interpreter());
|
||||
return proxy_type(obj.interpreter(), 1, &detail::pcall, args);
|
||||
}
|
||||
|
||||
template<class Ret BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
|
||||
typename boost::mpl::if_<boost::is_void<Ret>
|
||||
, luabind::detail::proxy_function_void_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
|
||||
, luabind::detail::proxy_function_caller<Ret, boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> > >::type
|
||||
resume_function(lua_State* L, const char* name BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _) )
|
||||
{
|
||||
assert(name && "luabind::resume_function() expects a function name");
|
||||
typedef boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> tuple_t;
|
||||
#if BOOST_PP_ITERATION() == 0
|
||||
tuple_t args;
|
||||
#else
|
||||
tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a));
|
||||
#endif
|
||||
typedef typename boost::mpl::if_<boost::is_void<Ret>
|
||||
, luabind::detail::proxy_function_void_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
|
||||
, luabind::detail::proxy_function_caller<Ret, boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> > >::type proxy_type;
|
||||
|
||||
lua_getglobal(L, name);
|
||||
|
||||
return proxy_type(L, 1, &detail::resume_impl, args);
|
||||
}
|
||||
|
||||
template<class Ret BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
|
||||
typename boost::mpl::if_<boost::is_void<Ret>
|
||||
, luabind::detail::proxy_function_void_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
|
||||
, luabind::detail::proxy_function_caller<Ret, boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> > >::type
|
||||
resume_function(luabind::object const& obj BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _) )
|
||||
{
|
||||
typedef boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> tuple_t;
|
||||
#if BOOST_PP_ITERATION() == 0
|
||||
tuple_t args;
|
||||
#else
|
||||
tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a));
|
||||
#endif
|
||||
typedef typename boost::mpl::if_<boost::is_void<Ret>
|
||||
, luabind::detail::proxy_function_void_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
|
||||
, luabind::detail::proxy_function_caller<Ret, boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> > >::type proxy_type;
|
||||
|
||||
obj.push(obj.interpreter());
|
||||
return proxy_type(obj.interpreter(), 1, &detail::resume_impl, args);
|
||||
}
|
||||
|
||||
template<class Ret BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
|
||||
typename boost::mpl::if_<boost::is_void<Ret>
|
||||
, luabind::detail::proxy_function_void_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
|
||||
, luabind::detail::proxy_function_caller<Ret, boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> > >::type
|
||||
resume(lua_State* L BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _) )
|
||||
{
|
||||
typedef boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> tuple_t;
|
||||
#if BOOST_PP_ITERATION() == 0
|
||||
tuple_t args;
|
||||
#else
|
||||
tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a));
|
||||
#endif
|
||||
typedef typename boost::mpl::if_<boost::is_void<Ret>
|
||||
, luabind::detail::proxy_function_void_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
|
||||
, luabind::detail::proxy_function_caller<Ret, boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> > >::type proxy_type;
|
||||
|
||||
return proxy_type(L, 0, &detail::resume_impl, args);
|
||||
}
|
||||
|
||||
|
||||
#undef LUABIND_OPERATOR_PARAMS
|
||||
#undef LUABIND_TUPLE_PARAMS
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -20,82 +20,325 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
// OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
#if !BOOST_PP_IS_ITERATING
|
||||
|
||||
#ifndef LUABIND_CALL_MEMBER_HPP_INCLUDED
|
||||
#define LUABIND_CALL_MEMBER_HPP_INCLUDED
|
||||
|
||||
#include <luabind/config.hpp>
|
||||
#include <luabind/detail/push_to_lua.hpp>
|
||||
#include <luabind/detail/convert_to_lua.hpp>
|
||||
#include <luabind/detail/pcall.hpp>
|
||||
#include <luabind/error.hpp>
|
||||
#include <luabind/detail/stack_utils.hpp>
|
||||
#include <luabind/detail/call_shared.hpp>
|
||||
#include <luabind/object.hpp>
|
||||
#include <luabind/object.hpp> // TODO: REMOVE DEPENDENCY
|
||||
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
|
||||
#include <boost/preprocessor/control/if.hpp>
|
||||
#include <boost/preprocessor/facilities/expand.hpp>
|
||||
#include <boost/preprocessor/repetition/enum.hpp>
|
||||
|
||||
#include <boost/mpl/apply_wrap.hpp>
|
||||
|
||||
namespace luabind
|
||||
{
|
||||
using adl::object;
|
||||
namespace detail
|
||||
{
|
||||
|
||||
namespace detail {
|
||||
namespace mpl = boost::mpl;
|
||||
|
||||
template<class R, typename PolicyList, unsigned int... Indices, typename... Args>
|
||||
R call_member_impl(lua_State* L, std::true_type /*void*/, meta::index_list<Indices...>, Args&&... args)
|
||||
{
|
||||
// don't count the function and self-reference
|
||||
// since those will be popped by pcall
|
||||
int top = lua_gettop(L) - 2;
|
||||
// if the proxy_member_caller returns non-void
|
||||
template<class Ret, class Tuple>
|
||||
class proxy_member_caller
|
||||
{
|
||||
// friend class luabind::object;
|
||||
public:
|
||||
|
||||
// pcall will pop the function and self reference
|
||||
// and all the parameters
|
||||
proxy_member_caller(lua_State* L_, const Tuple args)
|
||||
: L(L_)
|
||||
, m_args(args)
|
||||
, m_called(false)
|
||||
{
|
||||
}
|
||||
|
||||
proxy_member_caller(const proxy_member_caller& rhs)
|
||||
: L(rhs.L)
|
||||
, m_args(rhs.m_args)
|
||||
, m_called(rhs.m_called)
|
||||
{
|
||||
rhs.m_called = true;
|
||||
}
|
||||
|
||||
~proxy_member_caller()
|
||||
{
|
||||
if (m_called) return;
|
||||
|
||||
m_called = true;
|
||||
|
||||
// don't count the function and self-reference
|
||||
// since those will be popped by pcall
|
||||
int top = lua_gettop(L) - 2;
|
||||
|
||||
// pcall will pop the function and self reference
|
||||
// and all the parameters
|
||||
|
||||
push_args_from_tuple<1>::apply(L, m_args);
|
||||
if (pcall(L, boost::tuples::length<Tuple>::value + 1, 0))
|
||||
{
|
||||
assert(lua_gettop(L) == top + 1);
|
||||
#ifndef LUABIND_NO_EXCEPTIONS
|
||||
throw luabind::error(L);
|
||||
#else
|
||||
error_callback_fun e = get_error_callback();
|
||||
if (e) e(L);
|
||||
|
||||
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
|
||||
}
|
||||
// pops the return values from the function
|
||||
stack_pop pop(L, lua_gettop(L) - top);
|
||||
}
|
||||
|
||||
operator Ret()
|
||||
{
|
||||
typename mpl::apply_wrap2<default_policy,Ret,lua_to_cpp>::type converter;
|
||||
|
||||
m_called = true;
|
||||
|
||||
// don't count the function and self-reference
|
||||
// since those will be popped by pcall
|
||||
int top = lua_gettop(L) - 2;
|
||||
|
||||
// pcall will pop the function and self reference
|
||||
// and all the parameters
|
||||
push_args_from_tuple<1>::apply(L, m_args);
|
||||
if (pcall(L, boost::tuples::length<Tuple>::value + 1, 1))
|
||||
{
|
||||
assert(lua_gettop(L) == top + 1);
|
||||
#ifndef LUABIND_NO_EXCEPTIONS
|
||||
throw luabind::error(L);
|
||||
#else
|
||||
error_callback_fun e = get_error_callback();
|
||||
if (e) e(L);
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// pops the return values from the function
|
||||
stack_pop pop(L, lua_gettop(L) - top);
|
||||
|
||||
#ifndef LUABIND_NO_ERROR_CHECKING
|
||||
|
||||
if (converter.match(L, LUABIND_DECORATE_TYPE(Ret), -1) < 0)
|
||||
{
|
||||
assert(lua_gettop(L) == top + 1);
|
||||
#ifndef LUABIND_NO_EXCEPTIONS
|
||||
throw cast_failed(L, typeid(Ret));
|
||||
#else
|
||||
cast_failed_callback_fun e = get_cast_failed_callback();
|
||||
if (e) e(L, typeid(Ret));
|
||||
|
||||
assert(0 && "the lua function's return value could not be converted."
|
||||
"If you want to handle this error use luabind::set_error_callback()");
|
||||
std::terminate();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
return converter.apply(L, LUABIND_DECORATE_TYPE(Ret), -1);
|
||||
}
|
||||
|
||||
template<class Policies>
|
||||
Ret operator[](const Policies& p)
|
||||
{
|
||||
typedef typename find_conversion_policy<0, Policies>::type converter_policy;
|
||||
typename mpl::apply_wrap2<converter_policy,Ret,lua_to_cpp>::type converter;
|
||||
|
||||
m_called = true;
|
||||
|
||||
// don't count the function and self-reference
|
||||
// since those will be popped by pcall
|
||||
int top = lua_gettop(L) - 2;
|
||||
|
||||
// pcall will pop the function and self reference
|
||||
// and all the parameters
|
||||
|
||||
detail::push_args_from_tuple<1>::apply(L, m_args, p);
|
||||
if (pcall(L, boost::tuples::length<Tuple>::value + 1, 1))
|
||||
{
|
||||
assert(lua_gettop(L) == top + 1);
|
||||
#ifndef LUABIND_NO_EXCEPTIONS
|
||||
throw error(L);
|
||||
#else
|
||||
error_callback_fun e = get_error_callback();
|
||||
if (e) e(L);
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// pops the return values from the function
|
||||
stack_pop pop(L, lua_gettop(L) - top);
|
||||
|
||||
#ifndef LUABIND_NO_ERROR_CHECKING
|
||||
|
||||
if (converter.match(L, LUABIND_DECORATE_TYPE(Ret), -1) < 0)
|
||||
{
|
||||
assert(lua_gettop(L) == top + 1);
|
||||
#ifndef LUABIND_NO_EXCEPTIONS
|
||||
throw cast_failed(L, typeid(Ret));
|
||||
#else
|
||||
cast_failed_callback_fun e = get_cast_failed_callback();
|
||||
if (e) e(L, typeid(Ret));
|
||||
|
||||
assert(0 && "the lua function's return value could not be converted."
|
||||
"If you want to handle this error use luabind::set_error_callback()");
|
||||
std::terminate();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
return converter.apply(L, LUABIND_DECORATE_TYPE(Ret), -1);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
lua_State* L;
|
||||
Tuple m_args;
|
||||
mutable bool m_called;
|
||||
|
||||
meta::init_order{ (
|
||||
specialized_converter_policy_n<Indices, PolicyList, typename unwrapped<Args>::type, cpp_to_lua>().to_lua(L, unwrapped<Args>::get(std::forward<Args>(args))), 0)...
|
||||
};
|
||||
|
||||
if(pcall(L, sizeof...(Args)+1, 0))
|
||||
// if the proxy_member_caller returns void
|
||||
template<class Tuple>
|
||||
class proxy_member_void_caller
|
||||
{
|
||||
assert(lua_gettop(L) == top + 1);
|
||||
call_error(L);
|
||||
}
|
||||
// pops the return values from the function
|
||||
stack_pop pop(L, lua_gettop(L) - top);
|
||||
}
|
||||
friend class luabind::object;
|
||||
public:
|
||||
|
||||
template<class R, typename PolicyList, unsigned int... Indices, typename... Args>
|
||||
R call_member_impl(lua_State* L, std::false_type /*void*/, meta::index_list<Indices...>, Args&&... args)
|
||||
{
|
||||
// don't count the function and self-reference
|
||||
// since those will be popped by pcall
|
||||
int top = lua_gettop(L) - 2;
|
||||
proxy_member_void_caller(lua_State* L_, const Tuple args)
|
||||
: L(L_)
|
||||
, m_args(args)
|
||||
, m_called(false)
|
||||
{
|
||||
}
|
||||
|
||||
// pcall will pop the function and self reference
|
||||
// and all the parameters
|
||||
proxy_member_void_caller(const proxy_member_void_caller& rhs)
|
||||
: L(rhs.L)
|
||||
, m_args(rhs.m_args)
|
||||
, m_called(rhs.m_called)
|
||||
{
|
||||
rhs.m_called = true;
|
||||
}
|
||||
|
||||
~proxy_member_void_caller()
|
||||
{
|
||||
if (m_called) return;
|
||||
|
||||
m_called = true;
|
||||
|
||||
// don't count the function and self-reference
|
||||
// since those will be popped by pcall
|
||||
int top = lua_gettop(L) - 2;
|
||||
|
||||
// pcall will pop the function and self reference
|
||||
// and all the parameters
|
||||
|
||||
push_args_from_tuple<1>::apply(L, m_args);
|
||||
if (pcall(L, boost::tuples::length<Tuple>::value + 1, 0))
|
||||
{
|
||||
assert(lua_gettop(L) == top + 1);
|
||||
#ifndef LUABIND_NO_EXCEPTIONS
|
||||
throw luabind::error(L);
|
||||
#else
|
||||
error_callback_fun e = get_error_callback();
|
||||
if (e) e(L);
|
||||
|
||||
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
|
||||
}
|
||||
// pops the return values from the function
|
||||
stack_pop pop(L, lua_gettop(L) - top);
|
||||
}
|
||||
|
||||
template<class Policies>
|
||||
void operator[](const Policies& p)
|
||||
{
|
||||
m_called = true;
|
||||
|
||||
// don't count the function and self-reference
|
||||
// since those will be popped by pcall
|
||||
int top = lua_gettop(L) - 2;
|
||||
|
||||
// pcall will pop the function and self reference
|
||||
// and all the parameters
|
||||
|
||||
detail::push_args_from_tuple<1>::apply(L, m_args, p);
|
||||
if (pcall(L, boost::tuples::length<Tuple>::value + 1, 0))
|
||||
{
|
||||
assert(lua_gettop(L) == top + 1);
|
||||
#ifndef LUABIND_NO_EXCEPTIONS
|
||||
throw error(L);
|
||||
#else
|
||||
error_callback_fun e = get_error_callback();
|
||||
if (e) e(L);
|
||||
|
||||
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
|
||||
}
|
||||
// pops the return values from the function
|
||||
stack_pop pop(L, lua_gettop(L) - top);
|
||||
}
|
||||
|
||||
private:
|
||||
lua_State* L;
|
||||
Tuple m_args;
|
||||
mutable bool m_called;
|
||||
|
||||
meta::init_order{ (
|
||||
specialized_converter_policy_n<Indices, PolicyList, typename unwrapped<Args>::type, cpp_to_lua>().to_lua(L, unwrapped<Args>::get(std::forward<Args>(args))), 0)...
|
||||
};
|
||||
|
||||
if(pcall(L, sizeof...(Args)+1, 1))
|
||||
{
|
||||
assert(lua_gettop(L) == top + 1);
|
||||
call_error(L);
|
||||
}
|
||||
// pops the return values from the function
|
||||
stack_pop pop(L, lua_gettop(L) - top);
|
||||
|
||||
specialized_converter_policy_n<0, PolicyList, R, lua_to_cpp> converter;
|
||||
if(converter.match(L, decorate_type_t<R>(), -1) < 0) {
|
||||
cast_error<R>(L);
|
||||
}
|
||||
|
||||
return converter.to_cpp(L, decorate_type_t<R>(), -1);
|
||||
}
|
||||
|
||||
|
||||
} // detail
|
||||
|
||||
template<class R, typename PolicyList = no_policies, typename... Args>
|
||||
R call_member(object const& obj, const char* name, Args&&... args)
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, <luabind/detail/call_member.hpp>, 1))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
}
|
||||
|
||||
#endif // LUABIND_CALL_MEMBER_HPP_INCLUDED
|
||||
|
||||
#else
|
||||
#if BOOST_PP_ITERATION_FLAGS() == 1
|
||||
|
||||
#define LUABIND_TUPLE_PARAMS(z, n, data) const A##n *
|
||||
#define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n
|
||||
|
||||
template<class R BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
|
||||
typename boost::mpl::if_<boost::is_void<R>
|
||||
, luabind::detail::proxy_member_void_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
|
||||
, luabind::detail::proxy_member_caller<R, boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> > >::type
|
||||
call_member(object const& obj, const char* name BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _))
|
||||
{
|
||||
typedef boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> tuple_t;
|
||||
#if BOOST_PP_ITERATION() == 0
|
||||
tuple_t args;
|
||||
#else
|
||||
tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a));
|
||||
#endif
|
||||
|
||||
typedef typename boost::mpl::if_<boost::is_void<R>
|
||||
, luabind::detail::proxy_member_void_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
|
||||
, luabind::detail::proxy_member_caller<R, boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> > >::type proxy_type;
|
||||
|
||||
// this will be cleaned up by the proxy object
|
||||
// once the call has been made
|
||||
|
||||
@@ -111,17 +354,12 @@ namespace luabind
|
||||
// now the function and self objects
|
||||
// are on the stack. These will both
|
||||
// be popped by pcall
|
||||
|
||||
return detail::call_member_impl<R, PolicyList>(obj.interpreter(), std::is_void<R>(), meta::index_range<1, sizeof...(Args)+1>(), std::forward<Args>(args)...);
|
||||
return proxy_type(obj.interpreter(), args);
|
||||
}
|
||||
|
||||
template <class R, typename... Args>
|
||||
R call_member(wrap_base const* self, char const* fn, Args&&... args)
|
||||
{
|
||||
return self->call<R>(fn, std::forward<Args>(args)...);
|
||||
}
|
||||
#undef LUABIND_OPERATOR_PARAMS
|
||||
#undef LUABIND_TUPLE_PARAMS
|
||||
|
||||
}
|
||||
|
||||
#endif // LUABIND_CALL_MEMBER_HPP_INCLUDED
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
// Copyright (c) 2004 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.
|
||||
|
||||
#define N BOOST_PP_ITERATION()
|
||||
|
||||
#define LUABIND_UNWRAP_PARAMETER(z, n, _) \
|
||||
typename detail::unwrap_parameter_type<T, BOOST_PP_CAT(A, n)>::type \
|
||||
BOOST_PP_CAT(_, n)
|
||||
|
||||
template<class Self BOOST_PP_ENUM_TRAILING_PARAMS(N, class A)>
|
||||
struct BOOST_PP_CAT(call_operator, N)
|
||||
: detail::operator_<
|
||||
BOOST_PP_CAT(call_operator, N)<
|
||||
Self BOOST_PP_ENUM_TRAILING_PARAMS(N, A)
|
||||
>
|
||||
>
|
||||
{
|
||||
BOOST_PP_CAT(call_operator, N)(int) {}
|
||||
|
||||
template<class T, class Policies>
|
||||
struct apply
|
||||
{
|
||||
static void execute(
|
||||
lua_State* L
|
||||
, typename detail::unwrap_parameter_type<T, Self>::type self
|
||||
BOOST_PP_ENUM_TRAILING(N, LUABIND_UNWRAP_PARAMETER, _)
|
||||
)
|
||||
{
|
||||
using namespace detail;
|
||||
operator_result(
|
||||
L
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
, self(BOOST_PP_ENUM_PARAMS(N, _))
|
||||
#else
|
||||
, (self(BOOST_PP_ENUM_PARAMS(N, _)), detail::operator_void_return())
|
||||
#endif
|
||||
, (Policies*)0
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
static char const* name() { return "__call"; }
|
||||
};
|
||||
|
||||
#undef LUABIND_UNWRAP_PARAMETER
|
||||
#undef N
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
// This has been stripped from boost minus the compatibility for borland etc.
|
||||
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
|
||||
// Use, modification and distribution are subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt).
|
||||
//
|
||||
// See http://www.boost.org/libs/utility for most recent version including documentation.
|
||||
|
||||
// call_traits: defines typedefs for function usage
|
||||
// (see libs/utility/call_traits.htm)
|
||||
|
||||
/* Release notes:
|
||||
23rd July 2000:
|
||||
Fixed array specialization. (JM)
|
||||
Added Borland specific fixes for reference types
|
||||
(issue raised by Steve Cleary).
|
||||
*/
|
||||
|
||||
#ifndef LUABIND_CALL_TRAITS_HPP_INCLUDED
|
||||
#define LUABIND_CALL_TRAITS_HPP_INCLUDED
|
||||
|
||||
namespace luabind {
|
||||
namespace detail {
|
||||
|
||||
template <typename T, bool small_>
|
||||
struct ct_imp2
|
||||
{
|
||||
using param_type = const T&;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct ct_imp2<T, true>
|
||||
{
|
||||
using param_type = const T;
|
||||
};
|
||||
|
||||
template <typename T, bool isp, bool b1, bool b2>
|
||||
struct ct_imp
|
||||
{
|
||||
using param_type = const T&;
|
||||
};
|
||||
|
||||
template <typename T, bool isp, bool b2>
|
||||
struct ct_imp<T, isp, true, b2>
|
||||
{
|
||||
using param_type = typename ct_imp2<T, sizeof(T) <= sizeof(void*)>::param_type;
|
||||
};
|
||||
|
||||
template <typename T, bool isp, bool b1>
|
||||
struct ct_imp<T, isp, b1, true>
|
||||
{
|
||||
using param_type = typename ct_imp2<T, sizeof(T) <= sizeof(void*)>::param_type;
|
||||
};
|
||||
|
||||
template <typename T, bool b1, bool b2>
|
||||
struct ct_imp<T, true, b1, b2>
|
||||
{
|
||||
using param_type = const T;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct call_traits
|
||||
{
|
||||
public:
|
||||
using value_type = T;
|
||||
using reference = T&;
|
||||
using const_reference = const T&;
|
||||
|
||||
using param_type = typename ct_imp<
|
||||
T,
|
||||
std::is_pointer<T>::value,
|
||||
std::is_integral<T>::value || std::is_floating_point<T>::value,
|
||||
std::is_enum<T>::value
|
||||
>::param_type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct call_traits<T&>
|
||||
{
|
||||
using value_type = T&;
|
||||
using reference = T&;
|
||||
using const_reference = const T&;
|
||||
using param_type = T&;
|
||||
};
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
struct call_traits<T[N]>
|
||||
{
|
||||
private:
|
||||
using array_type = T[N];
|
||||
public:
|
||||
using value_type = const T*;
|
||||
using reference = array_type&;
|
||||
using const_reference = const array_type&;
|
||||
using param_type = const T* const;
|
||||
};
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
struct call_traits<const T[N]>
|
||||
{
|
||||
private:
|
||||
using array_type = const T[N];
|
||||
public:
|
||||
using value_type = const T*;
|
||||
using reference = array_type&;
|
||||
using const_reference = const array_type&;
|
||||
using param_type = const T* const;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
// Copyright (c) 2004 Daniel Wallin
|
||||
|
||||
// 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 CLASS_CACHE_040218_HPP
|
||||
#define CLASS_CACHE_040218_HPP
|
||||
|
||||
#include <luabind/prefix.hpp>
|
||||
#include <boost/type_traits/add_reference.hpp>
|
||||
#include <boost/type_traits/add_const.hpp>
|
||||
|
||||
namespace luabind { namespace detail {
|
||||
|
||||
#ifdef LUABIND_NOT_THREADSAFE
|
||||
|
||||
class class_rep;
|
||||
|
||||
template<class T>
|
||||
struct class_cache_impl
|
||||
{
|
||||
static lua_State* state;
|
||||
static class_rep* class_;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
lua_State* class_cache_impl<T>::state = 0;
|
||||
|
||||
template<class T>
|
||||
class_rep* class_cache_impl<T>::class_ = 0;
|
||||
|
||||
template<class T>
|
||||
struct class_cache
|
||||
: class_cache_impl<
|
||||
typename boost::add_reference<
|
||||
typename boost::add_const<
|
||||
T
|
||||
>::type
|
||||
>::type
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class_rep* get_class_rep(lua_State* L, void(*)(T*) = 0)
|
||||
{
|
||||
if (class_cache<T>::state != L)
|
||||
{
|
||||
class_cache<T>::state = L;
|
||||
|
||||
class_registry* registry = class_registry::get_registry(L);
|
||||
class_cache<T>::class_ = registry->find_class(typeid(T));
|
||||
}
|
||||
|
||||
return class_cache<T>::class_;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template<class T>
|
||||
class_rep* get_class_rep(lua_State* L, void(*)(T*) = 0)
|
||||
{
|
||||
class_registry* registry = class_registry::get_registry(L);
|
||||
return registry->find_class(typeid(T));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}} // namespace luabind::detail
|
||||
|
||||
#endif // CLASS_CACHE_040218_HPP
|
||||
|
||||
@@ -30,58 +30,56 @@
|
||||
#include <luabind/open.hpp>
|
||||
#include <luabind/typeid.hpp>
|
||||
|
||||
namespace luabind {
|
||||
namespace detail {
|
||||
namespace luabind { namespace detail
|
||||
{
|
||||
class class_rep;
|
||||
|
||||
class class_rep;
|
||||
struct LUABIND_API class_registry
|
||||
{
|
||||
class_registry(lua_State* L);
|
||||
|
||||
struct LUABIND_API class_registry
|
||||
{
|
||||
class_registry(lua_State* L);
|
||||
static class_registry* get_registry(lua_State* L);
|
||||
|
||||
static class_registry* get_registry(lua_State* L);
|
||||
int cpp_instance() const { return m_instance_metatable; }
|
||||
int cpp_class() const { return m_cpp_class_metatable; }
|
||||
|
||||
int cpp_instance() const { return m_instance_metatable; }
|
||||
int cpp_class() const { return m_cpp_class_metatable; }
|
||||
int lua_instance() const { return m_instance_metatable; }
|
||||
int lua_class() const { return m_lua_class_metatable; }
|
||||
int lua_function() const { return m_lua_function_metatable; }
|
||||
|
||||
int lua_instance() const { return m_instance_metatable; }
|
||||
int lua_class() const { return m_lua_class_metatable; }
|
||||
int lua_function() const { return m_lua_function_metatable; }
|
||||
void add_class(type_id const& info, class_rep* crep);
|
||||
|
||||
void add_class(type_id const& info, class_rep* crep);
|
||||
class_rep* find_class(type_id const& info) const;
|
||||
|
||||
class_rep* find_class(type_id const& info) const;
|
||||
std::map<type_id, class_rep*> const& get_classes() const
|
||||
{
|
||||
return m_classes;
|
||||
}
|
||||
|
||||
std::map<type_id, class_rep*> const& get_classes() const
|
||||
{
|
||||
return m_classes;
|
||||
}
|
||||
private:
|
||||
|
||||
private:
|
||||
std::map<type_id, class_rep*> m_classes;
|
||||
|
||||
std::map<type_id, class_rep*> m_classes;
|
||||
// this is a lua reference that points to the lua table
|
||||
// that is to be used as meta table for all C++ class
|
||||
// instances. It is a kind of v-table.
|
||||
int m_instance_metatable;
|
||||
|
||||
// this is a lua reference that points to the lua table
|
||||
// that is to be used as meta table for all C++ class
|
||||
// instances. It is a kind of v-table.
|
||||
int m_instance_metatable;
|
||||
// this is a lua reference to the metatable to be used
|
||||
// for all classes defined in C++.
|
||||
int m_cpp_class_metatable;
|
||||
|
||||
// this is a lua reference to the metatable to be used
|
||||
// for all classes defined in C++.
|
||||
int m_cpp_class_metatable;
|
||||
// this is a lua reference to the metatable to be used
|
||||
// for all classes defined in lua
|
||||
int m_lua_class_metatable;
|
||||
|
||||
// this is a lua reference to the metatable to be used
|
||||
// for all classes defined in lua
|
||||
int m_lua_class_metatable;
|
||||
// this metatable only contains a destructor
|
||||
// for luabind::Detail::free_functions::function_rep
|
||||
int m_lua_function_metatable;
|
||||
|
||||
// this metatable only contains a destructor
|
||||
// for luabind::Detail::free_functions::function_rep
|
||||
int m_lua_function_metatable;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}}
|
||||
|
||||
#endif // LUABIND_CLASS_REGISTRY_HPP_INCLUDED
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2003 Daniel Wallin and Arvid Norberg
|
||||
// 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"),
|
||||
@@ -24,12 +24,16 @@
|
||||
#ifndef LUABIND_CLASS_REP_HPP_INCLUDED
|
||||
#define LUABIND_CLASS_REP_HPP_INCLUDED
|
||||
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <luabind/config.hpp>
|
||||
#include <luabind/lua_include.hpp>
|
||||
#include <luabind/detail/object_rep.hpp>
|
||||
#include <luabind/detail/garbage_collector.hpp>
|
||||
#include <luabind/detail/operator_id.hpp>
|
||||
#include <luabind/detail/class_registry.hpp>
|
||||
@@ -39,174 +43,171 @@
|
||||
#include <luabind/typeid.hpp>
|
||||
#include <luabind/detail/ref.hpp>
|
||||
|
||||
namespace luabind {
|
||||
namespace detail {
|
||||
namespace luabind { namespace detail
|
||||
{
|
||||
|
||||
LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index);
|
||||
LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index);
|
||||
|
||||
struct class_registration;
|
||||
struct class_registration;
|
||||
|
||||
struct conversion_storage;
|
||||
struct conversion_storage;
|
||||
|
||||
// This function is used as a tag to identify "properties".
|
||||
LUABIND_API int property_tag(lua_State*);
|
||||
// This function is used as a tag to identify "properties".
|
||||
LUABIND_API int property_tag(lua_State*);
|
||||
|
||||
// this is class-specific information, poor man's vtable
|
||||
// this is allocated statically (removed by the compiler)
|
||||
// a pointer to this structure is stored in the lua tables'
|
||||
// metatable with the name __classrep
|
||||
// it is used when matching parameters to function calls
|
||||
// to determine possible implicit casts
|
||||
// it is also used when finding the best match for overloaded
|
||||
// methods
|
||||
// this is class-specific information, poor man's vtable
|
||||
// this is allocated statically (removed by the compiler)
|
||||
// a pointer to this structure is stored in the lua tables'
|
||||
// metatable with the name __classrep
|
||||
// it is used when matching parameters to function calls
|
||||
// to determine possible implicit casts
|
||||
// it is also used when finding the best match for overloaded
|
||||
// methods
|
||||
|
||||
class cast_graph;
|
||||
class class_id_map;
|
||||
class cast_graph;
|
||||
class class_id_map;
|
||||
|
||||
class LUABIND_API class_rep
|
||||
class LUABIND_API class_rep
|
||||
{
|
||||
friend struct class_registration;
|
||||
friend int super_callback(lua_State*);
|
||||
//TODO: avoid the lua-prefix
|
||||
friend int lua_class_gettable(lua_State*);
|
||||
friend int lua_class_settable(lua_State*);
|
||||
friend int static_class_gettable(lua_State*);
|
||||
public:
|
||||
|
||||
enum class_type
|
||||
{
|
||||
friend struct class_registration;
|
||||
friend int super_callback(lua_State*);
|
||||
//TODO: avoid the lua-prefix
|
||||
friend int lua_class_gettable(lua_State*);
|
||||
friend int lua_class_settable(lua_State*);
|
||||
friend int static_class_gettable(lua_State*);
|
||||
public:
|
||||
|
||||
enum class_type
|
||||
{
|
||||
cpp_class = 0,
|
||||
lua_class = 1
|
||||
};
|
||||
|
||||
// EXPECTS THE TOP VALUE ON THE LUA STACK TO
|
||||
// BE THE USER DATA WHERE THIS CLASS IS BEING
|
||||
// INSTANTIATED!
|
||||
class_rep(type_id const& type
|
||||
, const char* name
|
||||
, lua_State* L
|
||||
);
|
||||
|
||||
// used when creating a lua class
|
||||
// EXPECTS THE TOP VALUE ON THE LUA STACK TO
|
||||
// BE THE USER DATA WHERE THIS CLASS IS BEING
|
||||
// INSTANTIATED!
|
||||
class_rep(lua_State* L, const char* name);
|
||||
|
||||
~class_rep();
|
||||
|
||||
std::pair<void*, void*> allocate(lua_State* L) const;
|
||||
|
||||
// this is called as metamethod __call on the class_rep.
|
||||
static int constructor_dispatcher(lua_State* L);
|
||||
|
||||
struct base_info
|
||||
{
|
||||
int pointer_offset; // the offset added to the pointer to obtain a basepointer (due to multiple-inheritance)
|
||||
class_rep* base;
|
||||
};
|
||||
|
||||
void add_base_class(const base_info& binfo);
|
||||
|
||||
const std::vector<base_info>& bases() const throw() { return m_bases; }
|
||||
|
||||
void set_type(type_id const& t) { m_type = t; }
|
||||
type_id const& type() const throw() { return m_type; }
|
||||
|
||||
const char* name() const throw() { return m_name; }
|
||||
|
||||
// the lua reference to the metatable for this class' instances
|
||||
int metatable_ref() const throw() { return m_instance_metatable; }
|
||||
|
||||
void get_table(lua_State* L) const { m_table.push(L); }
|
||||
void get_default_table(lua_State* L) const { m_default_table.push(L); }
|
||||
|
||||
class_type get_class_type() const { return m_class_type; }
|
||||
|
||||
void add_static_constant(const char* name, int val);
|
||||
|
||||
static int super_callback(lua_State* L);
|
||||
|
||||
static int lua_settable_dispatcher(lua_State* L);
|
||||
|
||||
// called from the metamethod for __index
|
||||
// obj is the object pointer
|
||||
static int static_class_gettable(lua_State* L);
|
||||
|
||||
bool has_operator_in_lua(lua_State*, int id);
|
||||
|
||||
cast_graph const& casts() const
|
||||
{
|
||||
return *m_casts;
|
||||
}
|
||||
|
||||
class_id_map const& classes() const
|
||||
{
|
||||
return *m_classes;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Code common to both constructors
|
||||
void shared_init(lua_State * L);
|
||||
|
||||
void cache_operators(lua_State*);
|
||||
|
||||
// this is a pointer to the type_info structure for
|
||||
// this type
|
||||
// warning: this may be a problem when using dll:s, since
|
||||
// typeid() may actually return different pointers for the same
|
||||
// type.
|
||||
type_id m_type;
|
||||
|
||||
// a list of info for every class this class derives from
|
||||
// the information stored here is sufficient to do
|
||||
// type casts to the base classes
|
||||
std::vector<base_info> m_bases;
|
||||
|
||||
// the class' name (as given when registered to lua with class_)
|
||||
const char* m_name;
|
||||
|
||||
// a reference to this structure itself. Since this struct
|
||||
// is kept inside lua (to let lua collect it when lua_close()
|
||||
// is called) we need to lock it to prevent collection.
|
||||
// the actual reference is not currently used.
|
||||
detail::lua_reference m_self_ref;
|
||||
|
||||
// this should always be used when accessing
|
||||
// members in instances of a class.
|
||||
// this table contains c closures for all
|
||||
// member functions in this class, they
|
||||
// may point to both static and virtual functions
|
||||
handle m_table;
|
||||
|
||||
// this table contains default implementations of the
|
||||
// virtual functions in m_table.
|
||||
handle m_default_table;
|
||||
|
||||
// the type of this class.. determines if it's written in c++ or lua
|
||||
class_type m_class_type;
|
||||
|
||||
// this is a lua reference that points to the lua table
|
||||
// that is to be used as meta table for all instances
|
||||
// of this class.
|
||||
int m_instance_metatable;
|
||||
|
||||
std::map<const char*, int, ltstr> m_static_constants;
|
||||
|
||||
// the first time an operator is invoked
|
||||
// we check the associated lua table
|
||||
// and cache the result
|
||||
int m_operator_cache;
|
||||
|
||||
cast_graph* m_casts;
|
||||
class_id_map* m_classes;
|
||||
cpp_class = 0,
|
||||
lua_class = 1
|
||||
};
|
||||
|
||||
LUABIND_API bool is_class_rep(lua_State* L, int index);
|
||||
// EXPECTS THE TOP VALUE ON THE LUA STACK TO
|
||||
// BE THE USER DATA WHERE THIS CLASS IS BEING
|
||||
// INSTANTIATED!
|
||||
class_rep(type_id const& type
|
||||
, const char* name
|
||||
, lua_State* L
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
// used when creating a lua class
|
||||
// EXPECTS THE TOP VALUE ON THE LUA STACK TO
|
||||
// BE THE USER DATA WHERE THIS CLASS IS BEING
|
||||
// INSTANTIATED!
|
||||
class_rep(lua_State* L, const char* name);
|
||||
|
||||
~class_rep();
|
||||
|
||||
std::pair<void*,void*> allocate(lua_State* L) const;
|
||||
|
||||
// this is called as metamethod __call on the class_rep.
|
||||
static int constructor_dispatcher(lua_State* L);
|
||||
|
||||
struct base_info
|
||||
{
|
||||
int pointer_offset; // the offset added to the pointer to obtain a basepointer (due to multiple-inheritance)
|
||||
class_rep* base;
|
||||
};
|
||||
|
||||
void add_base_class(const base_info& binfo);
|
||||
|
||||
const std::vector<base_info>& bases() const throw() { return m_bases; }
|
||||
|
||||
void set_type(type_id const& t) { m_type = t; }
|
||||
type_id const& type() const throw() { return m_type; }
|
||||
|
||||
const char* name() const throw() { return m_name; }
|
||||
|
||||
// the lua reference to the metatable for this class' instances
|
||||
int metatable_ref() const throw() { return m_instance_metatable; }
|
||||
|
||||
void get_table(lua_State* L) const { m_table.push(L); }
|
||||
void get_default_table(lua_State* L) const { m_default_table.push(L); }
|
||||
|
||||
class_type get_class_type() const { return m_class_type; }
|
||||
|
||||
void add_static_constant(const char* name, int val);
|
||||
|
||||
static int super_callback(lua_State* L);
|
||||
|
||||
static int lua_settable_dispatcher(lua_State* L);
|
||||
|
||||
// called from the metamethod for __index
|
||||
// obj is the object pointer
|
||||
static int static_class_gettable(lua_State* L);
|
||||
|
||||
bool has_operator_in_lua(lua_State*, int id);
|
||||
|
||||
cast_graph const& casts() const
|
||||
{
|
||||
return *m_casts;
|
||||
}
|
||||
|
||||
class_id_map const& classes() const
|
||||
{
|
||||
return *m_classes;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void cache_operators(lua_State*);
|
||||
|
||||
// this is a pointer to the type_info structure for
|
||||
// this type
|
||||
// warning: this may be a problem when using dll:s, since
|
||||
// typeid() may actually return different pointers for the same
|
||||
// type.
|
||||
type_id m_type;
|
||||
|
||||
// a list of info for every class this class derives from
|
||||
// the information stored here is sufficient to do
|
||||
// type casts to the base classes
|
||||
std::vector<base_info> m_bases;
|
||||
|
||||
// the class' name (as given when registered to lua with class_)
|
||||
const char* m_name;
|
||||
|
||||
// a reference to this structure itself. Since this struct
|
||||
// is kept inside lua (to let lua collect it when lua_close()
|
||||
// is called) we need to lock it to prevent collection.
|
||||
// the actual reference is not currently used.
|
||||
detail::lua_reference m_self_ref;
|
||||
|
||||
// this should always be used when accessing
|
||||
// members in instances of a class.
|
||||
// this table contains c closures for all
|
||||
// member functions in this class, they
|
||||
// may point to both static and virtual functions
|
||||
handle m_table;
|
||||
|
||||
// this table contains default implementations of the
|
||||
// virtual functions in m_table.
|
||||
handle m_default_table;
|
||||
|
||||
// the type of this class.. determines if it's written in c++ or lua
|
||||
class_type m_class_type;
|
||||
|
||||
// this is a lua reference that points to the lua table
|
||||
// that is to be used as meta table for all instances
|
||||
// of this class.
|
||||
int m_instance_metatable;
|
||||
|
||||
std::map<const char*, int, ltstr> m_static_constants;
|
||||
|
||||
// the first time an operator is invoked
|
||||
// we check the associated lua table
|
||||
// and cache the result
|
||||
int m_operator_cache;
|
||||
|
||||
cast_graph* m_casts;
|
||||
class_id_map* m_classes;
|
||||
};
|
||||
|
||||
bool is_class_rep(lua_State* L, int index);
|
||||
|
||||
}}
|
||||
|
||||
//#include <luabind/detail/overload_rep_impl.hpp>
|
||||
|
||||
#endif // LUABIND_CLASS_REP_HPP_INCLUDED
|
||||
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
// Copyright Daniel Wallin 2008. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef LUABIND_COMPUTE_RANK_081006_HPP
|
||||
# define LUABIND_COMPUTE_RANK_081006_HPP
|
||||
|
||||
# include <luabind/config.hpp>
|
||||
# include <luabind/detail/policy.hpp>
|
||||
# include <boost/mpl/apply_wrap.hpp>
|
||||
# include <boost/mpl/begin_end.hpp>
|
||||
# include <boost/mpl/int.hpp>
|
||||
# include <boost/mpl/next.hpp>
|
||||
|
||||
namespace luabind { namespace detail {
|
||||
|
||||
namespace mpl = boost::mpl;
|
||||
|
||||
template <class Idx, class Iter, class End, class Policies>
|
||||
int compute_score_aux(
|
||||
lua_State*L, int index, Idx, Iter, End end, Policies const& policies)
|
||||
{
|
||||
typedef typename Iter::type arg_type;
|
||||
typedef typename find_conversion_policy<Idx::value, Policies>::type
|
||||
conversion_policy;
|
||||
typedef typename mpl::apply_wrap2<
|
||||
conversion_policy, arg_type, lua_to_cpp>::type converter;
|
||||
|
||||
int score = converter::match(L, LUABIND_DECORATE_TYPE(arg_type), index);
|
||||
|
||||
if (score < 0)
|
||||
return score;
|
||||
|
||||
if (conversion_policy::has_arg)
|
||||
++index;
|
||||
|
||||
int next = compute_score_aux(
|
||||
L
|
||||
, index
|
||||
, typename mpl::next<Idx>::type()
|
||||
, typename mpl::next<Iter>::type()
|
||||
, end
|
||||
, policies
|
||||
);
|
||||
|
||||
if (next < 0)
|
||||
return next;
|
||||
|
||||
return score + next;
|
||||
}
|
||||
|
||||
template <class Idx, class End, class Policies>
|
||||
int compute_score_aux(lua_State*, int, Idx, End, End, Policies const&)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class Signature, class Policies>
|
||||
int compute_score(lua_State* L, Signature, Policies const& policies)
|
||||
{
|
||||
return compute_score_aux(
|
||||
L
|
||||
, 1
|
||||
, mpl::int_<1>()
|
||||
, typename mpl::next<typename mpl::begin<Signature>::type>::type()
|
||||
, typename mpl::end<Signature>::type()
|
||||
, policies
|
||||
);
|
||||
}
|
||||
|
||||
}} // namespace luabind::detail
|
||||
|
||||
#endif // LUABIND_COMPUTE_RANK_081006_HPP
|
||||
@@ -2,64 +2,110 @@
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef LUABIND_DETAIL_CONSTRUCTOR_081018_HPP
|
||||
#define LUABIND_DETAIL_CONSTRUCTOR_081018_HPP
|
||||
#if !BOOST_PP_IS_ITERATING
|
||||
|
||||
#include <luabind/get_main_thread.hpp>
|
||||
#include <luabind/lua_argument_proxy.hpp>
|
||||
#include <luabind/wrapper_base.hpp>
|
||||
#include <luabind/detail/inheritance.hpp>
|
||||
# ifndef LUABIND_DETAIL_CONSTRUCTOR_081018_HPP
|
||||
# define LUABIND_DETAIL_CONSTRUCTOR_081018_HPP
|
||||
|
||||
namespace luabind {
|
||||
namespace detail {
|
||||
# include <luabind/get_main_thread.hpp>
|
||||
# include <luabind/object.hpp>
|
||||
# include <luabind/wrapper_base.hpp>
|
||||
# include <luabind/detail/inheritance.hpp>
|
||||
|
||||
inline void inject_backref(lua_State*, void*, void*)
|
||||
{}
|
||||
# include <boost/preprocessor/iteration/iterate.hpp>
|
||||
# include <boost/preprocessor/iteration/local.hpp>
|
||||
# include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
# include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
|
||||
template <class T>
|
||||
void inject_backref(lua_State* L, T* p, wrap_base*)
|
||||
{
|
||||
weak_ref(get_main_thread(L), L, 1).swap(wrap_access::ref(*p));
|
||||
}
|
||||
namespace luabind { namespace detail {
|
||||
|
||||
template< class T, class Pointer, class Signature, class Arguments, class ArgumentIndices >
|
||||
struct construct_aux_helper;
|
||||
inline void inject_backref(lua_State*, void*, void*)
|
||||
{}
|
||||
|
||||
template< class T, class Pointer, class Signature, typename... Arguments, unsigned int... ArgumentIndices >
|
||||
struct construct_aux_helper< T, Pointer, Signature, meta::type_list< Arguments... >, meta::index_list< ArgumentIndices... > >
|
||||
{
|
||||
using holder_type = pointer_holder<Pointer, T>;
|
||||
template <class T>
|
||||
void inject_backref(lua_State* L, T* p, wrap_base*)
|
||||
{
|
||||
weak_ref(get_main_thread(L), L, 1).swap(wrap_access::ref(*p));
|
||||
}
|
||||
|
||||
void operator()(argument const& self_, Arguments... args) const
|
||||
{
|
||||
object_rep* self = touserdata<object_rep>(self_);
|
||||
template <std::size_t Arity, class T, class Pointer, class Signature>
|
||||
struct construct_aux;
|
||||
|
||||
std::unique_ptr<T> instance(new T(args...));
|
||||
inject_backref(self_.interpreter(), instance.get(), instance.get());
|
||||
template <class T, class Pointer, class Signature>
|
||||
struct construct
|
||||
: construct_aux<mpl::size<Signature>::value - 2, T, Pointer, Signature>
|
||||
{};
|
||||
|
||||
void* naked_ptr = instance.get();
|
||||
Pointer ptr(instance.release());
|
||||
template <class T, class Pointer, class Signature>
|
||||
struct construct_aux<0, T, Pointer, Signature>
|
||||
{
|
||||
typedef pointer_holder<Pointer, T> holder_type;
|
||||
|
||||
void* storage = self->allocate(sizeof(holder_type));
|
||||
void operator()(argument const& self_) const
|
||||
{
|
||||
object_rep* self = touserdata<object_rep>(self_);
|
||||
class_rep* cls = self->crep();
|
||||
|
||||
self->set_instance(new (storage) holder_type(std::move(ptr), registered_class<T>::id, naked_ptr));
|
||||
}
|
||||
};
|
||||
std::auto_ptr<T> instance(new T);
|
||||
inject_backref(self_.interpreter(), instance.get(), instance.get());
|
||||
|
||||
void* naked_ptr = instance.get();
|
||||
Pointer ptr(instance.release());
|
||||
|
||||
template< class T, class Pointer, class Signature >
|
||||
struct construct :
|
||||
public construct_aux_helper <
|
||||
T,
|
||||
Pointer,
|
||||
Signature, typename meta::sub_range< Signature, 2, meta::size<Signature>::value >::type,
|
||||
typename meta::make_index_range<0, meta::size<Signature>::value - 2>::type >
|
||||
{
|
||||
};
|
||||
void* storage = self->allocate(sizeof(holder_type));
|
||||
|
||||
} // namespace detail
|
||||
self->set_instance(new (storage) holder_type(
|
||||
ptr, registered_class<T>::id, naked_ptr, cls));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace luabind
|
||||
# define BOOST_PP_ITERATION_PARAMS_1 \
|
||||
(3, (1, LUABIND_MAX_ARITY, <luabind/detail/constructor.hpp>))
|
||||
# include BOOST_PP_ITERATE()
|
||||
|
||||
}} // namespace luabind::detail
|
||||
|
||||
# endif // LUABIND_DETAIL_CONSTRUCTOR_081018_HPP
|
||||
|
||||
#else // !BOOST_PP_IS_ITERATING
|
||||
|
||||
# define N BOOST_PP_ITERATION()
|
||||
|
||||
template <class T, class Pointer, class Signature>
|
||||
struct construct_aux<N, T, Pointer, Signature>
|
||||
{
|
||||
typedef typename mpl::begin<Signature>::type first;
|
||||
typedef typename mpl::next<first>::type iter0;
|
||||
|
||||
# define BOOST_PP_LOCAL_MACRO(n) \
|
||||
typedef typename mpl::next< \
|
||||
BOOST_PP_CAT(iter,BOOST_PP_DEC(n))>::type BOOST_PP_CAT(iter,n); \
|
||||
typedef typename BOOST_PP_CAT(iter,n)::type BOOST_PP_CAT(a,BOOST_PP_DEC(n));
|
||||
|
||||
# define BOOST_PP_LOCAL_LIMITS (1,N)
|
||||
# include BOOST_PP_LOCAL_ITERATE()
|
||||
|
||||
typedef pointer_holder<Pointer, T> holder_type;
|
||||
|
||||
void operator()(argument const& self_, BOOST_PP_ENUM_BINARY_PARAMS(N,a,_)) const
|
||||
{
|
||||
object_rep* self = touserdata<object_rep>(self_);
|
||||
class_rep* cls = self->crep();
|
||||
|
||||
std::auto_ptr<T> instance(new T(BOOST_PP_ENUM_PARAMS(N,_)));
|
||||
inject_backref(self_.interpreter(), instance.get(), instance.get());
|
||||
|
||||
void* naked_ptr = instance.get();
|
||||
Pointer ptr(instance.release());
|
||||
|
||||
void* storage = self->allocate(sizeof(holder_type));
|
||||
|
||||
self->set_instance(new (storage) holder_type(
|
||||
ptr, registered_class<T>::id, naked_ptr, cls));
|
||||
}
|
||||
};
|
||||
|
||||
# undef N
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
// 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_CONVERSION_BASE_HPP_INCLUDED
|
||||
#define LUABIND_CONVERSION_BASE_HPP_INCLUDED
|
||||
|
||||
#include <type_traits>
|
||||
#include <luabind/lua_include.hpp>
|
||||
#include <luabind/detail/decorate_type.hpp>
|
||||
#include <luabind/detail/make_instance.hpp>
|
||||
#include <luabind/pointer_traits.hpp>
|
||||
#include <luabind/from_stack.hpp>
|
||||
|
||||
|
||||
namespace luabind {
|
||||
namespace detail {
|
||||
|
||||
// Something's strange with the references here... need to know when to copy :(
|
||||
template <class T, class Clone>
|
||||
void make_pointee_instance(lua_State* L, T&& x, std::true_type, Clone)
|
||||
{
|
||||
if(get_pointer(x))
|
||||
{
|
||||
make_pointer_instance(L, std::forward<T>(x));
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushnil(L);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void make_pointee_instance(lua_State* L, T&& x, std::false_type, std::true_type)
|
||||
{
|
||||
using value_type = typename std::remove_reference<T>::type;
|
||||
|
||||
std::unique_ptr<value_type> ptr(new value_type(std::move(x)));
|
||||
make_pointer_instance(L, std::move(ptr));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void make_pointee_instance(lua_State* L, T&& x, std::false_type, std::false_type)
|
||||
{
|
||||
// need a second make_instance that moves x into place
|
||||
make_pointer_instance(L, &x);
|
||||
}
|
||||
|
||||
template <class T, class Clone>
|
||||
void make_pointee_instance(lua_State* L, T&& x, Clone)
|
||||
{
|
||||
make_pointee_instance(L, std::forward<T>(x), has_get_pointer<T>(), Clone());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template <class T, class Enable>
|
||||
struct default_converter;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
// 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_CONVERSION_POLICIES_HPP_INCLUDED
|
||||
#define LUABIND_CONVERSION_POLICIES_HPP_INCLUDED
|
||||
|
||||
#include <luabind/detail/type_traits.hpp>
|
||||
#include <luabind/detail/meta.hpp>
|
||||
#include <luabind/detail/policy.hpp>
|
||||
#include <luabind/detail/conversion_policies/conversion_base.hpp>
|
||||
#include <luabind/detail/conversion_policies/enum_converter.hpp>
|
||||
#include <luabind/detail/conversion_policies/pointer_converter.hpp>
|
||||
#include <luabind/detail/conversion_policies/reference_converter.hpp>
|
||||
#include <luabind/detail/conversion_policies/value_converter.hpp>
|
||||
#include <luabind/detail/conversion_policies/lua_proxy_converter.hpp>
|
||||
#include <luabind/detail/conversion_policies/native_converter.hpp>
|
||||
#include <luabind/detail/conversion_policies/function_converter.hpp>
|
||||
#include <luabind/shared_ptr_converter.hpp>
|
||||
|
||||
namespace luabind {
|
||||
|
||||
template <>
|
||||
struct default_converter<lua_State*>
|
||||
{
|
||||
enum { consumed_args = 0 };
|
||||
|
||||
template <class U>
|
||||
lua_State* to_cpp(lua_State* L, U, int /*index*/)
|
||||
{
|
||||
return L;
|
||||
}
|
||||
|
||||
template <class U>
|
||||
static int match(lua_State*, U, int /*index*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class U>
|
||||
void converter_postcall(lua_State*, U, int) {}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
// This is the one that gets hit, if default_policy doesn't hit one of the specializations defined all over the place
|
||||
template< class T >
|
||||
struct default_converter_generator
|
||||
: public meta::select_ <
|
||||
meta::case_< is_lua_proxy_arg<T>, lua_proxy_converter<T> >,
|
||||
meta::case_< std::is_enum<typename std::remove_reference<T>::type>, enum_converter >,
|
||||
meta::case_< is_nonconst_pointer<T>, pointer_converter >,
|
||||
meta::case_< is_const_pointer<T>, const_pointer_converter >,
|
||||
meta::case_< is_nonconst_reference<T>, ref_converter >,
|
||||
meta::case_< is_const_reference<T>, const_ref_converter >,
|
||||
meta::default_< value_converter >
|
||||
> ::type
|
||||
{
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template <class T, class Enable>
|
||||
struct default_converter
|
||||
: detail::default_converter_generator<T>::type
|
||||
{};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
// 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_ENUM_CONVERTER_HPP_INCLUDED
|
||||
#define LUABIND_ENUM_CONVERTER_HPP_INCLUDED
|
||||
|
||||
#include <type_traits>
|
||||
#include <luabind/detail/type_traits.hpp>
|
||||
#include <luabind/detail/conversion_policies/conversion_base.hpp>
|
||||
|
||||
namespace luabind {
|
||||
namespace detail {
|
||||
|
||||
struct enum_converter
|
||||
{
|
||||
using type = enum_converter;
|
||||
using is_native = std::false_type;
|
||||
|
||||
enum { consumed_args = 1 };
|
||||
|
||||
void to_lua(lua_State* L, int val)
|
||||
{
|
||||
lua_pushnumber(L, val);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T to_cpp(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 no_match;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T to_cpp(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 no_match;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void converter_postcall(lua_State*, T, int) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
// Copyright Christian Neumüller 2013. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef LUABIND_FUNCTION_CONVERTER_HPP_INCLUDED
|
||||
#define LUABIND_FUNCTION_CONVERTER_HPP_INCLUDED
|
||||
#include <functional>
|
||||
#include <luabind/detail/deduce_signature.hpp>
|
||||
#include <luabind/detail/conversion_policies/conversion_base.hpp>
|
||||
#include <luabind/make_function.hpp>
|
||||
#include <luabind/detail/call_function.hpp>
|
||||
|
||||
namespace luabind {
|
||||
|
||||
template <typename R = object>
|
||||
struct function
|
||||
{
|
||||
using result_type = R;
|
||||
|
||||
function(luabind::object const& obj)
|
||||
: m_func(obj)
|
||||
{
|
||||
}
|
||||
|
||||
template< typename... Args>
|
||||
R operator() (Args&&... args)
|
||||
{
|
||||
return call_function<R>(m_func, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
private:
|
||||
object m_func;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template< typename T >
|
||||
struct is_function : public std::false_type {};
|
||||
|
||||
template< typename T >
|
||||
struct is_function< std::function< T > > : public std::true_type {};
|
||||
}
|
||||
|
||||
template< typename R, typename... Args, typename WrappedType >
|
||||
struct deduce_signature <std::function< R(Args...) >, WrappedType >
|
||||
{
|
||||
using type = meta::type_list< R, Args... >;
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
struct default_converter<F, typename std::enable_if<detail::is_function<remove_const_reference_t<F>>::value>::type>
|
||||
{
|
||||
using is_native = std::true_type;
|
||||
|
||||
enum { consumed_args = 1 };
|
||||
|
||||
template <class U>
|
||||
void converter_postcall(lua_State*, U const&, int)
|
||||
{}
|
||||
|
||||
template <class U>
|
||||
static int match(lua_State* L, U, int index)
|
||||
{
|
||||
if(lua_type(L, index) == LUA_TFUNCTION)
|
||||
return 0;
|
||||
if(luaL_getmetafield(L, index, "__call")) {
|
||||
lua_pop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
return no_match;
|
||||
}
|
||||
|
||||
template <class U>
|
||||
F to_cpp(lua_State* L, U, int index)
|
||||
{
|
||||
// If you get a compiler error here, you are probably trying to
|
||||
// get a function pointer from Lua. This is not supported:
|
||||
// you must use a type which is constructible from a
|
||||
// luabind::function, e.g. std::function or boost::function.
|
||||
return function<typename F::result_type>(object(from_stack(L, index)));
|
||||
}
|
||||
|
||||
void to_lua(lua_State* L, F value)
|
||||
{
|
||||
make_function(L, value).push(L);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace luabind
|
||||
|
||||
|
||||
#endif // LUABIND_FUNCTION_CONVERTER_HPP_INCLUDED
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
// 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_VALUE_WRAPPER_CONVERTER_HPP_INCLUDED
|
||||
#define LUABIND_VALUE_WRAPPER_CONVERTER_HPP_INCLUDED
|
||||
|
||||
#include <luabind/lua_proxy.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace luabind {
|
||||
namespace detail {
|
||||
|
||||
template <class U>
|
||||
struct lua_proxy_converter
|
||||
{
|
||||
using type = lua_proxy_converter<U>;
|
||||
using is_native = std::true_type;
|
||||
|
||||
enum { consumed_args = 1 };
|
||||
|
||||
template<class T>
|
||||
T to_cpp(lua_State* L, by_const_reference<T>, int index)
|
||||
{
|
||||
return T(from_stack(L, index));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T to_cpp(lua_State* L, by_value<T>, int index)
|
||||
{
|
||||
return to_cpp(L, by_const_reference<T>(), index);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static int match(lua_State* L, by_const_reference<T>, int index)
|
||||
{
|
||||
return lua_proxy_traits<T>::check(L, index)
|
||||
? max_hierarchy_depth
|
||||
: no_match;
|
||||
}
|
||||
|
||||
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 to_lua(lua_State* interpreter, T const& value_wrapper)
|
||||
{
|
||||
lua_proxy_traits<T>::unwrap(interpreter, value_wrapper);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,302 +0,0 @@
|
||||
// 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_NATIVE_CONVERTER_HPP_INCLUDED
|
||||
#define LUABIND_NATIVE_CONVERTER_HPP_INCLUDED
|
||||
|
||||
#include <type_traits>
|
||||
#include <string>
|
||||
#include <luabind/detail/policy.hpp>
|
||||
#include <luabind/detail/conversion_policies/conversion_base.hpp>
|
||||
#include <luabind/detail/type_traits.hpp>
|
||||
#include <luabind/detail/call_traits.hpp>
|
||||
#include <luabind/lua_include.hpp>
|
||||
|
||||
#if LUA_VERSION_NUM < 502
|
||||
# define lua_rawlen lua_objlen
|
||||
#endif
|
||||
|
||||
namespace luabind {
|
||||
|
||||
template <class T, class Derived = default_converter<T> >
|
||||
struct native_converter_base
|
||||
{
|
||||
using is_native = std::true_type;
|
||||
using value_type = typename detail::call_traits<T>::value_type;
|
||||
using param_type = typename detail::call_traits<T>::param_type;
|
||||
|
||||
enum { consumed_args = 1 };
|
||||
|
||||
template <class U>
|
||||
void converter_postcall(lua_State*, U const&, int)
|
||||
{}
|
||||
|
||||
int match(lua_State* L, by_value<T>, int index)
|
||||
{
|
||||
return Derived::compute_score(L, index);
|
||||
}
|
||||
|
||||
int match(lua_State* L, by_value<T const>, int index)
|
||||
{
|
||||
return Derived::compute_score(L, index);
|
||||
}
|
||||
|
||||
|
||||
int match(lua_State* L, by_const_reference<T>, int index)
|
||||
{
|
||||
return Derived::compute_score(L, index);
|
||||
}
|
||||
|
||||
value_type to_cpp(lua_State* L, by_value<T>, int index)
|
||||
{
|
||||
return derived().to_cpp_deferred(L, index);
|
||||
}
|
||||
|
||||
value_type to_cpp(lua_State* L, by_const_reference<T>, int index)
|
||||
{
|
||||
return derived().to_cpp_deferred(L, index);
|
||||
}
|
||||
|
||||
void to_lua(lua_State* L, param_type value)
|
||||
{
|
||||
derived().to_lua_deferred(L, value);
|
||||
}
|
||||
|
||||
Derived& derived()
|
||||
{
|
||||
return static_cast<Derived&>(*this);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename QualifiedT>
|
||||
struct integer_converter
|
||||
: native_converter_base<remove_const_reference_t<QualifiedT>>
|
||||
{
|
||||
using T = remove_const_reference_t<QualifiedT>;
|
||||
using value_type = typename native_converter_base<T>::value_type;
|
||||
using param_type = typename native_converter_base<T>::param_type;
|
||||
|
||||
static int compute_score(lua_State* L, int index)
|
||||
{
|
||||
return lua_type(L, index) == LUA_TNUMBER ? 0 : no_match;
|
||||
}
|
||||
|
||||
static value_type to_cpp_deferred(lua_State* L, int index)
|
||||
{
|
||||
if((std::is_unsigned<value_type>::value && sizeof(value_type) >= sizeof(lua_Integer)) || (sizeof(value_type) > sizeof(lua_Integer))) {
|
||||
return static_cast<T>(lua_tonumber(L, index));
|
||||
} else {
|
||||
return static_cast<T>(lua_tointeger(L, index));
|
||||
}
|
||||
}
|
||||
|
||||
void to_lua_deferred(lua_State* L, param_type value)
|
||||
{
|
||||
if((std::is_unsigned<value_type>::value && sizeof(value_type) >= sizeof(lua_Integer)) || (sizeof(value_type) > sizeof(lua_Integer)))
|
||||
{
|
||||
lua_pushnumber(L, (lua_Number)value);
|
||||
} else {
|
||||
lua_pushinteger(L, static_cast<lua_Integer>(value));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename QualifiedT>
|
||||
struct number_converter
|
||||
: native_converter_base<remove_const_reference_t<QualifiedT>>
|
||||
{
|
||||
using T = remove_const_reference_t<QualifiedT>;
|
||||
using value_type = typename native_converter_base<T>::value_type;
|
||||
using param_type = typename native_converter_base<T>::param_type;
|
||||
|
||||
static int compute_score(lua_State* L, int index)
|
||||
{
|
||||
return lua_type(L, index) == LUA_TNUMBER ? 0 : no_match;
|
||||
}
|
||||
|
||||
static value_type to_cpp_deferred(lua_State* L, int index)
|
||||
{
|
||||
return static_cast<T>(lua_tonumber(L, index));
|
||||
}
|
||||
|
||||
static void to_lua_deferred(lua_State* L, param_type value)
|
||||
{
|
||||
lua_pushnumber(L, static_cast<lua_Number>(value));
|
||||
}
|
||||
};
|
||||
|
||||
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 : no_match;
|
||||
}
|
||||
|
||||
static bool to_cpp_deferred(lua_State* L, int index)
|
||||
{
|
||||
return lua_toboolean(L, index) == 1;
|
||||
}
|
||||
|
||||
static void to_lua_deferred(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 : no_match;
|
||||
}
|
||||
|
||||
static std::string to_cpp_deferred(lua_State* L, int index)
|
||||
{
|
||||
return std::string(lua_tostring(L, index), lua_rawlen(L, index));
|
||||
}
|
||||
|
||||
static void to_lua_deferred(lua_State* L, std::string const& value)
|
||||
{
|
||||
lua_pushlstring(L, value.data(), value.size());
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct default_converter<std::string&>
|
||||
: default_converter<std::string>
|
||||
{};
|
||||
|
||||
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*>
|
||||
{
|
||||
using is_native = std::true_type;
|
||||
|
||||
enum { consumed_args = 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 : no_match;
|
||||
}
|
||||
|
||||
template <class U>
|
||||
static char const* to_cpp(lua_State* L, U, int index)
|
||||
{
|
||||
return lua_tostring(L, index);
|
||||
}
|
||||
|
||||
static void to_lua(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<const char* const&>
|
||||
: default_converter<char const*>
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct default_converter<const char*&>
|
||||
: 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 <std::size_t N>
|
||||
struct default_converter <char(&)[N]>
|
||||
: default_converter<char const*>
|
||||
{};
|
||||
|
||||
template <std::size_t N>
|
||||
struct default_converter <const char(&)[N]>
|
||||
: default_converter<char const*>
|
||||
{};
|
||||
|
||||
template <typename T>
|
||||
struct default_converter < T, typename std::enable_if< std::is_integral<remove_const_reference_t<T>>::value >::type >
|
||||
: integer_converter<T>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct default_converter < T, typename std::enable_if< std::is_floating_point<remove_const_reference_t<T>>::value >::type >
|
||||
: number_converter<T>
|
||||
{
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#if LUA_VERSION_NUM < 502
|
||||
# undef lua_rawlen
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,143 +0,0 @@
|
||||
// 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_POINTER_CONVERTER_HPP_INCLUDED
|
||||
#define LUABIND_POINTER_CONVERTER_HPP_INCLUDED
|
||||
|
||||
#include <type_traits>
|
||||
#include <luabind/lua_include.hpp>
|
||||
#include <luabind/detail/make_instance.hpp>
|
||||
#include <luabind/back_reference.hpp>
|
||||
|
||||
namespace luabind {
|
||||
|
||||
/*
|
||||
Todo: Remove code duplication
|
||||
*/
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct pointer_converter
|
||||
{
|
||||
using type = pointer_converter;
|
||||
using is_native = std::false_type;
|
||||
|
||||
pointer_converter()
|
||||
: result(0)
|
||||
{}
|
||||
|
||||
void* result;
|
||||
|
||||
enum { consumed_args = 1 };
|
||||
|
||||
template<class T>
|
||||
static void to_lua(lua_State* L, T* ptr)
|
||||
{
|
||||
if(ptr == 0)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
return;
|
||||
}
|
||||
|
||||
if(luabind::get_back_reference(L, ptr))
|
||||
return;
|
||||
|
||||
make_pointer_instance(L, ptr);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T* to_cpp(lua_State*, by_pointer<T>, int /*index*/)
|
||||
{
|
||||
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 no_match;
|
||||
|
||||
if(obj->is_const())
|
||||
return no_match;
|
||||
|
||||
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 /*index*/)
|
||||
{}
|
||||
};
|
||||
|
||||
struct const_pointer_converter
|
||||
{
|
||||
using type = const_pointer_converter;
|
||||
using is_native = std::false_type;
|
||||
|
||||
enum { consumed_args = 1 };
|
||||
|
||||
const_pointer_converter()
|
||||
: result(0)
|
||||
{}
|
||||
|
||||
void* result;
|
||||
|
||||
template<class T>
|
||||
void to_lua(lua_State* L, const T* ptr)
|
||||
{
|
||||
if(ptr == 0)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
return;
|
||||
}
|
||||
|
||||
if(luabind::get_back_reference(L, ptr))
|
||||
return;
|
||||
|
||||
make_pointer_instance(L, ptr);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T const* to_cpp(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 no_match; // 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) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,124 +0,0 @@
|
||||
// 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_REFERENCE_CONVERTER_HPP_INCLUDED
|
||||
#define LUABIND_REFERENCE_CONVERTER_HPP_INCLUDED
|
||||
|
||||
#include <type_traits>
|
||||
#include <luabind/detail/conversion_policies/conversion_base.hpp>
|
||||
#include <luabind/detail/conversion_policies/pointer_converter.hpp>
|
||||
#include <luabind/back_reference.hpp>
|
||||
|
||||
namespace luabind {
|
||||
|
||||
/*
|
||||
TODO: Remove code duplication
|
||||
*/
|
||||
namespace detail {
|
||||
|
||||
struct ref_converter : pointer_converter
|
||||
{
|
||||
using type = ref_converter;
|
||||
using is_native = std::false_type;
|
||||
|
||||
enum { consumed_args = 1 };
|
||||
|
||||
template<class T>
|
||||
void to_lua(lua_State* L, T& ref)
|
||||
{
|
||||
if(luabind::get_back_reference(L, ref))
|
||||
return;
|
||||
|
||||
make_pointee_instance(L, ref, std::false_type());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T& to_cpp(lua_State* L, by_reference<T>, int index)
|
||||
{
|
||||
assert(!lua_isnil(L, index));
|
||||
return *pointer_converter::to_cpp(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 no_match;
|
||||
|
||||
if(obj->is_const())
|
||||
return no_match;
|
||||
|
||||
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) {}
|
||||
};
|
||||
|
||||
struct const_ref_converter
|
||||
{
|
||||
using type = const_ref_converter;
|
||||
using is_native = std::false_type;
|
||||
|
||||
enum { consumed_args = 1 };
|
||||
|
||||
const_ref_converter()
|
||||
: result(0)
|
||||
{}
|
||||
|
||||
void* result;
|
||||
|
||||
template<class T>
|
||||
void to_lua(lua_State* L, T const& ref)
|
||||
{
|
||||
if(luabind::get_back_reference(L, ref))
|
||||
return;
|
||||
|
||||
make_pointee_instance(L, ref, std::false_type());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T const& to_cpp(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 no_match; // 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)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
// 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_VALUE_CONVERTER_HPP_INCLUDED
|
||||
#define LUABIND_VALUE_CONVERTER_HPP_INCLUDED
|
||||
|
||||
#include <type_traits>
|
||||
#include <luabind/lua_include.hpp>
|
||||
#include <luabind/back_reference.hpp>
|
||||
#include <luabind/detail/object_rep.hpp>
|
||||
|
||||
namespace luabind {
|
||||
namespace detail {
|
||||
|
||||
struct value_converter
|
||||
{
|
||||
using type = value_converter;
|
||||
using is_native = std::false_type;
|
||||
|
||||
enum { consumed_args = 1 };
|
||||
|
||||
value_converter()
|
||||
: result(0)
|
||||
{}
|
||||
|
||||
void* result;
|
||||
|
||||
template<class T>
|
||||
void to_lua(lua_State* L, T&& x)
|
||||
{
|
||||
if(luabind::get_back_reference(L, x))
|
||||
return;
|
||||
|
||||
make_value_instance(L, std::forward<T>(x));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T to_cpp(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 no_match;
|
||||
|
||||
object_rep* obj = get_instance(L, index);
|
||||
if(obj == 0) return no_match;
|
||||
|
||||
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) {}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -6,38 +6,36 @@
|
||||
# define LUABIND_CONVERSION_STORAGE_080930_HPP
|
||||
|
||||
# include <luabind/config.hpp>
|
||||
# include <type_traits>
|
||||
# include <boost/aligned_storage.hpp>
|
||||
|
||||
namespace luabind {
|
||||
namespace detail {
|
||||
namespace luabind { namespace detail {
|
||||
|
||||
using destruction_function = void(*)(void*);
|
||||
typedef void(*destruction_function)(void*);
|
||||
|
||||
// This is used by the converters in policy.hpp, and
|
||||
// class_rep::convert_to as temporary storage when constructing
|
||||
// holders.
|
||||
// This is used by the converters in policy.hpp, and
|
||||
// class_rep::convert_to as temporary storage when constructing
|
||||
// holders.
|
||||
|
||||
struct conversion_storage
|
||||
{
|
||||
conversion_storage()
|
||||
: destructor(0)
|
||||
{}
|
||||
struct conversion_storage
|
||||
{
|
||||
conversion_storage()
|
||||
: destructor(0)
|
||||
{}
|
||||
|
||||
~conversion_storage()
|
||||
{
|
||||
if(destructor)
|
||||
destructor(&data);
|
||||
}
|
||||
~conversion_storage()
|
||||
{
|
||||
if (destructor)
|
||||
destructor(&data);
|
||||
}
|
||||
|
||||
// Unfortunately the converters currently doesn't have access to
|
||||
// the actual type being converted when this is instantiated, so
|
||||
// we have to guess a max size.
|
||||
std::aligned_storage<128> data;
|
||||
destruction_function destructor;
|
||||
};
|
||||
// Unfortunately the converters currently doesn't have access to
|
||||
// the actual type being converted when this is instantiated, so
|
||||
// we have to guess a max size.
|
||||
boost::aligned_storage<128> data;
|
||||
destruction_function destructor;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace luabind::detail
|
||||
}} // namespace luabind::detail
|
||||
|
||||
#endif // LUABIND_CONVERSION_STORAGE_080930_HPP
|
||||
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
// 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_CONVERT_TO_LUA_HPP_INCLUDED
|
||||
#define LUABIND_CONVERT_TO_LUA_HPP_INCLUDED
|
||||
|
||||
#include <luabind/config.hpp>
|
||||
#include <luabind/detail/policy.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
|
||||
#include <boost/mpl/apply_wrap.hpp>
|
||||
|
||||
namespace luabind { namespace detail
|
||||
{
|
||||
template<bool IsReferenceWrapper = false>
|
||||
struct unwrap_ref
|
||||
{
|
||||
template<class T>
|
||||
static const T& get(const T& r) { return r; }
|
||||
|
||||
template<class T>
|
||||
struct apply
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct unwrap_ref<true>
|
||||
{
|
||||
template<class T>
|
||||
static T& get(const boost::reference_wrapper<T>& r) { return r.get(); }
|
||||
|
||||
template<class T>
|
||||
struct apply
|
||||
{
|
||||
typedef typename T::type& type;
|
||||
};
|
||||
};
|
||||
|
||||
namespace mpl = boost::mpl;
|
||||
|
||||
template<class T>
|
||||
void convert_to_lua(lua_State* L, const T& v)
|
||||
{
|
||||
typedef typename mpl::apply_wrap1<
|
||||
unwrap_ref<boost::is_reference_wrapper<T>::value>
|
||||
, T
|
||||
>::type value_type;
|
||||
|
||||
typename mpl::apply_wrap2<default_policy,value_type,cpp_to_lua>::type converter;
|
||||
|
||||
converter.apply(L, unwrap_ref<boost::is_reference_wrapper<T>::value>::get(v));
|
||||
}
|
||||
|
||||
template<int Index, class T, class Policies>
|
||||
void convert_to_lua_p(lua_State* L, const T& v, const Policies&)
|
||||
{
|
||||
typedef typename mpl::apply_wrap1<
|
||||
unwrap_ref<boost::is_reference_wrapper<T>::value>
|
||||
, T
|
||||
>::type value_type;
|
||||
|
||||
typedef typename find_conversion_policy<Index, Policies>::type converter_policy;
|
||||
typename mpl::apply_wrap2<converter_policy,value_type,cpp_to_lua>::type converter;
|
||||
|
||||
converter.apply(L, unwrap_ref<boost::is_reference_wrapper<T>::value>::get(v));
|
||||
}
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
#ifndef LUABIND_CRTP_ITERATOR_HPP_INCLUDED
|
||||
#define LUABIND_CRTP_ITERATOR_HPP_INCLUDED
|
||||
|
||||
#include <iterator>
|
||||
|
||||
namespace luabind {
|
||||
namespace detail {
|
||||
|
||||
template< typename CRTP, typename Category, typename ValueType, typename ReferenceType = ValueType&, typename DifferenceType = ptrdiff_t >
|
||||
class crtp_iterator :
|
||||
public std::iterator<Category, ValueType, DifferenceType, ValueType*, ReferenceType >
|
||||
{
|
||||
public:
|
||||
using base_type = std::iterator<Category, ValueType, DifferenceType, ValueType*, ReferenceType >;
|
||||
|
||||
|
||||
CRTP& operator++()
|
||||
{
|
||||
upcast().increment();
|
||||
return upcast();
|
||||
}
|
||||
|
||||
CRTP operator++(int)
|
||||
{
|
||||
CRTP tmp(upcast());
|
||||
upcast().increment();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool operator==(const CRTP& rhs)
|
||||
{
|
||||
return upcast().equal(rhs);
|
||||
}
|
||||
|
||||
bool operator!=(const CRTP& rhs)
|
||||
{
|
||||
return !upcast().equal(rhs);
|
||||
}
|
||||
|
||||
typename base_type::reference operator*()
|
||||
{
|
||||
return upcast().dereference();
|
||||
}
|
||||
|
||||
typename base_type::reference operator->()
|
||||
{
|
||||
return upcast().dereference();
|
||||
}
|
||||
|
||||
private:
|
||||
CRTP& upcast() { return static_cast<CRTP&>(*this); }
|
||||
const CRTP& upcast() const { return static_cast<const CRTP&>(*this); }
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -28,32 +28,28 @@
|
||||
#include <luabind/lua_include.hpp>
|
||||
#include <cassert>
|
||||
|
||||
namespace luabind {
|
||||
namespace detail {
|
||||
namespace luabind { namespace detail
|
||||
{
|
||||
struct stack_checker_type
|
||||
{
|
||||
stack_checker_type(lua_State* L)
|
||||
: m_L(L)
|
||||
, m_stack(lua_gettop(m_L))
|
||||
{}
|
||||
|
||||
struct stack_checker_type
|
||||
~stack_checker_type()
|
||||
{
|
||||
stack_checker_type(lua_State* L)
|
||||
: m_L(L)
|
||||
, m_stack(lua_gettop(m_L))
|
||||
{}
|
||||
assert(m_stack == lua_gettop(m_L));
|
||||
}
|
||||
|
||||
~stack_checker_type()
|
||||
{
|
||||
assert(m_stack == lua_gettop(m_L));
|
||||
}
|
||||
|
||||
lua_State* m_L;
|
||||
int m_stack;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
lua_State* m_L;
|
||||
int m_stack;
|
||||
};
|
||||
|
||||
}}
|
||||
#define LUABIND_CHECK_STACK(L) luabind::detail::stack_checker_type stack_checker_object(L)
|
||||
#else
|
||||
#define LUABIND_CHECK_STACK(L) do {} while (0)
|
||||
#endif
|
||||
|
||||
#endif // LUABIND_DEBUG_HPP_INCLUDED
|
||||
|
||||
|
||||
@@ -25,62 +25,242 @@
|
||||
#define LUABIND_DECORATE_TYPE_HPP_INCLUDED
|
||||
|
||||
#include <luabind/config.hpp>
|
||||
#include <luabind/detail/primitives.hpp>
|
||||
|
||||
namespace luabind {
|
||||
namespace luabind { namespace detail
|
||||
{
|
||||
|
||||
template<class T> struct by_value {};
|
||||
template<class T> struct by_const_reference {};
|
||||
template<class T> struct by_reference {};
|
||||
template<class T> struct by_rvalue_reference {};
|
||||
template<class T> struct by_pointer {};
|
||||
template<class T> struct by_const_pointer {};
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
template<class T>
|
||||
struct decorate_type
|
||||
struct decorated_type
|
||||
{
|
||||
using type = by_value<T>;
|
||||
static by_value<T> t;
|
||||
static inline by_value<T>& get() { return /*by_value<T>()*/t; }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct decorate_type<T*>
|
||||
by_value<T> decorated_type<T>::t;
|
||||
|
||||
template<class T>
|
||||
struct decorated_type<T*>
|
||||
{
|
||||
using type = by_pointer<T>;
|
||||
static by_pointer<T> t;
|
||||
static inline by_pointer<T>& get() { return /*by_pointer<T>()*/t; }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct decorate_type<const T*>
|
||||
by_pointer<T> decorated_type<T*>::t;
|
||||
|
||||
template<class T>
|
||||
struct decorated_type<const T*>
|
||||
{
|
||||
using type = by_const_pointer<T>;
|
||||
static by_const_pointer<T> t;
|
||||
static inline by_const_pointer<T> get() { return /*by_const_pointer<T>()*/t; }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct decorate_type<const T* const>
|
||||
by_const_pointer<T> decorated_type<const T*>::t;
|
||||
|
||||
template<class T>
|
||||
struct decorated_type<const T* const>
|
||||
{
|
||||
using type = by_const_pointer<T>;
|
||||
static by_const_pointer<T> t;
|
||||
static inline by_const_pointer<T>& get() { return /*by_const_pointer<T>()*/t; }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct decorate_type<T&>
|
||||
by_const_pointer<T> decorated_type<const T* const>::t;
|
||||
|
||||
template<class T>
|
||||
struct decorated_type<T&>
|
||||
{
|
||||
using type = by_reference<T>;
|
||||
static by_reference<T> t;
|
||||
static inline by_reference<T>& get() { return /*by_reference<T>()*/t; }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct decorate_type<const T&>
|
||||
by_reference<T> decorated_type<T&>::t;
|
||||
|
||||
template<class T>
|
||||
struct decorated_type<const T&>
|
||||
{
|
||||
using type = by_const_reference<T>;
|
||||
static by_const_reference<T> t;
|
||||
static inline by_const_reference<T>& get() { return /*by_const_reference<T>()*/t; }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct decorate_type<T&&>
|
||||
by_const_reference<T> decorated_type<const T&>::t;
|
||||
|
||||
#define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type<t>::get()
|
||||
|
||||
#else
|
||||
|
||||
#include <boost/type_traits/is_array.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
using type = by_rvalue_reference<T>;
|
||||
LUABIND_ANONYMOUS_FIX char decorated_type_array[64];
|
||||
}
|
||||
|
||||
template<class T>
|
||||
struct decorated_type_cref_impl
|
||||
{
|
||||
#if defined(BOOST_MSVC) && BOOST_MSVC == 1200
|
||||
template<class U>
|
||||
static by_const_reference<U> get(const U&)
|
||||
{
|
||||
return by_const_reference<U>();
|
||||
}
|
||||
static T data() { return reinterpret_cast<T>(decorated_type_array); }
|
||||
#else
|
||||
|
||||
static void(*data())(T)
|
||||
{ return (void(*)(T))0; }
|
||||
|
||||
template<class U>
|
||||
static by_const_reference<U> get(void(*f)(const U&))
|
||||
{ return by_const_reference<U>(); }
|
||||
#endif
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
using decorate_type_t = typename decorate_type<T>::type;
|
||||
template<class T>
|
||||
struct decorated_type_ref_impl
|
||||
{
|
||||
#if defined(BOOST_MSVC) && BOOST_MSVC == 1200
|
||||
template<class U>
|
||||
static by_reference<U> get(U&)
|
||||
{
|
||||
return by_reference<U>();
|
||||
}
|
||||
static T data() { return reinterpret_cast<T>(decorated_type_array); }
|
||||
#else
|
||||
static void(*data())(T)
|
||||
{ return (void(*)(T))0; }
|
||||
|
||||
}
|
||||
template<class U>
|
||||
static by_reference<U> get(void(*)(U&))
|
||||
{ return by_reference<U>(); }
|
||||
#endif
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct decorated_type_cptr_impl
|
||||
{
|
||||
#if defined(BOOST_MSVC) && BOOST_MSVC == 1200
|
||||
template<class U>
|
||||
static by_const_pointer<U> get(const U*)
|
||||
{
|
||||
return by_const_pointer<U>();
|
||||
}
|
||||
static T& data() { return reinterpret_cast<T&>(decorated_type_array); }
|
||||
#else
|
||||
static void(*data())(T)
|
||||
{ return (void(*)(T))0; }
|
||||
|
||||
template<class U>
|
||||
static by_const_pointer<U> get(void(*)(const U*))
|
||||
{ return by_const_pointer<U>(); }
|
||||
#endif
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct decorated_type_ptr_impl
|
||||
{
|
||||
#if defined(BOOST_MSVC) && BOOST_MSVC == 1200
|
||||
template<class U>
|
||||
static by_pointer<U> get(U*)
|
||||
{
|
||||
return by_pointer<U>();
|
||||
}
|
||||
static T& data() { return reinterpret_cast<T&>(decorated_type_array); }
|
||||
#else
|
||||
static void(*data())(T)
|
||||
{ return (void(*)(T))0; }
|
||||
|
||||
template<class U>
|
||||
static by_pointer<U> get(void(*)(U*))
|
||||
{ return by_pointer<U>(); }
|
||||
#endif
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct decorated_type_value_impl
|
||||
{
|
||||
#if defined(BOOST_MSVC) && BOOST_MSVC == 1200
|
||||
template<class U>
|
||||
static by_value<U> get(U&)
|
||||
{
|
||||
return by_value<U>();
|
||||
}
|
||||
static T& data() { return reinterpret_cast<T&>(decorated_type_array); }
|
||||
#else
|
||||
static void(*data())(T&)
|
||||
{ return (void(*)(T&))0; }
|
||||
|
||||
template<class U>
|
||||
static by_value<U> get(void(*)(U&))
|
||||
{ return by_value<U>(); }
|
||||
#endif
|
||||
};
|
||||
|
||||
template<>
|
||||
struct decorated_type_value_impl<void>
|
||||
{
|
||||
static by_value<void> get(int)
|
||||
{
|
||||
return by_value<void>();
|
||||
}
|
||||
static int data() { return 0; }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct decorated_type_array_impl
|
||||
{
|
||||
template<class U>
|
||||
static by_pointer<U> get(U*)
|
||||
{
|
||||
return by_pointer<U>();
|
||||
}
|
||||
|
||||
template<class U>
|
||||
static by_pointer<U> get(void(*)(U))
|
||||
{ return by_pointer<U>(); }
|
||||
|
||||
static T& data() { return reinterpret_cast<T&>(decorated_type_array); }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct decorated_type
|
||||
// : boost::mpl::if_<boost::is_array<T>
|
||||
// , decorated_type_array_impl<T>
|
||||
: boost::mpl::if_<luabind::detail::is_const_reference<T>
|
||||
, decorated_type_cref_impl<T>
|
||||
, typename boost::mpl::if_<luabind::detail::is_nonconst_reference<T>
|
||||
, decorated_type_ref_impl<T>
|
||||
, typename boost::mpl::if_<luabind::detail::is_nonconst_pointer<T>
|
||||
, decorated_type_ptr_impl<T>
|
||||
, typename boost::mpl::if_<luabind::detail::is_const_pointer<T>
|
||||
, decorated_type_cptr_impl<T>
|
||||
, decorated_type_value_impl<T>
|
||||
>::type
|
||||
>::type
|
||||
>::type
|
||||
>::type
|
||||
// >::type
|
||||
{
|
||||
};
|
||||
|
||||
#if defined(BOOST_MSVC) && BOOST_MSVC == 1200
|
||||
#define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type<t>::get(luabind::detail::decorated_type<t>::data())
|
||||
#else
|
||||
// #define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type<t>::get((void(*)(type<t>))0)
|
||||
#define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type<t>::get(luabind::detail::decorated_type<t>::data())
|
||||
//#define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type<t>::get(type<t>())
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
}}
|
||||
|
||||
#endif // LUABIND_DECORATE_TYPE_HPP_INCLUDED
|
||||
|
||||
|
||||
@@ -2,19 +2,117 @@
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#if !BOOST_PP_IS_ITERATING
|
||||
|
||||
# ifndef LUABIND_DEDUCE_SIGNATURE_080911_HPP
|
||||
# define LUABIND_DEDUCE_SIGNATURE_080911_HPP
|
||||
# define LUABIND_DEDUCE_SIGNATURE_080911_HPP
|
||||
|
||||
#include <luabind/detail/meta.hpp>
|
||||
#include <luabind/detail/type_traits.hpp>
|
||||
# include <luabind/detail/most_derived.hpp>
|
||||
|
||||
namespace luabind {
|
||||
namespace detail {
|
||||
# if LUABIND_MAX_ARITY <= 8
|
||||
# include <boost/mpl/vector/vector10.hpp>
|
||||
# else
|
||||
# include <boost/mpl/vector/vector50.hpp>
|
||||
# endif
|
||||
# include <boost/preprocessor/cat.hpp>
|
||||
# include <boost/preprocessor/iteration/iterate.hpp>
|
||||
# include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
|
||||
namespace luabind { namespace detail {
|
||||
|
||||
} // namespace detail
|
||||
namespace mpl = boost::mpl;
|
||||
|
||||
} // namespace luabind
|
||||
template <class R>
|
||||
mpl::vector1<R> deduce_signature(R(*)(), ...)
|
||||
{
|
||||
return mpl::vector1<R>();
|
||||
}
|
||||
|
||||
template <class R, class T>
|
||||
mpl::vector2<R,T&> deduce_signature(R(T::*)())
|
||||
{
|
||||
return mpl::vector2<R,T&>();
|
||||
}
|
||||
|
||||
template <class R, class T, class Wrapped>
|
||||
mpl::vector2<R,typename most_derived<T,Wrapped>::type&>
|
||||
deduce_signature(R(T::*)(), Wrapped*)
|
||||
{
|
||||
return mpl::vector2<R,typename most_derived<T,Wrapped>::type&>();
|
||||
}
|
||||
|
||||
template <class R, class T>
|
||||
mpl::vector2<R,T const&> deduce_signature(R(T::*)() const)
|
||||
{
|
||||
return mpl::vector2<R,T const&>();
|
||||
}
|
||||
|
||||
template <class R, class T, class Wrapped>
|
||||
mpl::vector2<R,typename most_derived<T,Wrapped>::type const&>
|
||||
deduce_signature(R(T::*)() const, Wrapped*)
|
||||
{
|
||||
return mpl::vector2<R,typename most_derived<T,Wrapped>::type const&>();
|
||||
}
|
||||
|
||||
# define BOOST_PP_ITERATION_PARAMS_1 \
|
||||
(3, (1, LUABIND_MAX_ARITY, <luabind/detail/deduce_signature.hpp>))
|
||||
# include BOOST_PP_ITERATE()
|
||||
|
||||
}} // namespace luabind::detail
|
||||
|
||||
# endif // LUABIND_DEDUCE_SIGNATURE_080911_HPP
|
||||
|
||||
#else // BOOST_PP_IS_ITERATING
|
||||
|
||||
# define N BOOST_PP_ITERATION()
|
||||
# define NPLUS1 BOOST_PP_INC(N)
|
||||
|
||||
template <class R, BOOST_PP_ENUM_PARAMS(N,class A)>
|
||||
BOOST_PP_CAT(mpl::vector,NPLUS1)<R, BOOST_PP_ENUM_PARAMS(N,A)>
|
||||
deduce_signature(R(*)(BOOST_PP_ENUM_PARAMS(N,A)), ...)
|
||||
{
|
||||
return BOOST_PP_CAT(mpl::vector,NPLUS1)<R,BOOST_PP_ENUM_PARAMS(N,A)>();
|
||||
}
|
||||
|
||||
# define NPLUS2 BOOST_PP_INC(NPLUS1)
|
||||
|
||||
template <class R, class T, BOOST_PP_ENUM_PARAMS(N,class A)>
|
||||
BOOST_PP_CAT(mpl::vector,NPLUS2)<R, T&, BOOST_PP_ENUM_PARAMS(N,A)>
|
||||
deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N,A)))
|
||||
{
|
||||
return BOOST_PP_CAT(mpl::vector,NPLUS2)<R,T&,BOOST_PP_ENUM_PARAMS(N,A)>();
|
||||
}
|
||||
|
||||
template <class R, class T, BOOST_PP_ENUM_PARAMS(N,class A), class Wrapped>
|
||||
BOOST_PP_CAT(mpl::vector,NPLUS2)<
|
||||
R, typename most_derived<T,Wrapped>::type&, BOOST_PP_ENUM_PARAMS(N,A)
|
||||
>
|
||||
deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N,A)), Wrapped*)
|
||||
{
|
||||
return BOOST_PP_CAT(mpl::vector,NPLUS2)<
|
||||
R,typename most_derived<T,Wrapped>::type&,BOOST_PP_ENUM_PARAMS(N,A)>();
|
||||
}
|
||||
|
||||
template <class R, class T, BOOST_PP_ENUM_PARAMS(N,class A)>
|
||||
BOOST_PP_CAT(mpl::vector,NPLUS2)<R, T const&, BOOST_PP_ENUM_PARAMS(N,A)>
|
||||
deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N,A)) const)
|
||||
{
|
||||
return BOOST_PP_CAT(mpl::vector,NPLUS2)<R,T const&,BOOST_PP_ENUM_PARAMS(N,A)>();
|
||||
}
|
||||
|
||||
template <class R, class T, BOOST_PP_ENUM_PARAMS(N,class A), class Wrapped>
|
||||
BOOST_PP_CAT(mpl::vector,NPLUS2)<
|
||||
R, typename most_derived<T,Wrapped>::type const&, BOOST_PP_ENUM_PARAMS(N,A)
|
||||
>
|
||||
deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N,A)) const, Wrapped*)
|
||||
{
|
||||
return BOOST_PP_CAT(mpl::vector,NPLUS2)<
|
||||
R,typename most_derived<T,Wrapped>::type const&,BOOST_PP_ENUM_PARAMS(N,A)>();
|
||||
}
|
||||
|
||||
# undef NPLUS2
|
||||
# undef NPLUS1
|
||||
# undef N
|
||||
|
||||
#endif // BOOST_PP_IS_ITERATING
|
||||
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
#include <luabind/config.hpp>
|
||||
#include <luabind/detail/class_rep.hpp>
|
||||
|
||||
namespace luabind {
|
||||
|
||||
namespace luabind
|
||||
{
|
||||
struct value;
|
||||
|
||||
struct value_vector : public std::vector<value>
|
||||
@@ -45,7 +45,7 @@ namespace luabind {
|
||||
|
||||
struct value
|
||||
{
|
||||
friend class std::vector<value>;
|
||||
friend class std::vector<value>;
|
||||
template<class T>
|
||||
value(const char* name, T v)
|
||||
: name_(name)
|
||||
@@ -65,7 +65,7 @@ namespace luabind {
|
||||
return v;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
|
||||
value() {}
|
||||
};
|
||||
@@ -93,18 +93,19 @@ namespace luabind {
|
||||
template<class From>
|
||||
struct enum_maker
|
||||
{
|
||||
explicit enum_maker(From& from) : from_(from) {}
|
||||
explicit enum_maker(From& from): from_(from) {}
|
||||
|
||||
From& operator[](const value& val)
|
||||
{
|
||||
from_.add_static_constant(val.name_, val.val_);
|
||||
return from_;
|
||||
}
|
||||
|
||||
|
||||
From& operator[](const value_vector& values)
|
||||
{
|
||||
for(const auto& val : values) {
|
||||
from_.add_static_constant(val.name_, val.val_);
|
||||
for (value_vector::const_iterator i = values.begin(); i != values.end(); ++i)
|
||||
{
|
||||
from_.add_static_constant(i->name_, i->val_);
|
||||
}
|
||||
|
||||
return from_;
|
||||
@@ -113,11 +114,10 @@ namespace luabind {
|
||||
From& from_;
|
||||
|
||||
private:
|
||||
void operator=(enum_maker const&); // C4512, assignment operator could not be generated
|
||||
void operator=(enum_maker const&); // C4512, assignment operator could not be generated
|
||||
template<class T> void operator,(T const&) const;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // LUABIND_ENUM_MAKER_HPP_INCLUDED
|
||||
|
||||
|
||||
@@ -5,70 +5,73 @@
|
||||
#ifndef LUABIND_FORMAT_SIGNATURE_081014_HPP
|
||||
# define LUABIND_FORMAT_SIGNATURE_081014_HPP
|
||||
|
||||
#include <luabind/config.hpp>
|
||||
#include <luabind/lua_include.hpp>
|
||||
#include <luabind/typeid.hpp>
|
||||
#include <luabind/detail/meta.hpp>
|
||||
# include <luabind/config.hpp>
|
||||
# include <luabind/lua_include.hpp>
|
||||
# include <luabind/typeid.hpp>
|
||||
|
||||
namespace luabind {
|
||||
namespace adl {
|
||||
# include <boost/mpl/begin_end.hpp>
|
||||
# include <boost/mpl/next.hpp>
|
||||
# include <boost/mpl/size.hpp>
|
||||
|
||||
class object;
|
||||
class argument;
|
||||
template <class Base>
|
||||
struct table;
|
||||
namespace luabind { namespace adl {
|
||||
|
||||
} // namespace adl
|
||||
class object;
|
||||
class argument;
|
||||
template <class Base>
|
||||
struct table;
|
||||
} // namespace adl
|
||||
|
||||
using adl::object;
|
||||
using adl::argument;
|
||||
using adl::table;
|
||||
using adl::object;
|
||||
using adl::argument;
|
||||
using adl::table;
|
||||
|
||||
namespace detail {
|
||||
} // namespace luabind
|
||||
|
||||
LUABIND_API std::string get_class_name(lua_State* L, type_id const& i);
|
||||
namespace luabind { namespace detail {
|
||||
|
||||
template <class T, class Enable = void>
|
||||
struct type_to_string
|
||||
{
|
||||
static void get(lua_State* L)
|
||||
{
|
||||
lua_pushstring(L, get_class_name(L, typeid(T)).c_str());
|
||||
}
|
||||
};
|
||||
LUABIND_API std::string get_class_name(lua_State* L, type_id const& i);
|
||||
|
||||
template <class T>
|
||||
struct type_to_string<T*>
|
||||
{
|
||||
static void get(lua_State* L)
|
||||
{
|
||||
type_to_string<T>::get(L);
|
||||
lua_pushstring(L, "*");
|
||||
lua_concat(L, 2);
|
||||
}
|
||||
};
|
||||
template <class T>
|
||||
struct type_to_string
|
||||
{
|
||||
static void get(lua_State* L)
|
||||
{
|
||||
lua_pushstring(L, get_class_name(L, typeid(T)).c_str());
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct type_to_string<T&>
|
||||
{
|
||||
static void get(lua_State* L)
|
||||
{
|
||||
type_to_string<T>::get(L);
|
||||
lua_pushstring(L, "&");
|
||||
lua_concat(L, 2);
|
||||
}
|
||||
};
|
||||
template <class T>
|
||||
struct type_to_string<T*>
|
||||
{
|
||||
static void get(lua_State* L)
|
||||
{
|
||||
type_to_string<T>::get(L);
|
||||
lua_pushstring(L, "*");
|
||||
lua_concat(L, 2);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct type_to_string<T const>
|
||||
{
|
||||
static void get(lua_State* L)
|
||||
{
|
||||
type_to_string<T>::get(L);
|
||||
lua_pushstring(L, " const");
|
||||
lua_concat(L, 2);
|
||||
}
|
||||
};
|
||||
template <class T>
|
||||
struct type_to_string<T&>
|
||||
{
|
||||
static void get(lua_State* L)
|
||||
{
|
||||
type_to_string<T>::get(L);
|
||||
lua_pushstring(L, "&");
|
||||
lua_concat(L, 2);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct type_to_string<T const>
|
||||
{
|
||||
static void get(lua_State* L)
|
||||
{
|
||||
type_to_string<T>::get(L);
|
||||
lua_pushstring(L, " const");
|
||||
lua_concat(L, 2);
|
||||
}
|
||||
};
|
||||
|
||||
# define LUABIND_TYPE_TO_STRING(x) \
|
||||
template <> \
|
||||
@@ -84,67 +87,67 @@ namespace luabind {
|
||||
LUABIND_TYPE_TO_STRING(x) \
|
||||
LUABIND_TYPE_TO_STRING(unsigned x)
|
||||
|
||||
LUABIND_INTEGRAL_TYPE_TO_STRING(char)
|
||||
LUABIND_INTEGRAL_TYPE_TO_STRING(short)
|
||||
LUABIND_INTEGRAL_TYPE_TO_STRING(int)
|
||||
LUABIND_INTEGRAL_TYPE_TO_STRING(long)
|
||||
LUABIND_INTEGRAL_TYPE_TO_STRING(char)
|
||||
LUABIND_INTEGRAL_TYPE_TO_STRING(short)
|
||||
LUABIND_INTEGRAL_TYPE_TO_STRING(int)
|
||||
LUABIND_INTEGRAL_TYPE_TO_STRING(long)
|
||||
|
||||
LUABIND_TYPE_TO_STRING(void)
|
||||
LUABIND_TYPE_TO_STRING(bool)
|
||||
LUABIND_TYPE_TO_STRING(std::string)
|
||||
LUABIND_TYPE_TO_STRING(lua_State)
|
||||
LUABIND_TYPE_TO_STRING(void)
|
||||
LUABIND_TYPE_TO_STRING(bool)
|
||||
LUABIND_TYPE_TO_STRING(std::string)
|
||||
LUABIND_TYPE_TO_STRING(lua_State)
|
||||
|
||||
LUABIND_TYPE_TO_STRING(luabind::object)
|
||||
LUABIND_TYPE_TO_STRING(luabind::argument)
|
||||
LUABIND_TYPE_TO_STRING(luabind::object)
|
||||
LUABIND_TYPE_TO_STRING(luabind::argument)
|
||||
|
||||
# undef LUABIND_INTEGRAL_TYPE_TO_STRING
|
||||
# undef LUABIND_TYPE_TO_STRING
|
||||
|
||||
template <class Base>
|
||||
struct type_to_string<table<Base> >
|
||||
{
|
||||
static void get(lua_State* L)
|
||||
{
|
||||
lua_pushstring(L, "table");
|
||||
}
|
||||
};
|
||||
template <class Base>
|
||||
struct type_to_string<table<Base> >
|
||||
{
|
||||
static void get(lua_State* L)
|
||||
{
|
||||
lua_pushstring(L, "table");
|
||||
}
|
||||
};
|
||||
|
||||
inline void format_signature_aux(lua_State*, bool, meta::type_list< >)
|
||||
{}
|
||||
template <class End>
|
||||
void format_signature_aux(lua_State*, bool, End, End)
|
||||
{}
|
||||
|
||||
template <class Signature>
|
||||
void format_signature_aux(lua_State* L, bool first, Signature)
|
||||
{
|
||||
if(!first)
|
||||
lua_pushstring(L, ",");
|
||||
type_to_string<typename meta::front<Signature>::type>::get(L);
|
||||
format_signature_aux(L, false, typename meta::pop_front<Signature>::type());
|
||||
}
|
||||
template <class Iter, class End>
|
||||
void format_signature_aux(lua_State* L, bool first, Iter, End end)
|
||||
{
|
||||
if (!first)
|
||||
lua_pushstring(L, ",");
|
||||
type_to_string<typename Iter::type>::get(L);
|
||||
format_signature_aux(L, false, typename mpl::next<Iter>::type(), end);
|
||||
}
|
||||
|
||||
template <class Signature>
|
||||
void format_signature(lua_State* L, char const* function, Signature)
|
||||
{
|
||||
using first = typename meta::front<Signature>::type;
|
||||
template <class Signature>
|
||||
void format_signature(lua_State* L, char const* function, Signature)
|
||||
{
|
||||
typedef typename mpl::begin<Signature>::type first;
|
||||
|
||||
type_to_string<first>::get(L);
|
||||
type_to_string<typename first::type>::get(L);
|
||||
|
||||
lua_pushstring(L, " ");
|
||||
lua_pushstring(L, function);
|
||||
lua_pushstring(L, " ");
|
||||
lua_pushstring(L, function);
|
||||
|
||||
lua_pushstring(L, "(");
|
||||
format_signature_aux(
|
||||
L
|
||||
, true
|
||||
, typename meta::pop_front<Signature>::type()
|
||||
);
|
||||
lua_pushstring(L, ")");
|
||||
constexpr size_t ncat = meta::size<Signature>::value * 2 + 2 + (meta::size<Signature>::value == 1 ? 1 : 0);
|
||||
lua_concat(L, static_cast<int>(ncat));
|
||||
}
|
||||
lua_pushstring(L, "(");
|
||||
format_signature_aux(
|
||||
L
|
||||
, true
|
||||
, typename mpl::next<first>::type()
|
||||
, typename mpl::end<Signature>::type()
|
||||
);
|
||||
lua_pushstring(L, ")");
|
||||
|
||||
} // namespace detail
|
||||
lua_concat(L, static_cast<int>(mpl::size<Signature>()) * 2 + 2);
|
||||
}
|
||||
|
||||
} // namespace luabind
|
||||
}} // namespace luabind::detail
|
||||
|
||||
#endif // LUABIND_FORMAT_SIGNATURE_081014_HPP
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2003 Daniel Wallin and Arvid Norberg
|
||||
// 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"),
|
||||
@@ -26,31 +26,28 @@
|
||||
|
||||
#include <luabind/config.hpp>
|
||||
|
||||
namespace luabind {
|
||||
namespace detail {
|
||||
namespace luabind { namespace detail
|
||||
{
|
||||
// function that is used as __gc metafunction on several objects
|
||||
template<class T>
|
||||
inline int garbage_collector(lua_State* L)
|
||||
{
|
||||
T* obj = static_cast<T*>(lua_touserdata(L, -1));
|
||||
obj->~T();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// function that is used as __gc metafunction on several objects
|
||||
template<class T>
|
||||
inline int garbage_collector(lua_State* L)
|
||||
template<class T>
|
||||
struct garbage_collector_s
|
||||
{
|
||||
static int apply(lua_State* L)
|
||||
{
|
||||
T* obj = static_cast<T*>(lua_touserdata(L, -1));
|
||||
obj->~T();
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct garbage_collector_s
|
||||
{
|
||||
static int apply(lua_State* L)
|
||||
{
|
||||
T* obj = static_cast<T*>(lua_touserdata(L, -1));
|
||||
obj->~T();
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}}
|
||||
|
||||
#endif // LUABIND_GARBAGE_COLLECTOR_HPP_INCLUDED
|
||||
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
// Copyright (c) 2005 Daniel Wallin
|
||||
|
||||
// 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_HAS_GET_POINTER_051022_HPP
|
||||
# define LUABIND_HAS_GET_POINTER_051022_HPP
|
||||
|
||||
# include <boost/type_traits/add_reference.hpp>
|
||||
|
||||
# ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
|
||||
# include <memory>
|
||||
# endif
|
||||
|
||||
namespace luabind { namespace detail {
|
||||
|
||||
namespace has_get_pointer_
|
||||
{
|
||||
|
||||
struct any
|
||||
{
|
||||
template<class T> any(T const&);
|
||||
};
|
||||
|
||||
struct no_overload_tag
|
||||
{};
|
||||
|
||||
typedef char (&yes)[1];
|
||||
typedef char (&no)[2];
|
||||
|
||||
no_overload_tag operator,(no_overload_tag, int);
|
||||
|
||||
//
|
||||
// On compilers with ADL, we need these generic overloads in this
|
||||
// namespace as well as in luabind::. Otherwise get_pointer(any)
|
||||
// will be found before them.
|
||||
//
|
||||
# ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
|
||||
|
||||
template<class T>
|
||||
T* get_pointer(T const volatile*);
|
||||
|
||||
template<class T>
|
||||
T* get_pointer(std::auto_ptr<T> const&);
|
||||
|
||||
# endif
|
||||
|
||||
//
|
||||
// On compilers that doesn't support ADL, the overload below has to
|
||||
// live in luabind::.
|
||||
//
|
||||
# ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
|
||||
}} // namespace detail::has_get_pointer_
|
||||
# endif
|
||||
|
||||
detail::has_get_pointer_::no_overload_tag
|
||||
get_pointer(detail::has_get_pointer_::any);
|
||||
|
||||
# ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
|
||||
namespace detail { namespace has_get_pointer_
|
||||
{
|
||||
# endif
|
||||
|
||||
template<class T>
|
||||
yes check(T const&);
|
||||
no check(no_overload_tag);
|
||||
|
||||
template<class T>
|
||||
struct impl
|
||||
{
|
||||
static typename boost::add_reference<T>::type x;
|
||||
|
||||
BOOST_STATIC_CONSTANT(bool,
|
||||
value = sizeof(has_get_pointer_::check( (get_pointer(x),0) )) == 1
|
||||
);
|
||||
|
||||
typedef boost::mpl::bool_<value> type;
|
||||
};
|
||||
|
||||
} // namespace has_get_pointer_
|
||||
|
||||
template<class T>
|
||||
struct has_get_pointer
|
||||
: has_get_pointer_::impl<T>::type
|
||||
{};
|
||||
|
||||
}} // namespace luabind::detail
|
||||
|
||||
#endif // LUABIND_HAS_GET_POINTER_051022_HPP
|
||||
|
||||
@@ -1,169 +1,168 @@
|
||||
// Copyright Daniel Wallin 2009. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef LUABIND_INHERITANCE_090217_HPP
|
||||
# define LUABIND_INHERITANCE_090217_HPP
|
||||
|
||||
# include <luabind/config.hpp>
|
||||
# include <cassert>
|
||||
# include <limits>
|
||||
# include <map>
|
||||
# include <memory>
|
||||
# include <vector>
|
||||
# include <luabind/typeid.hpp>
|
||||
# include <boost/scoped_ptr.hpp>
|
||||
|
||||
namespace luabind {
|
||||
namespace luabind { namespace detail {
|
||||
|
||||
namespace detail {
|
||||
typedef void*(*cast_function)(void*);
|
||||
typedef std::size_t class_id;
|
||||
|
||||
using cast_function = void*(*)(void*);
|
||||
using class_id = std::size_t;
|
||||
class_id const unknown_class = (std::numeric_limits<class_id>::max)();
|
||||
|
||||
constexpr class_id unknown_class = std::numeric_limits<class_id>::max();
|
||||
class class_rep;
|
||||
|
||||
class class_rep;
|
||||
class LUABIND_API cast_graph
|
||||
{
|
||||
public:
|
||||
cast_graph();
|
||||
~cast_graph();
|
||||
|
||||
class LUABIND_API cast_graph
|
||||
{
|
||||
public:
|
||||
cast_graph();
|
||||
~cast_graph();
|
||||
// `src` and `p` here describe the *most derived* object. This means that
|
||||
// for a polymorphic type, the pointer must be cast with
|
||||
// dynamic_cast<void*> before being passed in here, and `src` has to
|
||||
// match typeid(*p).
|
||||
std::pair<void*, int> cast(
|
||||
void* p, class_id src, class_id target
|
||||
, class_id dynamic_id, void const* dynamic_ptr) const;
|
||||
void insert(class_id src, class_id target, cast_function cast);
|
||||
|
||||
// `src` and `p` here describe the *most derived* object. This means that
|
||||
// for a polymorphic type, the pointer must be cast with
|
||||
// dynamic_cast<void*> before being passed in here, and `src` has to
|
||||
// match typeid(*p).
|
||||
std::pair<void*, int> cast(void* p, class_id src, class_id target, class_id dynamic_id, void const* dynamic_ptr) const;
|
||||
void insert(class_id src, class_id target, cast_function cast);
|
||||
private:
|
||||
class impl;
|
||||
boost::scoped_ptr<impl> m_impl;
|
||||
};
|
||||
|
||||
private:
|
||||
class impl;
|
||||
std::unique_ptr<impl> m_impl;
|
||||
};
|
||||
// Maps a type_id to a class_id. Note that this actually partitions the
|
||||
// id-space into two, using one half for "local" ids; ids that are used only as
|
||||
// keys into the conversion cache. This is needed because we need a unique key
|
||||
// even for types that hasn't been registered explicitly.
|
||||
class LUABIND_API class_id_map
|
||||
{
|
||||
public:
|
||||
class_id_map();
|
||||
|
||||
// Maps a type_id to a class_id. Note that this actually partitions the
|
||||
// id-space into two, using one half for "local" ids; ids that are used only as
|
||||
// keys into the conversion cache. This is needed because we need a unique key
|
||||
// even for types that hasn't been registered explicitly.
|
||||
class LUABIND_API class_id_map
|
||||
{
|
||||
public:
|
||||
class_id_map();
|
||||
class_id get(type_id const& type) const;
|
||||
class_id get_local(type_id const& type);
|
||||
void put(class_id id, type_id const& type);
|
||||
|
||||
class_id get(type_id const& type) const;
|
||||
class_id get_local(type_id const& type);
|
||||
void put(class_id id, type_id const& type);
|
||||
private:
|
||||
typedef std::map<type_id, class_id> map_type;
|
||||
map_type m_classes;
|
||||
class_id m_local_id;
|
||||
|
||||
private:
|
||||
using map_type = std::map<type_id, class_id>;
|
||||
map_type m_classes;
|
||||
class_id m_local_id;
|
||||
static class_id const local_id_base;
|
||||
};
|
||||
|
||||
static class_id const local_id_base;
|
||||
};
|
||||
inline class_id_map::class_id_map()
|
||||
: m_local_id(local_id_base)
|
||||
{}
|
||||
|
||||
inline class_id_map::class_id_map()
|
||||
: m_local_id(local_id_base)
|
||||
{}
|
||||
inline class_id class_id_map::get(type_id const& type) const
|
||||
{
|
||||
map_type::const_iterator i = m_classes.find(type);
|
||||
if (i == m_classes.end() || i->second >= local_id_base)
|
||||
return unknown_class;
|
||||
return i->second;
|
||||
}
|
||||
|
||||
inline class_id class_id_map::get(type_id const& type) const
|
||||
{
|
||||
map_type::const_iterator i = m_classes.find(type);
|
||||
if(i == m_classes.end() || i->second >= local_id_base) {
|
||||
return unknown_class;
|
||||
}
|
||||
else {
|
||||
return i->second;
|
||||
}
|
||||
}
|
||||
inline class_id class_id_map::get_local(type_id const& type)
|
||||
{
|
||||
std::pair<map_type::iterator, bool> result = m_classes.insert(
|
||||
std::make_pair(type, 0));
|
||||
|
||||
inline class_id class_id_map::get_local(type_id const& type)
|
||||
{
|
||||
std::pair<map_type::iterator, bool> result = m_classes.insert(std::make_pair(type, 0));
|
||||
if (result.second)
|
||||
result.first->second = m_local_id++;
|
||||
|
||||
if(result.second) result.first->second = m_local_id++;
|
||||
assert(m_local_id >= local_id_base);
|
||||
return result.first->second;
|
||||
}
|
||||
assert(m_local_id >= local_id_base);
|
||||
|
||||
inline void class_id_map::put(class_id id, type_id const& type)
|
||||
{
|
||||
assert(id < local_id_base);
|
||||
return result.first->second;
|
||||
}
|
||||
|
||||
std::pair<map_type::iterator, bool> result = m_classes.insert(
|
||||
std::make_pair(type, 0));
|
||||
inline void class_id_map::put(class_id id, type_id const& type)
|
||||
{
|
||||
assert(id < local_id_base);
|
||||
|
||||
assert(
|
||||
result.second
|
||||
|| result.first->second == id
|
||||
|| result.first->second >= local_id_base
|
||||
);
|
||||
std::pair<map_type::iterator, bool> result = m_classes.insert(
|
||||
std::make_pair(type, 0));
|
||||
|
||||
result.first->second = id;
|
||||
}
|
||||
assert(
|
||||
result.second
|
||||
|| result.first->second == id
|
||||
|| result.first->second >= local_id_base
|
||||
);
|
||||
|
||||
class class_map
|
||||
{
|
||||
public:
|
||||
class_rep* get(class_id id) const;
|
||||
void put(class_id id, class_rep* cls);
|
||||
result.first->second = id;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<class_rep*> m_classes;
|
||||
};
|
||||
class class_map
|
||||
{
|
||||
public:
|
||||
class_rep* get(class_id id) const;
|
||||
void put(class_id id, class_rep* cls);
|
||||
|
||||
inline class_rep* class_map::get(class_id id) const
|
||||
{
|
||||
if(id >= m_classes.size())
|
||||
return 0;
|
||||
return m_classes[id];
|
||||
}
|
||||
private:
|
||||
std::vector<class_rep*> m_classes;
|
||||
};
|
||||
|
||||
inline void class_map::put(class_id id, class_rep* cls)
|
||||
{
|
||||
if(id >= m_classes.size())
|
||||
m_classes.resize(id + 1);
|
||||
m_classes[id] = cls;
|
||||
}
|
||||
inline class_rep* class_map::get(class_id id) const
|
||||
{
|
||||
if (id >= m_classes.size())
|
||||
return 0;
|
||||
return m_classes[id];
|
||||
}
|
||||
|
||||
template <class S, class T>
|
||||
struct static_cast_
|
||||
{
|
||||
static void* execute(void* p)
|
||||
{
|
||||
return static_cast<T*>(static_cast<S*>(p));
|
||||
}
|
||||
};
|
||||
inline void class_map::put(class_id id, class_rep* cls)
|
||||
{
|
||||
if (id >= m_classes.size())
|
||||
m_classes.resize(id + 1);
|
||||
m_classes[id] = cls;
|
||||
}
|
||||
|
||||
template <class S, class T>
|
||||
struct dynamic_cast_
|
||||
{
|
||||
static void* execute(void* p)
|
||||
{
|
||||
return dynamic_cast<T*>(static_cast<S*>(p));
|
||||
}
|
||||
};
|
||||
template <class S, class T>
|
||||
struct static_cast_
|
||||
{
|
||||
static void* execute(void* p)
|
||||
{
|
||||
return static_cast<T*>(static_cast<S*>(p));
|
||||
}
|
||||
};
|
||||
|
||||
// Thread safe class_id allocation.
|
||||
LUABIND_API class_id allocate_class_id(type_id const& cls);
|
||||
template <class S, class T>
|
||||
struct dynamic_cast_
|
||||
{
|
||||
static void* execute(void* p)
|
||||
{
|
||||
return dynamic_cast<T*>(static_cast<S*>(p));
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct registered_class
|
||||
{
|
||||
static class_id const id;
|
||||
};
|
||||
// Thread safe class_id allocation.
|
||||
LUABIND_API class_id allocate_class_id(type_id const& cls);
|
||||
|
||||
template <class T>
|
||||
class_id const registered_class<T>::id = allocate_class_id(typeid(T));
|
||||
template <class T>
|
||||
struct registered_class
|
||||
{
|
||||
static class_id const id;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct registered_class<T const>
|
||||
: registered_class<T>
|
||||
{};
|
||||
template <class T>
|
||||
class_id const registered_class<T>::id = allocate_class_id(typeid(T));
|
||||
|
||||
} // namespace detail
|
||||
template <class T>
|
||||
struct registered_class<T const>
|
||||
: registered_class<T>
|
||||
{};
|
||||
|
||||
} // namespace luabind
|
||||
}} // namespace luabind::detail
|
||||
|
||||
#endif // LUABIND_INHERITANCE_090217_HPP
|
||||
|
||||
|
||||
@@ -6,160 +6,126 @@
|
||||
# define LUABIND_INSTANCE_HOLDER_081024_HPP
|
||||
|
||||
# include <luabind/detail/inheritance.hpp>
|
||||
# include <luabind/pointer_traits.hpp>
|
||||
# include <luabind/detail/class_rep.hpp> // TODO
|
||||
# include <luabind/get_pointer.hpp>
|
||||
# include <luabind/typeid.hpp>
|
||||
# include <boost/type_traits/is_polymorphic.hpp>
|
||||
# include <stdexcept>
|
||||
|
||||
namespace luabind {
|
||||
namespace detail {
|
||||
namespace luabind { namespace detail {
|
||||
|
||||
class instance_holder
|
||||
{
|
||||
public:
|
||||
instance_holder(bool pointee_const)
|
||||
: m_pointee_const(pointee_const)
|
||||
{}
|
||||
class instance_holder
|
||||
{
|
||||
public:
|
||||
instance_holder(class_rep* cls, bool pointee_const)
|
||||
: m_cls(cls)
|
||||
, m_pointee_const(pointee_const)
|
||||
{}
|
||||
|
||||
virtual ~instance_holder()
|
||||
{}
|
||||
virtual ~instance_holder()
|
||||
{}
|
||||
|
||||
virtual std::pair<void*, int> get(cast_graph const& casts, class_id target) const = 0;
|
||||
virtual void release() = 0;
|
||||
virtual std::pair<void*, int> get(class_id target) const = 0;
|
||||
|
||||
bool pointee_const() const
|
||||
{
|
||||
return m_pointee_const;
|
||||
}
|
||||
virtual void release() = 0;
|
||||
|
||||
private:
|
||||
bool m_pointee_const;
|
||||
};
|
||||
class_rep* get_class() const
|
||||
{
|
||||
return m_cls;
|
||||
}
|
||||
|
||||
template <class P, class Pointee = void const>
|
||||
class pointer_holder : public instance_holder
|
||||
{
|
||||
public:
|
||||
pointer_holder(P p, class_id dynamic_id, void* dynamic_ptr) :
|
||||
instance_holder(detail::is_pointer_to_const<P>()),
|
||||
p(std::move(p)), weak(0), dynamic_id(dynamic_id), dynamic_ptr(dynamic_ptr)
|
||||
{
|
||||
}
|
||||
bool pointee_const() const
|
||||
{
|
||||
return m_pointee_const;
|
||||
}
|
||||
|
||||
std::pair<void*, int> get(cast_graph const& casts, class_id target) const override
|
||||
{
|
||||
// if somebody wants the smart-ptr, he can get a reference to it
|
||||
if(target == registered_class<P>::id) return std::pair<void*, int>(&this->p, 0);
|
||||
private:
|
||||
class_rep* m_cls;
|
||||
bool m_pointee_const;
|
||||
};
|
||||
|
||||
void* naked_ptr = const_cast<void*>(static_cast<void const*>(weak ? weak : get_pointer(p)));
|
||||
if(!naked_ptr) return std::pair<void*, int>(nullptr, 0);
|
||||
namespace mpl = boost::mpl;
|
||||
|
||||
using pointee_type = typename std::remove_cv<typename std::remove_reference<decltype(*get_pointer(p))>::type>::type;
|
||||
inline mpl::false_ check_const_pointer(void*)
|
||||
{
|
||||
return mpl::false_();
|
||||
}
|
||||
|
||||
return casts.cast(naked_ptr,
|
||||
registered_class< pointee_type >::id,
|
||||
target, dynamic_id, dynamic_ptr);
|
||||
}
|
||||
inline mpl::true_ check_const_pointer(void const*)
|
||||
{
|
||||
return mpl::true_();
|
||||
}
|
||||
|
||||
explicit operator bool() const
|
||||
{
|
||||
return p ? true : false;
|
||||
}
|
||||
template <class T>
|
||||
void release_ownership(std::auto_ptr<T>& p)
|
||||
{
|
||||
p.release();
|
||||
}
|
||||
|
||||
void release() override
|
||||
{
|
||||
weak = const_cast<void*>(static_cast<void const*>(get_pointer(p)));
|
||||
release_ownership(p);
|
||||
}
|
||||
template <class P>
|
||||
void release_ownership(P const&)
|
||||
{
|
||||
throw std::runtime_error(
|
||||
"luabind: smart pointer does not allow ownership transfer");
|
||||
}
|
||||
|
||||
private:
|
||||
mutable P p;
|
||||
// weak will hold a possibly stale pointer to the object owned
|
||||
// by p once p has released it's owership. This is a workaround
|
||||
// to make adopt() work with virtual function wrapper classes.
|
||||
void* weak;
|
||||
class_id dynamic_id;
|
||||
void* dynamic_ptr;
|
||||
};
|
||||
template <class T>
|
||||
class_id static_class_id(T*)
|
||||
{
|
||||
return registered_class<T>::id;
|
||||
}
|
||||
|
||||
template <class ValueType>
|
||||
class value_holder :
|
||||
public instance_holder
|
||||
{
|
||||
public:
|
||||
// No need for dynamic_id / dynamic_ptr, since we always get the most derived type
|
||||
value_holder(lua_State* /*L*/, ValueType val)
|
||||
: instance_holder(false), val_(std::move(val))
|
||||
{}
|
||||
template <class P, class Pointee = void const>
|
||||
class pointer_holder : public instance_holder
|
||||
{
|
||||
public:
|
||||
pointer_holder(
|
||||
P p, class_id dynamic_id, void* dynamic_ptr, class_rep* cls
|
||||
)
|
||||
: instance_holder(cls, check_const_pointer(false ? get_pointer(p) : 0))
|
||||
, p(p)
|
||||
, weak(0)
|
||||
, dynamic_id(dynamic_id)
|
||||
, dynamic_ptr(dynamic_ptr)
|
||||
{}
|
||||
|
||||
explicit operator bool() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
std::pair<void*, int> get(class_id target) const
|
||||
{
|
||||
if (target == registered_class<P>::id)
|
||||
return std::pair<void*, int>(&this->p, 0);
|
||||
|
||||
std::pair<void*, int> get(cast_graph const& casts, class_id target) const override
|
||||
{
|
||||
const auto this_id = registered_class<ValueType>::id;
|
||||
void* const naked_ptr = const_cast<void*>((const void*)&val_);
|
||||
if(target == this_id) return std::pair<void*, int>(naked_ptr, 0);
|
||||
return casts.cast(naked_ptr, this_id, target, this_id, naked_ptr);
|
||||
}
|
||||
void* naked_ptr = const_cast<void*>(static_cast<void const*>(
|
||||
weak ? weak : get_pointer(p)));
|
||||
|
||||
void release() override
|
||||
{}
|
||||
if (!naked_ptr)
|
||||
return std::pair<void*, int>((void*)0, 0);
|
||||
|
||||
private:
|
||||
ValueType val_;
|
||||
};
|
||||
return get_class()->casts().cast(
|
||||
naked_ptr
|
||||
, static_class_id(false ? get_pointer(p) : 0)
|
||||
, target
|
||||
, dynamic_id
|
||||
, dynamic_ptr
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
Pointer types should automatically convert to reference types
|
||||
*/
|
||||
template <class ValueType>
|
||||
class pointer_like_holder :
|
||||
public instance_holder
|
||||
{
|
||||
public:
|
||||
// No need for dynamic_id / dynamic_ptr, since we always get the most derived type
|
||||
pointer_like_holder(lua_State* /*L*/, ValueType val, class_id dynamic_id, void* dynamic_ptr)
|
||||
:
|
||||
instance_holder(std::is_const< decltype(*get_pointer(val)) >::value),
|
||||
val_(std::move(val)),
|
||||
dynamic_id_(dynamic_id),
|
||||
dynamic_ptr_(dynamic_ptr)
|
||||
{
|
||||
}
|
||||
void release()
|
||||
{
|
||||
weak = const_cast<void*>(static_cast<void const*>(
|
||||
get_pointer(p)));
|
||||
release_ownership(p);
|
||||
}
|
||||
|
||||
explicit operator bool() const
|
||||
{
|
||||
return val_ ? true : false;
|
||||
}
|
||||
private:
|
||||
mutable P p;
|
||||
// weak will hold a possibly stale pointer to the object owned
|
||||
// by p once p has released it's owership. This is a workaround
|
||||
// to make adopt() work with virtual function wrapper classes.
|
||||
void* weak;
|
||||
class_id dynamic_id;
|
||||
void* dynamic_ptr;
|
||||
};
|
||||
|
||||
std::pair<void*, int> get(cast_graph const& casts, class_id target) const override
|
||||
{
|
||||
const auto value_id = registered_class<ValueType>::id;
|
||||
void* const naked_value_ptr = const_cast<void*>((const void*)&val_);
|
||||
if(target == value_id) return std::pair<void*, int>(naked_value_ptr, 0);
|
||||
// If we were to support automatic pointer conversion, this would be the place
|
||||
|
||||
using pointee_type = typename std::remove_cv<typename std::remove_reference<decltype(*get_pointer(val_))>::type >::type;
|
||||
const auto pointee_id = registered_class< pointee_type >::id;
|
||||
void* const naked_pointee_ptr = const_cast<void*>((const void*)get_pointer(val_));
|
||||
return casts.cast(naked_pointee_ptr, pointee_id, target, dynamic_id_, dynamic_ptr_);
|
||||
}
|
||||
|
||||
void release() override
|
||||
{}
|
||||
|
||||
private:
|
||||
ValueType val_;
|
||||
class_id dynamic_id_;
|
||||
void* dynamic_ptr_;
|
||||
// weak? must understand what the comment up there really means
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace luabind::detail
|
||||
}} // namespace luabind::detail
|
||||
|
||||
#endif // LUABIND_INSTANCE_HOLDER_081024_HPP
|
||||
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
// Copyright (c) 2004 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 IS_INDIRECT_CONST_040211_HPP
|
||||
#define IS_INDIRECT_CONST_040211_HPP
|
||||
|
||||
#include <luabind/detail/yes_no.hpp>
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
|
||||
namespace luabind {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class T>
|
||||
typename boost::is_const<T>::type
|
||||
is_indirect_const_check(T(*)(), int);
|
||||
|
||||
template<class T>
|
||||
typename boost::is_const<T>::type
|
||||
is_indirect_const_check(T*(*)(), long);
|
||||
|
||||
template<class T>
|
||||
typename boost::is_const<T>::type
|
||||
is_indirect_const_check(T&(*)(), long);
|
||||
|
||||
yes_t to_yes_no(boost::mpl::true_);
|
||||
no_t to_yes_no(boost::mpl::false_);
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// returns true for:
|
||||
// T = U* is_const<U>
|
||||
// T = U& is_const<U>
|
||||
// T = U is_const<U>
|
||||
template<class T>
|
||||
struct is_indirect_const
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(int, value = (
|
||||
sizeof(
|
||||
detail::to_yes_no(
|
||||
detail::is_indirect_const_check((T(*)())0, 0L)
|
||||
))
|
||||
== sizeof(detail::yes_t)
|
||||
));
|
||||
};
|
||||
|
||||
} // namespace luabind
|
||||
|
||||
#endif // IS_INDIRECT_CONST_040211_HPP
|
||||
|
||||
@@ -25,38 +25,36 @@
|
||||
|
||||
#include <luabind/config.hpp>
|
||||
|
||||
namespace luabind {
|
||||
namespace detail {
|
||||
namespace luabind { namespace detail
|
||||
{
|
||||
|
||||
#ifdef LUABIND_NOT_THREADSAFE
|
||||
LUABIND_API void not_threadsafe_defined_conflict();
|
||||
LUABIND_API void not_threadsafe_defined_conflict();
|
||||
#else
|
||||
LUABIND_API void not_threadsafe_not_defined_conflict();
|
||||
LUABIND_API void not_threadsafe_not_defined_conflict();
|
||||
#endif
|
||||
|
||||
#ifdef LUABIND_NO_ERROR_CHECKING
|
||||
LUABIND_API void no_error_checking_defined_conflict();
|
||||
LUABIND_API void no_error_checking_defined_conflict();
|
||||
#else
|
||||
LUABIND_API void no_error_checking_not_defined_conflict();
|
||||
LUABIND_API void no_error_checking_not_defined_conflict();
|
||||
#endif
|
||||
|
||||
inline void check_link_compatibility()
|
||||
{
|
||||
#ifdef LUABIND_NOT_THREADSAFE
|
||||
not_threadsafe_defined_conflict();
|
||||
#else
|
||||
not_threadsafe_not_defined_conflict();
|
||||
#endif
|
||||
|
||||
#ifdef LUABIND_NO_ERROR_CHECKING
|
||||
no_error_checking_defined_conflict();
|
||||
#else
|
||||
no_error_checking_not_defined_conflict();
|
||||
#endif
|
||||
}
|
||||
inline void check_link_compatibility()
|
||||
{
|
||||
#ifdef LUABIND_NOT_THREADSAFE
|
||||
not_threadsafe_defined_conflict();
|
||||
#else
|
||||
not_threadsafe_not_defined_conflict();
|
||||
#endif
|
||||
|
||||
#ifdef LUABIND_NO_ERROR_CHECKING
|
||||
no_error_checking_defined_conflict();
|
||||
#else
|
||||
no_error_checking_not_defined_conflict();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -5,167 +5,101 @@
|
||||
#ifndef LUABIND_DETAIL_MAKE_INSTANCE_090310_HPP
|
||||
# define LUABIND_DETAIL_MAKE_INSTANCE_090310_HPP
|
||||
|
||||
# include <boost/type_traits/is_polymorphic.hpp>
|
||||
# include <luabind/detail/inheritance.hpp>
|
||||
# include <luabind/detail/object_rep.hpp>
|
||||
|
||||
namespace luabind {
|
||||
namespace detail {
|
||||
namespace luabind { namespace detail {
|
||||
|
||||
template <class T>
|
||||
std::pair<class_id, void*> get_dynamic_class_aux(lua_State* L, T const* p, std::true_type)
|
||||
{
|
||||
lua_pushliteral(L, "__luabind_class_id_map");
|
||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
||||
class_id_map& class_ids = *static_cast<class_id_map*>(lua_touserdata(L, -1));
|
||||
lua_pop(L, 1);
|
||||
template <class T>
|
||||
std::pair<class_id, void*> get_dynamic_class_aux(
|
||||
lua_State* L, T const* p, mpl::true_)
|
||||
{
|
||||
lua_pushliteral(L, "__luabind_class_id_map");
|
||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
||||
|
||||
return std::make_pair(class_ids.get_local(typeid(*p)), dynamic_cast<void*>(const_cast<T*>(p)));
|
||||
}
|
||||
class_id_map& class_ids = *static_cast<class_id_map*>(
|
||||
lua_touserdata(L, -1));
|
||||
|
||||
template <class T>
|
||||
std::pair<class_id, void*> get_dynamic_class_aux(lua_State*, T const* p, std::false_type)
|
||||
{
|
||||
return std::make_pair(registered_class<T>::id, (void*)p);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
template <class T>
|
||||
std::pair<class_id, void*> get_dynamic_class(lua_State* L, T* p)
|
||||
{
|
||||
return get_dynamic_class_aux(L, p, std::is_polymorphic<T>());
|
||||
}
|
||||
return std::make_pair(
|
||||
class_ids.get_local(typeid(*p))
|
||||
, dynamic_cast<void*>(const_cast<T*>(p))
|
||||
);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
class_rep* get_pointee_class(class_map const& classes, T*)
|
||||
{
|
||||
return classes.get(registered_class<T>::id);
|
||||
}
|
||||
template <class T>
|
||||
std::pair<class_id, void*> get_dynamic_class_aux(
|
||||
lua_State*, T const* p, mpl::false_)
|
||||
{
|
||||
return std::make_pair(registered_class<T>::id, (void*)p);
|
||||
}
|
||||
|
||||
template <class P>
|
||||
class_rep* get_pointee_class(lua_State* L, P const& p, class_id dynamic_id)
|
||||
{
|
||||
lua_pushliteral(L, "__luabind_class_map");
|
||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
||||
template <class T>
|
||||
std::pair<class_id, void*> get_dynamic_class(lua_State* L, T* p)
|
||||
{
|
||||
return get_dynamic_class_aux(L, p, boost::is_polymorphic<T>());
|
||||
}
|
||||
|
||||
class_map const& classes = *static_cast<class_map*>(lua_touserdata(L, -1));
|
||||
template <class T>
|
||||
class_rep* get_pointee_class(class_map const& classes, T*)
|
||||
{
|
||||
return classes.get(registered_class<T>::id);
|
||||
}
|
||||
|
||||
lua_pop(L, 1);
|
||||
template <class P>
|
||||
class_rep* get_pointee_class(lua_State* L, P const& p, class_id dynamic_id)
|
||||
{
|
||||
lua_pushliteral(L, "__luabind_class_map");
|
||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
||||
|
||||
class_rep* cls = classes.get(dynamic_id);
|
||||
class_map const& classes = *static_cast<class_map*>(
|
||||
lua_touserdata(L, -1));
|
||||
|
||||
if(!cls) {
|
||||
cls = get_pointee_class(classes, get_pointer(p));
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
return cls;
|
||||
}
|
||||
class_rep* cls = classes.get(dynamic_id);
|
||||
|
||||
// Create an appropriate instance holder for the given pointer like object.
|
||||
template <class P>
|
||||
void make_pointer_instance(lua_State* L, P p)
|
||||
{
|
||||
std::pair<class_id, void*> dynamic = get_dynamic_class(L, get_pointer(p));
|
||||
if (!cls)
|
||||
cls = get_pointee_class(classes, get_pointer(p));
|
||||
|
||||
class_rep* cls = get_pointee_class(L, p, dynamic.first);
|
||||
return cls;
|
||||
}
|
||||
|
||||
if(!cls)
|
||||
{
|
||||
throw std::runtime_error("Trying to use unregistered class: " + std::string(typeid(P).name()));
|
||||
}
|
||||
// Create an appropriate instance holder for the given pointer like object.
|
||||
template <class P>
|
||||
void make_instance(lua_State* L, P p)
|
||||
{
|
||||
std::pair<class_id, void*> dynamic = get_dynamic_class(L, get_pointer(p));
|
||||
|
||||
object_rep* instance = push_new_instance(L, cls);
|
||||
class_rep* cls = get_pointee_class(L, p, dynamic.first);
|
||||
|
||||
using value_type = typename std::remove_reference<P>::type;
|
||||
using holder_type = pointer_holder<value_type>;
|
||||
if (!cls)
|
||||
{
|
||||
throw std::runtime_error("Trying to use unregistered class");
|
||||
}
|
||||
|
||||
void* storage = instance->allocate(sizeof(holder_type));
|
||||
object_rep* instance = push_new_instance(L, cls);
|
||||
|
||||
try
|
||||
{
|
||||
new (storage) holder_type(std::move(p), dynamic.first, dynamic.second);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
instance->deallocate(storage);
|
||||
lua_pop(L, 1);
|
||||
throw;
|
||||
}
|
||||
typedef pointer_holder<P> holder_type;
|
||||
|
||||
instance->set_instance(static_cast<holder_type*>(storage));
|
||||
}
|
||||
void* storage = instance->allocate(sizeof(holder_type));
|
||||
|
||||
try
|
||||
{
|
||||
new (storage) holder_type(p, dynamic.first, dynamic.second, cls);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
instance->deallocate(storage);
|
||||
lua_pop(L, 1);
|
||||
throw;
|
||||
}
|
||||
|
||||
template< typename ValueType >
|
||||
void make_value_instance(lua_State* L, ValueType&& val, std::true_type /* is smart ptr */)
|
||||
{
|
||||
if(get_pointer(val)) {
|
||||
std::pair<class_id, void*> dynamic = get_dynamic_class(L, get_pointer(val));
|
||||
class_rep* cls = get_pointee_class(L, val, dynamic.first);
|
||||
instance->set_instance(static_cast<holder_type*>(storage));
|
||||
}
|
||||
|
||||
using pointee_type = decltype(*get_pointer(val));
|
||||
|
||||
if(!cls) {
|
||||
throw std::runtime_error("Trying to use unregistered class: " + std::string(typeid(pointee_type).name()));
|
||||
}
|
||||
|
||||
object_rep* instance = push_new_instance(L, cls);
|
||||
|
||||
using value_type = typename std::remove_reference<ValueType>::type;
|
||||
using holder_type = pointer_like_holder<value_type>;
|
||||
|
||||
void* storage = instance->allocate(sizeof(holder_type));
|
||||
|
||||
try {
|
||||
new (storage) holder_type(L, std::forward<ValueType>(val), dynamic.first, dynamic.second);
|
||||
}
|
||||
catch(...) {
|
||||
instance->deallocate(storage);
|
||||
lua_pop(L, 1);
|
||||
throw;
|
||||
}
|
||||
|
||||
instance->set_instance(static_cast<holder_type*>(storage));
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
}
|
||||
|
||||
template< typename ValueType >
|
||||
void make_value_instance(lua_State* L, ValueType&& val, std::false_type /* smart ptr */)
|
||||
{
|
||||
const auto value_type_id = detail::registered_class<ValueType>::id;
|
||||
class_rep* cls = get_pointee_class(L, &val, value_type_id);
|
||||
|
||||
if(!cls) {
|
||||
throw std::runtime_error("Trying to use unregistered class: " + std::string(typeid(ValueType).name()));
|
||||
}
|
||||
|
||||
object_rep* instance = push_new_instance(L, cls);
|
||||
|
||||
using value_type = typename std::remove_reference<ValueType>::type;
|
||||
using holder_type = value_holder<value_type>;
|
||||
|
||||
void* storage = instance->allocate(sizeof(holder_type));
|
||||
|
||||
try {
|
||||
new (storage) holder_type(L, std::forward<ValueType>(val));
|
||||
}
|
||||
catch(...) {
|
||||
instance->deallocate(storage);
|
||||
lua_pop(L, 1);
|
||||
throw;
|
||||
}
|
||||
|
||||
instance->set_instance(static_cast<holder_type*>(storage));
|
||||
}
|
||||
|
||||
template< typename ValueType >
|
||||
void make_value_instance(lua_State* L, ValueType&& val)
|
||||
{
|
||||
make_value_instance(L, std::forward<ValueType>(val), has_get_pointer<ValueType>());
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace luabind
|
||||
}} // namespace luabind::detail
|
||||
|
||||
#endif // LUABIND_DETAIL_MAKE_INSTANCE_090310_HPP
|
||||
|
||||
|
||||
@@ -1,581 +0,0 @@
|
||||
// Copyright Michael Steinberg 2013. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef LUABIND_META_HPP_INCLUDED
|
||||
#define LUABIND_META_HPP_INCLUDED
|
||||
|
||||
#include <tuple>
|
||||
|
||||
namespace luabind {
|
||||
namespace meta {
|
||||
|
||||
struct type_list_tag {};
|
||||
struct index_list_tag {};
|
||||
|
||||
/*
|
||||
Index list and type list share pretty common patterns... is there a way to unify them?
|
||||
*/
|
||||
|
||||
template< unsigned int >
|
||||
struct count
|
||||
{};
|
||||
|
||||
template< unsigned int >
|
||||
struct index
|
||||
{};
|
||||
|
||||
template< typename Type >
|
||||
struct type
|
||||
{};
|
||||
|
||||
// Use this to unpack a parameter pack into a list of T's
|
||||
template< typename T, typename DontCare >
|
||||
struct unpack_helper
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
struct init_order {
|
||||
init_order(std::initializer_list<int>) {}
|
||||
};
|
||||
|
||||
// common operators
|
||||
template< typename T >
|
||||
struct size;
|
||||
|
||||
template< typename T, unsigned int Index > // Specializations so index lists can use the same syntax
|
||||
struct get;
|
||||
|
||||
template< typename... Lists >
|
||||
struct join;
|
||||
|
||||
template< typename List1, typename List2, typename... Lists >
|
||||
struct join< List1, List2, Lists... > {
|
||||
// Could try to join on both sides
|
||||
using type = typename join< typename join< List1, List2 >::type, Lists... >::type;
|
||||
};
|
||||
|
||||
// convenience
|
||||
template< typename T >
|
||||
struct front : public get< T, 0 >
|
||||
{
|
||||
};
|
||||
|
||||
template< typename List, typename T >
|
||||
struct push_front;
|
||||
|
||||
template< typename List, typename T >
|
||||
struct push_back;
|
||||
|
||||
template< typename T >
|
||||
struct pop_front;
|
||||
|
||||
template< typename T >
|
||||
struct pop_back;
|
||||
|
||||
template< typename List, unsigned int Index, typename T >
|
||||
struct replace;
|
||||
|
||||
template< typename List, unsigned int Index, template< typename > class T >
|
||||
struct enwrap;
|
||||
|
||||
template< typename List, template< typename > class T >
|
||||
struct enwrap_all;
|
||||
|
||||
template< typename List, unsigned int Index, template< typename > class T >
|
||||
struct transform;
|
||||
|
||||
template< typename List, unsigned int Index, template< typename > class Function >
|
||||
using transform_t = typename transform< List, Index, Function >::type;
|
||||
|
||||
template< typename List, template< typename > class Function >
|
||||
struct transform_all;
|
||||
|
||||
template< typename List, template< typename > class Function >
|
||||
using transform_all_t = typename transform_all< List, Function >::type;
|
||||
|
||||
|
||||
template< typename T, unsigned int start, unsigned int end >
|
||||
struct sub_range;
|
||||
|
||||
/*
|
||||
aliases
|
||||
*/
|
||||
template< typename T >
|
||||
using pop_front_t = typename pop_front<T>::type;
|
||||
|
||||
template< typename T1, typename... Types >
|
||||
using join_t = typename join< T1, Types... >::type;
|
||||
|
||||
template< typename T, unsigned int start, unsigned int end >
|
||||
using sub_range_t = typename sub_range< T, start, end >::type;
|
||||
|
||||
template< typename T, unsigned int index >
|
||||
using get_t = typename get< T, index >::type;
|
||||
|
||||
|
||||
// Used as terminator on type and index lists
|
||||
struct null_type {};
|
||||
|
||||
template< typename... Types >
|
||||
struct type_list : public type_list_tag
|
||||
{
|
||||
template< unsigned int Index >
|
||||
using at = typename get<type_list, Index>::type;
|
||||
};
|
||||
|
||||
template< typename... Types1, typename... Types2 >
|
||||
type_list<Types1..., Types2...> operator|(const type_list<Types1...>&, const type_list<Types2...>&) {
|
||||
return type_list<Types1..., Types2...>();
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
struct is_typelist : public std::false_type
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template< typename... Types >
|
||||
struct is_typelist< type_list< Types... > > : public std::true_type
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
/*
|
||||
Find type
|
||||
*/
|
||||
|
||||
template< typename TypeList, typename Type >
|
||||
struct contains;
|
||||
|
||||
template< typename Type0, typename... Types, typename Type >
|
||||
struct contains< type_list<Type0, Types...>, Type >
|
||||
: std::conditional< std::is_same<Type0, Type>::value, std::true_type, contains< type_list<Types...>, Type > >::type
|
||||
{
|
||||
};
|
||||
|
||||
template< typename Type >
|
||||
struct contains< type_list< >, Type >
|
||||
: std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
/*
|
||||
size
|
||||
*/
|
||||
|
||||
template< >
|
||||
struct size< type_list< > > {
|
||||
enum { value = 0 };
|
||||
};
|
||||
|
||||
template< typename Type0, typename... Types >
|
||||
struct size< type_list< Type0, Types... > > {
|
||||
enum { value = 1 + size< type_list<Types...> >::value };
|
||||
};
|
||||
|
||||
|
||||
template< typename... Types, typename Type >
|
||||
struct push_front< type_list<Types...>, Type >
|
||||
{
|
||||
using type = type_list< Type, Types... >;
|
||||
};
|
||||
|
||||
template< typename... Types, typename Type >
|
||||
struct push_back< type_list<Types...>, Type >
|
||||
{
|
||||
using type = type_list< Types..., Type >;
|
||||
};
|
||||
|
||||
/*
|
||||
pop_front
|
||||
*/
|
||||
|
||||
template< typename Type0, typename... Types >
|
||||
struct pop_front< type_list< Type0, Types... > >
|
||||
{
|
||||
using type = type_list< Types... >;
|
||||
};
|
||||
|
||||
template< >
|
||||
struct pop_front< type_list< > >
|
||||
{
|
||||
using type = type_list< >;
|
||||
};
|
||||
|
||||
/*
|
||||
Index access to type list
|
||||
*/
|
||||
template< typename Element0, typename... Elements, unsigned int Index >
|
||||
struct get< type_list<Element0, Elements...>, Index > {
|
||||
using type = typename get< type_list<Elements...>, Index - 1 >::type;
|
||||
};
|
||||
|
||||
template< typename Element0, typename... Elements >
|
||||
struct get< type_list<Element0, Elements...>, 0 >
|
||||
{
|
||||
using type = Element0;
|
||||
};
|
||||
|
||||
template< unsigned int Index >
|
||||
struct get< type_list< >, Index >
|
||||
{
|
||||
static_assert(size< type_list< int > >::value == 1, "Bad Index");
|
||||
};
|
||||
|
||||
/*
|
||||
Join Type Lists
|
||||
*/
|
||||
template< typename... Types1, typename... Types2 >
|
||||
struct join< type_list< Types1... >, type_list< Types2... > >
|
||||
{
|
||||
using type = type_list< Types1..., Types2... >;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
template< typename HeadList, typename TailList, typename Type, unsigned int Index >
|
||||
struct replace_helper;
|
||||
|
||||
template< typename... HeadTypes, typename CurrentType, typename... TailTypes, typename Type, unsigned int Index >
|
||||
struct replace_helper< type_list< HeadTypes... >, type_list< CurrentType, TailTypes... >, Type, Index> {
|
||||
using type = typename replace_helper< type_list< HeadTypes..., CurrentType >, type_list<TailTypes...>, Type, Index - 1 >::type;
|
||||
};
|
||||
|
||||
template< typename... HeadTypes, typename CurrentType, typename... TailTypes, typename Type >
|
||||
struct replace_helper< type_list< HeadTypes... >, type_list< CurrentType, TailTypes... >, Type, 0 > {
|
||||
using type = type_list< HeadTypes..., Type, TailTypes... >;
|
||||
};
|
||||
}
|
||||
|
||||
template< typename... Types, unsigned int Index, typename Type >
|
||||
struct replace< type_list< Types... >, Index, Type >
|
||||
{
|
||||
using TypeList = type_list< Types... >;
|
||||
|
||||
using type = join_t<
|
||||
sub_range_t< TypeList, 0, Index >,
|
||||
meta::type_list<Type>,
|
||||
sub_range_t< TypeList, Index + 1, sizeof...(Types) >
|
||||
>;
|
||||
};
|
||||
|
||||
/*
|
||||
Enwrap all elements of a type list in an template
|
||||
*/
|
||||
template< typename... Types, unsigned int Index, template< typename > class Enwrapper >
|
||||
struct enwrap< type_list< Types... >, Index, Enwrapper > {
|
||||
using type = join_t<
|
||||
sub_range_t< type_list<Types...>, 0, Index >,
|
||||
Enwrapper< get_t< type_list<Types...>, Index> >,
|
||||
sub_range_t< type_list<Types...>, Index + 1, sizeof...(Types) >
|
||||
>;
|
||||
};
|
||||
|
||||
template< typename... Types, template< typename > class Enwrapper >
|
||||
struct enwrap_all< type_list< Types... >, Enwrapper >
|
||||
{
|
||||
using type = type_list< Enwrapper< Types >... >;
|
||||
};
|
||||
|
||||
/*
|
||||
Transform a certain element of a type list
|
||||
*/
|
||||
template< typename T, unsigned int Index, template< typename > class Function >
|
||||
struct transform;
|
||||
|
||||
template< typename... Types, unsigned int Index, template< typename > class Function >
|
||||
struct transform< type_list< Types... >, Index, Function > {
|
||||
using type = join_t<
|
||||
sub_range_t< type_list<Types...>, 0, Index >,
|
||||
typename Function< get_t< type_list<Types...>, Index> >::type,
|
||||
sub_range_t< type_list<Types...>, Index + 1, sizeof...(Types) >
|
||||
>;
|
||||
};
|
||||
|
||||
/*
|
||||
Transform all elements of a type list
|
||||
*/
|
||||
template< typename... Types, template< typename > class Function >
|
||||
struct transform_all< type_list< Types... >, Function > {
|
||||
using type = type_list< typename Function<Types>::type... >;
|
||||
};
|
||||
|
||||
/*
|
||||
Tuple from type list
|
||||
*/
|
||||
template< class TypeList >
|
||||
struct make_tuple;
|
||||
|
||||
template< typename... Types >
|
||||
struct make_tuple< type_list< Types... > >
|
||||
{
|
||||
using type = std::tuple< Types... >;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Type selection
|
||||
*/
|
||||
|
||||
template< typename ConvertibleToTrueFalse, typename Result >
|
||||
struct case_ : public ConvertibleToTrueFalse {
|
||||
using type = Result;
|
||||
};
|
||||
|
||||
template< typename Result >
|
||||
struct default_ {
|
||||
using type = Result;
|
||||
};
|
||||
|
||||
|
||||
template< typename Case, typename... CaseList >
|
||||
struct select_
|
||||
{
|
||||
using type = typename std::conditional<
|
||||
std::is_convertible<Case, std::true_type>::value,
|
||||
typename Case::type,
|
||||
typename select_<CaseList...>::type
|
||||
>::type;
|
||||
};
|
||||
|
||||
template< typename Case >
|
||||
struct select_< Case >
|
||||
{
|
||||
using type = typename std::conditional<
|
||||
std::is_convertible<Case, std::true_type>::value,
|
||||
typename Case::type,
|
||||
null_type
|
||||
>::type;
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
struct select_< default_<T> > {
|
||||
using type = typename default_<T>::type;
|
||||
};
|
||||
|
||||
/*
|
||||
Create index lists to expand on type_lists
|
||||
*/
|
||||
|
||||
template< unsigned int... Indices >
|
||||
struct index_list : public index_list_tag
|
||||
{
|
||||
};
|
||||
|
||||
/*
|
||||
Index index list
|
||||
*/
|
||||
|
||||
namespace detail {
|
||||
|
||||
template< unsigned int Index, unsigned int Value0, unsigned int... Values >
|
||||
struct get_iterate {
|
||||
static const unsigned int value = get_iterate< Index - 1, Values... >::value;
|
||||
};
|
||||
|
||||
template< unsigned int Value0, unsigned int... Values >
|
||||
struct get_iterate< 0, Value0, Values... > {
|
||||
static const unsigned int value = Value0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template< unsigned int... Values, unsigned int Index >
|
||||
struct get< index_list< Values... >, Index >
|
||||
{
|
||||
static_assert(sizeof...(Values) > Index, "Bad Index");
|
||||
static const unsigned int value = detail::get_iterate< Index, Values... >::value;
|
||||
};
|
||||
|
||||
/*
|
||||
Index list size
|
||||
*/
|
||||
|
||||
template< unsigned int... Values >
|
||||
struct size< index_list< Values... > > {
|
||||
static const unsigned int value = sizeof...(Values);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Index list push front
|
||||
*/
|
||||
template< unsigned int... Indices, unsigned int Index >
|
||||
struct push_front< index_list< Indices... >, index<Index> >
|
||||
{
|
||||
using type = index_list< Index, Indices... >;
|
||||
};
|
||||
|
||||
/*
|
||||
Index list push back
|
||||
*/
|
||||
template< unsigned int... Indices, unsigned int Index >
|
||||
struct push_back< index_list< Indices... >, index<Index> >
|
||||
{
|
||||
using type = index_list< Indices..., Index >;
|
||||
};
|
||||
|
||||
/*
|
||||
Index list pop_front
|
||||
*/
|
||||
template< unsigned int Index0, unsigned int... Indices >
|
||||
struct pop_front< index_list< Index0, Indices... > > {
|
||||
using type = index_list< Indices... >;
|
||||
};
|
||||
|
||||
template< >
|
||||
struct pop_front< index_list< > > {
|
||||
using type = index_list< >;
|
||||
};
|
||||
|
||||
/*
|
||||
Index list range creation
|
||||
*/
|
||||
namespace detail {
|
||||
|
||||
template< unsigned int curr, unsigned int end, unsigned int... Indices >
|
||||
struct make_index_range :
|
||||
public make_index_range< curr + 1, end, Indices..., curr >
|
||||
{
|
||||
};
|
||||
|
||||
template< unsigned int end, unsigned int... Indices >
|
||||
struct make_index_range< end, end, Indices... >
|
||||
{
|
||||
using type = index_list< Indices... >;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
make_index_range< start, end >
|
||||
Creates the index list list of range [start, end)
|
||||
*/
|
||||
template< unsigned int start, unsigned int end >
|
||||
struct make_index_range {
|
||||
static_assert(end >= start, "end must be greater than or equal to start");
|
||||
using type = typename detail::make_index_range< start, end >::type;
|
||||
};
|
||||
|
||||
template< unsigned int start, unsigned int end >
|
||||
using index_range = typename make_index_range<start, end>::type;
|
||||
|
||||
namespace detail {
|
||||
// These implementation are not really efficient...
|
||||
template< typename SourceList, typename IndexList >
|
||||
struct sub_range_index;
|
||||
|
||||
template< typename SourceList, unsigned int... Indices >
|
||||
struct sub_range_index< SourceList, index_list< Indices... > > {
|
||||
using type = index_list< get< SourceList, Indices >::value... >;
|
||||
};
|
||||
|
||||
template< typename SourceList, typename IndexList >
|
||||
struct sub_range_type;
|
||||
|
||||
template< typename SourceList, unsigned int... Indices >
|
||||
struct sub_range_type< SourceList, index_list< Indices... > > {
|
||||
using type = type_list< typename get< SourceList, Indices >::type... >;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Index list sub_range [start, end)
|
||||
*/
|
||||
template< unsigned int start, unsigned int end, unsigned int... Indices >
|
||||
struct sub_range< index_list<Indices...>, start, end >
|
||||
{
|
||||
static_assert(end >= start, "end must be greater or equal to start");
|
||||
using type = typename detail::sub_range_index< index_list<Indices...>, typename make_index_range<start, end>::type >::type;
|
||||
};
|
||||
|
||||
/*
|
||||
Type list sub_range [start, end)
|
||||
*/
|
||||
template< unsigned int start, unsigned int end, typename... Types >
|
||||
struct sub_range< type_list<Types...>, start, end >
|
||||
{
|
||||
static_assert(end >= start, "end must be greater or equal to start");
|
||||
using type = typename detail::sub_range_type< type_list<Types...>, typename make_index_range<start, end>::type >::type;
|
||||
};
|
||||
|
||||
/*
|
||||
Index list sum
|
||||
*/
|
||||
|
||||
namespace detail {
|
||||
|
||||
template< typename T, T... Values >
|
||||
struct sum_values;
|
||||
|
||||
template< typename T, T Value0, T... Values >
|
||||
struct sum_values< T, Value0, Values... > {
|
||||
static const T value = Value0 + sum_values< T, Values... >::value;
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
struct sum_values< T >
|
||||
{
|
||||
static const T value = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
struct sum;
|
||||
|
||||
template< unsigned int... Args >
|
||||
struct sum< index_list<Args...> >
|
||||
{
|
||||
static const unsigned int value = detail::sum_values<unsigned int, Args...>::value;
|
||||
};
|
||||
|
||||
/*
|
||||
and_ or_
|
||||
*/
|
||||
|
||||
template< typename... ConvertiblesToTrueFalse >
|
||||
struct and_;
|
||||
|
||||
template< typename Convertible0, typename... Convertibles >
|
||||
struct and_< Convertible0, Convertibles... >
|
||||
: std::conditional <
|
||||
std::is_convertible< Convertible0, std::true_type >::value,
|
||||
and_< Convertibles... >,
|
||||
std::false_type > ::type
|
||||
{
|
||||
};
|
||||
|
||||
template< >
|
||||
struct and_< >
|
||||
: std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
template< typename... ConvertiblesToTrueFalse >
|
||||
struct or_;
|
||||
|
||||
template< typename Convertible0, typename... Convertibles >
|
||||
struct or_< Convertible0, Convertibles... >
|
||||
: std::conditional <
|
||||
std::is_convertible< Convertible0, std::true_type >::value,
|
||||
std::true_type,
|
||||
or_< Convertibles... >
|
||||
> ::type
|
||||
{
|
||||
};
|
||||
|
||||
template< >
|
||||
struct or_< >
|
||||
: std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
// Copyright (c) 2005 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 MOST_DERIVED_051018_HPP
|
||||
# define MOST_DERIVED_051018_HPP
|
||||
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/type_traits/is_base_and_derived.hpp>
|
||||
|
||||
namespace luabind { namespace detail {
|
||||
|
||||
template<class Class, class WrappedClass>
|
||||
struct most_derived
|
||||
{
|
||||
typedef typename boost::mpl::if_<
|
||||
boost::is_base_and_derived<Class, WrappedClass>
|
||||
, WrappedClass
|
||||
, Class
|
||||
>::type type;
|
||||
};
|
||||
|
||||
}} // namespace luabind::detail
|
||||
|
||||
#endif // MOST_DERIVED_051018_HPP
|
||||
|
||||
@@ -1,386 +0,0 @@
|
||||
// Copyright (c) 2005 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_OBJECT_050419_HPP
|
||||
#define LUABIND_OBJECT_050419_HPP
|
||||
|
||||
#include <tuple>
|
||||
|
||||
#include <luabind/nil.hpp>
|
||||
#include <luabind/handle.hpp>
|
||||
#include <luabind/from_stack.hpp>
|
||||
#include <luabind/detail/stack_utils.hpp>
|
||||
#include <luabind/detail/push_to_lua.hpp>
|
||||
#include <luabind/typeid.hpp>
|
||||
#include <luabind/detail/crtp_iterator.hpp>
|
||||
#include <luabind/lua_proxy_interface.hpp>
|
||||
#include <luabind/lua_index_proxy.hpp>
|
||||
#include <luabind/lua_iterator_proxy.hpp>
|
||||
#include <luabind/detail/class_rep.hpp>
|
||||
|
||||
#if LUA_VERSION_NUM < 502
|
||||
# define lua_pushglobaltable(L) lua_pushvalue(L, LUA_GLOBALSINDEX)
|
||||
#endif
|
||||
|
||||
namespace luabind {
|
||||
namespace adl {
|
||||
|
||||
// An object holds a reference to a Lua value residing
|
||||
// in the registry.
|
||||
class object :
|
||||
public lua_proxy_interface<object>
|
||||
{
|
||||
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&& value)
|
||||
{
|
||||
detail::push_to_lua(interpreter, std::forward<T>(value));
|
||||
detail::stack_pop pop(interpreter, 1);
|
||||
handle(interpreter, -1).swap(m_handle);
|
||||
}
|
||||
|
||||
template<class T, class Policies>
|
||||
object(lua_State* interpreter, T&& value, Policies const&)
|
||||
{
|
||||
detail::push_to_lua<1, Policies>(interpreter, std::forward<T>(value));
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
} // namespace adl
|
||||
|
||||
using adl::object;
|
||||
|
||||
template<>
|
||||
struct lua_proxy_traits<object>
|
||||
{
|
||||
using is_specialized = std::true_type;
|
||||
|
||||
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 R, typename PolicyList = no_policies, typename... Args>
|
||||
R call_function(luabind::object const& obj, Args&&... args)
|
||||
{
|
||||
obj.push(obj.interpreter());
|
||||
return call_pushed_function<R, PolicyList>(obj.interpreter(), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<class R, typename PolicyList = no_policies, typename... Args>
|
||||
R resume_function(luabind::object const& obj, Args&&... args)
|
||||
{
|
||||
obj.push(obj.interpreter());
|
||||
return resume_pushed_function<R, PolicyList>(obj.interpreter(), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// declared in luabind/lua_index_proxy.hpp
|
||||
template<typename Next>
|
||||
adl::index_proxy<Next>::operator object()
|
||||
{
|
||||
detail::stack_pop pop(m_interpreter, 1);
|
||||
push(m_interpreter);
|
||||
return object(from_stack(m_interpreter, -1));
|
||||
}
|
||||
|
||||
// declared in luabind/lua_proxy_interface.hpp
|
||||
template<typename ProxyType>
|
||||
template<typename PolicyList, typename... Args>
|
||||
object adl::lua_proxy_interface<ProxyType>::call(Args&&... args)
|
||||
{
|
||||
return call_function<object, PolicyList>(derived(), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// declared in luabind/lua_proxy_interface.hpp
|
||||
template<typename ProxyType>
|
||||
template<typename... Args>
|
||||
object adl::lua_proxy_interface<ProxyType>::operator()(Args&&... args)
|
||||
{
|
||||
return call<no_policies>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// declared in luabind/lua_iterator_proxy.hpp
|
||||
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));
|
||||
}
|
||||
|
||||
// declared in luabind/lua_iterator_proxy.hpp
|
||||
template<class AccessPolicy>
|
||||
object detail::basic_iterator<AccessPolicy>::key() const
|
||||
{
|
||||
return object(m_key);
|
||||
}
|
||||
|
||||
namespace adl {
|
||||
// Simple value_wrapper adaptor with the sole purpose of helping with
|
||||
// overload resolution. Use this as a function parameter type instead
|
||||
// of "object" or "argument" to restrict the parameter to Lua tables.
|
||||
template <class Base = object>
|
||||
struct table : Base
|
||||
{
|
||||
table(from_stack const& stack_reference)
|
||||
: Base(stack_reference)
|
||||
{}
|
||||
};
|
||||
|
||||
} // namespace adl
|
||||
|
||||
using adl::table;
|
||||
|
||||
template <class Base>
|
||||
struct lua_proxy_traits<adl::table<Base> >
|
||||
: lua_proxy_traits<Base>
|
||||
{
|
||||
static bool check(lua_State* L, int idx)
|
||||
{
|
||||
return lua_proxy_traits<Base>::check(L, idx) &&
|
||||
lua_istable(L, idx);
|
||||
}
|
||||
};
|
||||
|
||||
inline object newtable(lua_State* interpreter)
|
||||
{
|
||||
lua_newtable(interpreter);
|
||||
detail::stack_pop pop(interpreter, 1);
|
||||
return object(from_stack(interpreter, -1));
|
||||
}
|
||||
|
||||
// this could be optimized by returning a proxy
|
||||
inline object globals(lua_State* interpreter)
|
||||
{
|
||||
lua_pushglobaltable(interpreter);
|
||||
detail::stack_pop pop(interpreter, 1);
|
||||
return object(from_stack(interpreter, -1));
|
||||
}
|
||||
|
||||
// this could be optimized by returning a proxy
|
||||
inline object registry(lua_State* interpreter)
|
||||
{
|
||||
lua_pushvalue(interpreter, LUA_REGISTRYINDEX);
|
||||
detail::stack_pop pop(interpreter, 1);
|
||||
return object(from_stack(interpreter, -1));
|
||||
}
|
||||
|
||||
template<class ValueWrapper, class K>
|
||||
inline object gettable(ValueWrapper const& table, K&& key)
|
||||
{
|
||||
lua_State* interpreter = lua_proxy_traits<ValueWrapper>::interpreter(table);
|
||||
|
||||
lua_proxy_traits<ValueWrapper>::unwrap(interpreter, table);
|
||||
detail::stack_pop pop(interpreter, 2);
|
||||
detail::push_to_lua(interpreter, std::forward<K>(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&& key, T&& value)
|
||||
{
|
||||
lua_State* interpreter = lua_proxy_traits<ValueWrapper>::interpreter(table);
|
||||
|
||||
// TODO: Exception safe?
|
||||
|
||||
lua_proxy_traits<ValueWrapper>::unwrap(interpreter, table);
|
||||
detail::stack_pop pop(interpreter, 1);
|
||||
detail::push_to_lua(interpreter, std::forward<K>(key));
|
||||
detail::push_to_lua(interpreter, std::forward<T>(value));
|
||||
lua_settable(interpreter, -3);
|
||||
}
|
||||
|
||||
template<class ValueWrapper, class K>
|
||||
inline object rawget(ValueWrapper const& table, K&& key)
|
||||
{
|
||||
lua_State* interpreter = lua_proxy_traits<ValueWrapper>::interpreter(
|
||||
table
|
||||
);
|
||||
|
||||
lua_proxy_traits<ValueWrapper>::unwrap(interpreter, table);
|
||||
detail::stack_pop pop(interpreter, 2);
|
||||
detail::push_to_lua(interpreter, std::forward<K>(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&& key, T&& value)
|
||||
{
|
||||
lua_State* interpreter = lua_proxy_traits<ValueWrapper>::interpreter(
|
||||
table
|
||||
);
|
||||
|
||||
// TODO: Exception safe?
|
||||
|
||||
lua_proxy_traits<ValueWrapper>::unwrap(interpreter, table);
|
||||
detail::stack_pop pop(interpreter, 1);
|
||||
detail::push_to_lua(interpreter, std::forward<K>(key));
|
||||
detail::push_to_lua(interpreter, std::forward<T>(value));
|
||||
lua_rawset(interpreter, -3);
|
||||
}
|
||||
|
||||
template<class ValueWrapper>
|
||||
inline int type(ValueWrapper const& value)
|
||||
{
|
||||
lua_State* interpreter = lua_proxy_traits<ValueWrapper>::interpreter(value);
|
||||
|
||||
lua_proxy_traits<ValueWrapper>::unwrap(interpreter, value);
|
||||
detail::stack_pop pop(interpreter, 1);
|
||||
return lua_type(interpreter, -1);
|
||||
}
|
||||
|
||||
template <class ValueWrapper>
|
||||
inline object getmetatable(ValueWrapper const& obj)
|
||||
{
|
||||
lua_State* interpreter = lua_proxy_traits<ValueWrapper>::interpreter(obj);
|
||||
lua_proxy_traits<ValueWrapper>::unwrap(interpreter, obj);
|
||||
detail::stack_pop pop(interpreter, 2);
|
||||
lua_getmetatable(interpreter, -1);
|
||||
return object(from_stack(interpreter, -1));
|
||||
}
|
||||
|
||||
template <class ValueWrapper1, class ValueWrapper2>
|
||||
inline void setmetatable(ValueWrapper1 const& obj, ValueWrapper2 const& metatable)
|
||||
{
|
||||
lua_State* interpreter = lua_proxy_traits<ValueWrapper1>::interpreter(obj);
|
||||
lua_proxy_traits<ValueWrapper1>::unwrap(interpreter, obj);
|
||||
detail::stack_pop pop(interpreter, 1);
|
||||
lua_proxy_traits<ValueWrapper2>::unwrap(interpreter, metatable);
|
||||
lua_setmetatable(interpreter, -2);
|
||||
}
|
||||
|
||||
template <class ValueWrapper>
|
||||
inline std::tuple<const char*, object> getupvalue(ValueWrapper const& value, int index)
|
||||
{
|
||||
lua_State* interpreter = lua_proxy_traits<ValueWrapper>::interpreter(value);
|
||||
lua_proxy_traits<ValueWrapper>::unwrap(interpreter, value);
|
||||
detail::stack_pop pop(interpreter, 2);
|
||||
const char* name = lua_getupvalue(interpreter, -1, index);
|
||||
return std::make_tuple(name, object(from_stack(interpreter, -1)));
|
||||
}
|
||||
|
||||
template <class ValueWrapper1, class ValueWrapper2>
|
||||
inline void setupvalue(ValueWrapper1 const& function, int index, ValueWrapper2 const& value)
|
||||
{
|
||||
lua_State* interpreter = lua_proxy_traits<ValueWrapper1>::interpreter(function);
|
||||
|
||||
lua_proxy_traits<ValueWrapper1>::unwrap(interpreter, function);
|
||||
detail::stack_pop pop(interpreter, 1);
|
||||
lua_proxy_traits<ValueWrapper2>::unwrap(interpreter, value);
|
||||
lua_setupvalue(interpreter, -2, index);
|
||||
}
|
||||
|
||||
template <class GetValueWrapper>
|
||||
object property(GetValueWrapper const& get)
|
||||
{
|
||||
lua_State* interpreter = lua_proxy_traits<GetValueWrapper>::interpreter(get);
|
||||
lua_proxy_traits<GetValueWrapper>::unwrap(interpreter, get);
|
||||
lua_pushnil(interpreter);
|
||||
lua_pushcclosure(interpreter, &detail::property_tag, 2);
|
||||
detail::stack_pop pop(interpreter, 1);
|
||||
return object(from_stack(interpreter, -1));
|
||||
}
|
||||
|
||||
template <class GetValueWrapper, class SetValueWrapper>
|
||||
object property(GetValueWrapper const& get, SetValueWrapper const& set)
|
||||
{
|
||||
lua_State* interpreter = lua_proxy_traits<GetValueWrapper>::interpreter(get);
|
||||
lua_proxy_traits<GetValueWrapper>::unwrap(interpreter, get);
|
||||
lua_proxy_traits<SetValueWrapper>::unwrap(interpreter, set);
|
||||
lua_pushcclosure(interpreter, &detail::property_tag, 2);
|
||||
detail::stack_pop pop(interpreter, 1);
|
||||
return object(from_stack(interpreter, -1));
|
||||
}
|
||||
|
||||
} // namespace luabind
|
||||
|
||||
#if LUA_VERSION_NUM < 502
|
||||
#undef lua_pushglobaltable
|
||||
#endif
|
||||
|
||||
#include <luabind/detail/conversion_policies/conversion_policies.hpp>
|
||||
|
||||
#endif // LUABIND_OBJECT_050419_HPP
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
// Copyright (c) 2005 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.
|
||||
|
||||
#if !BOOST_PP_IS_ITERATING
|
||||
# error Do not include object_call.hpp directly!
|
||||
#endif
|
||||
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/facilities/intercept.hpp>
|
||||
|
||||
#define N BOOST_PP_ITERATION()
|
||||
|
||||
template<BOOST_PP_ENUM_PARAMS(N, class A)>
|
||||
call_proxy<
|
||||
Derived
|
||||
, boost::tuples::tuple<
|
||||
BOOST_PP_ENUM_BINARY_PARAMS(N, A, const* BOOST_PP_INTERCEPT)
|
||||
>
|
||||
> operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& a))
|
||||
{
|
||||
typedef boost::tuples::tuple<
|
||||
BOOST_PP_ENUM_BINARY_PARAMS(N, A, const* BOOST_PP_INTERCEPT)
|
||||
> arguments;
|
||||
|
||||
return call_proxy<Derived, arguments>(
|
||||
derived()
|
||||
, arguments(BOOST_PP_ENUM_PARAMS(N, &a))
|
||||
);
|
||||
}
|
||||
|
||||
#undef N
|
||||
|
||||
@@ -0,0 +1,224 @@
|
||||
// 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_OBJECT_PROXY_HPP_INCLUDED
|
||||
#define LUABIND_OBJECT_PROXY_HPP_INCLUDED
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include <luabind/config.hpp>
|
||||
#include <luabind/detail/policy.hpp>
|
||||
#include <luabind/error.hpp>
|
||||
#include <luabind/detail/convert_to_lua.hpp>
|
||||
#include <luabind/detail/debug.hpp>
|
||||
#include <luabind/detail/stack_utils.hpp>
|
||||
|
||||
#include <boost/mpl/apply_wrap.hpp>
|
||||
|
||||
namespace luabind
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
namespace mpl = boost::mpl;
|
||||
|
||||
template<class T, class Obj, class Policies>
|
||||
inline T object_cast_impl(const Obj& obj, const Policies&)
|
||||
{
|
||||
if (obj.lua_state() == 0)
|
||||
{
|
||||
#ifndef LUABIND_NO_EXCEPTIONS
|
||||
throw cast_failed(0, typeid(T));
|
||||
#else
|
||||
lua_State* L = obj.lua_state();
|
||||
cast_failed_callback_fun e = get_cast_failed_callback();
|
||||
if (e) e(L, typeid(T));
|
||||
|
||||
assert(0 && "object_cast failed. If you want to handle this error use luabind::set_error_callback()");
|
||||
std::terminate();
|
||||
#endif
|
||||
}
|
||||
|
||||
LUABIND_CHECK_STACK(obj.lua_state());
|
||||
|
||||
typedef typename detail::find_conversion_policy<0, Policies>::type converter_policy;
|
||||
typename mpl::apply_wrap2<converter_policy,T,lua_to_cpp>::type converter;
|
||||
|
||||
obj.pushvalue();
|
||||
|
||||
lua_State* L = obj.lua_state();
|
||||
detail::stack_pop p(L, 1);
|
||||
|
||||
#ifndef LUABIND_NO_ERROR_CHECKING
|
||||
|
||||
if (converter.match(L, LUABIND_DECORATE_TYPE(T), -1) < 0)
|
||||
{
|
||||
#ifndef LUABIND_NO_EXCEPTIONS
|
||||
throw cast_failed(L, typeid(T));
|
||||
#else
|
||||
cast_failed_callback_fun e = get_cast_failed_callback();
|
||||
if (e) e(L, typeid(T));
|
||||
|
||||
assert(0 && "object_cast failed. If you want to handle this error use luabind::set_error_callback()");
|
||||
std::terminate();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
return converter.apply(L, LUABIND_DECORATE_TYPE(T), -1);
|
||||
}
|
||||
|
||||
template<class T, class Obj, class Policies>
|
||||
boost::optional<T> object_cast_nothrow_impl(const Obj& obj, const Policies&)
|
||||
{
|
||||
typedef typename detail::find_conversion_policy<0, Policies>::type converter_policy;
|
||||
typename mpl::apply_wrap2<converter_policy,T,lua_to_cpp>::type converter;
|
||||
|
||||
if (obj.lua_state() == 0) return boost::optional<T>();
|
||||
LUABIND_CHECK_STACK(obj.lua_state());
|
||||
|
||||
obj.pushvalue();
|
||||
|
||||
lua_State* L = obj.lua_state();
|
||||
detail::stack_pop p(L, 1);
|
||||
|
||||
#ifndef LUABIND_NO_ERROR_CHECKING
|
||||
|
||||
if (converter.match(L, LUABIND_DECORATE_TYPE(T), -1) < 0)
|
||||
return boost::optional<T>();
|
||||
#endif
|
||||
|
||||
return boost::optional<T>(converter.apply(L, LUABIND_DECORATE_TYPE(T), -1));
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T object_cast(const object& obj)
|
||||
{ return detail::object_cast_impl<T>(obj, detail::null_type()); }
|
||||
|
||||
template<class T, class Policies>
|
||||
T object_cast(const object& obj, const Policies& p)
|
||||
{ return detail::object_cast_impl<T>(obj, p); }
|
||||
|
||||
template<class T>
|
||||
boost::optional<T> object_cast_nothrow(const object& obj)
|
||||
{ return detail::object_cast_nothrow_impl<T>(obj, detail::null_type()); }
|
||||
|
||||
template<class T, class Policies>
|
||||
boost::optional<T> object_cast_nothrow(const object& obj, const Policies& p)
|
||||
{ return detail::object_cast_nothrow_impl<T>(obj, p); }
|
||||
|
||||
|
||||
template<class T>
|
||||
T object_cast(const detail::proxy_object& obj)
|
||||
{ return detail::object_cast_impl<T>(obj, detail::null_type()); }
|
||||
|
||||
template<class T, class Policies>
|
||||
T object_cast(const detail::proxy_object& obj, const Policies& p)
|
||||
{ return detail::object_cast_impl<T>(obj, p); }
|
||||
|
||||
template<class T>
|
||||
boost::optional<T> object_cast_nothrow(const detail::proxy_object& obj)
|
||||
{ return detail::object_cast_nothrow_impl<T>(obj, detail::null_type()); }
|
||||
|
||||
template<class T, class Policies>
|
||||
boost::optional<T> object_cast_nothrow(const detail::proxy_object& obj, const Policies& p)
|
||||
{ return detail::object_cast_nothrow_impl<T>(obj, p); }
|
||||
|
||||
|
||||
template<class T>
|
||||
T object_cast(const detail::proxy_raw_object& obj)
|
||||
{ return detail::object_cast_impl<T>(obj, detail::null_type()); }
|
||||
|
||||
template<class T, class Policies>
|
||||
T object_cast(const detail::proxy_raw_object& obj, const Policies& p)
|
||||
{ return detail::object_cast_impl<T>(obj, p); }
|
||||
|
||||
template<class T>
|
||||
boost::optional<T> object_cast_nothrow(const detail::proxy_raw_object& obj)
|
||||
{ return detail::object_cast_nothrow_impl<T>(obj, detail::null_type()); }
|
||||
|
||||
template<class T, class Policies>
|
||||
boost::optional<T> object_cast_nothrow(const detail::proxy_raw_object& obj, const Policies& p)
|
||||
{ return detail::object_cast_nothrow_impl<T>(obj, p); }
|
||||
|
||||
|
||||
template<class T>
|
||||
T object_cast(const detail::proxy_array_object& obj)
|
||||
{ return detail::object_cast_impl<T>(obj, detail::null_type()); }
|
||||
|
||||
template<class T, class Policies>
|
||||
T object_cast(const detail::proxy_array_object& obj, const Policies& p)
|
||||
{ return detail::object_cast_impl<T>(obj, p); }
|
||||
|
||||
template<class T>
|
||||
boost::optional<T> object_cast_nothrow(const detail::proxy_array_object& obj)
|
||||
{ return detail::object_cast_nothrow_impl<T>(obj, detail::null_type()); }
|
||||
|
||||
template<class T, class Policies>
|
||||
boost::optional<T> object_cast_nothrow(const detail::proxy_array_object& obj, const Policies& p)
|
||||
{ return detail::object_cast_nothrow_impl<T>(obj, p); }
|
||||
|
||||
|
||||
|
||||
|
||||
inline object get_globals(lua_State* L)
|
||||
{
|
||||
lua_pushvalue(L, LUA_GLOBALSINDEX);
|
||||
detail::lua_reference ref;
|
||||
ref.set(L);
|
||||
return object(L, ref, true/*object::reference()*/);
|
||||
}
|
||||
|
||||
inline object get_registry(lua_State* L)
|
||||
{
|
||||
lua_pushvalue(L, LUA_REGISTRYINDEX);
|
||||
detail::lua_reference ref;
|
||||
ref.set(L);
|
||||
return object(L, ref, true/*object::reference()*/);
|
||||
}
|
||||
|
||||
inline object newtable(lua_State* L)
|
||||
{
|
||||
lua_newtable(L);
|
||||
detail::lua_reference ref;
|
||||
ref.set(L);
|
||||
return object(L, ref, true/*object::reference()*/);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
struct A
|
||||
{
|
||||
};
|
||||
|
||||
object f = class_<A>();
|
||||
|
||||
A* ptr = object_cast<A*>(f(), adopt(_1));
|
||||
|
||||
delete ptr;
|
||||
|
||||
*/
|
||||
|
||||
#endif // LUABIND_OBJECT_PROXY_HPP_INCLUDED
|
||||
@@ -24,114 +24,110 @@
|
||||
#ifndef LUABIND_OBJECT_REP_HPP_INCLUDED
|
||||
#define LUABIND_OBJECT_REP_HPP_INCLUDED
|
||||
|
||||
#include <boost/aligned_storage.hpp>
|
||||
#include <luabind/config.hpp>
|
||||
#include <luabind/detail/class_rep.hpp>
|
||||
#include <luabind/detail/instance_holder.hpp>
|
||||
#include <luabind/detail/ref.hpp>
|
||||
#include <type_traits> // std::aligned_storage
|
||||
#include <cstdlib>
|
||||
|
||||
namespace luabind {
|
||||
namespace detail {
|
||||
namespace luabind { namespace detail
|
||||
{
|
||||
class class_rep;
|
||||
|
||||
void finalize(lua_State* L, class_rep* crep);
|
||||
void finalize(lua_State* L, class_rep* crep);
|
||||
|
||||
// this class is allocated inside lua for each pointer.
|
||||
// it contains the actual c++ object-pointer.
|
||||
// it also tells if it is const or not.
|
||||
class LUABIND_API object_rep
|
||||
// this class is allocated inside lua for each pointer.
|
||||
// it contains the actual c++ object-pointer.
|
||||
// it also tells if it is const or not.
|
||||
class LUABIND_API object_rep
|
||||
{
|
||||
public:
|
||||
object_rep(instance_holder* instance, class_rep* crep);
|
||||
~object_rep();
|
||||
|
||||
const class_rep* crep() const { return m_classrep; }
|
||||
class_rep* crep() { return m_classrep; }
|
||||
|
||||
void set_instance(instance_holder* instance) { m_instance = instance; }
|
||||
|
||||
void add_dependency(lua_State* L, int index);
|
||||
void release_dependency_refs(lua_State* L);
|
||||
|
||||
std::pair<void*, int> get_instance(class_id target) const
|
||||
{
|
||||
public:
|
||||
object_rep(instance_holder* instance, class_rep* crep);
|
||||
~object_rep();
|
||||
if (m_instance == 0)
|
||||
return std::pair<void*, int>((void*)0, -1);
|
||||
return m_instance->get(target);
|
||||
}
|
||||
|
||||
const class_rep* crep() const { return m_classrep; }
|
||||
class_rep* crep() { return m_classrep; }
|
||||
|
||||
void set_instance(instance_holder* instance) { m_instance = instance; }
|
||||
|
||||
void add_dependency(lua_State* L, int index);
|
||||
|
||||
std::pair<void*, int> get_instance(class_id target) const
|
||||
{
|
||||
if(m_instance == 0)
|
||||
return std::pair<void*, int>(nullptr, -1);
|
||||
return m_instance->get(m_classrep->casts(), target);
|
||||
}
|
||||
|
||||
bool is_const() const
|
||||
{
|
||||
return m_instance && m_instance->pointee_const();
|
||||
}
|
||||
|
||||
void release()
|
||||
{
|
||||
if(m_instance)
|
||||
m_instance->release();
|
||||
}
|
||||
|
||||
void* allocate(std::size_t size)
|
||||
{
|
||||
if(size <= 32) {
|
||||
return &m_instance_buffer;
|
||||
}
|
||||
else {
|
||||
return std::malloc(size);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void deallocate(void* storage)
|
||||
{
|
||||
if(storage == &m_instance_buffer) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
std::free(storage);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
object_rep(object_rep const&) = delete;
|
||||
void operator=(object_rep const&) = delete;
|
||||
|
||||
instance_holder* m_instance;
|
||||
std::aligned_storage<32>::type m_instance_buffer;
|
||||
class_rep* m_classrep; // the class information about this object's type
|
||||
detail::lua_reference m_dependency_ref; // reference to lua table holding dependency references
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct delete_s
|
||||
bool is_const() const
|
||||
{
|
||||
static void apply(void* ptr)
|
||||
{
|
||||
delete static_cast<T*>(ptr);
|
||||
}
|
||||
};
|
||||
return m_instance && m_instance->pointee_const();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
struct destruct_only_s
|
||||
void release()
|
||||
{
|
||||
if (m_instance)
|
||||
m_instance->release();
|
||||
}
|
||||
|
||||
void* allocate(std::size_t size)
|
||||
{
|
||||
static void apply(void* ptr)
|
||||
{
|
||||
// Removes unreferenced formal parameter warning on VC7.
|
||||
(void)ptr;
|
||||
if (size <= 32)
|
||||
return &m_instance_buffer;
|
||||
return std::malloc(size);
|
||||
}
|
||||
|
||||
void deallocate(void* storage)
|
||||
{
|
||||
if (storage == &m_instance_buffer)
|
||||
return;
|
||||
std::free(storage);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
object_rep(object_rep const&)
|
||||
{}
|
||||
|
||||
void operator=(object_rep const&)
|
||||
{}
|
||||
|
||||
instance_holder* m_instance;
|
||||
boost::aligned_storage<32> m_instance_buffer;
|
||||
class_rep* m_classrep; // the class information about this object's type
|
||||
std::size_t m_dependency_cnt; // counts dependencies
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct delete_s
|
||||
{
|
||||
static void apply(void* ptr)
|
||||
{
|
||||
delete static_cast<T*>(ptr);
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct destruct_only_s
|
||||
{
|
||||
static void apply(void* ptr)
|
||||
{
|
||||
// Removes unreferenced formal parameter warning on VC7.
|
||||
(void)ptr;
|
||||
#ifndef NDEBUG
|
||||
int completeness_check[sizeof(T)];
|
||||
(void)completeness_check;
|
||||
int completeness_check[sizeof(T)];
|
||||
(void)completeness_check;
|
||||
#endif
|
||||
static_cast<T*>(ptr)->~T();
|
||||
}
|
||||
};
|
||||
static_cast<T*>(ptr)->~T();
|
||||
}
|
||||
};
|
||||
|
||||
LUABIND_API object_rep* get_instance(lua_State* L, int index);
|
||||
LUABIND_API void push_instance_metatable(lua_State* L);
|
||||
LUABIND_API object_rep* push_new_instance(lua_State* L, class_rep* cls);
|
||||
LUABIND_API object_rep* get_instance(lua_State* L, int index);
|
||||
LUABIND_API void push_instance_metatable(lua_State* L);
|
||||
LUABIND_API object_rep* push_new_instance(lua_State* L, class_rep* cls);
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace luabind
|
||||
}}
|
||||
|
||||
#endif // LUABIND_OBJECT_REP_HPP_INCLUDED
|
||||
|
||||
|
||||
@@ -26,58 +26,54 @@
|
||||
|
||||
#include <luabind/config.hpp>
|
||||
|
||||
namespace luabind {
|
||||
namespace detail {
|
||||
namespace luabind { namespace detail {
|
||||
|
||||
enum operator_id
|
||||
{
|
||||
op_add = 0,
|
||||
op_sub,
|
||||
op_mul,
|
||||
op_div,
|
||||
op_mod,
|
||||
op_pow,
|
||||
op_lt,
|
||||
op_le,
|
||||
op_eq,
|
||||
op_call,
|
||||
op_unm,
|
||||
op_tostring,
|
||||
op_concat,
|
||||
op_len,
|
||||
enum operator_id
|
||||
{
|
||||
op_add = 0,
|
||||
op_sub,
|
||||
op_mul,
|
||||
op_div,
|
||||
op_pow,
|
||||
op_lt,
|
||||
op_le,
|
||||
op_eq,
|
||||
op_call,
|
||||
op_unm,
|
||||
op_tostring,
|
||||
op_concat,
|
||||
op_len,
|
||||
|
||||
number_of_operators
|
||||
};
|
||||
number_of_operators
|
||||
};
|
||||
|
||||
inline const char* get_operator_name(int i)
|
||||
{
|
||||
static const char* a[number_of_operators] = {
|
||||
"__add", "__sub", "__mul", "__div", "__mod", "__pow",
|
||||
"__lt", "__le", "__eq", "__call", "__unm",
|
||||
"__tostring", "__concat", "__len" };
|
||||
return a[i];
|
||||
}
|
||||
inline const char* get_operator_name(int i)
|
||||
{
|
||||
static const char* a[number_of_operators] = {
|
||||
"__add", "__sub", "__mul", "__div", "__pow",
|
||||
"__lt", "__le", "__eq", "__call", "__unm",
|
||||
"__tostring", "__concat", "__len" };
|
||||
return a[i];
|
||||
}
|
||||
|
||||
inline const char* get_operator_symbol(int i)
|
||||
{
|
||||
static const char* a[number_of_operators] = {
|
||||
"+", "-", "*", "/", "%", "^", "<",
|
||||
"<=", "==", "()", "- (unary)",
|
||||
"tostring", "..", "#" };
|
||||
return a[i];
|
||||
}
|
||||
inline const char* get_operator_symbol(int i)
|
||||
{
|
||||
static const char* a[number_of_operators] = {
|
||||
"+", "-", "*", "/", "^", "<",
|
||||
"<=", "==", "()", "- (unary)",
|
||||
"tostring", "..", "#" };
|
||||
return a[i];
|
||||
}
|
||||
|
||||
inline bool is_unary(int i)
|
||||
{
|
||||
// the reason why unary minus is not considered a unary operator here is
|
||||
// that it always is given two parameters, where the second parameter always
|
||||
// is nil.
|
||||
return i == op_tostring;
|
||||
}
|
||||
inline bool is_unary(int i)
|
||||
{
|
||||
// the reason why unary minus is not considered a unary operator here is
|
||||
// that it always is given two parameters, where the second parameter always
|
||||
// is nil.
|
||||
return i == op_tostring;
|
||||
}
|
||||
|
||||
|
||||
} // namespace detail
|
||||
} // namespace luabind
|
||||
}}
|
||||
|
||||
#endif // LUABIND_OPERATOR_ID_HPP_INCLUDED
|
||||
|
||||
|
||||
@@ -33,34 +33,87 @@
|
||||
// to its suitability for any purpose.
|
||||
|
||||
#include <luabind/config.hpp>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
namespace luabind {
|
||||
|
||||
namespace luabind
|
||||
{
|
||||
template<class T>
|
||||
struct other
|
||||
{
|
||||
using type = T;
|
||||
typedef T type;
|
||||
};
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
namespace luabind { namespace detail
|
||||
{
|
||||
template<typename T>
|
||||
class unwrap_other
|
||||
{
|
||||
public:
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
} // namespace luabind
|
||||
template<typename T>
|
||||
class unwrap_other<other<T> >
|
||||
{
|
||||
public:
|
||||
typedef T type;
|
||||
};
|
||||
}} // namespace luabind::detail
|
||||
|
||||
namespace luabind {
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
class unwrap_other
|
||||
{
|
||||
public:
|
||||
using type = T;
|
||||
};
|
||||
# else // no partial specialization
|
||||
|
||||
template<typename T>
|
||||
class unwrap_other<other<T> >
|
||||
{
|
||||
public:
|
||||
using type = T;
|
||||
};
|
||||
}
|
||||
} // namespace luabind::detail
|
||||
#include <boost/type.hpp>
|
||||
|
||||
namespace luabind { namespace detail
|
||||
{
|
||||
typedef char (&yes_other_t)[1];
|
||||
typedef char (&no_other_t)[2];
|
||||
|
||||
no_other_t is_other_test(...);
|
||||
|
||||
template<typename T>
|
||||
yes_other_t is_other_test(type_< other<T> >);
|
||||
|
||||
template<bool wrapped>
|
||||
struct other_unwrapper
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct other_unwrapper<true>
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef typename T::type type;
|
||||
};
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class is_other
|
||||
{
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value = (
|
||||
sizeof(detail::is_other_test(type_<T>()))
|
||||
== sizeof(detail::yes_other_t)));
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class unwrap_other
|
||||
: public detail::other_unwrapper<
|
||||
is_other<T>::value
|
||||
>::template apply<T>
|
||||
{};
|
||||
|
||||
}} // namespace luabind::detail
|
||||
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
#endif // LUABIND_OTHER_HPP_INCLUDED
|
||||
|
||||
|
||||
@@ -25,14 +25,12 @@
|
||||
|
||||
#include <luabind/config.hpp>
|
||||
|
||||
#include <luabind/lua_state_fwd.hpp>
|
||||
struct lua_State;
|
||||
|
||||
namespace luabind {
|
||||
namespace detail {
|
||||
LUABIND_API int pcall(lua_State *L, int nargs, int nresults);
|
||||
LUABIND_API int resume_impl(lua_State *L, int nargs, int nresults);
|
||||
}
|
||||
}
|
||||
namespace luabind { namespace detail
|
||||
{
|
||||
LUABIND_API int pcall(lua_State *L, int nargs, int nresults);
|
||||
LUABIND_API int resume_impl(lua_State *L, int nargs, int nresults);
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
// Copyright (c) 2004 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 POINTEE_SIZEOF_040211_HPP
|
||||
#define POINTEE_SIZEOF_040211_HPP
|
||||
|
||||
#include <boost/mpl/int.hpp>
|
||||
|
||||
namespace luabind {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class T> T& deref_type(T(*)(), int);
|
||||
template<class T> T& deref_type(T*(*)(), long);
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// returns the indirect sizeof U, as in
|
||||
// sizeof(T*) = sizeof(T)
|
||||
// sizeof(T&) = sizeof(T)
|
||||
// sizeof(T) = sizeof(T)
|
||||
template<class T>
|
||||
struct pointee_sizeof
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(int, value = (
|
||||
sizeof(detail::deref_type((T(*)())0), 0L)
|
||||
));
|
||||
|
||||
typedef boost::mpl::int_<value> type;
|
||||
};
|
||||
|
||||
} // namespace luabind
|
||||
|
||||
#endif // POINTEE_SIZEOF_040211_HPP
|
||||
|
||||
+12
-46
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2003 Daniel Wallin and Arvid Norberg
|
||||
// Copyright (c) 2004 Daniel Wallin
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
@@ -20,55 +20,21 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
// OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
#ifndef LUABIND_CONVERT_TO_LUA_HPP_INCLUDED
|
||||
#define LUABIND_CONVERT_TO_LUA_HPP_INCLUDED
|
||||
#ifndef POINTEE_TYPEID_040211_HPP
|
||||
#define POINTEE_TYPEID_040211_HPP
|
||||
|
||||
#include <luabind/config.hpp>
|
||||
#include <luabind/detail/policy.hpp>
|
||||
#include <luabind/detail/type_traits.hpp>
|
||||
#include <luabind/typeid.hpp>
|
||||
|
||||
namespace luabind {
|
||||
namespace luabind { namespace detail {
|
||||
|
||||
namespace detail {
|
||||
template<class T>
|
||||
type_id pointee_typeid(T*)
|
||||
{
|
||||
return typeid(T);
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
struct unwrapped {
|
||||
static const bool is_wrapped_ref = false;
|
||||
using type = T;
|
||||
}} // namespace luabind::detail
|
||||
|
||||
static const T& get(const T& t) {
|
||||
return t;
|
||||
}
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
struct unwrapped< std::reference_wrapper< T > >
|
||||
{
|
||||
static const bool is_wrapped_ref = true;
|
||||
using type = T&;
|
||||
|
||||
static T& get(const std::reference_wrapper<T>& refwrap)
|
||||
{
|
||||
return refwrap.get();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using unwrapped_t = typename unwrapped< T >::type;
|
||||
|
||||
template<unsigned int PolicyIndex = 1, typename Policies = no_policies, typename T>
|
||||
void push_to_lua(lua_State* L, T&& v)
|
||||
{
|
||||
using value_type = unwrapped_t<remove_const_reference_t<T>>;
|
||||
|
||||
specialized_converter_policy_n<PolicyIndex, Policies, value_type, cpp_to_lua>()
|
||||
.to_lua(L, unwrapped<T>::get(v));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // POINTEE_TYPEID_040211_HPP
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -24,40 +24,62 @@
|
||||
#ifndef LUABIND_PRIMITIVES_HPP_INCLUDED
|
||||
#define LUABIND_PRIMITIVES_HPP_INCLUDED
|
||||
|
||||
// std::reference_wrapper...
|
||||
#include <type_traits> // std::true_type...
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
namespace luabind {
|
||||
namespace detail {
|
||||
#include <luabind/config.hpp>
|
||||
#include <luabind/detail/yes_no.hpp>
|
||||
|
||||
template<class T>
|
||||
struct type_ {};
|
||||
namespace luabind { namespace detail
|
||||
{
|
||||
template<class T>
|
||||
struct identity
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
struct ltstr
|
||||
{
|
||||
bool operator()(const char* s1, const char* s2) const { return std::strcmp(s1, s2) < 0; }
|
||||
};
|
||||
template<class T>
|
||||
struct type_ {};
|
||||
|
||||
template<int N>
|
||||
struct aligned
|
||||
{
|
||||
char storage[N];
|
||||
};
|
||||
struct null_type {};
|
||||
|
||||
// returns the offset added to a Derived* when cast to a Base*
|
||||
template<class Derived, class Base>
|
||||
ptrdiff_t ptr_offset(type_<Derived>, type_<Base>)
|
||||
{
|
||||
aligned<sizeof(Derived)> obj;
|
||||
Derived* ptr = reinterpret_cast<Derived*>(&obj);
|
||||
/* typedef char yes_t;
|
||||
typedef double no_t;*/
|
||||
|
||||
return ptrdiff_t(static_cast<char*>(static_cast<void*>(static_cast<Base*>(ptr)))
|
||||
- static_cast<char*>(static_cast<void*>(ptr)));
|
||||
}
|
||||
struct lua_to_cpp {};
|
||||
struct cpp_to_lua {};
|
||||
|
||||
template<class T> struct by_value {};
|
||||
template<class T> struct by_reference {};
|
||||
template<class T> struct by_const_reference {};
|
||||
template<class T> struct by_pointer {};
|
||||
template<class T> struct by_const_pointer {};
|
||||
|
||||
struct converter_policy_tag {};
|
||||
|
||||
struct ltstr
|
||||
{
|
||||
bool operator()(const char* s1, const char* s2) const { return std::strcmp(s1, s2) < 0; }
|
||||
};
|
||||
|
||||
template<int N>
|
||||
struct aligned
|
||||
{
|
||||
char storage[N];
|
||||
};
|
||||
|
||||
// returns the offset added to a Derived* when cast to a Base*
|
||||
// TODO: return ptrdiff
|
||||
template<class Derived, class Base>
|
||||
int ptr_offset(type_<Derived>, type_<Base>)
|
||||
{
|
||||
aligned<sizeof(Derived)> obj;
|
||||
Derived* ptr = reinterpret_cast<Derived*>(&obj);
|
||||
|
||||
return int(static_cast<char*>(static_cast<void*>(static_cast<Base*>(ptr)))
|
||||
- static_cast<char*>(static_cast<void*>(ptr)));
|
||||
}
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif // LUABIND_PRIMITIVES_HPP_INCLUDED
|
||||
|
||||
|
||||
@@ -5,31 +5,29 @@
|
||||
#ifndef LUABIND_PROPERTY_081020_HPP
|
||||
# define LUABIND_PROPERTY_081020_HPP
|
||||
|
||||
namespace luabind {
|
||||
namespace detail {
|
||||
namespace luabind { namespace detail {
|
||||
|
||||
template <class Class, class T, class Result = T>
|
||||
struct access_member_ptr
|
||||
{
|
||||
access_member_ptr(T Class::* mem_ptr)
|
||||
: mem_ptr(mem_ptr)
|
||||
{}
|
||||
template <class Class, class T, class Result = T>
|
||||
struct access_member_ptr
|
||||
{
|
||||
access_member_ptr(T Class::* mem_ptr)
|
||||
: mem_ptr(mem_ptr)
|
||||
{}
|
||||
|
||||
Result operator()(Class const& x) const
|
||||
{
|
||||
return const_cast<Class&>(x).*mem_ptr;
|
||||
}
|
||||
Result operator()(Class const& x) const
|
||||
{
|
||||
return const_cast<Class&>(x).*mem_ptr;
|
||||
}
|
||||
|
||||
void operator()(Class& x, T const& value) const
|
||||
{
|
||||
x.*mem_ptr = value;
|
||||
}
|
||||
void operator()(Class& x, T const& value) const
|
||||
{
|
||||
x.*mem_ptr = value;
|
||||
}
|
||||
|
||||
T Class::* mem_ptr;
|
||||
};
|
||||
T Class::* mem_ptr;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace luabind
|
||||
}} // namespace luabind::detail
|
||||
|
||||
#endif // LUABIND_PROPERTY_081020_HPP
|
||||
|
||||
|
||||
@@ -33,83 +33,80 @@
|
||||
namespace luabind
|
||||
{
|
||||
|
||||
namespace detail
|
||||
namespace detail
|
||||
{
|
||||
|
||||
struct lua_reference
|
||||
{
|
||||
|
||||
struct lua_reference
|
||||
lua_reference(lua_State* L_ = 0)
|
||||
: L(L_)
|
||||
, m_ref(LUA_NOREF)
|
||||
{}
|
||||
lua_reference(lua_reference const& r)
|
||||
: L(r.L)
|
||||
, m_ref(LUA_NOREF)
|
||||
{
|
||||
lua_reference(lua_State* L_ = 0)
|
||||
: L(L_)
|
||||
, m_ref(LUA_NOREF)
|
||||
{}
|
||||
lua_reference(lua_reference const& r)
|
||||
: L(r.L)
|
||||
, m_ref(LUA_NOREF)
|
||||
{
|
||||
if(!r.is_valid()) return;
|
||||
r.get(L);
|
||||
set(L);
|
||||
}
|
||||
~lua_reference() { reset(); }
|
||||
if (!r.is_valid()) return;
|
||||
r.get(L);
|
||||
set(L);
|
||||
}
|
||||
~lua_reference() { reset(); }
|
||||
|
||||
lua_State* state() const { return L; }
|
||||
lua_State* state() const { return L; }
|
||||
|
||||
void operator=(lua_reference const& r)
|
||||
{
|
||||
// TODO: self assignment problems
|
||||
reset();
|
||||
if(!r.is_valid()) return;
|
||||
r.get(r.state());
|
||||
set(r.state());
|
||||
}
|
||||
void operator=(lua_reference const& r)
|
||||
{
|
||||
// TODO: self assignment problems
|
||||
reset();
|
||||
if (!r.is_valid()) return;
|
||||
r.get(r.state());
|
||||
set(r.state());
|
||||
}
|
||||
|
||||
bool is_valid() const
|
||||
{
|
||||
return m_ref != LUA_NOREF;
|
||||
}
|
||||
bool is_valid() const
|
||||
{ return m_ref != LUA_NOREF; }
|
||||
|
||||
void set(lua_State* L_)
|
||||
{
|
||||
reset();
|
||||
L = L_;
|
||||
m_ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
}
|
||||
void set(lua_State* L_)
|
||||
{
|
||||
reset();
|
||||
L = L_;
|
||||
m_ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
}
|
||||
|
||||
void replace(lua_State* L_)
|
||||
{
|
||||
lua_rawseti(L_, LUA_REGISTRYINDEX, m_ref);
|
||||
}
|
||||
void replace(lua_State* L_)
|
||||
{
|
||||
lua_rawseti(L_, LUA_REGISTRYINDEX, m_ref);
|
||||
}
|
||||
|
||||
// L may not be the same pointer as
|
||||
// was used when creating this reference
|
||||
// since it may be a thread that shares
|
||||
// the same globals table.
|
||||
void get(lua_State* L_) const
|
||||
{
|
||||
assert(m_ref != LUA_NOREF);
|
||||
assert(L_);
|
||||
lua_rawgeti(L_, LUA_REGISTRYINDEX, m_ref);
|
||||
}
|
||||
// L may not be the same pointer as
|
||||
// was used when creating this reference
|
||||
// since it may be a thread that shares
|
||||
// the same globals table.
|
||||
void get(lua_State* L_) const
|
||||
{
|
||||
assert(m_ref != LUA_NOREF);
|
||||
assert(L_);
|
||||
lua_rawgeti(L_, LUA_REGISTRYINDEX, m_ref);
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
if(L && m_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, m_ref);
|
||||
m_ref = LUA_NOREF;
|
||||
}
|
||||
void reset()
|
||||
{
|
||||
if (L && m_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, m_ref);
|
||||
m_ref = LUA_NOREF;
|
||||
}
|
||||
|
||||
void swap(lua_reference& r)
|
||||
{
|
||||
assert(r.L == L);
|
||||
std::swap(r.m_ref, m_ref);
|
||||
}
|
||||
void swap(lua_reference& r)
|
||||
{
|
||||
assert(r.L == L);
|
||||
std::swap(r.m_ref, m_ref);
|
||||
}
|
||||
|
||||
private:
|
||||
lua_State* L;
|
||||
int m_ref;
|
||||
};
|
||||
private:
|
||||
lua_State* L;
|
||||
int m_ref;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}}
|
||||
|
||||
#endif // LUABIND_REF_HPP_INCLUDED
|
||||
|
||||
|
||||
@@ -25,5 +25,37 @@
|
||||
|
||||
#include <luabind/config.hpp>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/arithmetic/inc.hpp>
|
||||
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/mpl/size.hpp>
|
||||
#include <boost/mpl/remove.hpp>
|
||||
|
||||
namespace luabind
|
||||
{
|
||||
|
||||
namespace adl
|
||||
{
|
||||
class argument;
|
||||
}
|
||||
|
||||
template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(LUABIND_MAX_ARITY, class A, detail::null_type)>
|
||||
struct constructor
|
||||
{
|
||||
typedef BOOST_PP_CAT(
|
||||
boost::mpl::vector, BOOST_PP_INC(BOOST_PP_INC(LUABIND_MAX_ARITY)))<
|
||||
void, argument const&, BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)
|
||||
> signature0;
|
||||
|
||||
typedef typename boost::mpl::remove<
|
||||
signature0, detail::null_type>::type signature;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // LUABIND_SIGNATURE_MATCH_HPP_INCLUDED
|
||||
|
||||
|
||||
@@ -23,36 +23,30 @@
|
||||
#ifndef LUABIND_STACK_UTILS_HPP_INCLUDED
|
||||
#define LUABIND_STACK_UTILS_HPP_INCLUDED
|
||||
|
||||
#ifndef LUA_INCLUDE_HPP_INCLUDED
|
||||
#include <luabind/lua_include.hpp>
|
||||
#endif
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace luabind {
|
||||
namespace detail {
|
||||
namespace luabind { namespace detail
|
||||
{
|
||||
|
||||
struct stack_pop
|
||||
struct stack_pop
|
||||
{
|
||||
stack_pop(lua_State* L, int n)
|
||||
: m_state(L)
|
||||
, m_n(n)
|
||||
{
|
||||
}
|
||||
|
||||
~stack_pop()
|
||||
{
|
||||
stack_pop(lua_State* L, int n)
|
||||
: m_state(L)
|
||||
, m_n(n)
|
||||
{
|
||||
}
|
||||
lua_pop(m_state, m_n);
|
||||
}
|
||||
|
||||
~stack_pop()
|
||||
{
|
||||
lua_pop(m_state, m_n);
|
||||
}
|
||||
private:
|
||||
|
||||
private:
|
||||
|
||||
lua_State* m_state;
|
||||
int m_n;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace luabind
|
||||
lua_State* m_state;
|
||||
int m_n;
|
||||
};
|
||||
}}
|
||||
|
||||
#endif // LUABIND_STACK_UTILS_HPP_INCLUDED
|
||||
|
||||
|
||||
@@ -1,189 +0,0 @@
|
||||
// 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_TYPETRAITS_HPP_INCLUDED
|
||||
#define LUABIND_TYPETRAITS_HPP_INCLUDED
|
||||
|
||||
#include <type_traits>
|
||||
#include <functional> // reference_wrapper
|
||||
#include <luabind/detail/meta.hpp>
|
||||
|
||||
namespace luabind {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template< typename T >
|
||||
struct is_const_reference
|
||||
: public std::conditional< std::is_reference<T>::value && std::is_const<typename std::remove_reference<T>::type>::value, std::true_type, std::false_type >::type
|
||||
{
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_nonconst_reference
|
||||
: public std::conditional< std::is_reference<T>::value && !std::is_const<typename std::remove_reference<T>::type>::value, std::true_type, std::false_type >::type
|
||||
{
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_const_pointer
|
||||
: public std::conditional< std::is_const<typename std::remove_pointer<T>::type>::value && std::is_pointer<T>::value, std::true_type, std::false_type >::type
|
||||
{
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_nonconst_pointer :
|
||||
public std::conditional < std::is_pointer<T>::value && !std::is_const<typename std::remove_pointer<T>::type>::value, std::true_type, std::false_type >::type
|
||||
{
|
||||
};
|
||||
|
||||
template<int v1, int v2>
|
||||
struct max_c
|
||||
{
|
||||
enum { value = (v1 > v2) ? v1 : v2 };
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template< typename T >
|
||||
struct remove_const_reference {
|
||||
using type = typename std::remove_const<typename std::remove_reference<T>::type>::type;
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
using remove_const_reference_t = typename remove_const_reference<T>::type;
|
||||
|
||||
//
|
||||
// most_derived
|
||||
//
|
||||
|
||||
template<class A, class B>
|
||||
struct most_derived
|
||||
{
|
||||
using type = typename std::conditional<
|
||||
std::is_base_of<A, B>::value
|
||||
, B
|
||||
, A
|
||||
>::type;
|
||||
};
|
||||
|
||||
template< typename A, typename B >
|
||||
using most_derived_t = typename most_derived<A, B>::type;
|
||||
|
||||
//
|
||||
// null_type
|
||||
//
|
||||
|
||||
struct null_type {};
|
||||
|
||||
template< typename T >
|
||||
struct is_null_type : public std::false_type {};
|
||||
|
||||
template< >
|
||||
struct is_null_type< null_type > : public std::true_type {};
|
||||
|
||||
//
|
||||
// deduce_signature
|
||||
//
|
||||
|
||||
template< typename, typename > struct tagged_function;
|
||||
|
||||
template< typename T, typename WrappedType = null_type >
|
||||
struct deduce_signature;
|
||||
|
||||
template< typename R, typename... Args, typename WrappedType >
|
||||
struct deduce_signature < R(Args...), WrappedType >
|
||||
{
|
||||
using type = meta::type_list< R, Args... >;
|
||||
};
|
||||
|
||||
template< typename R, typename... Args, typename WrappedType >
|
||||
struct deduce_signature < R(*)(Args...), WrappedType >
|
||||
{
|
||||
using type = meta::type_list< R, Args... >;
|
||||
};
|
||||
|
||||
template< typename R, typename Class, typename... Args >
|
||||
struct deduce_signature < R(Class::*)(Args...), null_type >
|
||||
{
|
||||
using type = meta::type_list< R, Class&, Args... >;
|
||||
};
|
||||
|
||||
template< typename R, typename Class, typename... Args >
|
||||
struct deduce_signature < R(Class::*)(Args...) const, null_type >
|
||||
{
|
||||
using type = meta::type_list< R, Class const&, Args... >;
|
||||
};
|
||||
|
||||
template< typename R, typename Class, typename... Args, class WrappedType >
|
||||
struct deduce_signature < R(Class::*)(Args...), WrappedType >
|
||||
{
|
||||
using type = meta::type_list< R, typename most_derived<Class, WrappedType>::type&, Args... >;
|
||||
};
|
||||
|
||||
template< typename R, typename Class, typename... Args, class WrappedType >
|
||||
struct deduce_signature < R(Class::*)(Args...) const, WrappedType >
|
||||
{
|
||||
using type = meta::type_list< R, typename most_derived<Class, WrappedType>::type const&, Args... >;
|
||||
};
|
||||
|
||||
template< typename Signature, typename F, class WrappedType >
|
||||
struct deduce_signature< tagged_function< Signature, F >, WrappedType >
|
||||
{
|
||||
using type = Signature;
|
||||
};
|
||||
|
||||
template< typename T, typename WrappedType = null_type >
|
||||
using deduce_signature_t = typename deduce_signature<T, WrappedType>::type;
|
||||
|
||||
//
|
||||
// is_reference_wrapper
|
||||
//
|
||||
|
||||
template< typename T > struct is_reference_wrapper : public std::false_type { };
|
||||
template< typename T > struct is_reference_wrapper< std::reference_wrapper<T> > : public std::true_type { };
|
||||
|
||||
//
|
||||
// apply_reference_wrapper
|
||||
//
|
||||
|
||||
template< typename T > struct apply_reference_wrapper { using type = T; };
|
||||
template< typename T > struct apply_reference_wrapper< std::reference_wrapper<T> > { using type = T&; };
|
||||
|
||||
template< typename T >
|
||||
using apply_reference_wrapper_t = typename apply_reference_wrapper<T>::type;
|
||||
|
||||
//
|
||||
// identity
|
||||
//
|
||||
|
||||
template< typename T > struct identity { using type = T; };
|
||||
|
||||
template< typename T >
|
||||
using identity_t = typename identity<T>::type;
|
||||
|
||||
template< typename Dst > Dst implicit_cast(typename identity<Dst>::type t) { return t; }
|
||||
|
||||
} // namespace luabind
|
||||
|
||||
#endif // LUABIND_TYPETRAITS_HPP_INCLUDED
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
// 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_TYPETRAITS_HPP_INCLUDED
|
||||
#define LUABIND_TYPETRAITS_HPP_INCLUDED
|
||||
|
||||
#include <luabind/config.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/type_traits/is_reference.hpp>
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
#include <luabind/detail/primitives.hpp>
|
||||
|
||||
namespace luabind { namespace detail
|
||||
{
|
||||
|
||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
template<class T>
|
||||
struct is_const_type
|
||||
{
|
||||
typedef typename boost::mpl::if_<boost::is_const<T>
|
||||
, yes_t
|
||||
, no_t
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<bool is_Reference = false>
|
||||
struct is_const_reference_helper
|
||||
{
|
||||
template<class>
|
||||
struct apply
|
||||
{
|
||||
enum
|
||||
{
|
||||
value = false
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
template<class T>
|
||||
typename is_const_type<T>::type is_const_reference_tester(T&);
|
||||
no_t is_const_reference_tester(...);
|
||||
|
||||
template<>
|
||||
struct is_const_reference_helper<true>
|
||||
{
|
||||
template<class T>
|
||||
struct apply
|
||||
{
|
||||
static T getT();
|
||||
|
||||
enum
|
||||
{
|
||||
value = sizeof(is_const_reference_tester(getT())) == sizeof(yes_t)
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_const_reference
|
||||
: is_const_reference_helper<boost::is_reference<T>::value>::template apply<T>
|
||||
{
|
||||
typedef boost::mpl::bool_<value> type;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template<class T>
|
||||
struct is_const_reference
|
||||
{
|
||||
enum { value = false };
|
||||
typedef boost::mpl::bool_<value> type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_const_reference<const T&>
|
||||
{
|
||||
enum { value = true };
|
||||
typedef boost::mpl::bool_<value> type;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
template<class T>
|
||||
struct is_nonconst_reference
|
||||
{
|
||||
enum
|
||||
{
|
||||
value = boost::is_reference<T>::value && !is_const_reference<T>::value
|
||||
};
|
||||
typedef boost::mpl::bool_<value> type;
|
||||
};
|
||||
|
||||
template<class A>
|
||||
yes_t is_const_pointer_helper(void(*)(const A*));
|
||||
no_t is_const_pointer_helper(...);
|
||||
|
||||
template<class T>
|
||||
struct is_const_pointer
|
||||
{
|
||||
enum { value = sizeof(is_const_pointer_helper((void(*)(T))0)) == sizeof(yes_t) };
|
||||
typedef boost::mpl::bool_<value> type;
|
||||
};
|
||||
|
||||
template<class A>
|
||||
yes_t is_nonconst_pointer_helper(void(*)(A*));
|
||||
no_t is_nonconst_pointer_helper(...);
|
||||
|
||||
template<class T>
|
||||
struct is_nonconst_pointer
|
||||
{
|
||||
enum { value = sizeof(is_nonconst_pointer_helper((void(*)(T))0)) == sizeof(yes_t) && !is_const_pointer<T>::value };
|
||||
typedef boost::mpl::bool_<value> type;
|
||||
};
|
||||
/*
|
||||
template<class T>
|
||||
struct is_constructable_from_helper
|
||||
{
|
||||
static yes_t check(const T&);
|
||||
static no_t check(...);
|
||||
};
|
||||
|
||||
template<class T, class From>
|
||||
struct is_constructable_from
|
||||
{
|
||||
static From getFrom();
|
||||
|
||||
enum
|
||||
{
|
||||
value = sizeof(is_constructable_from_helper<T>::check(getFrom())) == sizeof(yes_t)
|
||||
};
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_const_member_function_helper
|
||||
{
|
||||
static no_t test(...);
|
||||
template<class R>
|
||||
static yes_t test(R(T::*)() const);
|
||||
template<class R, class A1>
|
||||
static yes_t test(R(T::*)(A1) const);
|
||||
template<class R, class A1, class A2>
|
||||
static yes_t test(R(T::*)(A1,A2) const);
|
||||
template<class R, class A1, class A2, class A3>
|
||||
static yes_t test(R(T::*)(A1,A2,A3) const);
|
||||
};
|
||||
|
||||
template<class T, class U>
|
||||
struct is_const_member_function
|
||||
{
|
||||
static U getU();
|
||||
|
||||
enum
|
||||
{
|
||||
value = sizeof(is_const_member_function_helper<T>::test(getU())) == sizeof(yes_t)
|
||||
};
|
||||
};
|
||||
*/
|
||||
|
||||
template<int v1, int v2>
|
||||
struct max_c
|
||||
{
|
||||
enum { value = (v1>v2)?v1:v2 };
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif // LUABIND_TYPETRAITS_HPP_INCLUDED
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
// Copyright (c) 2004 Daniel Wallin
|
||||
|
||||
// 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 YES_NO_040211_HPP
|
||||
#define YES_NO_040211_HPP
|
||||
|
||||
namespace luabind { namespace detail {
|
||||
|
||||
typedef char(&yes_t)[1];
|
||||
typedef char(&no_t)[2];
|
||||
|
||||
}} // namespace luabind::detail
|
||||
|
||||
#endif // YES_NO_040211_HPP
|
||||
|
||||
Reference in New Issue
Block a user