Falaise  4.0.1
SuperNEMO Software Toolkit
service_handle.h
Go to the documentation of this file.
1 //! \file service_handle.h
2 //! \brief Simple access to services via a smart pointer
3 #ifndef SERVICE_HANDLE_HH
4 #define SERVICE_HANDLE_HH
5 
6 #include <exception>
7 
10 
11 namespace snemo {
12 
13 //! Exception reporting that a service is missing in the provider
14 class missing_service_error : public std::runtime_error {
15  using std::runtime_error::runtime_error;
16 };
17 
18 //! Exception reporting that a service is provided, but of the wrong type
19 class bad_service_type : public std::runtime_error {
20  using std::runtime_error::runtime_error;
21 };
22 
23 //! Exception reporting that a service_handle is empty
24 class bad_service_access : public std::runtime_error {
25  using std::runtime_error::runtime_error;
26 };
27 
28 //! Make a @ref service_handle from a @ref datatools::service_manager provider
29 /*!
30  * Free template function used by constructor of @ref service_handle. As with that
31  * class, the template parameter must have defined @ref service_traits.
32  *
33  * \tparam T type of service to make
34  * \param[in] provider service provider to extract service from
35  * \returns raw pointer to service interface
36  * \throw missing_service_error if provider cannot supply the service
37  * \throw bad_service_type if provider cannot supply a service of type T
38  *
39  * \sa snemo::service_handle
40  * \sa snemo::service_traits
41  */
42 template <typename T>
44  using Service_t = typename service_traits<T>::service_type;
45  std::string serviceName{service_label<T>::value};
46 
47  if (!provider.has(serviceName)) {
48  throw missing_service_error{"No service of type '" + serviceName + "' available"};
49  }
50 
51  if (!provider.is_a<Service_t>(serviceName)) {
52  throw bad_service_type{"Service is not of requested type '" + serviceName + "'"};
53  }
54 
55  // extract and return the underlying type
56  return service_traits<T>::get(provider.grab<Service_t>(serviceName));
57 }
58 
59 //! \brief Semi-smart pointer holding a service interface
60 /*!
61  * Provides a convenient adaptor interface over @ref datatools::service_manager
62  * to ease checked access and use of service interfaces. It may be constructed
63  * from a @ref datatools::service_manager instance as
64  *
65  * ```cpp
66  * void example(datatools::service_manager& p) {
67  * snemo::service_handle<some_service_type> someSvc{p};
68  *
69  * // ... use someSvc ...
70  * someSvc->some_service_memfn();
71  * }
72  * ```
73  *
74  * The template parameter must be a type for which a specialization of @ref
75  * snemo::service_traits exists otherwise a compile-time error will be emitted
76  * Access and use of the service is checked at construction and access via
77  *
78  * - The constructor will throw a @ref snemo::missing_service_error or @ref snemo::bad_service_type
79  * if the provider does not hold the service, or it is held but not of the
80  * required type.
81  * - The dereference operator will throw @ref snemo::bad_service_access if the
82  * held service interface is `nullptr`
83  *
84  * It is only a semi-smart pointer as it does not own the raw
85  * pointer to the service interface. The lifetime of service interface pointers is expected, but not
86  * guaranteed, to be equal to the lifetime of an `flreconstruct` process.
87  *
88  * \sa falaise::processing::module
89  */
90 template <typename T>
92  public:
93  //! Default constructor
94  service_handle() = default;
95 
96  //! Construct from a service provider
98 
99  //! Return pointer to service interface
100  /*!
101  * \throws bad_service_access if pointer is null
102  */
103  T* operator->() const {
104  if (instance != nullptr) return instance;
105 
106  throw bad_service_access{"service handle is nullptr"};
107  }
108 
109  private:
110  T* instance = nullptr;
111 };
112 
113 } // namespace snemo
114 
115 #endif // SERVICE_HANDLE_HH
T * operator->() const
Return pointer to service interface.
Definition: service_handle.h:103
bool has(const std::string &name_) const
Types for defining service class traits.
Semi-smart pointer holding a service interface.
Definition: service_handle.h:91
T & grab(const std::string &name_)
bool is_a(const std::string &name_) const
Template struct for defining trait types and functions for a service.
Definition: service_traits.h:44
Exception reporting that a service is provided, but of the wrong type.
Definition: service_handle.h:19
typename boost::mpl::c_str< typename service_traits< T >::label_type >::type service_label
Convenience type alias for extracting the label of a service.
Definition: service_traits.h:55
Definition: calo_tapered_scin_box_model.h:54
Exception reporting that a service_handle is empty.
Definition: service_handle.h:24
T * service_maker(datatools::service_manager &provider)
Make a service_handle from a datatools::service_manager provider.
Definition: service_handle.h:43
service_handle()=default
Default constructor.
service_handle(datatools::service_manager &sm)
Construct from a service provider.
Definition: service_handle.h:97
Exception reporting that a service is missing in the provider.
Definition: service_handle.h:14