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 // vim: set sw=2 expandtab :
4 
12 
13 ////////////////////////////////////////////////////////////////////////
14 // Utility for including the service type in a static_assert
15 #define ART_DETAIL_STRINGIZED_VALUE(value) #value
16 #define ART_DETAIL_STRINGIZED_TYPE(svc) ART_DETAIL_STRINGIZED_VALUE(svc)
17 
18 // Define a member function returning the typeid of the service.
19 #define DEFINE_ART_SERVICE_TYPEID(svc) \
20  art::TypeID get_typeid() const override { return TypeID{typeid(svc)}; }
21 
22 // Define a member function to return the scope of the service, and a
23 // static to provide compile-time help when we have the concrete helper
24 // class instead of a base.
25 #define DEFINE_ART_SERVICE_SCOPE(scopeArg) \
26  ServiceScope scope() const override { return scope_val; } \
27  static constexpr ServiceScope scope_val{ServiceScope::scopeArg};
28 
29 #define DEFINE_ART_SERVICE_RETRIEVER(svc) \
30  void* retrieve(std::shared_ptr<ServiceWrapperBase>& swb) \
31  const final override \
32  { \
33  return &std::dynamic_pointer_cast<ServiceWrapper<svc>>(swb)->get(); \
34  }
35 
36 #define DEFINE_ART_SERVICE_MAKER(svc, scopeArg) \
37  std::unique_ptr<ServiceWrapperBase> make(fhicl::ParameterSet const& pset, \
38  ActivityRegistry& reg) \
39  const final override \
40  { \
41  if constexpr (is_shared(ServiceScope::scopeArg) && \
42  detail::handle_allowed_v<svc>) { \
43  SharedResourcesRegistry::instance()->registerSharedResource( \
44  SharedResource<svc>); \
45  } else if constexpr (is_legacy(ServiceScope::scopeArg)) { \
46  ensure_only_one_thread(pset); \
47  } \
48  return std::make_unique<ServiceWrapper<svc>>(pset, reg); \
49  }
50 
51 // CreateHelper.
52 #define DEFINE_ART_SERVICE_HELPER_CREATE(svc) \
53  static std::unique_ptr<ServiceHelperBase> createHelper() \
54  { \
55  return std::make_unique<ServiceHelper<svc>>(); \
56  }
57 
58 // Declare a service with scope.
59 #define ART_DETAIL_DECLARE_SERVICE(svc, scopeArg) \
60  namespace art::detail { \
61  template <> \
62  struct ServiceHelper<svc> : public ServiceImplHelper, \
63  public ServiceLGMHelper, \
64  public ServiceLGRHelper { \
65  DEFINE_ART_SERVICE_TYPEID(svc) \
66  DEFINE_ART_SERVICE_SCOPE(scopeArg) \
67  DEFINE_ART_SERVICE_RETRIEVER(svc) \
68  DEFINE_ART_SERVICE_MAKER(svc, scopeArg) \
69  bool \
70  is_interface_impl() const override \
71  { \
72  return false; \
73  } \
74  }; \
75  }
76 
77 // Declare an interface for a service with scope.
78 #define ART_DETAIL_DECLARE_SERVICE_INTERFACE(iface, scopeArg) \
79  namespace art::detail { \
80  template <> \
81  struct ServiceHelper<iface> : public ServiceInterfaceHelper, \
82  public ServiceLGRHelper { \
83  DEFINE_ART_SERVICE_TYPEID(iface) \
84  DEFINE_ART_SERVICE_SCOPE(scopeArg) \
85  DEFINE_ART_SERVICE_RETRIEVER(iface) \
86  }; \
87  }
88 
89 // Define a service with scope implementing an interface.
90 #define ART_DETAIL_DECLARE_SERVICE_INTERFACE_IMPL(svc, iface, scopeArg) \
91  namespace art::detail { \
92  template <> \
93  struct ServiceHelper<svc> : public ServiceInterfaceImplHelper, \
94  public ServiceLGMHelper, \
95  public ServiceLGRHelper { \
96  DEFINE_ART_SERVICE_TYPEID(svc) \
97  DEFINE_ART_SERVICE_SCOPE(scopeArg) \
98  DEFINE_ART_SERVICE_RETRIEVER(svc) \
99  DEFINE_ART_SERVICE_MAKER(svc, scopeArg) \
100  art::TypeID \
101  get_interface_typeid() const final override \
102  { \
103  return TypeID{typeid(iface)}; \
104  } \
105  std::unique_ptr<ServiceWrapperBase> \
106  convert( \
107  std::shared_ptr<ServiceWrapperBase> const& swb) const final override \
108  { \
109  return std::dynamic_pointer_cast<ServiceWrapper<svc>>(swb) \
110  ->getAs<iface>(); \
111  } \
112  static_assert(is_shared(ServiceHelper<iface>::scope_val) || \
113  is_legacy(ServiceHelper<svc>::scope_val), \
114  "\n\nart error: An implementation that inherits from a " \
115  "LEGACY interface\n" \
116  " must be a LEGACY service\n\n"); \
117  }; \
118  }
119 
120 // Declare a system service (requires support code in Event Processor)
121 // since system services have no maker function.
122 #define ART_DETAIL_DECLARE_SYSTEM_SERVICE(svc, scopeArg) \
123  namespace art::detail { \
124  template <> \
125  struct ServiceHelper<svc> : public ServiceImplHelper, \
126  public ServiceLGRHelper { \
127  DEFINE_ART_SERVICE_TYPEID(svc) \
128  DEFINE_ART_SERVICE_SCOPE(scopeArg) \
129  bool \
130  is_interface_impl() const override \
131  { \
132  return false; \
133  } \
134  DEFINE_ART_SERVICE_RETRIEVER(svc) \
135  }; \
136  }
137 
138 // Define the C-linkage function to create the helper.
139 #define DEFINE_ART_SH_CREATE(svc) DEFINE_ART_SH_CREATE_DETAIL(svc, service)
140 
141 #define DEFINE_ART_SIH_CREATE(svc) DEFINE_ART_SH_CREATE_DETAIL(svc, iface)
142 
143 #define DEFINE_ART_SH_CREATE_DETAIL(svc, type) \
144  EXTERN_C_FUNC_DECLARE_START \
145  std::unique_ptr<art::detail::ServiceHelperBase> create_##type##_helper() \
146  { \
147  return std::make_unique<art::detail::ServiceHelper<svc>>(); \
148  } \
149  EXTERN_C_FUNC_DECLARE_END
150 
151 #endif /* art_Framework_Services_Registry_detail_helper_macros_h */
152 
153 // Local Variables:
154 // mode: c++
155 // End: