From 70a2b88898c3fd452f9e16a6c706d17a4f4b1460 Mon Sep 17 00:00:00 2001 From: q66 Date: Sun, 11 Sep 2016 19:57:42 +0200 Subject: [PATCH] allow non-static methods to be bound to Function --- ostd/functional.hh | 9 ++------ ostd/type_traits.hh | 54 ++++++++++++++++++++++++++++----------------- 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/ostd/functional.hh b/ostd/functional.hh index aa731e2..2f58dad 100644 --- a/ostd/functional.hh +++ b/ostd/functional.hh @@ -571,16 +571,11 @@ namespace detail { return !!f; } - template - inline auto func_invoke_helper(F &&f, A &&...args) { - return forward(f)(forward(args)...); - } - template struct FuncInvokeVoidReturnWrapper { template static R call(A &&...args) { - return func_invoke_helper(forward(args)...); + return func_invoke(forward(args)...); } }; @@ -588,7 +583,7 @@ namespace detail { struct FuncInvokeVoidReturnWrapper { template static void call(A &&...args) { - func_invoke_helper(forward(args)...); + func_invoke(forward(args)...); } }; diff --git a/ostd/type_traits.hh b/ostd/type_traits.hh index 3bfb90e..d39c444 100644 --- a/ostd/type_traits.hh +++ b/ostd/type_traits.hh @@ -1452,7 +1452,24 @@ namespace detail { #define OSTD_FWD(T, _v) static_cast(_v) template - auto func_invoke(InvokeAny, A &&...) -> InvokeNat; + inline auto func_invoke(InvokeAny, A &&...) -> InvokeNat; + + /* forward declarations, later defined in functional */ + template< + typename F, typename T, typename ...A, + typename = EnableIf< + IsMemberFunctionPointer> && + IsBaseOf< + RemoveReference>>, + RemoveReference + > + > + > + inline auto func_invoke(F &&f, T &&v, A &&...args) -> + decltype((OSTD_FWD(T, v).*f)(OSTD_FWD(A, args)...)) + { + return (OSTD_FWD(T, v).*f)(OSTD_FWD(A, args)...); + } template< typename F, typename T, typename ...A, @@ -1464,21 +1481,11 @@ namespace detail { > > > - auto func_invoke(F &&f, T &&v, A &&...args) -> - decltype((OSTD_FWD(T, v).*f)(OSTD_FWD(A, args)...)); - - template< - typename F, typename T, typename ...A, - typename = EnableIf< - IsMemberFunctionPointer> && - IsBaseOf< - RemoveReference>>, - RemoveReference - > - > - > - auto func_invoke(F &&f, T &&v, A &&...args) -> - decltype(((*OSTD_FWD(T, v)).*f)(OSTD_FWD(A, args)...)); + inline auto func_invoke(F &&f, T &&v, A &&...args) -> + decltype(((*OSTD_FWD(T, v)).*f)(OSTD_FWD(A, args)...)) + { + return ((*OSTD_FWD(T, v)).*f)(OSTD_FWD(A, args)...); + } template< typename F, typename T, @@ -1490,7 +1497,9 @@ namespace detail { > > > - auto func_invoke(F &&f, T &&v) -> decltype(OSTD_FWD(T, v).*f); + inline auto func_invoke(F &&f, T &&v) -> decltype(OSTD_FWD(T, v).*f) { + return OSTD_FWD(T, v).*f; + } template< typename F, typename T, @@ -1502,11 +1511,16 @@ namespace detail { > > > - auto func_invoke(F &&f, T &&v) -> decltype((*OSTD_FWD(T, v)).*f); + inline auto func_invoke(F &&f, T &&v) -> decltype((*OSTD_FWD(T, v)).*f) { + return (*OSTD_FWD(T, v)).*f; + } template - auto func_invoke(F &&f, A &&...args) -> - decltype(OSTD_FWD(F, f)(OSTD_FWD(A, args)...)); + inline auto func_invoke(F &&f, A &&...args) -> + decltype(OSTD_FWD(F, f)(OSTD_FWD(A, args)...)) + { + return OSTD_FWD(F, f)(OSTD_FWD(A, args)...); + } #undef OSTD_FWD template