diff options
author | HampusM <hampus@hampusmat.com> | 2022-06-02 20:50:28 +0200 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2022-06-13 17:57:00 +0200 |
commit | 7578eb6f79afbb421298088ee53da620eb04037f (patch) | |
tree | 6784011258b6967e75cf8478356c651c1c45938b /src/util/function_impl.hpp | |
parent | ea5cd08dd67f9bc4351ecebdda9e310a8072ae32 (diff) |
refactor: rename .tpp files to end with _impl.hpp
Diffstat (limited to 'src/util/function_impl.hpp')
-rw-r--r-- | src/util/function_impl.hpp | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/src/util/function_impl.hpp b/src/util/function_impl.hpp new file mode 100644 index 0000000..9d3d38c --- /dev/null +++ b/src/util/function_impl.hpp @@ -0,0 +1,76 @@ +#pragma once + +#include "function.hpp" + +#include <utility> + +template <typename> +struct remove_cv_seq; + +template <typename Return, typename... Args> +struct remove_cv_seq<Return(Args...)> +{ + using type = Return(Args...); +}; + +template <typename Return, typename... Args> +struct remove_cv_seq<Return(Args...) const> +{ + using type = Return(Args...); +}; + +template <typename Return, typename... Args> +struct remove_cv_seq<Return(Args...) &> +{ + using type = Return(Args...); +}; + +template <typename Function> +constexpr inline auto extract_signature(Function * /*unused*/) noexcept +{ + return Signature<typename remove_cv_seq<Function>::type>(); +} + +template <typename Class, typename Function> +constexpr inline auto extract_signature(Function Class::* /*unused*/) noexcept +{ + return Signature<typename remove_cv_seq<Function>::type>(); +} + +template <typename Function> +constexpr inline auto extract_signature(Function const & /*unused*/) noexcept + -> decltype(&Function::operator(), extract_signature(&Function::operator())) +{ + return extract_signature(&Function::operator()); +} + +template <typename Function, typename Return, typename... Args> +inline auto +get_normalized_lambda(Function &&func, Signature<Return(Args...)> /*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<Function>(func)); + + return +[](Args... args) noexcept( + noexcept(std::declval<Function>()(std::forward<Args>(args)...))) -> Return + { + return static_func(std::forward<Args>(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 <typename Function> +constexpr auto normalize_lambda(Function &&func) noexcept +{ + return get_normalized_lambda( + std::forward<Function>(func), + extract_signature(std::forward<Function>(func))); +} |