diff --git a/sol/resolve.hpp b/sol/resolve.hpp index 4e8d331b..57964559 100644 --- a/sol/resolve.hpp +++ b/sol/resolve.hpp @@ -26,6 +26,9 @@ #include "tuple.hpp" namespace sol { + // Clang has distinct problems with constexpr arguments, + // so don't use the constexpr versions inside of clang. +#ifndef __clang__ namespace detail { template(Args...)>> inline constexpr auto resolve_i(types, F&&)->R(meta::unqualified_t::*)(Args...) { @@ -87,10 +90,77 @@ namespace sol { return detail::resolve_v(std::is_member_object_pointer(), mem_ptr); } - template + template>> = meta::enabler> inline constexpr auto resolve(F&& f) -> decltype(detail::resolve_i(types(), std::forward(f))) { return detail::resolve_i(types(), std::forward(f)); } +#else + namespace detail { + template(Args...)>> + inline auto resolve_i(types, F&&)->R(meta::unqualified_t::*)(Args...) { + using Sig = R(Args...); + typedef meta::unqualified_t Fu; + return static_cast(&Fu::operator()); + } + + template> + inline auto resolve_f(std::true_type, F&& f) + -> decltype(resolve_i(types>(), std::forward(f))) { + return resolve_i(types>(), std::forward(f)); + } + + template + inline void resolve_f(std::false_type, F&&) { + static_assert(meta::has_deducible_signature::value, + "Cannot use no-template-parameter call with an overloaded functor: specify the signature"); + } + + template> + inline auto resolve_i(types<>, F&& f) -> decltype(resolve_f(meta::has_deducible_signature(), std::forward(f))) { + return resolve_f(meta::has_deducible_signature {}, std::forward(f)); + } + + template> + inline auto resolve_i(types, F&& f) -> decltype(resolve_i(types(), std::forward(f))) { + return resolve_i(types(), std::forward(f)); + } + + template + inline Sig C::* resolve_v(std::false_type, Sig C::* mem_func_ptr) { + return mem_func_ptr; + } + + template + inline Sig C::* resolve_v(std::true_type, Sig C::* mem_variable_ptr) { + return mem_variable_ptr; + } + } // detail + + template + inline auto resolve(R fun_ptr(Args...))->R(*)(Args...) { + return fun_ptr; + } + + template + inline Sig* resolve(Sig* fun_ptr) { + return fun_ptr; + } + + template + inline auto resolve(R(C::*mem_ptr)(Args...))->R(C::*)(Args...) { + return mem_ptr; + } + + template + inline Sig C::* resolve(Sig C::* mem_ptr) { + return detail::resolve_v(std::is_member_object_pointer(), mem_ptr); + } + + template + inline auto resolve(F&& f) -> decltype(detail::resolve_i(types(), std::forward(f))) { + return detail::resolve_i(types(), std::forward(f)); + } +#endif } // sol #endif // SOL_RESOLVE_HPP