22 #ifndef GEARS_FUNCTIONAL_INVOKE_HPP
23 #define GEARS_FUNCTIONAL_INVOKE_HPP
25 #include "../meta/alias.hpp"
28 namespace functional {
30 using namespace gears::meta;
31 template <
typename Fun,
typename Obj,
typename... Args,
32 typename Result = decltype((std::declval<Obj>().*std::declval<Fun>())(std::declval<Args>()...)),
33 bool NoExcept = noexcept((std::declval<Obj>().*std::declval<Fun>())(std::declval<Args>()...)),
36 constexpr Result
invoke(Fun&& fun, Obj&& obj, Args&&... args) noexcept(NoExcept) {
37 return (std::forward<Obj>(obj).*std::forward<Fun>(fun))(std::forward<Args>(args)...);
40 template <
typename Fun,
typename Obj,
typename... Args,
41 typename Result = decltype(((*std::declval<Obj>()).*std::declval<Fun>())(std::declval<Args>()...)),
42 bool NoExcept = noexcept(((*std::declval<Obj>()).*std::declval<Fun>())(std::declval<Args>()...)),
45 constexpr Result
invoke(Fun&& fun, Obj&& obj, Args&&... args) noexcept(NoExcept) {
46 return ((*std::forward<Obj>(obj)).*std::forward<Fun>(fun))(std::forward<Args>(args)...);
49 template <
typename Fun,
typename Obj,
50 typename Result = decltype(std::declval<Obj>().*std::declval<Fun>()),
51 bool NoExcept = noexcept(std::declval<Obj>().*std::declval<Fun>()),
54 constexpr Result
invoke(Fun&& fun, Obj&& obj) noexcept(NoExcept) {
55 return std::forward<Obj>(obj).*std::forward<Fun>(fun);
58 template <
typename Fun,
typename Obj,
59 typename Result = decltype((*std::declval<Obj>()).*std::declval<Fun>()),
60 bool NoExcept = noexcept((*std::declval<Obj>()).*std::declval<Fun>()),
63 constexpr Result
invoke(Fun&& fun, Obj&& obj) noexcept(NoExcept) {
64 return (*std::forward<Obj>(obj)).*std::forward<Fun>(fun);
67 template <
typename Fun,
typename... Args,
68 typename Result = decltype(std::declval<Fun>()(std::declval<Args>()...)),
69 bool NoExcept = noexcept(std::declval<Fun>()(std::declval<Args>()...)),
71 constexpr Result
invoke(Fun&& fun, Args&&... args) noexcept(NoExcept) {
72 return std::forward<Fun>(fun)(std::forward<Args>(args)...);
76 #ifndef GEARS_FOR_DOXYGEN_ONLY
77 template <
typename Deduced = meta::deduced,
typename... Args,
78 typename Expected = decltype(
detail::invoke(std::declval<Args>()...)),
79 typename Result = meta::If<meta::is_deduced<Deduced>, Expected, Deduced>,
81 meta::EnableIf<meta::Any<std::is_convertible<Expected, Result>, std::is_void<Result>>> = meta::_>
83 template<
typename... Args>
85 constexpr Result
invoke(Args&&... args) noexcept(NoExcept) {
117 #endif // GEARS_FUNCTIONAL_INVOKE_HPP