add C++17 invoke function

This commit is contained in:
bolero-MURAKAMI 2017-10-11 17:18:48 +09:00
parent 64e1994734
commit eec9c86920
4 changed files with 50 additions and 7 deletions

View file

@ -12,6 +12,7 @@
#include <sprout/functional/base.hpp>
#include <sprout/functional/functor.hpp>
#include <sprout/functional/adaptor.hpp>
#include <sprout/functional/invoke.hpp>
#include <sprout/functional/ref.hpp>
#include <sprout/functional/mem_fn.hpp>
#include <sprout/functional/bind.hpp>

View file

@ -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 <sprout/config.hpp>
#include <sprout/utility/forward.hpp>
#include <sprout/type_traits/invoke_result.hpp>
#include <sprout/type_traits/is_nothrow_invocable.hpp>
#include <sprout/type_traits/detail/invoke.hpp>
namespace sprout {
//
// invoke
//
template<typename F, typename... Args>
inline SPROUT_CONSTEXPR typename sprout::invoke_result<F, Args...>::type
invoke(F&& f, Args&&... args) SPROUT_NOEXCEPT_IF((sprout::is_nothrow_invocable<F, Args...>::value)) {
return sprout::detail::invoke(sprout::forward<F>(f), sprout::forward<Args>(args)...);
}
} // namespace sprout
#endif // #ifndef SPROUT_FUNCTIONAL_INVOKE_HPP

View file

@ -13,29 +13,39 @@
#include <sprout/type_traits/identity.hpp>
#include <sprout/type_traits/voider.hpp>
#include <sprout/detail/nil_base.hpp>
#include <sprout/utility/implicit_cast.hpp>
#include <sprout/utility/forward.hpp>
namespace sprout {
namespace detail {
template<typename F, typename... Args>
inline SPROUT_CONSTEXPR decltype(std::declval<F>()(std::declval<Args>()...))
invoke(F&&, Args&&...) SPROUT_NOEXCEPT_IF_EXPR(std::declval<F>()(std::declval<Args>()...));
invoke(F&& f, Args&&... args) SPROUT_NOEXCEPT_IF_EXPR(std::declval<F>()(std::declval<Args>()...)) {
return sprout::forward<F>(f)(sprout::forward<Args>(args)...);
}
template<typename Base, typename T, typename Derived>
inline SPROUT_CONSTEXPR decltype(std::declval<Derived>().*(std::declval<T Base::*>()))
invoke(T Base::*, Derived&&) SPROUT_NOEXCEPT_IF_EXPR(std::declval<Derived>().*(std::declval<T Base::*>()));
invoke(T Base::* pm, Derived&& d) SPROUT_NOEXCEPT_IF_EXPR(std::declval<Derived>().*(std::declval<T Base::*>())) {
return sprout::forward<Derived>(d).*(pm);
}
template<typename PMD, typename Pointer>
inline SPROUT_CONSTEXPR decltype((*std::declval<Pointer>()).*(std::declval<PMD>()))
invoke(PMD&&, Pointer&&) SPROUT_NOEXCEPT_IF_EXPR((*std::declval<Pointer>()).*(std::declval<PMD>()));
invoke(PMD&& pmd, Pointer&& ptr) SPROUT_NOEXCEPT_IF_EXPR((*std::declval<Pointer>()).*(std::declval<PMD>())) {
return sprout::forward<Pointer>(ptr).*(sprout::forward<PMD>(pmd));
}
template<typename Base, typename T, typename Derived, typename... Args>
inline SPROUT_CONSTEXPR decltype((std::declval<Derived>().*(std::declval<T Base::*>()))(std::declval<Args>()...))
invoke(T Base::*, Derived&&, Args&&...) SPROUT_NOEXCEPT_IF_EXPR((std::declval<Derived>().*(std::declval<T Base::*>()))(std::declval<Args>()...));
invoke(T Base::* pm, Derived&& d, Args&&... args) SPROUT_NOEXCEPT_IF_EXPR((std::declval<Derived>().*(std::declval<T Base::*>()))(std::declval<Args>()...)) {
return (sprout::forward<Derived>(d).*(pm))(sprout::forward<Args>(args)...);
}
template<typename PMF, typename Pointer, typename... Args>
inline SPROUT_CONSTEXPR decltype(((*std::declval<Pointer>()).*(std::declval<PMF>()))(std::declval<Args>()...))
invoke(PMF&& pmf, Pointer&& ptr, Args&&... args) SPROUT_NOEXCEPT_IF_EXPR(((*std::declval<Pointer>()).*(std::declval<PMF>()))(std::declval<Args>()...));
invoke(PMF&& pmf, Pointer&& ptr, Args&&... args) SPROUT_NOEXCEPT_IF_EXPR(((*std::declval<Pointer>()).*(std::declval<PMF>()))(std::declval<Args>()...)) {
return (sprout::forward<Pointer>(ptr).*(sprout::forward<PMF>(pmf)))(sprout::forward<Args>(args)...);
}
template<typename R, typename F, typename... Args>
inline SPROUT_CONSTEXPR R
@ -55,7 +65,7 @@ namespace sprout {
template<typename R, typename PMF, typename Pointer, typename... Args>
inline SPROUT_CONSTEXPR decltype(R(((*std::declval<Pointer>()).*(std::declval<PMF>()))(std::declval<Args>()...)))
invoke(PMF&& pmf, Pointer&& ptr, Args&&... args) SPROUT_NOEXCEPT_IF_EXPR(R(((*std::declval<Pointer>()).*(std::declval<PMF>()))(std::declval<Args>()...)));
invoke(PMF&&, Pointer&&, Args&&...) SPROUT_NOEXCEPT_IF_EXPR(R(((*std::declval<Pointer>()).*(std::declval<PMF>()))(std::declval<Args>()...)));
} // namespace detail
namespace detail {

View file

@ -11,6 +11,7 @@
#include <sprout/config.hpp>
#include <sprout/type_traits/integral_constant.hpp>
#include <sprout/type_traits/invoke_result.hpp>
#include <sprout/type_traits/is_invocable.hpp>
#include <sprout/type_traits/detail/invoke.hpp>
namespace sprout {