LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
ServicesManager.h
Go to the documentation of this file.
1 #ifndef art_Framework_Services_Registry_ServicesManager_h
2 #define art_Framework_Services_Registry_ServicesManager_h
3 
5 // ServicesManager
6 //
7 // ======================================================================
8 
18 #include "cetlib_except/demangle.h"
19 
20 #include <map>
21 #include <memory>
22 #include <string>
23 #include <utility>
24 #include <vector>
25 
26 namespace cet {
27  class LibraryManager;
28 }
29 
30 namespace art {
31  class ActivityRegistry;
32  class MasterProductRegistry;
33  struct ProcessConfiguration;
34  class ProducingServiceSignals;
35  class ServicesManager;
36 }
37 
38 namespace fhicl {
39  class ParameterSet;
40 }
41 
43 public:
44  // non-copyable:
45  ServicesManager(ServicesManager const&) = delete;
46  ServicesManager& operator=(ServicesManager const&) = delete;
47 
48  using ParameterSets = std::vector<fhicl::ParameterSet>;
49 
50  explicit ServicesManager(ParameterSets const&,
51  cet::LibraryManager const&,
53  ~ServicesManager();
54 
55  template <typename T,
56  typename = std::enable_if_t<detail::ServiceHelper<T>::scope_val !=
57  ServiceScope::PER_SCHEDULE>>
58  T& get();
59 
60  template <typename T,
61  typename = std::enable_if_t<detail::ServiceHelper<T>::scope_val ==
62  ServiceScope::PER_SCHEDULE>>
63  T& get(ScheduleID);
64 
65  // Returns true of the particular service is accessible -- that is, it
66  // either can be made (if requested) or has already been made.
67  template <class T>
68  bool
69  isAvailable() const
70  {
71  return factory_.find(TypeID(typeid(T))) != factory_.end();
72  }
73 
74  template <typename T,
75  typename = std::enable_if_t<detail::ServiceHelper<T>::scope_val !=
76  ServiceScope::PER_SCHEDULE>>
77  void put(std::unique_ptr<T>&& premade_service);
78 
79  // SP<T> must be convertible to std::shared_ptr<T>.
80  template <typename SP,
81  typename = std::enable_if_t<
83  ServiceScope::PER_SCHEDULE>>
84  void put(std::vector<SP>&& premade_services); // force all the services that
85  // are not alrady made into
86  // existance
87 
88  // using 'reg'. The order of creation will be the registration order.
89  void forceCreation();
90 
91  void registerProducts(MasterProductRegistry& mpr,
92  ProductDescriptions& productsToProduce,
93  ProducingServiceSignals& signals,
94  ProcessConfiguration const& pc);
95 
96  void getParameterSets(ParameterSets& out) const;
97 
98 private:
99  using SHBCREATOR_t = std::unique_ptr<detail::ServiceHelperBase> (*)();
100  using NameIndex = std::map<std::string, detail::ServiceCache::iterator>;
101  using TypeIDs = std::vector<TypeID>;
102 
103  void fillCache_(ParameterSets const& psets, cet::LibraryManager const& lm);
104 
105  std::pair<detail::ServiceCache::iterator, bool> insertImpl_(
106  fhicl::ParameterSet const& pset,
107  std::unique_ptr<detail::ServiceHelperBase>&& helper);
108 
109  void insertInterface_(fhicl::ParameterSet const& pset,
110  std::unique_ptr<detail::ServiceHelperBase>&& helper,
112 
113  // these are real things that we use.
116  NameIndex index_{};
117 
118  TypeIDs requestedCreationOrder_{};
119  detail::ServiceStack actualCreationOrder_{};
120  std::vector<std::string> configErrMsgs_{};
121 
122 }; // ServicesManager
123 
124 // ----------------------------------------------------------------------
125 
126 template <typename T, typename>
127 T&
129 {
130  // Find the correct ServiceCacheEntry object.
131  auto it = factory_.find(TypeID{typeid(T)});
132  if (it == factory_.end())
134  << "art::ServicesManager unable to find the service of type '"
135  << cet::demangle_symbol(typeid(T).name()) << "'.\n";
136  return it->second.get<T>(registry_, actualCreationOrder_);
137 } // get<>()
138 
139 template <typename T, typename>
140 T&
142 {
143  // Find the correct ServiceCacheEntry object.
144  auto it = factory_.find(TypeID{typeid(T)});
145  if (it == factory_.end())
147  << "art::ServicesManager unable to find the service of type '"
148  << cet::demangle_symbol(typeid(T).name()) << "'.\n";
149  return it->second.get<T>(registry_, actualCreationOrder_, sID);
150 } // get<>()
151 
152 template <typename T, typename>
153 void
154 art::ServicesManager::put(std::unique_ptr<T>&& premade_service)
155 {
156  std::unique_ptr<detail::ServiceHelperBase> service_helper(
158  TypeID const id{typeid(T)};
159  detail::ServiceCache::const_iterator it = factory_.find(id);
160  if (it != factory_.end()) {
161  throw art::Exception(art::errors::LogicError, "Service")
162  << "The system has manually added service of type "
163  << cet::demangle_symbol(id.name())
164  << ", but the service system already has a configured service"
165  << " of that type\n";
166  }
169  std::move(premade_service)));
170  actualCreationOrder_.push(swb);
171  factory_.emplace(
172  id, detail::ServiceCacheEntry(std::move(swb), std::move(service_helper)));
173 }
174 
175 template <typename SP, typename>
176 void
177 art::ServicesManager::put(std::vector<SP>&& premade_services)
178 {
179  using element_type = typename SP::element_type;
180  std::unique_ptr<detail::ServiceHelperBase> service_helper(
182  TypeID const id{typeid(element_type)};
183  detail::ServiceCache::const_iterator it = factory_.find(id);
184  if (it != factory_.end()) {
185  throw art::Exception(art::errors::LogicError, "Service:")
186  << "The system has manually added service of type "
187  << cet::demangle_symbol(id.name())
188  << ", but the service system already has a configured service"
189  << " of that type\n";
190  }
192  new detail::ServiceWrapper<element_type,
194  std::move(premade_services)));
195  actualCreationOrder_.push(swb);
196  factory_.emplace(
197  id, detail::ServiceCacheEntry(std::move(swb), std::move(service_helper)));
198 }
199 
200  // ======================================================================
201 
202 #endif /* art_Framework_Services_Registry_ServicesManager_h */
203 
204 // Local Variables:
205 // mode: c++
206 // End:
std::vector< fhicl::ParameterSet > ParameterSets
intermediate_table::iterator iterator
std::vector< BranchDescription > ProductDescriptions
std::map< TypeID, detail::ServiceCacheEntry > ServiceCache
Definition: ServiceCache.h:11
std::stack< WrapperBase_ptr > ServiceStack
Definition: ServiceStack.h:10
void put(std::unique_ptr< T > &&premade_service)
std::shared_ptr< detail::ServiceWrapperBase > WrapperBase_ptr
intermediate_table::const_iterator const_iterator
parameter set interface
std::map< std::string, detail::ServiceCache::iterator > NameIndex
bool isAvailable() const
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
HLT enums.
art::ActivityRegistry & registry_
std::vector< TypeID > TypeIDs