#ifndef GNR_CIFY_HPP # define GNR_CIFY_HPP # pragma once #include #include namespace gnr { namespace cify_ { template struct signature { }; // template struct remove_cv_seq; // template struct remove_cv_seq { using type = R(A...); }; template struct remove_cv_seq { using type = R(A...); }; template struct remove_cv_seq { using type = R(A...); }; template struct remove_cv_seq { using type = R(A...); }; // template struct remove_cv_seq { using type = R(A...); }; template struct remove_cv_seq { using type = R(A...); }; template struct remove_cv_seq { using type = R(A...); }; template struct remove_cv_seq { using type = R(A...); }; // template struct remove_cv_seq { using type = R(A...); }; template struct remove_cv_seq { using type = R(A...); }; template struct remove_cv_seq { using type = R(A...); }; template struct remove_cv_seq { using type = R(A...); }; template constexpr inline auto extract_signature(F*) noexcept { return signature::type>(); } template constexpr inline auto extract_signature(F C::*) noexcept { return signature::type>(); } template constexpr inline auto extract_signature(F const&) noexcept -> decltype(&F::operator(), extract_signature(&F::operator())) { return extract_signature(&F::operator()); } ////////////////////////////////////////////////////////////////////////////// template inline auto cify(F&& fu, signature) noexcept { static auto f(std::forward(fu)); if (static bool full; full) { f.~F(); new (std::addressof(f)) F(std::forward(fu)); } else { full = true; } return +[](A... args) noexcept(noexcept( std::declval()(std::forward(args)...))) -> R { return f(std::forward(args)...); }; } template inline auto cify_once(F&& fu, signature) noexcept { static auto f(std::forward(fu)); return +[](A... args) noexcept(noexcept( std::declval()(std::forward(args)...))) -> R { return f(std::forward(args)...); }; } } ////////////////////////////////////////////////////////////////////////////// template auto cify(F&& f) noexcept { return cify_::cify(std::forward(f), cify_::extract_signature(std::forward(f)) ); } template auto cify_once(F&& f) noexcept { return cify_::cify_once(std::forward(f), cify_::extract_signature(std::forward(f)) ); } } #endif // GNR_CIFY_HPP