LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
helper_macros.h
Go to the documentation of this file.
1 #ifndef art_Framework_Services_Registry_detail_helper_macros_h
2 #define art_Framework_Services_Registry_detail_helper_macros_h
3 // service_macros.h
5 //
6 // Helper macros needed by the user-callable macros defined in
7 // ServiceMacros.h.
8 //
9 // No user-serviceable parts.
10 //
12 
17 #include "cetlib/compiler_macros.h"
18 
20 // Utility for including the service type in a static_assert
21 #define ART_DETAIL_STRINGIZED_VALUE(value) #value
22 #define ART_DETAIL_STRINGIZED_TYPE(svc) ART_DETAIL_STRINGIZED_VALUE(svc)
23 
25 // Describe the correct inheritance based on scope.
26 
27 // Maker.
28 #define DEFINE_ART_SH_L_G_SCOPE_M_INTERFACE \
29 public \
30  ServiceLGMHelper
31 
32 #define DEFINE_ART_SH_LEGACY_SCOPE_M_INTERFACE \
33  DEFINE_ART_SH_L_G_SCOPE_M_INTERFACE
34 
35 #define DEFINE_ART_SH_GLOBAL_SCOPE_M_INTERFACE \
36  DEFINE_ART_SH_L_G_SCOPE_M_INTERFACE
37 
38 #define DEFINE_ART_SH_PER_SCHEDULE_SCOPE_M_INTERFACE \
39 public \
40  ServicePSMHelper
41 
42 #define DEFINE_ART_SH_SCOPE_M_INTERFACE(scopeArg) \
43  DEFINE_ART_SH_##scopeArg##_SCOPE_M_INTERFACE
44 
45 // Retriever.
46 #define DEFINE_ART_SH_L_G_SCOPE_R_INTERFACE \
47 public \
48  ServiceLGRHelper
49 
50 #define DEFINE_ART_SH_LEGACY_SCOPE_R_INTERFACE \
51  DEFINE_ART_SH_L_G_SCOPE_R_INTERFACE
52 
53 #define DEFINE_ART_SH_GLOBAL_SCOPE_R_INTERFACE \
54  DEFINE_ART_SH_L_G_SCOPE_R_INTERFACE
55 
56 #define DEFINE_ART_SH_PER_SCHEDULE_SCOPE_R_INTERFACE \
57 public \
58  ServicePSRHelper
59 
60 #define DEFINE_ART_SH_SCOPE_R_INTERFACE(scopeArg) \
61  DEFINE_ART_SH_##scopeArg##_SCOPE_R_INTERFACE
62 
64 // Define a member function returning the typeid of the service.
65 #define DEFINE_ART_SERVICE_TYPEID(svc) \
66  art::TypeID get_typeid() const override { return TypeID{typeid(svc)}; }
67 
69 // Define a member function to return the scope of the service, and a
70 // static to provide compile-time help when we have the concrete helper
71 // class instead of a base.
72 #define DEFINE_ART_SERVICE_SCOPE(scopeArg) \
73  ServiceScope scope() const override { return ServiceScope::scopeArg; } \
74  static constexpr ServiceScope scope_val[[gnu::unused]]{ \
75  ServiceScope::scopeArg};
76 
78 // Define a member function to retrieve the desired service.
79 
80 // Legacy and global services.
81 #define DEFINE_ART_L_G_SERVICE_RETRIEVER(svc, scopeArg) \
82  void* retrieve(std::shared_ptr<ServiceWrapperBase>& swb) \
83  const final override \
84  { \
85  return &dynamic_cast<ServiceWrapper<svc, ServiceScope::scopeArg>*>( \
86  swb.get()) \
87  ->get(); \
88  }
89 
90 // Legacy service.
91 #define DEFINE_ART_LEGACY_SERVICE_RETRIEVER(svc) \
92  DEFINE_ART_L_G_SERVICE_RETRIEVER(svc, LEGACY)
93 
94 // Global service.
95 #define DEFINE_ART_GLOBAL_SERVICE_RETRIEVER(svc) \
96  DEFINE_ART_L_G_SERVICE_RETRIEVER(svc, GLOBAL)
97 
98 // Per-schedule service.
99 #define DEFINE_ART_PER_SCHEDULE_SERVICE_RETRIEVER(svc) \
100  void* retrieve(std::shared_ptr<ServiceWrapperBase>& swb, \
101  ScheduleID const sID) const final override \
102  { \
103  return &dynamic_cast<ServiceWrapper<svc, ServiceScope::PER_SCHEDULE>*>( \
104  swb.get()) \
105  ->get(sID); \
106  }
107 
109 // Define a member function to make the desired service.
110 
111 // Legacy and global services.
112 #define DEFINE_ART_L_G_SERVICE_MAKER(svc, scopeArg) \
113  std::unique_ptr<ServiceWrapperBase> make(fhicl::ParameterSet const& cfg, \
114  ActivityRegistry& reg) \
115  const final override \
116  { \
117  return std::make_unique<ServiceWrapper<svc, ServiceScope::scopeArg>>(cfg, \
118  reg); \
119  }
120 
121 // Legacy services.
122 #define DEFINE_ART_LEGACY_SERVICE_MAKER(svc) \
123  DEFINE_ART_L_G_SERVICE_MAKER(svc, LEGACY)
124 
125 // Global services.
126 #define DEFINE_ART_GLOBAL_SERVICE_MAKER(svc) \
127  DEFINE_ART_L_G_SERVICE_MAKER(svc, GLOBAL)
128 
129 // Per-schedule services.
130 #define DEFINE_ART_PER_SCHEDULE_SERVICE_MAKER(svc) \
131  std::unique_ptr<ServiceWrapperBase> make( \
132  fhicl::ParameterSet const& cfg, ActivityRegistry& reg, size_t nSchedules) \
133  const final override \
134  { \
135  return std::make_unique<ServiceWrapper<svc, ServiceScope::PER_SCHEDULE>>( \
136  cfg, reg, nSchedules); \
137  }
138 
139 // CreateHelper.
140 #define DEFINE_ART_SERVICE_HELPER_CREATE(svc) \
141  static std::unique_ptr<art::detail::ServiceHelperBase> createHelper() \
142  { \
143  return std::make_unique<art::detail::ServiceHelper<svc>>(); \
144  }
145 
147 // Detail macros invoked by user-visible macros.
148 
150 // Multi-schedule-aware service declarations.
151 
152 // Declare a multi-schedule-aware service.
153 #define DECLARE_ART_SERVICE_DETAIL(svc, scopeArg) \
154  namespace art { \
155  namespace detail { \
156  template <> \
157  struct ServiceHelper<svc> : public ServiceImplHelper, \
158  DEFINE_ART_SH_SCOPE_M_INTERFACE(scopeArg), \
159  DEFINE_ART_SH_SCOPE_R_INTERFACE(scopeArg) { \
160  DEFINE_ART_SERVICE_TYPEID(svc) \
161  DEFINE_ART_SERVICE_SCOPE(scopeArg) \
162  bool \
163  is_interface_impl() const override \
164  { \
165  return false; \
166  } \
167  DEFINE_ART_##scopeArg##_SERVICE_MAKER(svc) DEFINE_ART_##scopeArg \
168  ##_SERVICE_RETRIEVER(svc) \
169  }; \
170  } \
171  }
172 
173 // Declare an interface for services.
174 #define DECLARE_ART_SERVICE_INTERFACE_DETAIL(iface, scopeArg) \
175  namespace art { \
176  namespace detail { \
177  template <> \
178  struct ServiceHelper<iface> \
179  : public ServiceInterfaceHelper, \
180  DEFINE_ART_SH_SCOPE_R_INTERFACE(scopeArg) { \
181  DEFINE_ART_SERVICE_TYPEID(iface) \
182  DEFINE_ART_SERVICE_SCOPE(scopeArg) \
183  DEFINE_ART_##scopeArg##_SERVICE_RETRIEVER(iface) \
184  }; \
185  } \
186  }
187 
188 // Define a multi-schedule-aware service implementing an interface.
189 #define DECLARE_ART_SERVICE_INTERFACE_IMPL_DETAIL(svc, iface, scopeArg) \
190  namespace art { \
191  namespace detail { \
192  template <> \
193  struct ServiceHelper<svc> : public ServiceInterfaceImplHelper, \
194  DEFINE_ART_SH_SCOPE_M_INTERFACE(scopeArg), \
195  DEFINE_ART_SH_SCOPE_R_INTERFACE(scopeArg) { \
196  DEFINE_ART_SERVICE_TYPEID(svc) \
197  DEFINE_ART_SERVICE_SCOPE(scopeArg) \
198  DEFINE_ART_##scopeArg##_SERVICE_MAKER(svc) DEFINE_ART_##scopeArg \
199  ##_SERVICE_RETRIEVER(svc) art::TypeID \
200  get_interface_typeid() const final override \
201  { \
202  return TypeID{typeid(iface)}; \
203  } \
204  std::unique_ptr<ServiceWrapperBase> \
205  convert( \
206  std::shared_ptr<ServiceWrapperBase> const& swb) const final override \
207  { \
208  return std::unique_ptr<art::detail::ServiceWrapperBase>( \
209  static_cast<art::detail::ServiceWrapperBase*>( \
210  std::dynamic_pointer_cast< \
211  ServiceWrapper<svc, ServiceScope::scopeArg>>(swb) \
212  ->getAs<iface>())); \
213  } \
214  static_assert(scope_val == \
215  ServiceHelper<iface>::scope_val, /* Safety check */ \
216  "Scope mismatch between interface " #iface \
217  " and implementation " #svc); \
218  }; \
219  } \
220  }
221 
223 // Declare a system service (requires support code in Event Processor)
224 // since system services have no maker function.
225 #define DECLARE_ART_SYSTEM_SERVICE_DETAIL(svc, scopeArg) \
226  namespace art { \
227  namespace detail { \
228  template <> \
229  struct ServiceHelper<svc> : public ServiceImplHelper, \
230  DEFINE_ART_SH_SCOPE_R_INTERFACE(scopeArg) { \
231  DEFINE_ART_SERVICE_TYPEID(svc) \
232  DEFINE_ART_SERVICE_SCOPE(scopeArg) \
233  bool \
234  is_interface_impl() const override \
235  { \
236  return false; \
237  } \
238  DEFINE_ART_##scopeArg##_SERVICE_RETRIEVER(svc) \
239  }; \
240  } \
241  }
242 
244 // Define the C-linkage function to create the helper.
245 #define DEFINE_ART_SH_CREATE(svc) DEFINE_ART_SH_CREATE_DETAIL(svc, service)
246 
247 #define DEFINE_ART_SIH_CREATE(svc) DEFINE_ART_SH_CREATE_DETAIL(svc, iface)
248 
249 #define DEFINE_ART_SH_CREATE_DETAIL(svc, type) \
250  EXTERN_C_FUNC_DECLARE_START \
251  std::unique_ptr<art::detail::ServiceHelperBase> create_##type##_helper() \
252  { \
253  return std::make_unique<art::detail::ServiceHelper<svc>>(); \
254  } \
255  EXTERN_C_FUNC_DECLARE_END
256 
257 #endif /* art_Framework_Services_Registry_detail_helper_macros_h */
258 
259 // Local Variables:
260 // mode: c++
261 // End: