| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- // This file is distributed under the BSD License.
- // See "license.txt" for details.
- // Copyright 2009-2012, Jonathan Turner ([email protected])
- // Copyright 2009-2017, Jason Turner ([email protected])
- // 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_PROXY_FUNCTIONS_DETAIL_HPP_
- #define CHAISCRIPT_PROXY_FUNCTIONS_DETAIL_HPP_
- #include <functional>
- #include <stdexcept>
- #include <vector>
- #include <array>
- #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;
- ~arity_error() noexcept override = default;
- int got;
- int expected;
- };
- }
- namespace dispatch
- {
- namespace detail
- {
- /**
- * Used by Proxy_Function_Impl to return a list of all param types
- * it contains.
- */
- template<typename Ret, typename ... Params>
- std::vector<Type_Info> build_param_type_list(Ret (*)(Params...))
- {
- /// \note somehow this is responsible for a large part of the code generation
- return { user_type<Ret>(), user_type<Params>()... };
- }
- /**
- * 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<typename Ret, typename ... Params>
- bool compare_types_cast(Ret (*)(Params...),
- const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions)
- {
- try {
- std::vector<Boxed_Value>::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<int>{(boxed_cast<Params>(params[i++], &t_conversions), 0)...};
- return true;
- } catch (const exception::bad_boxed_cast &) {
- return false;
- }
- }
- template<typename Callable, typename Ret, typename ... Params, size_t ... I>
- Ret call_func(const chaiscript::dispatch::detail::Function_Signature<Ret (Params...)> &,
- std::index_sequence<I...>, const Callable &f,
- const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions)
- {
- (void)params; (void)t_conversions;
- return f(boxed_cast<Params>(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<typename Callable, typename Ret, typename ... Params>
- Boxed_Value call_func(const chaiscript::dispatch::detail::Function_Signature<Ret (Params...)> &sig, const Callable &f,
- const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions)
- {
- return Handle_Return<Ret>::handle(call_func(sig, std::index_sequence_for<Params...>{}, f, params, t_conversions));
- }
- template<typename Callable, typename ... Params>
- Boxed_Value call_func(const chaiscript::dispatch::detail::Function_Signature<void (Params...)> &sig, const Callable &f,
- const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions)
- {
- call_func(sig, std::index_sequence_for<Params...>{}, f, params, t_conversions);
- #ifdef CHAISCRIPT_MSVC
- #pragma warning(push)
- #pragma warning(disable : 4702)
- #endif
- // MSVC is reporting that this is unreachable code - and it's wrong.
- return Handle_Return<void>::handle();
- #ifdef CHAISCRIPT_MSVC
- #pragma warning(pop)
- #endif
- }
- }
- }
- }
- #endif
|