1 #ifndef GAUDIKERNEL_INVOKE_H 2 #define GAUDIKERNEL_INVOKE_H 5 #if __cplusplus > 201402L 12 #include <type_traits> 29 template <
class Base,
class T,
class Derived,
class... Args>
31 noexcept( ( std::forward<Derived>(
ref ).*pmf )( std::forward<Args>(
args )... ) ) )
32 -> std::enable_if_t<std::is_function<T>::value && std::is_base_of<Base, std::decay_t<Derived>>::value,
33 decltype( ( std::forward<Derived>(
ref ).*pmf )( std::forward<Args>(
args )... ) )>
35 return ( std::forward<Derived>(
ref ).*pmf )( std::forward<Args>(
args )... );
38 template <
class Base,
class T,
class RefWrap,
class... Args>
40 Args&&...
args ) noexcept( noexcept( (
ref.
get().*pmf )( std::forward<Args>(
args )... ) ) )
41 -> std::enable_if_t<std::is_function<T>::value &&
is_reference_wrapper<std::decay_t<RefWrap>>::value,
42 decltype( (
ref.
get().*pmf )( std::forward<Args>(
args )... ) )>
45 return (
ref.get().*pmf )( std::forward<Args>( args )... );
48 template <
class Base,
class T,
class Pointer,
class... Args>
49 auto INVOKE( T Base::*pmf, Pointer&& ptr, Args&&...
args ) noexcept(
50 noexcept( ( ( *std::forward<Pointer>( ptr ) ).*pmf )( std::forward<Args>(
args )... ) ) )
51 -> std::enable_if_t<std::is_function<T>::value && !
is_reference_wrapper<std::decay_t<Pointer>>::value &&
52 !std::is_base_of<Base, std::decay_t<Pointer>>::value,
53 decltype( ( ( *std::forward<Pointer>( ptr ) ).*pmf )( std::forward<Args>(
args )... ) )>
55 return ( ( *std::forward<Pointer>( ptr ) ).*pmf )( std::forward<Args>(
args )... );
58 template <
class Base,
class T,
class Derived>
59 auto INVOKE( T Base::*pmd, Derived&&
ref ) noexcept( noexcept( std::forward<Derived>(
ref ).*pmd ) )
60 -> std::enable_if_t<!std::is_function<T>::value && std::is_base_of<Base, std::decay_t<Derived>>::value,
61 decltype( std::forward<Derived>(
ref ).*pmd )>
63 return std::forward<Derived>(
ref ).*pmd;
66 template <
class Base,
class T,
class RefWrap>
68 -> std::enable_if_t<!std::is_function<T>::value &&
is_reference_wrapper<std::decay_t<RefWrap>>::value,
69 decltype(
ref.
get().*pmd )>
71 return ref.get().*pmd;
74 template <
class Base,
class T,
class Po
inter>
75 auto INVOKE( T Base::*pmd, Pointer&& ptr ) noexcept( noexcept( ( *std::forward<Pointer>( ptr ) ).*pmd ) )
76 -> std::enable_if_t<!std::is_function<T>::value && !
is_reference_wrapper<std::decay_t<Pointer>>::value &&
77 !std::is_base_of<Base, std::decay_t<Pointer>>::value,
78 decltype( ( *std::forward<Pointer>( ptr ) ).*pmd )>
80 return ( *std::forward<Pointer>( ptr ) ).*pmd;
83 template <
class F,
class... Args>
84 auto INVOKE( F&& f, Args&&...
args ) noexcept( noexcept( std::forward<F>( f )( std::forward<Args>(
args )... ) ) )
85 -> std::enable_if_t<!std::is_member_pointer<std::decay_t<F>>::value,
86 decltype( std::forward<F>( f )( std::forward<Args>(
args )... ) )>
88 return std::forward<F>( f )( std::forward<Args>( args )... );
92 template <
class F,
class... ArgTypes>
95 noexcept( noexcept( detail2::
INVOKE(
std::forward<F>( f ),
std::forward<ArgTypes>(
args )... ) ) )
96 -> decltype( detail2::
INVOKE(
std::forward<F>( f ),
std::forward<ArgTypes>(
args )... ) )
98 return detail2::INVOKE( std::forward<F>( f ), std::forward<ArgTypes>( args )... );
auto INVOKE(T Base::*pmf, Derived &&ref, Args &&...args) noexcept( noexcept((std::forward< Derived >(ref).*pmf)(std::forward< Args >(args)...))) -> std::enable_if_t< std::is_function< T >::value &&std::is_base_of< Base, std::decay_t< Derived >>::value, decltype((std::forward< Derived >(ref).*pmf)(std::forward< Args >(args)...))>
auto invoke(F &&f, ArgTypes &&...args) noexcept(noexcept(detail2::INVOKE(std::forward< F >(f), std::forward< ArgTypes >(args)...))) -> decltype(detail2::INVOKE(std::forward< F >(f), std::forward< ArgTypes >(args)...))
Helper functions to set/get the application return code.