diff --git a/CMakeLists.txt b/CMakeLists.txt index f1b3108d..24093339 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -213,7 +213,7 @@ endif() include_directories(include) -set(Chai_INCLUDES include/chaiscript/chaiscript.hpp include/chaiscript/chaiscript_threading.hpp include/chaiscript/dispatchkit/bad_boxed_cast.hpp include/chaiscript/dispatchkit/bind_first.hpp include/chaiscript/dispatchkit/bootstrap.hpp include/chaiscript/dispatchkit/bootstrap_stl.hpp include/chaiscript/dispatchkit/boxed_cast.hpp include/chaiscript/dispatchkit/boxed_cast_helper.hpp include/chaiscript/dispatchkit/boxed_number.hpp include/chaiscript/dispatchkit/boxed_value.hpp include/chaiscript/dispatchkit/dispatchkit.hpp include/chaiscript/dispatchkit/type_conversions.hpp include/chaiscript/dispatchkit/dynamic_object.hpp include/chaiscript/dispatchkit/exception_specification.hpp include/chaiscript/dispatchkit/function_call.hpp include/chaiscript/dispatchkit/function_call_detail.hpp include/chaiscript/dispatchkit/handle_return.hpp include/chaiscript/dispatchkit/operators.hpp include/chaiscript/dispatchkit/proxy_constructors.hpp include/chaiscript/dispatchkit/proxy_functions.hpp include/chaiscript/dispatchkit/proxy_functions_detail.hpp include/chaiscript/dispatchkit/register_function.hpp include/chaiscript/dispatchkit/type_info.hpp include/chaiscript/language/chaiscript_algebraic.hpp include/chaiscript/language/chaiscript_common.hpp include/chaiscript/language/chaiscript_engine.hpp include/chaiscript/language/chaiscript_eval.hpp include/chaiscript/language/chaiscript_parser.hpp include/chaiscript/language/chaiscript_prelude.hpp include/chaiscript/language/chaiscript_prelude_docs.hpp include/chaiscript/utility/utility.hpp include/chaiscript/utility/json.hpp include/chaiscript/utility/json_wrap.hpp) +set(Chai_INCLUDES include/chaiscript/chaiscript.hpp include/chaiscript/chaiscript_threading.hpp include/chaiscript/dispatchkit/bad_boxed_cast.hpp include/chaiscript/dispatchkit/bind_first.hpp include/chaiscript/dispatchkit/bootstrap.hpp include/chaiscript/dispatchkit/bootstrap_stl.hpp include/chaiscript/dispatchkit/boxed_cast.hpp include/chaiscript/dispatchkit/boxed_cast_helper.hpp include/chaiscript/dispatchkit/boxed_number.hpp include/chaiscript/dispatchkit/boxed_value.hpp include/chaiscript/dispatchkit/dispatchkit.hpp include/chaiscript/dispatchkit/type_conversions.hpp include/chaiscript/dispatchkit/dynamic_object.hpp include/chaiscript/dispatchkit/exception_specification.hpp include/chaiscript/dispatchkit/function_call.hpp include/chaiscript/dispatchkit/function_call_detail.hpp include/chaiscript/dispatchkit/handle_return.hpp include/chaiscript/dispatchkit/operators.hpp include/chaiscript/dispatchkit/proxy_constructors.hpp include/chaiscript/dispatchkit/proxy_functions.hpp include/chaiscript/dispatchkit/register_function.hpp include/chaiscript/dispatchkit/type_info.hpp include/chaiscript/language/chaiscript_algebraic.hpp include/chaiscript/language/chaiscript_common.hpp include/chaiscript/language/chaiscript_engine.hpp include/chaiscript/language/chaiscript_eval.hpp include/chaiscript/language/chaiscript_parser.hpp include/chaiscript/language/chaiscript_prelude.hpp include/chaiscript/language/chaiscript_prelude_docs.hpp include/chaiscript/utility/utility.hpp include/chaiscript/utility/json.hpp include/chaiscript/utility/json_wrap.hpp) set_source_files_properties(${Chai_INCLUDES} PROPERTIES HEADER_FILE_ONLY TRUE) diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 1f519dc8..0be76626 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -28,7 +28,6 @@ #include "operators.hpp" #include "proxy_constructors.hpp" #include "proxy_functions.hpp" -#include "proxy_functions_detail.hpp" #include "register_function.hpp" #include "type_info.hpp" #include "../utility/utility.hpp" diff --git a/include/chaiscript/dispatchkit/callable_traits.hpp b/include/chaiscript/dispatchkit/callable_traits.hpp index 765e6d67..1f971c95 100644 --- a/include/chaiscript/dispatchkit/callable_traits.hpp +++ b/include/chaiscript/dispatchkit/callable_traits.hpp @@ -13,53 +13,6 @@ 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 - { - 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 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 - { - 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 Arity diff --git a/include/chaiscript/dispatchkit/function_call_detail.hpp b/include/chaiscript/dispatchkit/function_call_detail.hpp index 8ed6115c..f941d2ef 100644 --- a/include/chaiscript/dispatchkit/function_call_detail.hpp +++ b/include/chaiscript/dispatchkit/function_call_detail.hpp @@ -141,22 +141,6 @@ namespace chaiscript template std::function build_function_caller_helper(Ret (Params...), const std::vector &funcs, const Type_Conversions_State *t_conversions) { - /* - if (funcs.size() == 1) - { - std::shared_ptr> pfi = - std::dynamic_pointer_cast > - (funcs[0]); - - if (pfi) - { - return pfi->internal_function(); - } - // 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->get():nullptr)); } } diff --git a/include/chaiscript/dispatchkit/handle_return.hpp b/include/chaiscript/dispatchkit/handle_return.hpp index ca353ecf..6c3da813 100644 --- a/include/chaiscript/dispatchkit/handle_return.hpp +++ b/include/chaiscript/dispatchkit/handle_return.hpp @@ -20,11 +20,19 @@ class Boxed_Number; namespace chaiscript { + template std::shared_ptr fun(const T &t); + + template + std::shared_ptr assignable_fun( + std::reference_wrapper> t_func, + std::shared_ptr> t_ptr + ); + namespace dispatch { - template class Proxy_Function_Callable_Impl; template class Assignable_Proxy_Function_Impl; + namespace detail { /** @@ -53,7 +61,7 @@ namespace chaiscript { static Boxed_Value handle(const std::function &f) { return Boxed_Value( - chaiscript::make_shared>>(f) + chaiscript::fun(f) ); } }; @@ -68,7 +76,7 @@ namespace chaiscript { static Boxed_Value handle(const std::shared_ptr> &f) { return Boxed_Value( - chaiscript::make_shared>(std::ref(*f),f) + assignable_fun(std::ref(*f), f) ); } }; @@ -88,14 +96,13 @@ namespace chaiscript { static Boxed_Value handle(std::function &f) { return Boxed_Value( - chaiscript::make_shared>(std::ref(f), - std::shared_ptr>()) + assignable_fun(std::ref(f), std::shared_ptr>()) ); } static Boxed_Value handle(const std::function &f) { return Boxed_Value( - chaiscript::make_shared>>(f) + chaiscript::fun(f) ); } }; diff --git a/include/chaiscript/dispatchkit/proxy_constructors.hpp b/include/chaiscript/dispatchkit/proxy_constructors.hpp index a5ad41ec..05a03978 100644 --- a/include/chaiscript/dispatchkit/proxy_constructors.hpp +++ b/include/chaiscript/dispatchkit/proxy_constructors.hpp @@ -17,13 +17,32 @@ namespace chaiscript namespace detail { - template - Proxy_Function build_constructor_(Class (*)(Params...)) + template + Proxy_Function build_constructor_(Class (*)(Params...), std::index_sequence) { - auto call = dispatch::detail::Constructor(); + return [](){ + class Func final : public dispatch::Proxy_Function_Impl_Base + { + public: + Func() + : dispatch::Proxy_Function_Impl_Base({user_type>(), user_type()...}) + { + } - return Proxy_Function( - chaiscript::make_shared (Params...), decltype(call)>>(call)); + bool compare_types_with_cast(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override + { + return compare_types_with_cast_impl(params, t_conversions); + } + + protected: + Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override + { + return Handle_Return>::handle(std::make_shared(boxed_cast(params[I], &t_conversions)...)); + } + }; + + return chaiscript::make_shared(); + }(); } } } @@ -44,7 +63,7 @@ namespace chaiscript Proxy_Function constructor() { T *f = nullptr; - return (dispatch::detail::build_constructor_(f)); + return dispatch::detail::build_constructor_(f, std::make_index_sequence::arity>()); } } diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index e7a8ad90..9e96cc02 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -21,15 +21,34 @@ #include "../chaiscript_defines.hpp" #include "boxed_cast.hpp" #include "boxed_value.hpp" -#include "proxy_functions_detail.hpp" #include "type_info.hpp" #include "dynamic_object.hpp" +#include "callable_traits.hpp" +#include "handle_return.hpp" namespace chaiscript { class Type_Conversions; namespace exception { class bad_boxed_cast; -struct arity_error; + /** + * Exception thrown when there is a mismatch in number of + * parameters during Proxy_Function execution + */ + struct arity_error : std::range_error + { + arity_error(int t_got, int t_expected) + : std::range_error("Function dispatch arity mismatch"), + got(t_got), expected(t_expected) + { + } + + arity_error(const arity_error &) = default; + + virtual ~arity_error() noexcept {} + + int got; + int expected; + }; } // namespace exception } // namespace chaiscript @@ -559,6 +578,48 @@ namespace chaiscript return ""; } + bool operator==(const Proxy_Function_Base &t_func) const override + { + const auto *t_other = dynamic_cast(&t_func); + return + t_other != nullptr && + t_other->m_types.size() == m_types.size() && + [this, &t_other](){ + auto begin1 = std::begin(m_types); + const auto end1 = std::end(m_types); + auto begin2 = std::begin(t_other->m_types); + + while (begin1 != end1) { + if (*begin1 != *begin2) { + return false; + } + if (begin1->is_const() != begin2->is_const()) { + return false; + } + ++begin1; + ++begin2; + } + + return true; + }(); + } + + template + static bool compare_types_with_cast_impl(const std::vector ¶ms, const Type_Conversions_State &t_conversions) + { + try { + std::vector::size_type i = 0; + (void)i; (void)params; (void)t_conversions; + // this is ok because the order of evaluation of initializer lists is well defined + (void)std::initializer_list{(boxed_cast(params[i++], &t_conversions), 0)...}; + return true; + } catch (const exception::bad_boxed_cast &) { + return false; + } + } + + + bool call_match(const std::vector &vals, const Type_Conversions_State &t_conversions) const override { return static_cast(vals.size()) == get_arity() @@ -569,41 +630,6 @@ namespace chaiscript }; - - /// For any callable object - template - class Proxy_Function_Callable_Impl final : 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)) - { - } - - bool compare_types_with_cast(const std::vector &vals, const Type_Conversions_State &t_conversions) const override - { - return detail::compare_types_cast(static_cast(nullptr), vals, t_conversions); - } - - bool operator==(const Proxy_Function_Base &t_func) const override - { - return dynamic_cast *>(&t_func) != nullptr; - } - - - protected: - Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override - { - typedef typename detail::Function_Signature::Return_Type Return_Type; - return detail::Do_Call::template go(m_f, params, t_conversions); - } - - private: - Callable m_f; - }; - - class Assignable_Proxy_Function : public Proxy_Function_Impl_Base { public: @@ -615,47 +641,6 @@ namespace chaiscript virtual void assign(const std::shared_ptr &t_rhs) = 0; }; - template - class Assignable_Proxy_Function_Impl final : public Assignable_Proxy_Function - { - 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)) - { - assert(!m_shared_ptr_holder || m_shared_ptr_holder.get() == &m_f.get()); - } - - bool compare_types_with_cast(const std::vector &vals, const Type_Conversions_State &t_conversions) const override - { - return detail::compare_types_cast(static_cast(nullptr), vals, t_conversions); - } - - bool operator==(const Proxy_Function_Base &t_func) const override - { - return dynamic_cast *>(&t_func) != nullptr; - } - - std::function internal_function() const - { - return m_f.get(); - } - - void assign(const std::shared_ptr &t_rhs) override { - m_f.get() = dispatch::functor(t_rhs, nullptr); - } - - protected: - Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override - { - return detail::Do_Call::result_type>::template go(m_f.get(), params, t_conversions); - } - - - private: - std::reference_wrapper> m_f; - std::shared_ptr> m_shared_ptr_holder; - }; /// Attribute getter Proxy_Function implementation diff --git a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp deleted file mode 100644 index 69b88a82..00000000 --- a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp +++ /dev/null @@ -1,151 +0,0 @@ -// This file is distributed under the BSD License. -// See "license.txt" for details. -// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2016, Jason Turner (jason@emptycrate.com) -// http://www.chaiscript.com - -#ifndef CHAISCRIPT_PROXY_FUNCTIONS_DETAIL_HPP_ -#define CHAISCRIPT_PROXY_FUNCTIONS_DETAIL_HPP_ - -#include -#include -#include -#include - -#include "../chaiscript_defines.hpp" -#include "boxed_cast.hpp" -#include "boxed_value.hpp" -#include "handle_return.hpp" -#include "type_info.hpp" -#include "callable_traits.hpp" - -namespace chaiscript { -class Type_Conversions_State; -namespace exception { -class bad_boxed_cast; -} // namespace exception -} // namespace chaiscript - -namespace chaiscript -{ - namespace exception - { - /** - * Exception thrown when there is a mismatch in number of - * parameters during Proxy_Function execution - */ - struct arity_error : std::range_error - { - arity_error(int t_got, int t_expected) - : std::range_error("Function dispatch arity mismatch"), - got(t_got), expected(t_expected) - { - } - - arity_error(const arity_error &) = default; - - virtual ~arity_error() noexcept {} - - int got; - int expected; - }; - } - - namespace dispatch - { - namespace detail - { - /** - * Used by Proxy_Function_Impl to return a list of all param types - * it contains. - */ - template - std::vector build_param_type_list(Ret (*)(Params...)) - { - /// \note somehow this is responsible for a large part of the code generation - return { user_type(), user_type()... }; - } - - - /** - * Used by Proxy_Function_Impl to determine if it is equivalent to another - * Proxy_Function_Impl object. This function is primarily used to prevent - * registration of two functions with the exact same signatures - */ - template - bool compare_types_cast(Ret (*)(Params...), - const std::vector ¶ms, const Type_Conversions_State &t_conversions) - { - try { - std::vector::size_type i = 0; - (void)i; - (void)params; (void)t_conversions; - // this is ok because the order of evaluation of initializer lists is well defined - (void)std::initializer_list{(boxed_cast(params[i++], &t_conversions), 0)...}; - return true; - } catch (const exception::bad_boxed_cast &) { - return false; - } - } - - - template - Ret call_func(const chaiscript::dispatch::detail::Function_Signature &, - std::index_sequence, const Callable &f, - const std::vector ¶ms, const Type_Conversions_State &t_conversions) - { - (void)params; (void)t_conversions; - return f(boxed_cast(params[I], &t_conversions)...); - } - - - /** - * Used by Proxy_Function_Impl to perform typesafe execution of a function. - * The function attempts to unbox each parameter to the expected type. - * 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 chaiscript::dispatch::detail::Function_Signature &sig, const Callable &f, - const std::vector ¶ms, const Type_Conversions_State &t_conversions) - { - return call_func(sig, std::index_sequence_for{}, f, params, t_conversions); - } - - } - } - -} - - -namespace chaiscript -{ - namespace dispatch - { - namespace detail - { - template - struct Do_Call - { - template - static Boxed_Value go(const Callable &fun, const std::vector ¶ms, const Type_Conversions_State &t_conversions) - { - return Handle_Return::handle(call_func(Function_Signature(), fun, params, t_conversions)); - } - }; - - template<> - struct Do_Call - { - template - static Boxed_Value go(const Callable &fun, const std::vector ¶ms, const Type_Conversions_State &t_conversions) - { - call_func(Function_Signature(), fun, params, t_conversions); - return Handle_Return::handle(); - } - }; - } - } -} - -#endif diff --git a/include/chaiscript/dispatchkit/register_function.hpp b/include/chaiscript/dispatchkit/register_function.hpp index 8334b7b6..7139ca1f 100644 --- a/include/chaiscript/dispatchkit/register_function.hpp +++ b/include/chaiscript/dispatchkit/register_function.hpp @@ -11,6 +11,8 @@ #include "bind_first.hpp" #include "proxy_functions.hpp" +#include "handle_return.hpp" +#include "function_call.hpp" namespace chaiscript { @@ -35,45 +37,396 @@ namespace chaiscript /// \endcode /// /// \sa \ref adding_functions + // + // + template + Proxy_Function assignable_fun( + std::reference_wrapper> t_func, + std::shared_ptr> t_ptr, + std::index_sequence) + { + return [t_func, t_ptr](){ + class Func final : public dispatch::Assignable_Proxy_Function + { + public: + Func(std::reference_wrapper> t_f, std::shared_ptr> t_p) + : Assignable_Proxy_Function({user_type(), user_type()...}), + m_f(std::move(t_f)), m_shared_ptr_holder(std::move(t_p)) + { + assert(!m_shared_ptr_holder || m_shared_ptr_holder.get() == &m_f.get()); + } + + bool compare_types_with_cast(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override + { + return compare_types_with_cast_impl(params, t_conversions); + } + + void assign(const std::shared_ptr &t_rhs) override { + m_f.get() = dispatch::functor(t_rhs, nullptr); + } + + protected: + Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override + { + m_f(boxed_cast(params.at(I), &t_conversions)...); + return dispatch::detail::Handle_Return::handle(); + } + + private: + std::reference_wrapper> m_f; + std::shared_ptr> m_shared_ptr_holder; + }; + + return chaiscript::make_shared(t_func, t_ptr); + }(); + } + + template + Proxy_Function assignable_fun( + std::reference_wrapper> t_func, + std::shared_ptr> t_ptr, + std::index_sequence) + { + return [t_func, t_ptr](){ + class Func final : public dispatch::Assignable_Proxy_Function + { + public: + Func(std::reference_wrapper> t_f, std::shared_ptr> t_p) + : Assignable_Proxy_Function({user_type(), user_type()...}), + m_f(std::move(t_f)), m_shared_ptr_holder(std::move(t_p)) + { + assert(!m_shared_ptr_holder || m_shared_ptr_holder.get() == &m_f.get()); + } + + bool compare_types_with_cast(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override + { + return compare_types_with_cast_impl(params, t_conversions); + } + + void assign(const std::shared_ptr &t_rhs) override { + m_f.get() = dispatch::functor(t_rhs, nullptr); + } + + protected: + Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override + { + return dispatch::detail::Handle_Return::handle(m_f(boxed_cast(params.at(I), &t_conversions)...)); + } + + private: + std::reference_wrapper> m_f; + std::shared_ptr> m_shared_ptr_holder; + }; + + return chaiscript::make_shared(t_func, t_ptr); + }(); + } + + template + Proxy_Function assignable_fun( + std::reference_wrapper> t_func, + std::shared_ptr> t_ptr + ) + { + return assignable_fun(std::move(t_func), std::move(t_ptr), std::make_index_sequence()); + } + + + template + Proxy_Function fun(const T &t_func, void (*)(Param...), std::index_sequence) + { + return [t_func](){ + class Func final : public dispatch::Proxy_Function_Impl_Base + { + public: + Func(const T &func) + : dispatch::Proxy_Function_Impl_Base({user_type(), user_type()...}), + m_f(func) + { + } + + bool compare_types_with_cast(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override + { + return compare_types_with_cast_impl(params, t_conversions); + } + + protected: + Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override + { + m_f(boxed_cast(params[I], &t_conversions)...); + return dispatch::detail::Handle_Return::handle(); + } + + private: + T m_f; + }; + + return chaiscript::make_shared(t_func); + }(); + } + + template + Proxy_Function fun(const T &t_func, Ret (*)(Param...), std::index_sequence) + { + return [t_func](){ + class Func final : public dispatch::Proxy_Function_Impl_Base + { + public: + Func(const T &func) + : dispatch::Proxy_Function_Impl_Base({user_type(), user_type()...}), + m_f(func) + { + } + + bool compare_types_with_cast(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override + { + return compare_types_with_cast_impl(params, t_conversions); + } + + protected: + Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override + { + return dispatch::detail::Handle_Return::handle(m_f(boxed_cast(params.at(I), &t_conversions)...)); + } + + private: + T m_f; + }; + + return chaiscript::make_shared(t_func); + }(); + } + template Proxy_Function fun(const T &t) { typedef typename dispatch::detail::Callable_Traits::Signature Signature; - - return Proxy_Function( - chaiscript::make_shared>(t)); + Signature *f = nullptr; + return fun(t, f, std::make_index_sequence::arity>()); } - template - Proxy_Function fun(Ret (*func)(Param...)) + template + Proxy_Function fun(void (*t_func)(Param...), std::index_sequence) { - auto fun_call = dispatch::detail::Fun_Caller(func); + return [t_func](){ + class Func final : public dispatch::Proxy_Function_Impl_Base + { + public: + Func(decltype(t_func) func) + : dispatch::Proxy_Function_Impl_Base({user_type(), user_type()...}), + m_f(func) + { + } - return Proxy_Function( - chaiscript::make_shared>(fun_call)); + bool compare_types_with_cast(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override + { + return compare_types_with_cast_impl(params, t_conversions); + } + + protected: + Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override + { + (*m_f)(boxed_cast(params[I], &t_conversions)...); + return dispatch::detail::Handle_Return::handle(); + } + + private: + decltype(t_func) m_f; + }; + + return chaiscript::make_shared(t_func); + }(); + } + + template + Proxy_Function fun(Ret (*t_func)(Param...), std::index_sequence) + { + return [t_func](){ + class Func final : public dispatch::Proxy_Function_Impl_Base + { + public: + Func(decltype(t_func) func) + : dispatch::Proxy_Function_Impl_Base({user_type(), user_type()...}), + m_f(func) + { + } + + bool compare_types_with_cast(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override + { + return compare_types_with_cast_impl(params, t_conversions); + } + + protected: + Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override + { + return dispatch::detail::Handle_Return::handle((*m_f)(boxed_cast(params[I], &t_conversions)...)); + } + + private: + decltype(t_func) m_f; + }; + + return chaiscript::make_shared(t_func); + }(); + } + + + + template + Proxy_Function fun(void (Class::*t_func)(Param...) const, std::index_sequence) + { + return [t_func](){ + class Func final : public dispatch::Proxy_Function_Impl_Base + { + public: + Func(decltype(t_func) func) + : dispatch::Proxy_Function_Impl_Base({user_type(), user_type(), user_type()...}), + m_f(func) + { + } + + bool compare_types_with_cast(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override + { + return compare_types_with_cast_impl(params, t_conversions); + } + + protected: + Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override + { + const Class &o = static_cast(boxed_cast(params[0], &t_conversions)); + (o.*m_f)(boxed_cast(params[I+1], &t_conversions)...); + return dispatch::detail::Handle_Return::handle(); + } + + private: + decltype(t_func) m_f; + }; + + return chaiscript::make_shared(t_func); + }(); + } + + template + Proxy_Function fun(Ret (Class::*t_func)(Param...) const, std::index_sequence) + { + return [t_func](){ + class Func final : public dispatch::Proxy_Function_Impl_Base + { + public: + Func(decltype(t_func) func) + : dispatch::Proxy_Function_Impl_Base({user_type(), user_type(), user_type()...}), + m_f(func) + { + } + + bool compare_types_with_cast(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override + { + return compare_types_with_cast_impl(params, t_conversions); + } + + protected: + Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override + { + const Class &o = static_cast(boxed_cast(params[0], &t_conversions)); + return dispatch::detail::Handle_Return::handle((o.*m_f)(boxed_cast(params[I+1], &t_conversions)...)); + } + + private: + decltype(t_func) m_f; + }; + + return chaiscript::make_shared(t_func); + }(); + } + + + template + Proxy_Function fun(void (Class::*t_func)(Param...), std::index_sequence) + { + return [t_func](){ + class Func final : public dispatch::Proxy_Function_Impl_Base + { + public: + Func(decltype(t_func) func) + : dispatch::Proxy_Function_Impl_Base({user_type(), user_type(), user_type()...}), + m_f(func) + { + } + + bool compare_types_with_cast(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override + { + return compare_types_with_cast_impl(params, t_conversions); + } + + protected: + Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override + { + Class &o = static_cast(boxed_cast(params[0], &t_conversions)); + (o.*m_f)(boxed_cast(params[I+1], &t_conversions)...); + return dispatch::detail::Handle_Return::handle(); + } + + private: + decltype(t_func) m_f; + }; + + return chaiscript::make_shared(t_func); + }(); + } + + template + Proxy_Function fun(Ret (Class::*t_func)(Param...), std::index_sequence) + { + return [t_func](){ + class Func final : public dispatch::Proxy_Function_Impl_Base + { + public: + Func(decltype(t_func) func) + : dispatch::Proxy_Function_Impl_Base({user_type(), user_type(), user_type()...}), + m_f(func) + { + } + + bool compare_types_with_cast(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override + { + return compare_types_with_cast_impl(params, t_conversions); + } + + protected: + Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override + { + Class &o = static_cast(boxed_cast(params[0], &t_conversions)); + return dispatch::detail::Handle_Return::handle((o.*m_f)(boxed_cast(params[I+1], &t_conversions)...)); + } + + private: + decltype(t_func) m_f; + }; + + return chaiscript::make_shared(t_func); + }(); } template Proxy_Function fun(Ret (Class::*t_func)(Param...) const) { - auto call = dispatch::detail::Const_Caller(t_func); - - return Proxy_Function( - chaiscript::make_shared>(call)); + return fun(t_func, std::make_index_sequence()); } + template + Proxy_Function fun(Ret (*func)(Param...)) + { + return fun(func, std::make_index_sequence()); + } + + template Proxy_Function fun(Ret (Class::*t_func)(Param...)) { - auto call = dispatch::detail::Caller(t_func); - - return Proxy_Function( - chaiscript::make_shared>(call)); - + return fun(t_func, std::make_index_sequence()); } - template::value>::type*/> Proxy_Function fun(T Class::* m /*, typename std::enable_if::value>::type* = 0*/ ) { diff --git a/include/chaiscript/dispatchkit/type_info.hpp b/include/chaiscript/dispatchkit/type_info.hpp index 9dfdb8f0..f515a3dc 100644 --- a/include/chaiscript/dispatchkit/type_info.hpp +++ b/include/chaiscript/dispatchkit/type_info.hpp @@ -53,6 +53,11 @@ namespace chaiscript || *ti.m_type_info == *m_type_info; } + constexpr bool operator!=(const Type_Info &ti) const noexcept + { + return !(*this == ti); + } + constexpr bool operator==(const std::type_info &ti) const noexcept { return !is_undef() && (*m_type_info) == ti; diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index b692538c..859491ca 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -24,7 +24,6 @@ #include "../dispatchkit/dispatchkit.hpp" #include "../dispatchkit/dynamic_object_detail.hpp" #include "../dispatchkit/proxy_functions.hpp" -#include "../dispatchkit/proxy_functions_detail.hpp" #include "../dispatchkit/register_function.hpp" #include "../dispatchkit/type_info.hpp" #include "chaiscript_algebraic.hpp"