// This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. // PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com #ifndef CHAISCRIPT_FUNCTION_CALL_DETAIL_HPP_ #define CHAISCRIPT_FUNCTION_CALL_DETAIL_HPP_ #include #include #include #include #include #include "boxed_cast.hpp" #include "boxed_number.hpp" #include "boxed_value.hpp" #include "proxy_functions.hpp" #include "type_conversions.hpp" namespace chaiscript::dispatch::detail { /// used internally for unwrapping a function call's types template struct Build_Function_Caller_Helper { Build_Function_Caller_Helper(std::vector t_funcs, const Type_Conversions *t_conversions) : m_funcs(std::move(t_funcs)) , m_conversions(t_conversions) { } Ret call(const chaiscript::Function_Params ¶ms, const Type_Conversions_State &t_state) { if constexpr (std::is_arithmetic_v && !std::is_same_v>, bool>) { return Boxed_Number(dispatch::dispatch(m_funcs, params, t_state)).get_as(); } else if constexpr (std::is_same_v) { dispatch::dispatch(m_funcs, params, t_state); } else { return boxed_cast(dispatch::dispatch(m_funcs, params, t_state), &t_state); } } template Ret operator()(P &&...param) { std::array params{box

(std::forward

(param))...}; if (m_conversions) { Type_Conversions_State state(*m_conversions, m_conversions->conversion_saves()); return call(chaiscript::Function_Params{params}, state); } else { Type_Conversions conv; Type_Conversions_State state(conv, conv.conversion_saves()); return call(chaiscript::Function_Params{params}, state); } } template static Boxed_Value box(Q &&q) { if constexpr (std::is_same_v>) { return std::forward(q); } else if constexpr (std::is_reference_v

) { return Boxed_Value(std::ref(std::forward(q))); } else { return Boxed_Value(std::forward(q)); } } std::vector m_funcs; const Type_Conversions *m_conversions; }; /// \todo what happens if t_conversions is deleted out from under us?! 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)); } } // namespace chaiscript::dispatch::detail #endif