From eec9c8692057794be759503f8974829a3c77396f Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Wed, 11 Oct 2017 17:18:48 +0900 Subject: [PATCH] add C++17 invoke function --- sprout/functional.hpp | 1 + sprout/functional/invoke.hpp | 31 +++++++++++++++++++++ sprout/type_traits/detail/invoke.hpp | 24 +++++++++++----- sprout/type_traits/is_nothrow_invocable.hpp | 1 + 4 files changed, 50 insertions(+), 7 deletions(-) create mode 100644 sprout/functional/invoke.hpp diff --git a/sprout/functional.hpp b/sprout/functional.hpp index 62b8ee79..7bc4772c 100644 --- a/sprout/functional.hpp +++ b/sprout/functional.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/sprout/functional/invoke.hpp b/sprout/functional/invoke.hpp new file mode 100644 index 00000000..d39a2310 --- /dev/null +++ b/sprout/functional/invoke.hpp @@ -0,0 +1,31 @@ +/*============================================================================= + Copyright (c) 2011 RiSK (sscrisk) + https://github.com/sscrisk/CEL---ConstExpr-Library + + Copyright (c) 2011-2017 Bolero MURAKAMI + https://github.com/bolero-MURAKAMI/Sprout + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#ifndef SPROUT_FUNCTIONAL_INVOKE_HPP +#define SPROUT_FUNCTIONAL_INVOKE_HPP + +#include +#include +#include +#include +#include + +namespace sprout { + // + // invoke + // + template + inline SPROUT_CONSTEXPR typename sprout::invoke_result::type + invoke(F&& f, Args&&... args) SPROUT_NOEXCEPT_IF((sprout::is_nothrow_invocable::value)) { + return sprout::detail::invoke(sprout::forward(f), sprout::forward(args)...); + } +} // namespace sprout + +#endif // #ifndef SPROUT_FUNCTIONAL_INVOKE_HPP diff --git a/sprout/type_traits/detail/invoke.hpp b/sprout/type_traits/detail/invoke.hpp index 45267ffb..e6b0af6d 100644 --- a/sprout/type_traits/detail/invoke.hpp +++ b/sprout/type_traits/detail/invoke.hpp @@ -13,29 +13,39 @@ #include #include #include -#include +#include namespace sprout { namespace detail { template inline SPROUT_CONSTEXPR decltype(std::declval()(std::declval()...)) - invoke(F&&, Args&&...) SPROUT_NOEXCEPT_IF_EXPR(std::declval()(std::declval()...)); + invoke(F&& f, Args&&... args) SPROUT_NOEXCEPT_IF_EXPR(std::declval()(std::declval()...)) { + return sprout::forward(f)(sprout::forward(args)...); + } template inline SPROUT_CONSTEXPR decltype(std::declval().*(std::declval())) - invoke(T Base::*, Derived&&) SPROUT_NOEXCEPT_IF_EXPR(std::declval().*(std::declval())); + invoke(T Base::* pm, Derived&& d) SPROUT_NOEXCEPT_IF_EXPR(std::declval().*(std::declval())) { + return sprout::forward(d).*(pm); + } template inline SPROUT_CONSTEXPR decltype((*std::declval()).*(std::declval())) - invoke(PMD&&, Pointer&&) SPROUT_NOEXCEPT_IF_EXPR((*std::declval()).*(std::declval())); + invoke(PMD&& pmd, Pointer&& ptr) SPROUT_NOEXCEPT_IF_EXPR((*std::declval()).*(std::declval())) { + return sprout::forward(ptr).*(sprout::forward(pmd)); + } template inline SPROUT_CONSTEXPR decltype((std::declval().*(std::declval()))(std::declval()...)) - invoke(T Base::*, Derived&&, Args&&...) SPROUT_NOEXCEPT_IF_EXPR((std::declval().*(std::declval()))(std::declval()...)); + invoke(T Base::* pm, Derived&& d, Args&&... args) SPROUT_NOEXCEPT_IF_EXPR((std::declval().*(std::declval()))(std::declval()...)) { + return (sprout::forward(d).*(pm))(sprout::forward(args)...); + } template inline SPROUT_CONSTEXPR decltype(((*std::declval()).*(std::declval()))(std::declval()...)) - invoke(PMF&& pmf, Pointer&& ptr, Args&&... args) SPROUT_NOEXCEPT_IF_EXPR(((*std::declval()).*(std::declval()))(std::declval()...)); + invoke(PMF&& pmf, Pointer&& ptr, Args&&... args) SPROUT_NOEXCEPT_IF_EXPR(((*std::declval()).*(std::declval()))(std::declval()...)) { + return (sprout::forward(ptr).*(sprout::forward(pmf)))(sprout::forward(args)...); + } template inline SPROUT_CONSTEXPR R @@ -55,7 +65,7 @@ namespace sprout { template inline SPROUT_CONSTEXPR decltype(R(((*std::declval()).*(std::declval()))(std::declval()...))) - invoke(PMF&& pmf, Pointer&& ptr, Args&&... args) SPROUT_NOEXCEPT_IF_EXPR(R(((*std::declval()).*(std::declval()))(std::declval()...))); + invoke(PMF&&, Pointer&&, Args&&...) SPROUT_NOEXCEPT_IF_EXPR(R(((*std::declval()).*(std::declval()))(std::declval()...))); } // namespace detail namespace detail { diff --git a/sprout/type_traits/is_nothrow_invocable.hpp b/sprout/type_traits/is_nothrow_invocable.hpp index 7521f0df..80e87507 100644 --- a/sprout/type_traits/is_nothrow_invocable.hpp +++ b/sprout/type_traits/is_nothrow_invocable.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include namespace sprout {