From 03143a9f83111f9cfe822ed79aedf03663182ee8 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 22 May 2015 09:30:42 -0600 Subject: [PATCH 01/11] Phase one of getting rid of std::function usage --- .../dispatchkit/callable_traits.hpp | 39 +++++++++++++++++++ .../dispatchkit/proxy_functions.hpp | 39 +++++++++++++++++++ .../dispatchkit/proxy_functions_detail.hpp | 25 ++++++------ .../dispatchkit/register_function.hpp | 12 +++++- 4 files changed, 102 insertions(+), 13 deletions(-) create mode 100644 include/chaiscript/dispatchkit/callable_traits.hpp diff --git a/include/chaiscript/dispatchkit/callable_traits.hpp b/include/chaiscript/dispatchkit/callable_traits.hpp new file mode 100644 index 0000000..447d39c --- /dev/null +++ b/include/chaiscript/dispatchkit/callable_traits.hpp @@ -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 + struct Function_Signature + { + typedef T Signature; + }; + + template + struct Callable_Traits + { + + template + static Ret deduce_ret_type(Ret (T::*)(Param...) const); + + template + static Function_Signature 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 + diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index 39011ca..0bd8b7c 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -549,6 +549,45 @@ namespace chaiscript virtual bool compare_types_with_cast(const std::vector &vals, const Type_Conversions &t_conversions) const = 0; }; + + + /// For any callable object + template + 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(nullptr))), + m_f(std::move(f)), m_dummy_func(nullptr) + { + } + + virtual ~Proxy_Function_Callable_Impl() {} + + virtual bool compare_types_with_cast(const std::vector &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 *>(&t_func) != nullptr; + } + + + protected: + virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE + { + typedef typename detail::Callable_Traits::Return_Type Return_Type; + return detail::Do_Call::go(m_f, params, t_conversions); + } + + + private: + Callable m_f; + Func *m_dummy_func; + }; + /// The standard typesafe function call implementation of Proxy_Function /// It takes a std::function<> object and performs runtime /// type checking of Boxed_Value parameters, in a type safe manner diff --git a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp index b90c8d6..66e7713 100644 --- a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp @@ -16,6 +16,7 @@ #include "boxed_value.hpp" #include "handle_return.hpp" #include "type_info.hpp" +#include "callable_traits.hpp" namespace chaiscript { class Type_Conversions; @@ -111,8 +112,8 @@ namespace chaiscript struct Call_Func { - template - static Ret do_call(const std::function &f, + template + static Ret do_call(const Callable &f, const std::vector ¶ms, const Type_Conversions &t_conversions, InnerParams &&... innerparams) { return Call_Func::do_call(f, params, t_conversions, std::forward(innerparams)..., params[sizeof...(Params) - count]); @@ -126,8 +127,8 @@ namespace chaiscript #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 #endif - template - static Ret do_call(const std::function &f, + template + static Ret do_call(const Callable &f, const std::vector &, const Type_Conversions &t_conversions, InnerParams &&... innerparams) { return f(boxed_cast(std::forward(innerparams), &t_conversions)...); @@ -143,8 +144,8 @@ namespace chaiscript * if any unboxing fails the execution of the function fails and * the bad_boxed_cast is passed up to the caller. */ - template - Ret call_func(const std::function &f, + template + Ret call_func(const chaiscript::dispatch::detail::Function_Signature &, const Callable &f, const std::vector ¶ms, const Type_Conversions &t_conversions) { if (params.size() == sizeof...(Params)) @@ -170,20 +171,20 @@ namespace chaiscript template struct Do_Call { - template - static Boxed_Value go(const std::function &fun, const std::vector ¶ms, const Type_Conversions &t_conversions) + template + static Boxed_Value go(const Callable &fun, const std::vector ¶ms, const Type_Conversions &t_conversions) { - return Handle_Return::handle(call_func(fun, params, t_conversions)); + return Handle_Return::handle(call_func(typename Callable_Traits::Signature_Object(), fun, params, t_conversions)); } }; template<> struct Do_Call { - template - static Boxed_Value go(const std::function &fun, const std::vector ¶ms, const Type_Conversions &t_conversions) + template + static Boxed_Value go(const Callable &fun, const std::vector ¶ms, const Type_Conversions &t_conversions) { - call_func(fun, params, t_conversions); + call_func(typename Callable_Traits::Signature_Object(), fun, params, t_conversions); return Handle_Return::handle(); } }; diff --git a/include/chaiscript/dispatchkit/register_function.hpp b/include/chaiscript/dispatchkit/register_function.hpp index 4998ede..e526de5 100644 --- a/include/chaiscript/dispatchkit/register_function.hpp +++ b/include/chaiscript/dispatchkit/register_function.hpp @@ -19,6 +19,7 @@ namespace chaiscript { namespace detail { + template struct FunctionSignature { @@ -108,8 +109,17 @@ namespace chaiscript template Proxy_Function fun(const T &t) { + typedef typename dispatch::detail::Callable_Traits::Signature Signature; + return Proxy_Function( - chaiscript::make_shared::Signature>>(dispatch::detail::to_function(t))); + chaiscript::make_shared>(t)); + } + + template + Proxy_Function fun(Ret (*func)(Param...)) + { + return Proxy_Function( + chaiscript::make_shared::Signature>>(dispatch::detail::to_function(func))); } template From 630c618ae7d87bd7bee7979997f31bad7fecd803 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 22 May 2015 09:39:21 -0600 Subject: [PATCH 02/11] Remove automagic wrapping to std::function<> --- include/chaiscript/chaiscript_stdlib.hpp | 2 +- .../chaiscript/dispatchkit/register_function.hpp | 16 ---------------- unittests/compiled_tests.cpp | 3 +-- 3 files changed, 2 insertions(+), 19 deletions(-) diff --git a/include/chaiscript/chaiscript_stdlib.hpp b/include/chaiscript/chaiscript_stdlib.hpp index 92483fd..dc6ff46 100644 --- a/include/chaiscript/chaiscript_stdlib.hpp +++ b/include/chaiscript/chaiscript_stdlib.hpp @@ -47,7 +47,7 @@ namespace chaiscript #ifndef CHAISCRIPT_NO_THREADS lib->add(standard_library::future_type>("future")); - lib->add(chaiscript::fun (const std::function &)>([](const std::function &t_func){ return std::async(std::launch::async, t_func);}), "async"); + lib->add(chaiscript::fun([](const std::function &t_func){ return std::async(std::launch::async, t_func);}), "async"); #endif return lib; diff --git a/include/chaiscript/dispatchkit/register_function.hpp b/include/chaiscript/dispatchkit/register_function.hpp index e526de5..829a7d5 100644 --- a/include/chaiscript/dispatchkit/register_function.hpp +++ b/include/chaiscript/dispatchkit/register_function.hpp @@ -144,22 +144,6 @@ namespace chaiscript } - /// \brief Creates a new Proxy_Function object from a std::function object - /// \param[in] f std::function to expose to ChaiScript - /// - /// \b Example: - /// \code - /// std::function f = get_some_function(); - /// chaiscript::ChaiScript chai; - /// chai.add(fun(f), "some_function"); - /// \endcode - /// - /// \sa \ref adding_functions - template - Proxy_Function fun(const std::function &f) - { - return Proxy_Function(chaiscript::make_shared>(f)); - } /// \brief Creates a new Proxy_Function object from a free function, member function or data member and binds the first parameter of it diff --git a/unittests/compiled_tests.cpp b/unittests/compiled_tests.cpp index b49f90e..c856e9a 100644 --- a/unittests/compiled_tests.cpp +++ b/unittests/compiled_tests.cpp @@ -37,8 +37,7 @@ TEST_CASE("C++11 Lambdas Can Be Registered") // in an std::function or provide the signature chaiscript::ChaiScript chai; - // provide the signature - chai.add(chaiscript::fun([] { return "hello"; } ), "f1"); + chai.add(chaiscript::fun([]()->std::string { return "hello"; } ), "f1"); // wrap chai.add(chaiscript::fun(std::function([] { return "world"; } )), "f2"); From 48933bc32caa999b9876822b361488784f702417 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 22 May 2015 10:28:28 -0600 Subject: [PATCH 03/11] Use std::ref to make free functions callable --- include/chaiscript/dispatchkit/callable_traits.hpp | 12 ++++++++---- include/chaiscript/dispatchkit/proxy_functions.hpp | 8 ++++---- .../dispatchkit/proxy_functions_detail.hpp | 8 ++++---- include/chaiscript/dispatchkit/register_function.hpp | 5 ++++- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/include/chaiscript/dispatchkit/callable_traits.hpp b/include/chaiscript/dispatchkit/callable_traits.hpp index 447d39c..8a95d7e 100644 --- a/include/chaiscript/dispatchkit/callable_traits.hpp +++ b/include/chaiscript/dispatchkit/callable_traits.hpp @@ -14,22 +14,26 @@ namespace chaiscript { template struct Function_Signature { + + template + static Ret deduce_ret_type(Function_Signature *); + typedef T Signature; + typedef Function_Signature *ptr_type; + typedef decltype(deduce_ret_type(ptr_type(nullptr))) Return_Type; + }; template struct Callable_Traits { - template - static Ret deduce_ret_type(Ret (T::*)(Param...) const); - template static Function_Signature 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; + typedef typename Signature_Object::Return_Type Return_Type; }; } } diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index 0bd8b7c..5856f45 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -578,8 +578,8 @@ namespace chaiscript protected: virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE { - typedef typename detail::Callable_Traits::Return_Type Return_Type; - return detail::Do_Call::go(m_f, params, t_conversions); + typedef typename detail::Function_Signature::Return_Type Return_Type; + return detail::Do_Call::template go(m_f, params, t_conversions); } @@ -621,7 +621,7 @@ namespace chaiscript protected: virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE { - return detail::Do_Call::result_type>::go(m_f, params, t_conversions); + return detail::Do_Call::result_type>::template go(m_f, params, t_conversions); } @@ -682,7 +682,7 @@ namespace chaiscript protected: virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE { - return detail::Do_Call::result_type>::go(m_f.get(), params, t_conversions); + return detail::Do_Call::result_type>::template go(m_f.get(), params, t_conversions); } diff --git a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp index 66e7713..fbd1843 100644 --- a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp @@ -171,20 +171,20 @@ namespace chaiscript template struct Do_Call { - template + template static Boxed_Value go(const Callable &fun, const std::vector ¶ms, const Type_Conversions &t_conversions) { - return Handle_Return::handle(call_func(typename Callable_Traits::Signature_Object(), fun, params, t_conversions)); + return Handle_Return::handle(call_func(Function_Signature(), fun, params, t_conversions)); } }; template<> struct Do_Call { - template + template static Boxed_Value go(const Callable &fun, const std::vector ¶ms, const Type_Conversions &t_conversions) { - call_func(typename Callable_Traits::Signature_Object(), fun, params, t_conversions); + call_func(Function_Signature(), fun, params, t_conversions); return Handle_Return::handle(); } }; diff --git a/include/chaiscript/dispatchkit/register_function.hpp b/include/chaiscript/dispatchkit/register_function.hpp index 829a7d5..093bd41 100644 --- a/include/chaiscript/dispatchkit/register_function.hpp +++ b/include/chaiscript/dispatchkit/register_function.hpp @@ -118,8 +118,11 @@ namespace chaiscript template Proxy_Function fun(Ret (*func)(Param...)) { + auto f_ref = std::ref(*func); + return Proxy_Function( - chaiscript::make_shared::Signature>>(dispatch::detail::to_function(func))); + chaiscript::make_shared>(f_ref)); + } template From 0b812942d422046660409d021aef61a998edcf5b Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 22 May 2015 11:35:58 -0600 Subject: [PATCH 04/11] Finish removing std::function<> --- .../dispatchkit/callable_traits.hpp | 25 +++++++++++++++++++ .../dispatchkit/register_function.hpp | 17 ++++++++++--- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/include/chaiscript/dispatchkit/callable_traits.hpp b/include/chaiscript/dispatchkit/callable_traits.hpp index 8a95d7e..49978d2 100644 --- a/include/chaiscript/dispatchkit/callable_traits.hpp +++ b/include/chaiscript/dispatchkit/callable_traits.hpp @@ -10,6 +10,31 @@ namespace chaiscript { namespace dispatch { namespace detail { + template + struct Const_Caller + { + Const_Caller(Ret (Class::*t_func)(Param...) const) : m_func(t_func) {} + + template + Ret operator()(const Class &o, Inner&& ... inner) const { + return (o.*m_func)(std::forward(inner)...); + } + + Ret (Class::*m_func)(Param...) const; + }; + + template + struct Caller + { + Caller(Ret (Class::*t_func)(Param...)) : m_func(t_func) {} + + template + Ret operator()(Class &o, Inner&& ... inner) const { + return (o.*m_func)(std::forward(inner)...); + } + + Ret (Class::*m_func)(Param...); + }; template struct Function_Signature diff --git a/include/chaiscript/dispatchkit/register_function.hpp b/include/chaiscript/dispatchkit/register_function.hpp index 093bd41..438c723 100644 --- a/include/chaiscript/dispatchkit/register_function.hpp +++ b/include/chaiscript/dispatchkit/register_function.hpp @@ -126,17 +126,26 @@ namespace chaiscript } template - Proxy_Function fun(Ret (Class::*func)(Param...) const) + Proxy_Function fun(Ret (Class::*t_func)(Param...) const) { + auto call = dispatch::detail::Const_Caller(t_func); + return Proxy_Function( - chaiscript::make_shared::Signature>>(dispatch::detail::to_function(func))); + chaiscript::make_shared>(call)); } template - Proxy_Function fun(Ret (Class::*func)(Param...)) + Proxy_Function fun(Ret (Class::*t_func)(Param...)) { + auto call = dispatch::detail::Caller(t_func); + return Proxy_Function( - chaiscript::make_shared::Signature>>(dispatch::detail::to_function(func))); + chaiscript::make_shared>(call)); + +/* + return Proxy_Function( + chaiscript::make_shared::Signature>>(dispatch::detail::to_function(t_func))); +*/ } From df724b5c33561ca1bb975c09d9d7f794c3389442 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 22 May 2015 12:13:49 -0600 Subject: [PATCH 05/11] Completely remove Proxy_Function_Impl --- .../dispatchkit/callable_traits.hpp | 11 +++ .../dispatchkit/function_call_detail.hpp | 2 + .../chaiscript/dispatchkit/handle_return.hpp | 8 +- .../dispatchkit/proxy_constructors.hpp | 15 +--- .../dispatchkit/proxy_functions.hpp | 41 ---------- .../dispatchkit/register_function.hpp | 74 ------------------- 6 files changed, 21 insertions(+), 130 deletions(-) diff --git a/include/chaiscript/dispatchkit/callable_traits.hpp b/include/chaiscript/dispatchkit/callable_traits.hpp index 49978d2..e1fe612 100644 --- a/include/chaiscript/dispatchkit/callable_traits.hpp +++ b/include/chaiscript/dispatchkit/callable_traits.hpp @@ -7,9 +7,20 @@ #ifndef CHAISCRIPT_CALLABLE_TRAITS_HPP_ #define CHAISCRIPT_CALLABLE_TRAITS_HPP_ +#include + namespace chaiscript { namespace dispatch { namespace detail { + template + struct Constructor + { + template + std::shared_ptr operator()(Inner&& ... inner) const { + return std::make_shared(std::forward(inner)...); + } + }; + template struct Const_Caller { diff --git a/include/chaiscript/dispatchkit/function_call_detail.hpp b/include/chaiscript/dispatchkit/function_call_detail.hpp index 9410d15..fb6b5fc 100644 --- a/include/chaiscript/dispatchkit/function_call_detail.hpp +++ b/include/chaiscript/dispatchkit/function_call_detail.hpp @@ -95,6 +95,7 @@ namespace chaiscript template std::function build_function_caller_helper(Ret (Params...), const std::vector &funcs, const Type_Conversions *t_conversions) { + /* if (funcs.size() == 1) { std::shared_ptr> pfi = @@ -108,6 +109,7 @@ namespace chaiscript // looks like this either wasn't a Proxy_Function_Impl or the types didn't match // we cannot make any other guesses or assumptions really, so continuing } +*/ return std::function(Build_Function_Caller_Helper(funcs, t_conversions?*t_conversions:Type_Conversions())); } diff --git a/include/chaiscript/dispatchkit/handle_return.hpp b/include/chaiscript/dispatchkit/handle_return.hpp index d028e85..d5bdb9d 100644 --- a/include/chaiscript/dispatchkit/handle_return.hpp +++ b/include/chaiscript/dispatchkit/handle_return.hpp @@ -23,7 +23,7 @@ namespace chaiscript { namespace dispatch { - template class Proxy_Function_Impl; + template class Proxy_Function_Callable_Impl; template class Assignable_Proxy_Function_Impl; namespace detail @@ -54,7 +54,7 @@ namespace chaiscript { static Boxed_Value handle(const std::function &f) { return Boxed_Value( - chaiscript::make_shared>(f) + chaiscript::make_shared>>(f) ); } }; @@ -64,7 +64,7 @@ namespace chaiscript { static Boxed_Value handle(const std::function &f) { return Boxed_Value( - chaiscript::make_shared>(f) + chaiscript::make_shared>>(f) ); } }; @@ -111,7 +111,7 @@ namespace chaiscript static Boxed_Value handle(const std::function &f) { return Boxed_Value( - chaiscript::make_shared>(f) + chaiscript::make_shared>>(f) ); } }; diff --git a/include/chaiscript/dispatchkit/proxy_constructors.hpp b/include/chaiscript/dispatchkit/proxy_constructors.hpp index 2866d97..063c557 100644 --- a/include/chaiscript/dispatchkit/proxy_constructors.hpp +++ b/include/chaiscript/dispatchkit/proxy_constructors.hpp @@ -16,21 +16,14 @@ namespace chaiscript { namespace detail { - /** - * A constructor function, used for creating a new object - * of a given type with a given set of params - */ - template - std::shared_ptr constructor_(Params ... params) - { - return std::make_shared(params...); - } template Proxy_Function build_constructor_(Class (*)(Params...)) { - typedef std::shared_ptr (sig)(Params...); - return Proxy_Function(static_cast(new Proxy_Function_Impl(std::function(&(constructor_))))); + auto call = dispatch::detail::Constructor(); + + return Proxy_Function( + chaiscript::make_shared (Params...), decltype(call)>>(call)); } } } diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index 5856f45..35dc100 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -588,47 +588,6 @@ namespace chaiscript Func *m_dummy_func; }; - /// The standard typesafe function call implementation of Proxy_Function - /// It takes a std::function<> object and performs runtime - /// type checking of Boxed_Value parameters, in a type safe manner - template - class Proxy_Function_Impl : public Proxy_Function_Impl_Base - { - public: - Proxy_Function_Impl(std::function f) - : Proxy_Function_Impl_Base(detail::build_param_type_list(static_cast(nullptr))), - m_f(std::move(f)), m_dummy_func(nullptr) - { - } - - virtual ~Proxy_Function_Impl() {} - - virtual bool compare_types_with_cast(const std::vector &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 *>(&t_func) != nullptr; - } - - std::function internal_function() const - { - return m_f; - } - - protected: - virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE - { - return detail::Do_Call::result_type>::template go(m_f, params, t_conversions); - } - - - private: - std::function m_f; - Func *m_dummy_func; - }; class Assignable_Proxy_Function : public Proxy_Function_Impl_Base { diff --git a/include/chaiscript/dispatchkit/register_function.hpp b/include/chaiscript/dispatchkit/register_function.hpp index 438c723..ecec5ea 100644 --- a/include/chaiscript/dispatchkit/register_function.hpp +++ b/include/chaiscript/dispatchkit/register_function.hpp @@ -15,76 +15,6 @@ namespace chaiscript { - namespace dispatch - { - namespace detail - { - - template - struct FunctionSignature - { - }; - - template - struct FunctionSignature > - { - typedef Sig Signature; - }; - - template - std::function to_function(Ret (*func)(Args...)) - { - return std::function(func); - } - - - template - std::function to_function(Ret (Class::*func)(Args...)) - { -#ifdef CHAISCRIPT_MSVC - /// \todo this std::mem_fn wrap shouldn't be necessary but type conversions for - /// std::function for member function pointers seems to be broken in MSVC - return std::function(std::mem_fn(func)); -#else - return std::function(func); -#endif - } - - template - std::function to_function(Ret (Class::*func)(Args...) const) - { -#if defined(CHAISCRIPT_MSVC) || defined(CHAISCRIPT_LIBCPP) - /// \todo this std::mem_fn wrap shouldn't be necessary but type conversions for - /// std::function for member function pointers seems to be broken in MSVC - return std::function([func](const Class &o, Args... args)->Ret { - return (o.*func)(std::forward(args)...); - }); -#else - return std::function(func); -#endif - } - - template - std::function to_function_callable(Ret (Class::*)(Args...), T t) - { - return std::function(t); - } - - template - std::function to_function_callable(Ret (Class::*)(Args...) const, T t) - { - return std::function(t); - } - - - template - auto to_function(T t) -> decltype(to_function_callable(&T::operator(), t)) - { - return to_function_callable(&T::operator(), t); - } - - } - } /// \brief Creates a new Proxy_Function object from a free function, member function or data member /// \param[in] t Function / member to expose @@ -142,10 +72,6 @@ namespace chaiscript return Proxy_Function( chaiscript::make_shared>(call)); -/* - return Proxy_Function( - chaiscript::make_shared::Signature>>(dispatch::detail::to_function(t_func))); -*/ } From e0234d942e8ed00a600ee8e48e08b0f86444570f Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 22 May 2015 19:40:56 -0600 Subject: [PATCH 06/11] Various cleanups and fixes for older compilers --- .../chaiscript/dispatchkit/bootstrap_stl.hpp | 14 ++++---- .../chaiscript/dispatchkit/boxed_number.hpp | 22 ++++++------- .../dispatchkit/callable_traits.hpp | 33 ++++++++++--------- .../dispatchkit/proxy_functions.hpp | 12 +++---- .../dispatchkit/proxy_functions_detail.hpp | 2 +- 5 files changed, 41 insertions(+), 42 deletions(-) diff --git a/include/chaiscript/dispatchkit/bootstrap_stl.hpp b/include/chaiscript/dispatchkit/bootstrap_stl.hpp index ad31f6b..650124c 100644 --- a/include/chaiscript/dispatchkit/bootstrap_stl.hpp +++ b/include/chaiscript/dispatchkit/bootstrap_stl.hpp @@ -243,18 +243,18 @@ namespace chaiscript template ModulePtr random_access_container_type(const std::string &/*type*/, ModulePtr m = std::make_shared()) { - // cppcheck-suppress syntaxError - typedef typename ContainerType::reference(ContainerType::*indexoper)(size_t); - //In the interest of runtime safety for the m, we prefer the at() method for [] access, //to throw an exception in an out of bounds condition. m->add( - fun(std::function - (std::mem_fn(static_cast(&ContainerType::at)))), "[]"); + fun( + [](ContainerType &c, int index) -> typename ContainerType::reference { + return c.at(index); + }), "[]"); + m->add( fun( - [](const ContainerType *c, int index) -> typename ContainerType::const_reference { - return c->at(index); + [](const ContainerType &c, int index) -> typename ContainerType::const_reference { + return c.at(index); }), "[]"); return m; diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index a57ed7a..fa3ba6c 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -60,7 +60,7 @@ namespace chaiscript { private: template - static void check_divide_by_zero(T t, typename std::enable_if::value>::type* = nullptr) + inline static void check_divide_by_zero(T t, typename std::enable_if::value>::type* = nullptr) { #ifndef CHAISCRIPT_NO_PROTECT_DIVIDEBYZERO if (t == 0) { @@ -70,7 +70,7 @@ namespace chaiscript } template - static void check_divide_by_zero(T, typename std::enable_if::value>::type* = nullptr) + inline static void check_divide_by_zero(T, typename std::enable_if::value>::type* = nullptr) { } @@ -78,7 +78,7 @@ namespace chaiscript { template - static Boxed_Value go(Operators::Opers t_oper, const T &t, const U &u, const Boxed_Value &) + inline static Boxed_Value go(Operators::Opers t_oper, const T &t, const U &u, const Boxed_Value &) { switch (t_oper) { @@ -103,7 +103,7 @@ namespace chaiscript struct binary { template - static Boxed_Value go(Operators::Opers t_oper, T &t, const U &u, const Boxed_Value &t_lhs) + inline static Boxed_Value go(Operators::Opers t_oper, T &t, const U &u, const Boxed_Value &t_lhs) { switch (t_oper) { @@ -140,7 +140,7 @@ namespace chaiscript struct binary_int { template - static Boxed_Value go(Operators::Opers t_oper, T &t, const U &u, const Boxed_Value &t_lhs) + inline static Boxed_Value go(Operators::Opers t_oper, T &t, const U &u, const Boxed_Value &t_lhs) { switch (t_oper) { @@ -173,7 +173,7 @@ namespace chaiscript struct const_binary_int { template - static Boxed_Value go(Operators::Opers t_oper, const T &t, const U &u, const Boxed_Value &) + inline static Boxed_Value go(Operators::Opers t_oper, const T &t, const U &u, const Boxed_Value &) { switch (t_oper) { @@ -201,7 +201,7 @@ namespace chaiscript struct const_binary { template - static Boxed_Value go(Operators::Opers t_oper, const T &t, const U &u, const Boxed_Value &) + inline static Boxed_Value go(Operators::Opers t_oper, const T &t, const U &u, const Boxed_Value &) { switch (t_oper) { @@ -227,7 +227,7 @@ namespace chaiscript template struct Go { - static Boxed_Value go(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) + inline static Boxed_Value go(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) { if (t_oper > Operators::boolean_flag && t_oper < Operators::non_const_flag) { @@ -249,7 +249,7 @@ namespace chaiscript template struct Go { - static Boxed_Value go(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) + inline static Boxed_Value go(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) { if (t_oper > Operators::boolean_flag && t_oper < Operators::non_const_flag) { @@ -269,7 +269,7 @@ namespace chaiscript }; template - static Boxed_Value oper_rhs(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) + inline static Boxed_Value oper_rhs(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) { const auto &inp_ = t_rhs.get_type_info(); @@ -310,7 +310,7 @@ namespace chaiscript } } - static Boxed_Value oper(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) + inline static Boxed_Value oper(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) { const Type_Info &inp_ = t_lhs.get_type_info(); diff --git a/include/chaiscript/dispatchkit/callable_traits.hpp b/include/chaiscript/dispatchkit/callable_traits.hpp index e1fe612..5ffa093 100644 --- a/include/chaiscript/dispatchkit/callable_traits.hpp +++ b/include/chaiscript/dispatchkit/callable_traits.hpp @@ -47,29 +47,32 @@ namespace chaiscript { Ret (Class::*m_func)(Param...); }; + template struct Function_Signature { - - template - static Ret deduce_ret_type(Function_Signature *); - - typedef T Signature; - typedef Function_Signature *ptr_type; - typedef decltype(deduce_ret_type(ptr_type(nullptr))) Return_Type; - }; + template + struct Function_Signature + { + typedef Ret Return_Type; + typedef Ret (Signature)(Params...); + }; + + template + struct Function_Signature + { + typedef Ret Return_Type; + typedef Ret (Signature)(Params...); + }; + + template struct Callable_Traits { - - template - static Function_Signature deduce_sig_type(Ret (T::*)(Param...) const); - - typedef typename decltype(deduce_sig_type(&T::operator()))::Signature Signature; - typedef decltype(deduce_sig_type(&T::operator())) Signature_Object; - typedef typename Signature_Object::Return_Type Return_Type; + typedef typename Function_Signature::Signature Signature; + typedef typename Function_Signature::Return_Type Return_Type; }; } } diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index 35dc100..e0a413a 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -558,7 +558,7 @@ namespace chaiscript public: Proxy_Function_Callable_Impl(Callable f) : Proxy_Function_Impl_Base(detail::build_param_type_list(static_cast(nullptr))), - m_f(std::move(f)), m_dummy_func(nullptr) + m_f(std::move(f)) { } @@ -566,7 +566,7 @@ namespace chaiscript virtual bool compare_types_with_cast(const std::vector &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE { - return detail::compare_types_cast(m_dummy_func, vals, t_conversions); + return detail::compare_types_cast(static_cast(nullptr), vals, t_conversions); } virtual bool operator==(const Proxy_Function_Base &t_func) const CHAISCRIPT_OVERRIDE @@ -582,10 +582,8 @@ namespace chaiscript return detail::Do_Call::template go(m_f, params, t_conversions); } - private: Callable m_f; - Func *m_dummy_func; }; @@ -611,17 +609,16 @@ namespace chaiscript public: Assignable_Proxy_Function_Impl(std::reference_wrapper> t_f, std::shared_ptr> t_ptr) : Assignable_Proxy_Function(detail::build_param_type_list(static_cast(nullptr))), - m_f(std::move(t_f)), m_shared_ptr_holder(std::move(t_ptr)), m_dummy_func(nullptr) + m_f(std::move(t_f)), m_shared_ptr_holder(std::move(t_ptr)) { assert(!m_shared_ptr_holder || m_shared_ptr_holder.get() == &m_f.get()); - } virtual ~Assignable_Proxy_Function_Impl() {} virtual bool compare_types_with_cast(const std::vector &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE { - return detail::compare_types_cast(m_dummy_func, vals, t_conversions); + return detail::compare_types_cast(static_cast(nullptr), vals, t_conversions); } virtual bool operator==(const Proxy_Function_Base &t_func) const CHAISCRIPT_OVERRIDE @@ -648,7 +645,6 @@ namespace chaiscript private: std::reference_wrapper> m_f; std::shared_ptr> m_shared_ptr_holder; - Func *m_dummy_func; }; /// Attribute getter Proxy_Function implementation template diff --git a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp index fbd1843..fb1418e 100644 --- a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp @@ -98,7 +98,7 @@ namespace chaiscript template bool compare_types_cast(Ret (*)(Params...), const std::vector ¶ms, const Type_Conversions &t_conversions) - { + { try { Try_Cast::do_try(params, 0, t_conversions); } catch (const exception::bad_boxed_cast &) { From 919c3f2b4a77c9a83026fa30290caf89ec3d3d96 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 23 May 2015 13:10:29 -0600 Subject: [PATCH 07/11] Finish removing std::function and std::bind internally --- .../chaiscript/language/chaiscript_engine.hpp | 39 ++++++++--------- .../chaiscript/language/chaiscript_eval.hpp | 43 ++++++++++--------- 2 files changed, 42 insertions(+), 40 deletions(-) diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 5b3602b..233f906 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -356,13 +356,14 @@ namespace chaiscript add(t_lib); } - m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::dump_system, std::ref(m_engine)), "dump_system"); - m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::dump_object, std::ref(m_engine)), "dump_object"); - m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::is_type, std::ref(m_engine)), "is_type"); - m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::type_name, std::ref(m_engine)), "type_name"); - m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::function_exists, std::ref(m_engine)), "function_exists"); - m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_function_objects, std::ref(m_engine)), "get_functions"); - m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_scripting_objects, std::ref(m_engine)), "get_objects"); + m_engine.add(fun([this](){ m_engine.dump_system(); }), "dump_system"); + m_engine.add(fun([this](const Boxed_Value &t_bv){ m_engine.dump_object(t_bv); }), "dump_object"); + m_engine.add(fun([this](const Boxed_Value &t_bv, const std::string &t_type){ return m_engine.is_type(t_bv, t_type); }), "is_type"); + m_engine.add(fun([this](const Boxed_Value &t_bv){ return m_engine.type_name(t_bv); }), "type_name"); + m_engine.add(fun([this](const std::string &t_f){ return m_engine.function_exists(t_f); }), "function_exists"); + m_engine.add(fun([this](){ return m_engine.get_function_objects(); }), "get_functions"); + m_engine.add(fun([this](){ return m_engine.get_scripting_objects(); }), "get_objects"); + m_engine.add(chaiscript::make_shared( [this](const std::vector &t_params) { return m_engine.call_exists(t_params); @@ -375,10 +376,10 @@ namespace chaiscript return t_fun(t_params, this->m_engine.conversions()); }), "call"); - m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_type_name, std::ref(m_engine)), "name"); + m_engine.add(fun([this](const Type_Info &t_ti){ return m_engine.get_type_name(t_ti); }), "name"); - m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_type, std::ref(m_engine)), "type"); - m_engine.add(fun([this](const std::string &t_type_name){ return this->m_engine.get_type(t_type_name, true); }), "type"); + m_engine.add(fun([this](const std::string &t_type_name, bool t_throw){ return m_engine.get_type(t_type_name, t_throw); }), "type"); + m_engine.add(fun([this](const std::string &t_type_name){ return m_engine.get_type(t_type_name, true); }), "type"); m_engine.add(fun( [=](const Type_Info &t_from, const Type_Info &t_to, const std::function &t_func) { @@ -387,24 +388,22 @@ namespace chaiscript ), "add_type_conversion"); - typedef std::string (ChaiScript::*load_mod_1)(const std::string&); - typedef void (ChaiScript::*load_mod_2)(const std::string&, const std::string&); - m_engine.add(fun(static_cast(&ChaiScript::load_module), this), "load_module"); - m_engine.add(fun(static_cast(&ChaiScript::load_module), this), "load_module"); + m_engine.add(fun([this](const std::string &t_module, const std::string &t_file){ return load_module(t_module, t_file); }), "load_module"); + m_engine.add(fun([this](const std::string &t_module){ return load_module(t_module); }), "load_module"); - m_engine.add(fun(&ChaiScript::use, this), "use"); - m_engine.add(fun(&ChaiScript::internal_eval_file, this), "eval_file"); - m_engine.add(fun(&ChaiScript::internal_eval, this), "eval"); - m_engine.add(fun(&ChaiScript::internal_eval_ast, this), "eval"); + m_engine.add(fun([this](const std::string &t_file){ return use(t_file); }), "use"); + m_engine.add(fun([this](const std::string &t_file){ return internal_eval_file(t_file); }), "eval_file"); + m_engine.add(fun([this](const std::string &t_str){ return internal_eval(t_str); }), "eval"); + m_engine.add(fun([this](const AST_NodePtr &t_ast){ return internal_eval_ast(t_ast); }), "eval"); m_engine.add(fun(&ChaiScript::version_major), "version_major"); m_engine.add(fun(&ChaiScript::version_minor), "version_minor"); m_engine.add(fun(&ChaiScript::version_patch), "version_patch"); m_engine.add(fun(&ChaiScript::version), "version"); - m_engine.add(fun(&ChaiScript::add_global_const, this), "add_global_const"); - m_engine.add(fun(&ChaiScript::add_global, this), "add_global"); + m_engine.add(fun([this](const Boxed_Value &t_bv, const std::string &t_name){ add_global_const(t_bv, t_name); }), "add_global_const"); + m_engine.add(fun([this](const Boxed_Value &t_bv, const std::string &t_name){ add_global(t_bv, t_name); }), "add_global"); do_eval(ChaiScript_Prelude::chaiscript_prelude(), "standard prelude"); } diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 2e8a922..895dcad 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -1418,36 +1418,40 @@ namespace chaiscript std::shared_ptr guard; if (guardnode) { guard = std::make_shared - (std::bind(chaiscript::eval::detail::eval_function, - std::ref(t_ss), guardnode, - t_param_names, std::placeholders::_1, std::map()), static_cast(numparams), guardnode); + ([&t_ss, t_param_names, guardnode](const std::vector &t_params) { + return chaiscript::eval::detail::eval_function(t_ss, guardnode, t_param_names, t_params, std::map()); + }, static_cast(numparams), guardnode); } try { const std::string & l_annotation = annotation?annotation->text:""; - const std::string & function_name = children[static_cast(1 + class_offset)]->text; + auto node = children.back(); if (function_name == class_name) { param_types.push_front(class_name, Type_Info()); - t_ss.add(std::make_shared(class_name, std::make_shared(std::bind(chaiscript::eval::detail::eval_function, - std::ref(t_ss), children.back(), t_param_names, std::placeholders::_1, std::map()), - static_cast(numparams), children.back(), param_types, l_annotation, guard)), + + t_ss.add(std::make_shared(class_name, + std::make_shared( + [&t_ss, t_param_names, node](const std::vector &t_params) { + return chaiscript::eval::detail::eval_function(t_ss, node, t_param_names, t_params, std::map()); + }, + static_cast(numparams), node, param_types, l_annotation, guard)), function_name); } else { - // if the type is unknown, then this generates a function that looks up the type // at runtime. Defining the type first before this is called is better auto type = t_ss.get_type(class_name, false); param_types.push_front(class_name, type); - t_ss.add( - std::make_shared(class_name, - std::make_shared(std::bind(chaiscript::eval::detail::eval_function, - std::ref(t_ss), children.back(), - t_param_names, std::placeholders::_1, std::map()), static_cast(numparams), children.back(), - param_types, l_annotation, guard), type), function_name); + t_ss.add(std::make_shared(class_name, + std::make_shared( + [&t_ss, t_param_names, node](const std::vector &t_params) { + return chaiscript::eval::detail::eval_function(t_ss, node, t_param_names, t_params, std::map()); + }, + static_cast(numparams), node, param_types, l_annotation, guard), type), + function_name); } } catch (const exception::reserved_word_error &e) { @@ -1473,15 +1477,14 @@ namespace chaiscript std::string class_name = (itr != d.end())?std::string(boxed_cast(itr->second)):this->children[0]->text; try { + std::string attr_name = this->children[static_cast(1 + class_offset)]->text; + t_ss.add( std::make_shared( std::move(class_name), - fun(std::function( - std::bind(static_cast(&dispatch::Dynamic_Object::get_attr), - std::placeholders::_1, - this->children[static_cast(1 + class_offset)]->text - )) - ), + fun([attr_name](dispatch::Dynamic_Object &t_obj) { + return t_obj.get_attr(attr_name); + }), true ), this->children[static_cast(1 + class_offset)]->text); From bb2938307cbbdf481377ece40d4aa0ac30015804 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 23 May 2015 16:16:39 -0600 Subject: [PATCH 08/11] Move prelude into stdlib so it's not included everywhere --- include/chaiscript/chaiscript_stdlib.hpp | 3 +++ include/chaiscript/language/chaiscript_engine.hpp | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/chaiscript/chaiscript_stdlib.hpp b/include/chaiscript/chaiscript_stdlib.hpp index dc6ff46..c07e64c 100644 --- a/include/chaiscript/chaiscript_stdlib.hpp +++ b/include/chaiscript/chaiscript_stdlib.hpp @@ -18,6 +18,7 @@ #include "dispatchkit/bootstrap.hpp" #include "dispatchkit/bootstrap_stl.hpp" #include "dispatchkit/boxed_value.hpp" +#include "language/chaiscript_prelude.chai" #ifndef CHAISCRIPT_NO_THREADS #include @@ -50,6 +51,8 @@ namespace chaiscript lib->add(chaiscript::fun([](const std::function &t_func){ return std::async(std::launch::async, t_func);}), "async"); #endif + lib->eval(ChaiScript_Prelude::chaiscript_prelude() /*, "standard prelude"*/ ); + return lib; } diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 233f906..a7d3bad 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -44,7 +44,6 @@ #include "../dispatchkit/exception_specification.hpp" #include "chaiscript_parser.hpp" -#include "chaiscript_prelude.chai" namespace chaiscript { @@ -405,7 +404,6 @@ namespace chaiscript m_engine.add(fun([this](const Boxed_Value &t_bv, const std::string &t_name){ add_global_const(t_bv, t_name); }), "add_global_const"); m_engine.add(fun([this](const Boxed_Value &t_bv, const std::string &t_name){ add_global(t_bv, t_name); }), "add_global"); - do_eval(ChaiScript_Prelude::chaiscript_prelude(), "standard prelude"); } From 26a00341761dfefdf624c9ec3ca8878160d0de5f Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 1 Jun 2015 16:07:10 -0600 Subject: [PATCH 09/11] Fixes for g++4.6 --- include/chaiscript/chaiscript_defines.hpp | 2 +- .../dispatchkit/proxy_functions_detail.hpp | 21 ++++++++++++------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/include/chaiscript/chaiscript_defines.hpp b/include/chaiscript/chaiscript_defines.hpp index 6d0fd99..5b3bea5 100644 --- a/include/chaiscript/chaiscript_defines.hpp +++ b/include/chaiscript/chaiscript_defines.hpp @@ -35,7 +35,7 @@ #define CHAISCRIPT_HAS_THREAD_LOCAL #endif -#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ >= 6) +#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 6) #define CHAISCRIPT_GCC_4_6 #endif diff --git a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp index d8a10cc..8257f9b 100644 --- a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp @@ -68,7 +68,10 @@ namespace chaiscript #ifdef CHAISCRIPT_GCC_4_6 /// \todo REMOVE THIS WHEN WE DROP G++4.6 - + // + // + + // Forward declaration template struct Try_Cast; @@ -101,7 +104,7 @@ namespace chaiscript template bool compare_types_cast(Ret (*)(Params...), const std::vector ¶ms, const Type_Conversions &t_conversions) - { + { try { Try_Cast::do_try(params, 0, t_conversions); } catch (const exception::bad_boxed_cast &) { @@ -115,8 +118,8 @@ namespace chaiscript struct Call_Func { - template - static Ret do_call(const std::function &f, + template + static Ret do_call(const Callable &f, const std::vector ¶ms, const Type_Conversions &t_conversions, InnerParams &&... innerparams) { return Call_Func::do_call(f, params, t_conversions, std::forward(innerparams)..., params[sizeof...(Params) - count]); @@ -130,8 +133,8 @@ namespace chaiscript #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 #endif - template - static Ret do_call(const std::function &f, + template + static Ret do_call(const Callable &f, const std::vector &, const Type_Conversions &t_conversions, InnerParams &&... innerparams) { return f(boxed_cast(std::forward(innerparams), &t_conversions)...); @@ -147,8 +150,8 @@ namespace chaiscript * if any unboxing fails the execution of the function fails and * the bad_boxed_cast is passed up to the caller. */ - template - Ret call_func(const std::function &f, + template + Ret call_func(const chaiscript::dispatch::detail::Function_Signature &, const Callable &f, const std::vector ¶ms, const Type_Conversions &t_conversions) { if (params.size() == sizeof...(Params)) @@ -159,6 +162,8 @@ namespace chaiscript throw exception::arity_error(static_cast(params.size()), sizeof...(Params)); } + + #else template From 38a83e3e56dbdcfb53b7686423d8e62b2f100e0d Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 2 Jun 2015 17:35:31 -0600 Subject: [PATCH 10/11] Fix MSVC2013 builds --- include/chaiscript/dispatchkit/callable_traits.hpp | 14 ++++++++++++++ include/chaiscript/dispatchkit/handle_return.hpp | 1 - .../chaiscript/dispatchkit/register_function.hpp | 5 ++--- include/chaiscript/language/chaiscript_parser.hpp | 2 -- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/include/chaiscript/dispatchkit/callable_traits.hpp b/include/chaiscript/dispatchkit/callable_traits.hpp index 5ffa093..9954eea 100644 --- a/include/chaiscript/dispatchkit/callable_traits.hpp +++ b/include/chaiscript/dispatchkit/callable_traits.hpp @@ -12,6 +12,7 @@ namespace chaiscript { namespace dispatch { namespace detail { + template struct Constructor { @@ -34,6 +35,19 @@ namespace chaiscript { Ret (Class::*m_func)(Param...) const; }; + template + struct Fun_Caller + { + Fun_Caller(Ret( * t_func)(Param...) ) : m_func(t_func) {} + + template + Ret operator()(Inner&& ... inner) const { + return (m_func)(std::forward(inner)...); + } + + Ret(*m_func)(Param...); + }; + template struct Caller { diff --git a/include/chaiscript/dispatchkit/handle_return.hpp b/include/chaiscript/dispatchkit/handle_return.hpp index d5bdb9d..e3a8254 100644 --- a/include/chaiscript/dispatchkit/handle_return.hpp +++ b/include/chaiscript/dispatchkit/handle_return.hpp @@ -9,7 +9,6 @@ #include #include -#include #include #include "boxed_number.hpp" diff --git a/include/chaiscript/dispatchkit/register_function.hpp b/include/chaiscript/dispatchkit/register_function.hpp index ecec5ea..598dd8b 100644 --- a/include/chaiscript/dispatchkit/register_function.hpp +++ b/include/chaiscript/dispatchkit/register_function.hpp @@ -7,7 +7,6 @@ #ifndef CHAISCRIPT_REGISTER_FUNCTION_HPP_ #define CHAISCRIPT_REGISTER_FUNCTION_HPP_ -#include #include #include "bind_first.hpp" @@ -48,10 +47,10 @@ namespace chaiscript template Proxy_Function fun(Ret (*func)(Param...)) { - auto f_ref = std::ref(*func); + auto fun_call = dispatch::detail::Fun_Caller(func); return Proxy_Function( - chaiscript::make_shared>(f_ref)); + chaiscript::make_shared>(fun_call)); } diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 1fdc4f5..e35165b 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -7,8 +7,6 @@ #ifndef CHAISCRIPT_PARSER_HPP_ #define CHAISCRIPT_PARSER_HPP_ -#include -#include #include #include #include From ecafb4aad02356badd6eb3f92bf6af03329ab4e1 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 2 Jun 2015 18:20:13 -0600 Subject: [PATCH 11/11] Add missing cstring --- include/chaiscript/language/chaiscript_parser.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index e35165b..7588d40 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -14,6 +14,8 @@ #include #include #include +#include + #include "../dispatchkit/boxed_value.hpp" #include "chaiscript_common.hpp"