CMS 3D CMS Logo

ServicesManager.h
Go to the documentation of this file.
1 #ifndef ServiceRegistry_ServicesManager_h
2 #define ServiceRegistry_ServicesManager_h
3 // -*- C++ -*-
4 //
5 // Package: ServiceRegistry
6 // Class : ServicesManager
7 //
16 //
17 // Original Author: Chris Jones
18 // Created: Mon Sep 5 13:33:01 EDT 2005
19 //
20 
21 // user include files
31 
32 // system include files
33 #include <memory>
34 
35 #include <cassert>
36 #include <vector>
37 
38 // forward declarations
39 namespace edm {
40  class ParameterSet;
41  class ServiceToken;
42 
43  namespace serviceregistry {
44 
46  public:
47  struct MakerHolder {
48  MakerHolder(std::shared_ptr<ServiceMakerBase> iMaker, ParameterSet& iPSet, ActivityRegistry&);
49  bool add(ServicesManager&) const;
50 
53  ActivityRegistry* registry_; // We do not use propagate_const because the registry itself is mutable
54  //Services construction is not allowed to occur across threads
55  CMS_SA_ALLOW mutable bool wasAdded_;
56  };
57  typedef std::map<TypeIDBase, std::shared_ptr<ServiceWrapperBase>> Type2Service;
58  typedef std::map<TypeIDBase, MakerHolder> Type2Maker;
59 
60  ServicesManager(std::vector<ParameterSet>& iConfiguration);
61 
67  ServiceLegacy iLegacy,
68  std::vector<ParameterSet>& iConfiguration,
69  bool associate = true);
70 
71  ServicesManager(ServicesManager const&) = delete; // stop default
72  ServicesManager const& operator=(ServicesManager const&) = delete; // stop default
74 
75  // ---------- const member functions ---------------------
76  template <typename T>
77  T& get() const {
78  Type2Service::const_iterator itFound = type2Service_.find(TypeIDBase(typeid(T)));
79  Type2Maker::const_iterator itFoundMaker;
80  if (itFound == type2Service_.end()) {
81  //do on demand building of the service
82  if (nullptr == type2Maker_.get() ||
83  type2Maker_->end() == (itFoundMaker = type2Maker_->find(TypeIDBase(typeid(T))))) {
84  auto demangled = typeDemangle(typeid(T).name());
86  "Service Request unable to find requested service with compiler type name '",
87  demangled.c_str(),
88  "'.\n");
89  } else {
90  const_cast<ServicesManager&>(*this).createServiceFor(itFoundMaker->second);
91  itFound = type2Service_.find(TypeIDBase(typeid(T)));
92  //the 'add()' should have put the service into the list
93  assert(itFound != type2Service_.end());
94  }
95  }
96  //convert it to its actual type
97  std::shared_ptr<ServiceWrapper<T>> ptr(std::dynamic_pointer_cast<ServiceWrapper<T>>(itFound->second));
98  assert(nullptr != ptr.get());
99  return ptr->get();
100  }
101 
103  template <typename T>
104  bool isAvailable() const {
105  Type2Service::const_iterator itFound = type2Service_.find(TypeIDBase(typeid(T)));
106  Type2Maker::const_iterator itFoundMaker;
107  if (itFound == type2Service_.end()) {
108  //do on demand building of the service
109  if (nullptr == type2Maker_.get() ||
110  type2Maker_->end() == (itFoundMaker = type2Maker_->find(TypeIDBase(typeid(T))))) {
111  return false;
112  } else {
113  //Actually create the service in order to 'flush out' any
114  // configuration errors for the service
115  const_cast<ServicesManager&>(*this).createServiceFor(itFoundMaker->second);
116  itFound = type2Service_.find(TypeIDBase(typeid(T)));
117  //the 'add()' should have put the service into the list
118  assert(itFound != type2Service_.end());
119  }
120  }
121  return true;
122  }
123 
124  // ---------- static member functions --------------------
125 
126  // ---------- member functions ---------------------------
128  template <typename T>
129  bool put(std::shared_ptr<ServiceWrapper<T>> iPtr, bool iOverride = false) {
130  Type2Service::const_iterator itFound = type2Service_.find(TypeIDBase(typeid(T)));
131  if (itFound != type2Service_.end() and not iOverride) {
132  return false;
133  }
134  type2Service_[TypeIDBase(typeid(T))] = iPtr;
135  actualCreationOrder_.push_back(TypeIDBase(typeid(T)));
136  return true;
137  }
138 
140  void connect(ActivityRegistry& iOther);
141 
143  void connectTo(ActivityRegistry& iOther);
144 
149 
150  private:
151  void fillListOfMakers(std::vector<ParameterSet>&);
152  void createServices();
153  void createServiceFor(MakerHolder const&);
154 
155  // ---------- member data --------------------------------
156  //hold onto the Manager passed in from the ServiceToken so that
157  // the ActivityRegistry of that Manager does not go out of scope
158  // This must be first to get the Service destructors called in
159  // the correct order.
161 
165  std::vector<TypeIDBase> requestedCreationOrder_;
166  std::vector<TypeIDBase> actualCreationOrder_;
167  };
168  } // namespace serviceregistry
169 } // namespace edm
170 
171 #endif
bool put(std::shared_ptr< ServiceWrapper< T >> iPtr, bool iOverride=false)
returns false if put fails because a service of this type already exists
MakerHolder(std::shared_ptr< ServiceMakerBase > iMaker, ParameterSet &iPSet, ActivityRegistry &)
#define CMS_SA_ALLOW
void fillListOfMakers(std::vector< ParameterSet > &)
ServicesManager const & operator=(ServicesManager const &)=delete
void createServiceFor(MakerHolder const &)
void copySlotsTo(ActivityRegistry &)
copy our Service&#39;s slots to the argument&#39;s signals
std::map< TypeIDBase, MakerHolder > Type2Maker
edm::propagate_const< std::shared_ptr< ServiceMakerBase > > maker_
assert(be >=bs)
static void throwThis(Code category, char const *message0="", char const *message1="", char const *message2="", char const *message3="", char const *message4="")
Definition: EDMException.cc:85
constexpr element_type const * get() const
std::vector< TypeIDBase > actualCreationOrder_
void connectTo(ActivityRegistry &iOther)
causes iOther&#39;s signals to be forward to us
demangled
Definition: symbols.py:70
void copySlotsFrom(ActivityRegistry &)
the copy the argument&#39;s slots to the our signals
std::vector< TypeIDBase > requestedCreationOrder_
std::string typeDemangle(char const *mangledName)
edm::propagate_const< std::unique_ptr< Type2Maker > > type2Maker_
ServicesManager(std::vector< ParameterSet > &iConfiguration)
HLT enums.
std::map< TypeIDBase, std::shared_ptr< ServiceWrapperBase > > Type2Service
edm::propagate_const< std::shared_ptr< ServicesManager > > associatedManager_
long double T
bool isAvailable() const
returns true of the particular service is accessible
void connect(ActivityRegistry &iOther)
causes our ActivityRegistry&#39;s signals to be forwarded to iOther