Use std::ref to make free functions callable

This commit is contained in:
Jason Turner
2015-05-22 10:28:28 -06:00
parent 630c618ae7
commit 48933bc32c
4 changed files with 20 additions and 13 deletions

View File

@@ -14,22 +14,26 @@ namespace chaiscript {
template<typename T> template<typename T>
struct Function_Signature struct Function_Signature
{ {
template<typename Ret, typename ... Param>
static Ret deduce_ret_type(Function_Signature<Ret (Param...)> *);
typedef T Signature; typedef T Signature;
typedef Function_Signature<T> *ptr_type;
typedef decltype(deduce_ret_type(ptr_type(nullptr))) Return_Type;
}; };
template<typename T> template<typename T>
struct Callable_Traits struct Callable_Traits
{ {
template<typename Ret, typename ... Param>
static Ret deduce_ret_type(Ret (T::*)(Param...) const);
template<typename Ret, typename ... Param> template<typename Ret, typename ... Param>
static Function_Signature<Ret (Param...)> deduce_sig_type(Ret (T::*)(Param...) const); static Function_Signature<Ret (Param...)> deduce_sig_type(Ret (T::*)(Param...) const);
typedef decltype(deduce_ret_type(&T::operator())) Return_Type;
typedef typename decltype(deduce_sig_type(&T::operator()))::Signature Signature; typedef typename decltype(deduce_sig_type(&T::operator()))::Signature Signature;
typedef decltype(deduce_sig_type(&T::operator())) Signature_Object; typedef decltype(deduce_sig_type(&T::operator())) Signature_Object;
typedef typename Signature_Object::Return_Type Return_Type;
}; };
} }
} }

View File

@@ -578,8 +578,8 @@ namespace chaiscript
protected: protected:
virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
{ {
typedef typename detail::Callable_Traits<Callable>::Return_Type Return_Type; typedef typename detail::Function_Signature<Func>::Return_Type Return_Type;
return detail::Do_Call<Return_Type>::go(m_f, params, t_conversions); return detail::Do_Call<Return_Type>::template go<Func>(m_f, params, t_conversions);
} }
@@ -621,7 +621,7 @@ namespace chaiscript
protected: protected:
virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
{ {
return detail::Do_Call<typename std::function<Func>::result_type>::go(m_f, params, t_conversions); return detail::Do_Call<typename std::function<Func>::result_type>::template go<Func>(m_f, params, t_conversions);
} }
@@ -682,7 +682,7 @@ namespace chaiscript
protected: protected:
virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
{ {
return detail::Do_Call<typename std::function<Func>::result_type>::go(m_f.get(), params, t_conversions); return detail::Do_Call<typename std::function<Func>::result_type>::template go<Func>(m_f.get(), params, t_conversions);
} }

View File

@@ -171,20 +171,20 @@ namespace chaiscript
template<typename Ret> template<typename Ret>
struct Do_Call struct Do_Call
{ {
template<typename Callable> template<typename Signature, typename Callable>
static Boxed_Value go(const Callable &fun, const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions) static Boxed_Value go(const Callable &fun, const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions)
{ {
return Handle_Return<Ret>::handle(call_func(typename Callable_Traits<Callable>::Signature_Object(), fun, params, t_conversions)); return Handle_Return<Ret>::handle(call_func(Function_Signature<Signature>(), fun, params, t_conversions));
} }
}; };
template<> template<>
struct Do_Call<void> struct Do_Call<void>
{ {
template<typename Callable> template<typename Signature, typename Callable>
static Boxed_Value go(const Callable &fun, const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions) static Boxed_Value go(const Callable &fun, const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions)
{ {
call_func(typename Callable_Traits<Callable>::Signature_Object(), fun, params, t_conversions); call_func(Function_Signature<Signature>(), fun, params, t_conversions);
return Handle_Return<void>::handle(); return Handle_Return<void>::handle();
} }
}; };

View File

@@ -118,8 +118,11 @@ namespace chaiscript
template<typename Ret, typename ... Param> template<typename Ret, typename ... Param>
Proxy_Function fun(Ret (*func)(Param...)) Proxy_Function fun(Ret (*func)(Param...))
{ {
auto f_ref = std::ref(*func);
return Proxy_Function( return Proxy_Function(
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Impl<typename dispatch::detail::FunctionSignature<decltype(dispatch::detail::to_function(func)) >::Signature>>(dispatch::detail::to_function(func))); chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Callable_Impl<Ret (Param...), decltype(f_ref)>>(f_ref));
} }
template<typename Ret, typename Class, typename ... Param> template<typename Ret, typename Class, typename ... Param>