LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
ServiceWrapper.h
Go to the documentation of this file.
1 #ifndef art_Framework_Services_Registry_detail_ServiceWrapper_h
2 #define art_Framework_Services_Registry_detail_ServiceWrapper_h
3 
4 // ======================================================================
5 //
6 // ServiceWrapper - Class template through which the framework manages
7 // the lifetime of a service.
8 //
9 // ======================================================================
10 
12 
15 #include "cetlib/container_algorithms.h"
16 #include "cetlib/metaprogramming.h"
17 #include <memory>
18 #include <type_traits>
19 
20 namespace art {
21  // Forward declaration
22  class ActivityRegistry;
23  class ModuleDescription;
24  class ProducingService;
25 
26  namespace detail {
27 
28  using cet::enable_if_function_exists_t;
29 
30  // General template.
31  template <typename T, ServiceScope SCOPE>
33 
34  // Partial specialization.
35  template <typename T>
37 
38  // If we have a constructor taking fhicl::ParameterSet const& and
39  // ActivityRegistry&, use it. Otherwise, call a one-argument
40  // constructor taking fhicl::ParameterSet const& only.
41  template <typename T>
42  std::enable_if_t<std::is_constructible<T,
43  fhicl::ParameterSet const&,
44  ActivityRegistry&>::value,
45  std::shared_ptr<T>>
46  makeServiceFrom(fhicl::ParameterSet const& ps, ActivityRegistry& areg)
47  {
48  static_assert(
50  "\n\nart-error: A service that inherits from art::ProducingService\n"
51  " cannot have a constructor that takes an ActivityRegistry&\n"
52  " argument. Contact artists@fnal.gov for guidance.\n");
53  return std::make_shared<T>(ps, areg);
54  }
55 
56  template <typename T>
57  std::enable_if_t<!std::is_constructible<T,
58  fhicl::ParameterSet const&,
60  std::shared_ptr<T>>
61  makeServiceFrom(fhicl::ParameterSet const& ps, ActivityRegistry&)
62  {
63  return std::make_shared<T>(ps);
64  }
65 
66  } // namespace detail
67 } // namespace art
68 
69 // ----------------------------------------------------------------------
70 
71 // General template.
72 template <typename T, art::ServiceScope SCOPE>
74 public:
75  // Non-copyable.
76  ServiceWrapper(ServiceWrapper const&) = delete;
77  ServiceWrapper& operator=(ServiceWrapper const&) = delete;
78 
79  // C'tor from ParameterSet, ActivityRegistry.
81  : service_ptr_{makeServiceFrom<T>(ps, areg)}
82  {}
83 
84  // C'tor from shared_ptr.
85  explicit ServiceWrapper(std::shared_ptr<T>&& p) : service_ptr_{std::move(p)}
86  {}
87 
88  T&
89  get()
90  {
91  return *service_ptr_;
92  }
93 
94  template <typename U,
97  getAs() const
98  {
99  return new ServiceWrapper<U, SCOPE>{
100  std::static_pointer_cast<U>(service_ptr_)};
101  }
102 
103 private:
104  template <typename U = T>
107  ProductDescriptions& productsToProduce,
108  ProducingServiceSignals& signals,
109  ModuleDescription const& md)
110  {
111  service_ptr_->registerCallbacks(signals);
112  service_ptr_->setModuleDescription(md);
113  service_ptr_->registerProducts(mpr, productsToProduce, md);
114  }
115 
116  template <typename U = T>
121  ModuleDescription const&)
122  {}
123 
124  void
126  ProductDescriptions& productsToProduce,
127  ProducingServiceSignals& signals,
128  ModuleDescription const& md) override
129  {
130  doRegisterProducts(mpr, productsToProduce, signals, md);
131  }
132 
133  std::shared_ptr<T> service_ptr_;
134 
135 }; // ServiceWrapper<T, ServiceScope>
136 
137 // Partially-specialized template.
138 template <typename T>
140  : public ServiceWrapperBase {
141 public:
142  // Non-copyable.
143  ServiceWrapper(ServiceWrapper const&) = delete;
144  void operator=(ServiceWrapper const&) = delete;
145 
146  // C'tor from shared_ptrs.
147  explicit ServiceWrapper(std::vector<std::shared_ptr<T>>&& service_ptrs)
148  : service_ptrs_{std::move(service_ptrs)}
149  {}
150 
151  // C'tor from collection of convertible-to-shared-ptr
152  template <class SP>
153  explicit ServiceWrapper(std::vector<SP>&& service_ptrs)
154  {
155  service_ptrs_.reserve(service_ptrs.size());
156  for (auto&& up : service_ptrs) {
157  service_ptrs_.emplace_back(std::move(up));
158  }
159  }
160 
161  // C'tor from ParameterSet, ActivityRegistry, nSchedules.
163  ActivityRegistry& areg,
164  size_t const nSchedules)
165  {
166  service_ptrs_.reserve(nSchedules);
168  for (size_t iSched{}; iSched < nSchedules; ++iSched, id = id.next()) {
169  service_ptrs_.emplace_back(new T{ps, areg, id});
170  }
171  }
172 
173  T&
174  get(ScheduleID sID)
175  {
176  return *service_ptrs_.at(sID.id());
177  }
178 
179  template <typename U,
182  getAs() const
183  {
184  std::vector<std::shared_ptr<U>> converted_ptrs(service_ptrs_.size());
185  cet::transform_all(service_ptrs_,
186  converted_ptrs.begin(),
187  [](std::shared_ptr<T> const& ptr_in) {
188  return std::static_pointer_cast<U>(ptr_in);
189  });
191  std::move(converted_ptrs));
192  }
193 
194 private:
195  // No products can be registered for per-schedule services.
196  void
200  ModuleDescription const&) override
201  {}
202 
203  std::vector<std::shared_ptr<T>> service_ptrs_{};
204 };
205 
206 // ======================================================================
207 
208 #endif /* art_Framework_Services_Registry_detail_ServiceWrapper_h */
209 
210 // Local Variables:
211 // mode: c++
212 // End:
ServiceScope
Definition: ServiceScope.h:5
ServiceWrapper(fhicl::ParameterSet const &ps, ActivityRegistry &areg, size_t const nSchedules)
static ScheduleID first()
Definition: ScheduleID.h:82
std::enable_if_t< std::is_base_of< ProducingService, U >::value > doRegisterProducts(MasterProductRegistry &mpr, ProductDescriptions &productsToProduce, ProducingServiceSignals &signals, ModuleDescription const &md)
std::vector< BranchDescription > ProductDescriptions
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
ServiceWrapper & operator=(ServiceWrapper const &)=delete
std::enable_if_t< std::is_constructible< T, fhicl::ParameterSet const &, ActivityRegistry & >::value, std::shared_ptr< T > > makeServiceFrom(fhicl::ParameterSet const &ps, ActivityRegistry &areg)
void registerProducts(MasterProductRegistry &, ProductDescriptions &, ProducingServiceSignals &, ModuleDescription const &) override
ServiceWrapper(fhicl::ParameterSet const &ps, ActivityRegistry &areg)
std::string value(boost::any const &)
std::enable_if_t<!std::is_base_of< ProducingService, U >::value > doRegisterProducts(MasterProductRegistry &, ProductDescriptions &, ProducingServiceSignals &, ModuleDescription const &)
HLT enums.
ServiceWrapper< U, SCOPE > * getAs() const
ServiceWrapper(std::shared_ptr< T > &&p)
ServiceWrapper< U, art::ServiceScope::PER_SCHEDULE > * getAs() const
ServiceWrapper(ServiceWrapper const &)=delete
void registerProducts(MasterProductRegistry &mpr, ProductDescriptions &productsToProduce, ProducingServiceSignals &signals, ModuleDescription const &md) override
ServiceWrapper(std::vector< std::shared_ptr< T >> &&service_ptrs)
std::shared_ptr< T > service_ptr_