ServiceUtil.h
Go to the documentation of this file.
1 /**
2  * @file ServiceUtil.h
3  * @brief Utilities related to art service access
4  * @author Jonathan Paley (jpaley@fnal.gov)
5  *
6  * This library is currently a pure header.
7  *
8  */
9 
10 #ifndef COREUTILS_SERVICEUTIL
11 #define COREUTILS_SERVICEUTIL
12 
13 // GArSoft libraries
14 #include "CoreUtils/UncopiableAndUnmovableClass.h"
15 
16 // framework libraries
19 #include "cetlib_except/demangle.h"
20 
21 // C/C++ standard libraries
22 #include <type_traits>
23 #include <typeinfo>
24 
25 
26 namespace gar {
27 
28  namespace details {
29  template <typename PROVIDER>
31  } // namespace details
32 
33 
34  /** **************************************************************************
35  * @brief Returns a constant pointer to the provider of specified service
36  * @tparam T type of the service
37  * @return a constant pointer to the provider of specified service
38  * @throws ::art::Exception (category ::art::errors::NotFound) if pointer is null
39  *
40  * This function relies on the following service and provider interface:
41  * - provider is not movable nor copiable
42  * - service contains a type "provider_type" defined as the class of the
43  * service provider
44  * - service contains a method "provider()" that returns a non-null pointer
45  * to a service provider; the service provider is owned and managed by
46  * the service, and the caller is not responsible of regulating the object
47  * lifetime, nor it should attempt to
48  *
49  * Violations of the protocol yield compilation errors (in case non-compliance
50  * can be statically detected), or throw of exceptions.
51  *
52  * Example of usage:
53  *
54  * auto const* geom = gar::providerFrom<geo::GeometryGAr>();
55  *
56  * retrieves the service provider for GArSoft geometry.
57  * This requires the inclusion of "Geometry/GeometryGAr.h" header, where the
58  * service is declared. Typically, both ServiceUtil.h and the header of the
59  * provider class are included in the service header.
60  *
61  */
62  template <class T>
63  typename T::provider_type const* providerFrom()
64  {
65  details::ServiceRequirementsChecker<T>(); // instantiate a temporary...
66 
67  // retrieve the provider
69  typename T::provider_type const* pProvider = h->provider();
70  if (!pProvider) {
72  << "Service <" << cet::demangle_symbol(typeid(T).name())
73  << "> offered a null provider";
74  }
75 
76  return pProvider;
77 
78  } // providerFrom()
79 
80 
81  //----------------------------------------------------------------------------
82  namespace details {
83  /// Compiles only if PROVIDER class satisfied service provider requirements
84  template <typename PROVIDER>
86 
87  using provider_type = PROVIDER;
88 
89  // static checks on provider class: not copiable nor movable
90  static_assert(
92  "Service provider classes must not be copiable"
93  );
94  static_assert(
96  "Service provider classes must not be copiable"
97  );
98  static_assert(
100  "Service provider classes must not be movable"
101  );
102  static_assert(
104  "Service provider classes must not be movable"
105  );
106 
107  }; // ServiceProviderRequirementsChecker
108 
109 
110  template <typename SERVICE>
112 
113  // require SERVICE::provider_type to be a type
114  using provider_type = typename SERVICE::provider_type;
115 
116  // expected type for SERVICE::provider() method
117  using provider_func_type = provider_type const* (SERVICE::*)() const;
118 
119  /// Checker for the provider
121 
122  // check the provider() method
123  static_assert(
124  std::is_same<decltype(&SERVICE::provider), provider_func_type>::value,
125  "provider() method has unsupported signature"
126  );
127 
128  }; // ServiceRequirementsChecker
129 
130  } // namespace details
131 
132 } // namespace gar
133 
134 #endif //#COREUTILS_SERVICEUTIL
135 
static QCString name
Definition: declinfo.cpp:673
provider_type const *(SERVICE::*)() const provider_func_type
Definition: ServiceUtil.h:117
Compiles only if PROVIDER class satisfied service provider requirements.
Definition: ServiceUtil.h:85
virtual const provider_type * provider() const override
ServiceProviderRequirementsChecker< provider_type > provider_checker
Checker for the provider.
Definition: ServiceUtil.h:120
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
General GArSoft Utilities.
T::provider_type const * providerFrom()
Returns a constant pointer to the provider of specified service.
Definition: ServiceUtil.h:63
typename SERVICE::provider_type provider_type
Definition: ServiceUtil.h:114