Medical Imaging Interaction Toolkit  2018.4.99-3e3f1a6e
Medical Imaging Interaction Toolkit
usServiceInterface.h
Go to the documentation of this file.
1 /*============================================================================
2 
3  Library: CppMicroServices
4 
5  Copyright (c) German Cancer Research Center (DKFZ)
6  All rights reserved.
7 
8  Licensed under the Apache License, Version 2.0 (the "License");
9  you may not use this file except in compliance with the License.
10  You may obtain a copy of the License at
11 
12  http://www.apache.org/licenses/LICENSE-2.0
13 
14  Unless required by applicable law or agreed to in writing, software
15  distributed under the License is distributed on an "AS IS" BASIS,
16  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  See the License for the specific language governing permissions and
18  limitations under the License.
19 
20 ============================================================================*/
21 
22 
23 #ifndef USSERVICEINTERFACE_H
24 #define USSERVICEINTERFACE_H
25 
26 #include <usGlobalConfig.h>
27 #include <usServiceException.h>
28 
29 #include <map>
30 #include <string>
31 #include <typeinfo>
32 
33 US_BEGIN_NAMESPACE
34 std::string GetDemangledName(const std::type_info& typeInfo);
35 US_END_NAMESPACE
36 
50 template<class T> std::string us_service_interface_iid()
51 {
52  return US_PREPEND_NAMESPACE(GetDemangledName)(typeid(T));
53 }
54 
56 template<> inline std::string us_service_interface_iid<void>() { return std::string(); }
58 
59 
104 #define US_DECLARE_SERVICE_INTERFACE(_service_interface_type, _service_interface_id) \
105  template<> inline std::string us_service_interface_iid<_service_interface_type>() \
106  { return _service_interface_id; } \
107 
108 
109 US_BEGIN_NAMESPACE
110 
111 class ServiceFactory;
112 
119 template<class Interface>
120 struct InterfaceType {};
121 
138 typedef std::map<std::string, void*> InterfaceMap;
139 
140 
141 template<class I>
143 {
144  if (us_service_interface_iid<I>().empty())
145  {
146  throw ServiceException(std::string("The interface class ") + typeid(I).name() +
147  " uses an invalid id in its US_DECLARE_SERVICE_INTERFACE macro call.");
148  }
149  im.insert(std::make_pair(std::string(us_service_interface_iid<I>()),
150  static_cast<void*>(static_cast<I*>(i))));
151  return true;
152 }
153 
154 template<>
156 {
157  return false;
158 }
159 
160 
178 template<class I1, class I2 = void, class I3 = void>
180 {
185 
192  template<class Impl>
193  MakeInterfaceMap(Impl* impl)
194  : m_factory(nullptr)
195  , m_interface1(static_cast<I1*>(impl))
196  , m_interface2(static_cast<I2*>(impl))
197  , m_interface3(static_cast<I3*>(impl))
198  {}
199 
206  : m_factory(factory)
207  , m_interface1(nullptr)
208  , m_interface2(nullptr)
209  , m_interface3(nullptr)
210  {
211  if (factory == nullptr)
212  {
213  throw ServiceException("The service factory argument must not be nullptr.");
214  }
215  }
216 
217  operator InterfaceMap ()
218  {
219  InterfaceMap sim;
220  InsertInterfaceType(sim, m_interface1);
221  InsertInterfaceType(sim, m_interface2);
222  InsertInterfaceType(sim, m_interface3);
223 
224  if (m_factory)
225  {
226  sim.insert(std::make_pair(std::string("org.cppmicroservices.factory"),
227  static_cast<void*>(m_factory)));
228  }
229 
230  return sim;
231  }
232 };
233 
235 template<class I1, class I2>
236 struct MakeInterfaceMap<I1,I2,void>
237 {
238  ServiceFactory* m_factory;
239  I1* m_interface1;
240  I2* m_interface2;
241 
242  template<class Impl>
243  MakeInterfaceMap(Impl* impl)
244  : m_factory(nullptr)
245  , m_interface1(static_cast<I1*>(impl))
246  , m_interface2(static_cast<I2*>(impl))
247  {}
248 
250  : m_factory(factory)
251  , m_interface1(nullptr)
252  , m_interface2(nullptr)
253  {
254  if (factory == nullptr)
255  {
256  throw ServiceException("The service factory argument must not be nullptr.");
257  }
258  }
259 
260  operator InterfaceMap ()
261  {
262  InterfaceMap sim;
263  InsertInterfaceType(sim, m_interface1);
264  InsertInterfaceType(sim, m_interface2);
265 
266  if (m_factory)
267  {
268  sim.insert(std::make_pair(std::string("org.cppmicroservices.factory"),
269  static_cast<void*>(m_factory)));
270  }
271 
272  return sim;
273  }
274 };
275 
276 template<class I1>
277 struct MakeInterfaceMap<I1,void,void>
278 {
279  ServiceFactory* m_factory;
280  I1* m_interface1;
281 
282  template<class Impl>
283  MakeInterfaceMap(Impl* impl)
284  : m_factory(nullptr)
285  , m_interface1(static_cast<I1*>(impl))
286  {}
287 
289  : m_factory(factory)
290  , m_interface1(nullptr)
291  {
292  if (factory == nullptr)
293  {
294  throw ServiceException("The service factory argument must not be nullptr.");
295  }
296  }
297 
298  operator InterfaceMap ()
299  {
300  InterfaceMap sim;
301  InsertInterfaceType(sim, m_interface1);
302 
303  if (m_factory)
304  {
305  sim.insert(std::make_pair(std::string("org.cppmicroservices.factory"),
306  static_cast<void*>(m_factory)));
307  }
308 
309  return sim;
310  }
311 };
312 
313 template<>
314 struct MakeInterfaceMap<void,void,void>;
316 
329 template<class I1>
331 {
332  InterfaceMap::const_iterator iter = map.find(us_service_interface_iid<I1>());
333  if (iter != map.end())
334  {
335  return reinterpret_cast<I1*>(iter->second);
336  }
337  return nullptr;
338 }
339 
340 US_END_NAMESPACE
341 
342 
343 #endif // USSERVICEINTERFACE_H
bool InsertInterfaceType(InterfaceMap &im, I *i)
MakeInterfaceMap(ServiceFactory *factory)
ServiceFactory * m_factory
std::string GetDemangledName(const std::type_info &typeInfo)
std::map< std::string, void * > InterfaceMap
I1 * ExtractInterface(const InterfaceMap &map)
std::string us_service_interface_iid()
bool InsertInterfaceType< void >(InterfaceMap &, void *)