#pragma once #include "function.hpp" #include template struct remove_cv_seq; template struct remove_cv_seq { using type = Return(Args...); }; template struct remove_cv_seq { using type = Return(Args...); }; template struct remove_cv_seq { using type = Return(Args...); }; template constexpr inline auto extract_signature(Function * /*unused*/) noexcept { return Signature::type>(); } template constexpr inline auto extract_signature(Function Class::* /*unused*/) noexcept { return Signature::type>(); } template constexpr inline auto extract_signature(Function const & /*unused*/) noexcept -> decltype(&Function::operator(), extract_signature(&Function::operator())) { return extract_signature(&Function::operator()); } template inline auto get_normalized_lambda(Function &&func, Signature /*unused*/) noexcept { // Static copy of func. This will make it accessible for the lambda without using a // lamda capture static auto static_func = Function(std::forward(func)); return +[](Args... args) noexcept( noexcept(std::declval()(std::forward(args)...))) -> Return { return static_func(std::forward(args)...); }; } /** * Normalizes the type signature of a lambda function. * * This will make a lambda with captures passable to other functions. * * @param func A lambda function * @returns The lambda function normalized. */ template constexpr auto normalize_lambda(Function &&func) noexcept { return get_normalized_lambda( std::forward(func), extract_signature(std::forward(func))); }