diff --git a/include/chaiscript/dispatchkit/function_signature.hpp b/include/chaiscript/dispatchkit/function_signature.hpp index 11c780a4..7c351ec2 100644 --- a/include/chaiscript/dispatchkit/function_signature.hpp +++ b/include/chaiscript/dispatchkit/function_signature.hpp @@ -4,121 +4,142 @@ #include namespace chaiscript::dispatch::detail { - template - struct Function_Params - { - }; - template - struct Function_Signature { - using Param_Types = Params; - using Return_Type = Ret; - constexpr static const bool is_object = IsObject; - constexpr static const bool is_member_object = IsMemberObject; - constexpr static const bool is_noexcept = IsNoExcept; - template - constexpr Function_Signature(T &&) noexcept {} - constexpr Function_Signature() noexcept = default; - }; +template +struct Function_Params +{ +}; - // Free functions +template +struct Function_Signature +{ + using Param_Types = Params; + using Return_Type = Ret; + constexpr static const bool is_object = IsObject; + constexpr static const bool is_member_object = IsMemberObject; + constexpr static const bool is_noexcept = IsNoExcept; + template + constexpr Function_Signature(T &&) noexcept {} + constexpr Function_Signature() noexcept = default; +}; - template - Function_Signature(Ret (*f)(Param...)) -> Function_Signature>; +// Free functions - template - Function_Signature(Ret (*f)(Param...) noexcept) -> Function_Signature, true>; +template +Function_Signature(Ret (*f)(Param...))->Function_Signature>; - // no reference specifier +template +Function_Signature(Ret (*f)(Param...) noexcept)->Function_Signature, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) volatile) -> Function_Signature, false, true>; +// no reference specifier - template - Function_Signature(Ret (Class::*f)(Param ...) volatile noexcept) -> Function_Signature, true, true>; +template +Function_Signature(Ret (Class::*f)(Param...) volatile)->Function_Signature, false, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) volatile const) -> Function_Signature, false, true>; +template +Function_Signature(Ret (Class::*f)(Param...) volatile noexcept)->Function_Signature, true, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) volatile const noexcept) -> Function_Signature, true, true>; +template +Function_Signature(Ret (Class::*f)(Param...) volatile const)->Function_Signature, false, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) ) -> Function_Signature, false, true>; +template +Function_Signature(Ret (Class::*f)(Param...) volatile const noexcept)->Function_Signature, true, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) noexcept) -> Function_Signature, true, true>; +template +Function_Signature(Ret (Class::*f)(Param...))->Function_Signature, false, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) const) -> Function_Signature, false, true>; +template +Function_Signature(Ret (Class::*f)(Param...) noexcept)->Function_Signature, true, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) const noexcept) -> Function_Signature, true, true>; +template +Function_Signature(Ret (Class::*f)(Param...) const)->Function_Signature, false, true>; - // & reference specifier +template +Function_Signature(Ret (Class::*f)(Param...) const noexcept)->Function_Signature, true, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) volatile &) -> Function_Signature, false, true>; +// & reference specifier - template - Function_Signature(Ret (Class::*f)(Param ...) volatile & noexcept) -> Function_Signature, true, true>; +template +Function_Signature(Ret (Class::*f)(Param...) volatile &)->Function_Signature, false, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) volatile const &) -> Function_Signature, false, true>; +template +Function_Signature(Ret (Class::*f)(Param...) volatile &noexcept)->Function_Signature, true, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) volatile const & noexcept) -> Function_Signature, true, true>; +template +Function_Signature(Ret (Class::*f)(Param...) volatile const &)->Function_Signature, false, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) & ) -> Function_Signature, false, true>; +template +Function_Signature(Ret (Class::*f)(Param...) volatile const &noexcept)->Function_Signature, true, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) & noexcept) -> Function_Signature, true, true>; +template +Function_Signature(Ret (Class::*f)(Param...) &)->Function_Signature, false, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) const &) -> Function_Signature, false, true>; +template +Function_Signature(Ret (Class::*f)(Param...) & noexcept)->Function_Signature, true, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) const & noexcept) -> Function_Signature, true, true>; +template +Function_Signature(Ret (Class::*f)(Param...) const &)->Function_Signature, false, true>; - // && reference specifier +template +Function_Signature(Ret (Class::*f)(Param...) const &noexcept)->Function_Signature, true, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) volatile &&) -> Function_Signature, false, true>; +// && reference specifier - template - Function_Signature(Ret (Class::*f)(Param ...) volatile && noexcept) -> Function_Signature, true, true>; +template +Function_Signature(Ret (Class::*f)(Param...) volatile &&)->Function_Signature, false, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) volatile const &&) -> Function_Signature, false, true>; +template +Function_Signature(Ret (Class::*f)(Param...) volatile &&noexcept)->Function_Signature, true, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) volatile const && noexcept) -> Function_Signature, true, true>; +template +Function_Signature(Ret (Class::*f)(Param...) volatile const &&)->Function_Signature, false, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) &&) -> Function_Signature, false, true>; +template +Function_Signature(Ret (Class::*f)(Param...) volatile const &&noexcept)->Function_Signature, true, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) && noexcept) -> Function_Signature, true, true>; +template +Function_Signature(Ret (Class::*f)(Param...) &&)->Function_Signature, false, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) const &&) -> Function_Signature, false, true>; +template +Function_Signature(Ret (Class::*f)(Param...) && noexcept)->Function_Signature, true, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) const && noexcept) -> Function_Signature, true, true>; +template +Function_Signature(Ret (Class::*f)(Param...) const &&)->Function_Signature, false, true>; - template - Function_Signature(Ret (Class::*f)) -> Function_Signature, true, true, true>; +template +Function_Signature(Ret (Class::*f)(Param...) const &&noexcept)->Function_Signature, true, true>; - template - Function_Signature(Func &&) -> Function_Signature< - typename decltype(Function_Signature{&std::decay_t::operator()})::Return_Type, - typename decltype(Function_Signature{&std::decay_t::operator()})::Param_Types, - decltype(Function_Signature{&std::decay_t::operator()})::is_noexcept, - false, - false, - true - >; +template +Function_Signature(Ret(Class::*f))->Function_Signature, true, true, true>; + +// primary template handles types that have no nested ::type member: +template> +struct has_call_operator : std::false_type +{ +}; + +// specialization recognizes types that do have a nested ::type member: +template +struct has_call_operator> : std::true_type +{ +}; + +template +auto function_signature(const Func &f) +{ + if constexpr (has_call_operator::value) { + return Function_Signature< + typename decltype(Function_Signature{ &std::decay_t::operator() })::Return_Type, + typename decltype(Function_Signature{ &std::decay_t::operator() })::Param_Types, + decltype(Function_Signature{ &std::decay_t::operator() })::is_noexcept, + false, + false, + true>{}; + } else { + return Function_Signature{ f }; + } } +}// namespace chaiscript::dispatch::detail + #endif diff --git a/include/chaiscript/dispatchkit/register_function.hpp b/include/chaiscript/dispatchkit/register_function.hpp index 907b0035..9a61bfe9 100644 --- a/include/chaiscript/dispatchkit/register_function.hpp +++ b/include/chaiscript/dispatchkit/register_function.hpp @@ -87,7 +87,7 @@ namespace chaiscript template Proxy_Function fun(T &&t) { - return dispatch::detail::make_callable(std::forward(t), dispatch::detail::Function_Signature{t}); + return dispatch::detail::make_callable(std::forward(t), dispatch::detail::function_signature(t)); }