Loading [MathJax]/extensions/tex2jax.js
The Gaudi Framework  v31r0 (aeb156f0)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
invoke.h
Go to the documentation of this file.
1 #ifndef GAUDIKERNEL_INVOKE_H
2 #define GAUDIKERNEL_INVOKE_H
3 #include <functional>
4 
5 #if __cplusplus > 201402L
6 namespace Gaudi {
7  using std::invoke;
8 }
9 #else
10 
11 # include <type_traits>
12 # include <utility>
13 
14 namespace Gaudi {
15  namespace detail2 {
16 
17  // An implemention of std::invoke based on
18  // http://en.cppreference.com/w/cpp/utility/functional/invoke
19  template <class T>
21  template <class U>
22  struct is_reference_wrapper<std::reference_wrapper<U>> : std::true_type {};
23 
24  template <class Base, class T, class Derived, class... Args>
25  auto INVOKE( T Base::*pmf, Derived&& ref, Args&&... args ) noexcept(
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 )... );
30  }
31 
32  template <class Base, class T, class RefWrap, class... Args>
33  auto INVOKE( T Base::*pmf, RefWrap&& ref,
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 )... ) )>
37 
38  {
39  return ( ref.get().*pmf )( std::forward<Args>( args )... );
40  }
41 
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 )... );
49  }
50 
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;
56  }
57 
58  template <class Base, class T, class RefWrap>
59  auto INVOKE( T Base::*pmd, RefWrap&& ref ) noexcept( noexcept( ref.get().*pmd ) )
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;
63  }
64 
65  template <class Base, class T, class Pointer>
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;
71  }
72 
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 )... );
78  }
79  } // namespace detail2
80 
81  template <class F, class... ArgTypes>
82  auto invoke( F&& f, ArgTypes&&... args )
83  // exception specification for QoI
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 )... );
87  }
88 } // namespace Gaudi
89 #endif
90 #endif
STL namespace.
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)...))
Definition: invoke.h:82
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)...))>
Definition: invoke.h:25
Helper functions to set/get the application return code.
Definition: __init__.py:1