1 #ifndef GAUDIKERNEL_INVOKE_H 2 #define GAUDIKERNEL_INVOKE_H 5 #if __cplusplus > 201402L 11 # include <type_traits> 24 template <
class Base,
class T,
class Derived,
class... Args>
26 noexcept( ( std::forward<Derived>(
ref ).*pmf )( std::forward<Args>(
args )... ) ) )
27 -> std::enable_if_t<std::is_function<T>::value && std::is_base_of<Base, std::decay_t<Derived>>::value,
28 decltype( ( std::forward<Derived>(
ref ).*pmf )( std::forward<Args>(
args )... ) )> {
29 return ( std::forward<Derived>(
ref ).*pmf )( std::forward<Args>(
args )... );
32 template <
class Base,
class T,
class RefWrap,
class... Args>
34 Args&&...
args ) noexcept( noexcept( (
ref.
get().*pmf )( std::forward<Args>(
args )... ) ) )
35 -> std::enable_if_t<std::is_function<T>::value &&
is_reference_wrapper<std::decay_t<RefWrap>>::value,
36 decltype( (
ref.
get().*pmf )( std::forward<Args>(
args )... ) )>
39 return (
ref.get().*pmf )( std::forward<Args>( args )... );
42 template <
class Base,
class T,
class Pointer,
class... Args>
43 auto INVOKE( T Base::*pmf, Pointer&& ptr, Args&&...
args ) noexcept(
44 noexcept( ( ( *std::forward<Pointer>( ptr ) ).*pmf )( std::forward<Args>(
args )... ) ) )
45 -> std::enable_if_t<std::is_function<T>::value && !
is_reference_wrapper<std::decay_t<Pointer>>::value &&
46 !std::is_base_of<Base, std::decay_t<Pointer>>::value,
47 decltype( ( ( *std::forward<Pointer>( ptr ) ).*pmf )( std::forward<Args>(
args )... ) )> {
48 return ( ( *std::forward<Pointer>( ptr ) ).*pmf )( std::forward<Args>(
args )... );
51 template <
class Base,
class T,
class Derived>
52 auto INVOKE( T Base::*pmd, Derived&&
ref ) noexcept( noexcept( std::forward<Derived>(
ref ).*pmd ) )
53 -> std::enable_if_t<!std::is_function<T>::value && std::is_base_of<Base, std::decay_t<Derived>>::value,
54 decltype( std::forward<Derived>(
ref ).*pmd )> {
55 return std::forward<Derived>(
ref ).*pmd;
58 template <
class Base,
class T,
class RefWrap>
60 -> std::enable_if_t<!std::is_function<T>::value &&
is_reference_wrapper<std::decay_t<RefWrap>>::value,
61 decltype(
ref.
get().*pmd )> {
62 return ref.get().*pmd;
65 template <
class Base,
class T,
class Po
inter>
66 auto INVOKE( T Base::*pmd, Pointer&& ptr ) noexcept( noexcept( ( *std::forward<Pointer>( ptr ) ).*pmd ) )
67 -> std::enable_if_t<!std::is_function<T>::value && !
is_reference_wrapper<std::decay_t<Pointer>>::value &&
68 !std::is_base_of<Base, std::decay_t<Pointer>>::value,
69 decltype( ( *std::forward<Pointer>( ptr ) ).*pmd )> {
70 return ( *std::forward<Pointer>( ptr ) ).*pmd;
73 template <
class F,
class... Args>
74 auto INVOKE( F&& f, Args&&...
args ) noexcept( noexcept( std::forward<F>( f )( std::forward<Args>(
args )... ) ) )
75 -> std::enable_if_t<!std::is_member_pointer<std::decay_t<F>>::value,
76 decltype( std::forward<F>( f )( std::forward<Args>(
args )... ) )> {
77 return std::forward<F>( f )( std::forward<Args>( args )... );
81 template <
class F,
class... ArgTypes>
84 noexcept( noexcept( detail2::
INVOKE(
std::forward<F>( f ),
std::forward<ArgTypes>(
args )... ) ) )
85 -> decltype( detail2::
INVOKE(
std::forward<F>( f ),
std::forward<ArgTypes>(
args )... ) ) {
86 return detail2::INVOKE( std::forward<F>( f ), std::forward<ArgTypes>( 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)...))
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)...))>
Helper functions to set/get the application return code.