Phase one of getting rid of std::function usage
This commit is contained in:
39
include/chaiscript/dispatchkit/callable_traits.hpp
Normal file
39
include/chaiscript/dispatchkit/callable_traits.hpp
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
// This file is distributed under the BSD License.
|
||||||
|
// See "license.txt" for details.
|
||||||
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
|
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
||||||
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
|
#ifndef CHAISCRIPT_CALLABLE_TRAITS_HPP_
|
||||||
|
#define CHAISCRIPT_CALLABLE_TRAITS_HPP_
|
||||||
|
|
||||||
|
namespace chaiscript {
|
||||||
|
namespace dispatch {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct Function_Signature
|
||||||
|
{
|
||||||
|
typedef T Signature;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct Callable_Traits
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename Ret, typename ... Param>
|
||||||
|
static Ret deduce_ret_type(Ret (T::*)(Param...) const);
|
||||||
|
|
||||||
|
template<typename Ret, typename ... Param>
|
||||||
|
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 decltype(deduce_sig_type(&T::operator())) Signature_Object;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@@ -549,6 +549,45 @@ namespace chaiscript
|
|||||||
virtual bool compare_types_with_cast(const std::vector<Boxed_Value> &vals, const Type_Conversions &t_conversions) const = 0;
|
virtual bool compare_types_with_cast(const std::vector<Boxed_Value> &vals, const Type_Conversions &t_conversions) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// For any callable object
|
||||||
|
template<typename Func, typename Callable>
|
||||||
|
class Proxy_Function_Callable_Impl : public Proxy_Function_Impl_Base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Proxy_Function_Callable_Impl(Callable f)
|
||||||
|
: Proxy_Function_Impl_Base(detail::build_param_type_list(static_cast<Func *>(nullptr))),
|
||||||
|
m_f(std::move(f)), m_dummy_func(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~Proxy_Function_Callable_Impl() {}
|
||||||
|
|
||||||
|
virtual bool compare_types_with_cast(const std::vector<Boxed_Value> &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
||||||
|
{
|
||||||
|
return detail::compare_types_cast(m_dummy_func, vals, t_conversions);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool operator==(const Proxy_Function_Base &t_func) const CHAISCRIPT_OVERRIDE
|
||||||
|
{
|
||||||
|
return dynamic_cast<const Proxy_Function_Callable_Impl<Func, Callable> *>(&t_func) != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
||||||
|
{
|
||||||
|
typedef typename detail::Callable_Traits<Callable>::Return_Type Return_Type;
|
||||||
|
return detail::Do_Call<Return_Type>::go(m_f, params, t_conversions);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
Callable m_f;
|
||||||
|
Func *m_dummy_func;
|
||||||
|
};
|
||||||
|
|
||||||
/// The standard typesafe function call implementation of Proxy_Function
|
/// The standard typesafe function call implementation of Proxy_Function
|
||||||
/// It takes a std::function<> object and performs runtime
|
/// It takes a std::function<> object and performs runtime
|
||||||
/// type checking of Boxed_Value parameters, in a type safe manner
|
/// type checking of Boxed_Value parameters, in a type safe manner
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
#include "boxed_value.hpp"
|
#include "boxed_value.hpp"
|
||||||
#include "handle_return.hpp"
|
#include "handle_return.hpp"
|
||||||
#include "type_info.hpp"
|
#include "type_info.hpp"
|
||||||
|
#include "callable_traits.hpp"
|
||||||
|
|
||||||
namespace chaiscript {
|
namespace chaiscript {
|
||||||
class Type_Conversions;
|
class Type_Conversions;
|
||||||
@@ -111,8 +112,8 @@ namespace chaiscript
|
|||||||
struct Call_Func
|
struct Call_Func
|
||||||
{
|
{
|
||||||
|
|
||||||
template<typename ... InnerParams>
|
template<typename Callable, typename ... InnerParams>
|
||||||
static Ret do_call(const std::function<Ret (Params...)> &f,
|
static Ret do_call(const Callable &f,
|
||||||
const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions, InnerParams &&... innerparams)
|
const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions, InnerParams &&... innerparams)
|
||||||
{
|
{
|
||||||
return Call_Func<Ret, count - 1, Params...>::do_call(f, params, t_conversions, std::forward<InnerParams>(innerparams)..., params[sizeof...(Params) - count]);
|
return Call_Func<Ret, count - 1, Params...>::do_call(f, params, t_conversions, std::forward<InnerParams>(innerparams)..., params[sizeof...(Params) - count]);
|
||||||
@@ -126,8 +127,8 @@ namespace chaiscript
|
|||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable : 4100) /// Disable unreferenced formal parameter warning, which only shows up in MSVC I don't think there's any way around it \todo evaluate this
|
#pragma warning(disable : 4100) /// Disable unreferenced formal parameter warning, which only shows up in MSVC I don't think there's any way around it \todo evaluate this
|
||||||
#endif
|
#endif
|
||||||
template<typename ... InnerParams>
|
template<typename Callable, typename ... InnerParams>
|
||||||
static Ret do_call(const std::function<Ret (Params...)> &f,
|
static Ret do_call(const Callable &f,
|
||||||
const std::vector<Boxed_Value> &, const Type_Conversions &t_conversions, InnerParams &&... innerparams)
|
const std::vector<Boxed_Value> &, const Type_Conversions &t_conversions, InnerParams &&... innerparams)
|
||||||
{
|
{
|
||||||
return f(boxed_cast<Params>(std::forward<InnerParams>(innerparams), &t_conversions)...);
|
return f(boxed_cast<Params>(std::forward<InnerParams>(innerparams), &t_conversions)...);
|
||||||
@@ -143,8 +144,8 @@ namespace chaiscript
|
|||||||
* if any unboxing fails the execution of the function fails and
|
* if any unboxing fails the execution of the function fails and
|
||||||
* the bad_boxed_cast is passed up to the caller.
|
* the bad_boxed_cast is passed up to the caller.
|
||||||
*/
|
*/
|
||||||
template<typename Ret, typename ... Params>
|
template<typename Callable, typename Ret, typename ... Params>
|
||||||
Ret call_func(const std::function<Ret (Params...)> &f,
|
Ret call_func(const chaiscript::dispatch::detail::Function_Signature<Ret (Params...)> &, const Callable &f,
|
||||||
const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions)
|
const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions)
|
||||||
{
|
{
|
||||||
if (params.size() == sizeof...(Params))
|
if (params.size() == sizeof...(Params))
|
||||||
@@ -170,20 +171,20 @@ namespace chaiscript
|
|||||||
template<typename Ret>
|
template<typename Ret>
|
||||||
struct Do_Call
|
struct Do_Call
|
||||||
{
|
{
|
||||||
template<typename Fun>
|
template<typename Callable>
|
||||||
static Boxed_Value go(const std::function<Fun> &fun, const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions)
|
static Boxed_Value go(const Callable &fun, const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions)
|
||||||
{
|
{
|
||||||
return Handle_Return<Ret>::handle(call_func(fun, params, t_conversions));
|
return Handle_Return<Ret>::handle(call_func(typename Callable_Traits<Callable>::Signature_Object(), fun, params, t_conversions));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct Do_Call<void>
|
struct Do_Call<void>
|
||||||
{
|
{
|
||||||
template<typename Fun>
|
template<typename Callable>
|
||||||
static Boxed_Value go(const std::function<Fun> &fun, const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions)
|
static Boxed_Value go(const Callable &fun, const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions)
|
||||||
{
|
{
|
||||||
call_func(fun, params, t_conversions);
|
call_func(typename Callable_Traits<Callable>::Signature_Object(), fun, params, t_conversions);
|
||||||
return Handle_Return<void>::handle();
|
return Handle_Return<void>::handle();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -19,6 +19,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct FunctionSignature
|
struct FunctionSignature
|
||||||
{
|
{
|
||||||
@@ -108,8 +109,17 @@ namespace chaiscript
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
Proxy_Function fun(const T &t)
|
Proxy_Function fun(const T &t)
|
||||||
{
|
{
|
||||||
|
typedef typename dispatch::detail::Callable_Traits<T>::Signature Signature;
|
||||||
|
|
||||||
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(t)) >::Signature>>(dispatch::detail::to_function(t)));
|
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Callable_Impl<Signature, T>>(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename ... Param>
|
||||||
|
Proxy_Function fun(Ret (*func)(Param...))
|
||||||
|
{
|
||||||
|
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)));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename Class, typename ... Param>
|
template<typename Ret, typename Class, typename ... Param>
|
||||||
|
Reference in New Issue
Block a user