sdbus-c++  1.2.0
High-level C++ D-Bus library based on systemd D-Bus implementation
TypeTraits.h
Go to the documentation of this file.
1 
27 #ifndef SDBUS_CXX_TYPETRAITS_H_
28 #define SDBUS_CXX_TYPETRAITS_H_
29 
30 #include <type_traits>
31 #include <string>
32 #include <vector>
33 #include <map>
34 #include <cstdint>
35 #include <functional>
36 #include <memory>
37 #include <tuple>
38 
39 // Forward declarations
40 namespace sdbus {
41  class Variant;
42  template <typename... _ValueTypes> class Struct;
43  class ObjectPath;
44  class Signature;
45  class UnixFd;
46  class MethodCall;
47  class MethodReply;
48  class Signal;
49  class Message;
50  class PropertySetCall;
51  class PropertyGetReply;
52  template <typename... _Results> class Result;
53  class Error;
54 }
55 
56 namespace sdbus {
57 
58  // Callbacks from sdbus-c++
59  using method_callback = std::function<void(MethodCall msg)>;
60  using async_reply_handler = std::function<void(MethodReply& reply, const Error* error)>;
61  using signal_handler = std::function<void(Signal& signal)>;
62  using message_handler = std::function<void(Message& msg)>;
63  using property_set_callback = std::function<void(PropertySetCall& msg)>;
64  using property_get_callback = std::function<void(PropertyGetReply& reply)>;
65 
66  // Type-erased RAII-style handle to callbacks/subscriptions registered to sdbus-c++
67  using Slot = std::unique_ptr<void, std::function<void(void*)>>;
68 
69  // Tag specifying that an owning slot handle shall be returned from the function
70  struct request_slot_t { explicit request_slot_t() = default; };
71  inline constexpr request_slot_t request_slot{};
72  // Tag specifying that the library shall own the slot resulting from the call of the function (so-called floating slot)
73  struct floating_slot_t { explicit floating_slot_t() = default; };
74  inline constexpr floating_slot_t floating_slot{};
75  // Deprecated name for the above -- a floating slot
76  struct dont_request_slot_t { explicit dont_request_slot_t() = default; };
77  [[deprecated("Replaced by floating_slot")]] inline constexpr dont_request_slot_t dont_request_slot{};
78  // Tag denoting the assumption that the caller has already obtained message ownership
79  struct adopt_message_t { explicit adopt_message_t() = default; };
80  inline constexpr adopt_message_t adopt_message{};
81  // Tag denoting the assumption that the caller has already obtained fd ownership
82  struct adopt_fd_t { explicit adopt_fd_t() = default; };
83  inline constexpr adopt_fd_t adopt_fd{};
84 
85  // Template specializations for getting D-Bus signatures from C++ types
86  template <typename _T>
87  struct signature_of
88  {
89  static constexpr bool is_valid = false;
90 
91  static const std::string str()
92  {
93  // sizeof(_T) < 0 is here to make compiler not being able to figure out
94  // the assertion expression before the template instantiation takes place.
95  static_assert(sizeof(_T) < 0, "Unknown DBus type");
96  return "";
97  }
98  };
99 
100  template <>
101  struct signature_of<void>
102  {
103  static constexpr bool is_valid = true;
104 
105  static const std::string str()
106  {
107  return "";
108  }
109  };
110 
111  template <>
112  struct signature_of<bool>
113  {
114  static constexpr bool is_valid = true;
115 
116  static const std::string str()
117  {
118  return "b";
119  }
120  };
121 
122  template <>
123  struct signature_of<uint8_t>
124  {
125  static constexpr bool is_valid = true;
126 
127  static const std::string str()
128  {
129  return "y";
130  }
131  };
132 
133  template <>
134  struct signature_of<int16_t>
135  {
136  static constexpr bool is_valid = true;
137 
138  static const std::string str()
139  {
140  return "n";
141  }
142  };
143 
144  template <>
145  struct signature_of<uint16_t>
146  {
147  static constexpr bool is_valid = true;
148 
149  static const std::string str()
150  {
151  return "q";
152  }
153  };
154 
155  template <>
156  struct signature_of<int32_t>
157  {
158  static constexpr bool is_valid = true;
159 
160  static const std::string str()
161  {
162  return "i";
163  }
164  };
165 
166  template <>
167  struct signature_of<uint32_t>
168  {
169  static constexpr bool is_valid = true;
170 
171  static const std::string str()
172  {
173  return "u";
174  }
175  };
176 
177  template <>
178  struct signature_of<int64_t>
179  {
180  static constexpr bool is_valid = true;
181 
182  static const std::string str()
183  {
184  return "x";
185  }
186  };
187 
188  template <>
189  struct signature_of<uint64_t>
190  {
191  static constexpr bool is_valid = true;
192 
193  static const std::string str()
194  {
195  return "t";
196  }
197  };
198 
199  template <>
200  struct signature_of<double>
201  {
202  static constexpr bool is_valid = true;
203 
204  static const std::string str()
205  {
206  return "d";
207  }
208  };
209 
210  template <>
211  struct signature_of<char*>
212  {
213  static constexpr bool is_valid = true;
214 
215  static const std::string str()
216  {
217  return "s";
218  }
219  };
220 
221  template <>
222  struct signature_of<const char*>
223  {
224  static constexpr bool is_valid = true;
225 
226  static const std::string str()
227  {
228  return "s";
229  }
230  };
231 
232  template <std::size_t _N>
233  struct signature_of<char[_N]>
234  {
235  static constexpr bool is_valid = true;
236 
237  static const std::string str()
238  {
239  return "s";
240  }
241  };
242 
243  template <std::size_t _N>
244  struct signature_of<const char[_N]>
245  {
246  static constexpr bool is_valid = true;
247 
248  static const std::string str()
249  {
250  return "s";
251  }
252  };
253 
254  template <>
255  struct signature_of<std::string>
256  {
257  static constexpr bool is_valid = true;
258 
259  static const std::string str()
260  {
261  return "s";
262  }
263  };
264 
265  template <typename... _ValueTypes>
266  struct signature_of<Struct<_ValueTypes...>>
267  {
268  static constexpr bool is_valid = true;
269 
270  static const std::string str()
271  {
272  std::string signature;
273  signature += "(";
274  (signature += ... += signature_of<_ValueTypes>::str());
275  signature += ")";
276  return signature;
277  }
278  };
279 
280  template <>
282  {
283  static constexpr bool is_valid = true;
284 
285  static const std::string str()
286  {
287  return "v";
288  }
289  };
290 
291  template <>
293  {
294  static constexpr bool is_valid = true;
295 
296  static const std::string str()
297  {
298  return "o";
299  }
300  };
301 
302  template <>
304  {
305  static constexpr bool is_valid = true;
306 
307  static const std::string str()
308  {
309  return "g";
310  }
311  };
312 
313  template <>
315  {
316  static constexpr bool is_valid = true;
317 
318  static const std::string str()
319  {
320  return "h";
321  }
322  };
323 
324  template <typename _Element>
325  struct signature_of<std::vector<_Element>>
326  {
327  static constexpr bool is_valid = true;
328 
329  static const std::string str()
330  {
331  return "a" + signature_of<_Element>::str();
332  }
333  };
334 
335  template <typename _Key, typename _Value>
336  struct signature_of<std::map<_Key, _Value>>
337  {
338  static constexpr bool is_valid = true;
339 
340  static const std::string str()
341  {
342  return "a{" + signature_of<_Key>::str() + signature_of<_Value>::str() + "}";
343  }
344  };
345 
346 
347  // Function traits implementation inspired by (c) kennytm,
348  // https://github.com/kennytm/utils/blob/master/traits.hpp
349  template <typename _Type>
351  : public function_traits<decltype(&_Type::operator())>
352  {};
353 
354  template <typename _Type>
355  struct function_traits<const _Type>
356  : public function_traits<_Type>
357  {};
358 
359  template <typename _Type>
360  struct function_traits<_Type&>
361  : public function_traits<_Type>
362  {};
363 
364  template <typename _ReturnType, typename... _Args>
366  {
367  typedef _ReturnType result_type;
368  typedef std::tuple<_Args...> arguments_type;
369  typedef std::tuple<std::decay_t<_Args>...> decayed_arguments_type;
370 
371  typedef _ReturnType function_type(_Args...);
372 
373  static constexpr std::size_t arity = sizeof...(_Args);
374 
375 // template <size_t _Idx, typename _Enabled = void>
376 // struct arg;
377 //
378 // template <size_t _Idx>
379 // struct arg<_Idx, std::enable_if_t<(_Idx < arity)>>
380 // {
381 // typedef std::tuple_element_t<_Idx, arguments_type> type;
382 // };
383 //
384 // template <size_t _Idx>
385 // struct arg<_Idx, std::enable_if_t<!(_Idx < arity)>>
386 // {
387 // typedef void type;
388 // };
389 
390  template <size_t _Idx>
391  struct arg
392  {
393  typedef std::tuple_element_t<_Idx, std::tuple<_Args...>> type;
394  };
395 
396  template <size_t _Idx>
397  using arg_t = typename arg<_Idx>::type;
398  };
399 
400  template <typename _ReturnType, typename... _Args>
401  struct function_traits<_ReturnType(_Args...)>
402  : public function_traits_base<_ReturnType, _Args...>
403  {
404  static constexpr bool is_async = false;
405  static constexpr bool has_error_param = false;
406  };
407 
408  template <typename... _Args>
409  struct function_traits<void(const Error*, _Args...)>
410  : public function_traits_base<void, _Args...>
411  {
412  static constexpr bool has_error_param = true;
413  };
414 
415  template <typename... _Args, typename... _Results>
416  struct function_traits<void(Result<_Results...>, _Args...)>
417  : public function_traits_base<std::tuple<_Results...>, _Args...>
418  {
419  static constexpr bool is_async = true;
420  using async_result_t = Result<_Results...>;
421  };
422 
423  template <typename... _Args, typename... _Results>
424  struct function_traits<void(Result<_Results...>&&, _Args...)>
425  : public function_traits_base<std::tuple<_Results...>, _Args...>
426  {
427  static constexpr bool is_async = true;
428  using async_result_t = Result<_Results...>;
429  };
430 
431  template <typename _ReturnType, typename... _Args>
432  struct function_traits<_ReturnType(*)(_Args...)>
433  : public function_traits<_ReturnType(_Args...)>
434  {};
435 
436  template <typename _ClassType, typename _ReturnType, typename... _Args>
437  struct function_traits<_ReturnType(_ClassType::*)(_Args...)>
438  : public function_traits<_ReturnType(_Args...)>
439  {
440  typedef _ClassType& owner_type;
441  };
442 
443  template <typename _ClassType, typename _ReturnType, typename... _Args>
444  struct function_traits<_ReturnType(_ClassType::*)(_Args...) const>
445  : public function_traits<_ReturnType(_Args...)>
446  {
447  typedef const _ClassType& owner_type;
448  };
449 
450  template <typename _ClassType, typename _ReturnType, typename... _Args>
451  struct function_traits<_ReturnType(_ClassType::*)(_Args...) volatile>
452  : public function_traits<_ReturnType(_Args...)>
453  {
454  typedef volatile _ClassType& owner_type;
455  };
456 
457  template <typename _ClassType, typename _ReturnType, typename... _Args>
458  struct function_traits<_ReturnType(_ClassType::*)(_Args...) const volatile>
459  : public function_traits<_ReturnType(_Args...)>
460  {
461  typedef const volatile _ClassType& owner_type;
462  };
463 
464  template <typename FunctionType>
465  struct function_traits<std::function<FunctionType>>
466  : public function_traits<FunctionType>
467  {};
468 
469  template <class _Function>
470  constexpr auto is_async_method_v = function_traits<_Function>::is_async;
471 
472  template <class _Function>
473  constexpr auto has_error_param_v = function_traits<_Function>::has_error_param;
474 
475  template <typename _FunctionType>
476  using function_arguments_t = typename function_traits<_FunctionType>::arguments_type;
477 
478  template <typename _FunctionType, size_t _Idx>
479  using function_argument_t = typename function_traits<_FunctionType>::template arg_t<_Idx>;
480 
481  template <typename _FunctionType>
482  constexpr auto function_argument_count_v = function_traits<_FunctionType>::arity;
483 
484  template <typename _FunctionType>
485  using function_result_t = typename function_traits<_FunctionType>::result_type;
486 
487  template <typename _Function>
489  {
491  };
492 
493  template <typename _Function>
494  using tuple_of_function_input_arg_types_t = typename tuple_of_function_input_arg_types<_Function>::type;
495 
496  template <typename _Function>
498  {
499  typedef typename function_traits<_Function>::result_type type;
500  };
501 
502  template <typename _Function>
503  using tuple_of_function_output_arg_types_t = typename tuple_of_function_output_arg_types<_Function>::type;
504 
505  template <typename _Type>
507  {
508  static const std::string str()
509  {
510  return signature_of<std::decay_t<_Type>>::str();
511  }
512  };
513 
514  template <typename... _Types>
515  struct aggregate_signature<std::tuple<_Types...>>
516  {
517  static const std::string str()
518  {
519  std::string signature;
520  (void)(signature += ... += signature_of<std::decay_t<_Types>>::str());
521  return signature;
522  }
523  };
524 
525  template <typename _Function>
527  {
528  static const std::string str()
529  {
531  }
532  };
533 
534  template <typename _Function>
536  {
537  static const std::string str()
538  {
540  }
541  };
542 
543  namespace detail
544  {
545  template <class _Function, class _Tuple, typename... _Args, std::size_t... _I>
546  constexpr decltype(auto) apply_impl( _Function&& f
547  , Result<_Args...>&& r
548  , _Tuple&& t
549  , std::index_sequence<_I...> )
550  {
551  return std::forward<_Function>(f)(std::move(r), std::get<_I>(std::forward<_Tuple>(t))...);
552  }
553 
554  template <class _Function, class _Tuple, std::size_t... _I>
555  constexpr decltype(auto) apply_impl( _Function&& f
556  , const Error* e
557  , _Tuple&& t
558  , std::index_sequence<_I...> )
559  {
560  return std::forward<_Function>(f)(e, std::get<_I>(std::forward<_Tuple>(t))...);
561  }
562 
563  // For non-void returning functions, apply_impl simply returns function return value (a tuple of values).
564  // For void-returning functions, apply_impl returns an empty tuple.
565  template <class _Function, class _Tuple, std::size_t... _I>
566  constexpr decltype(auto) apply_impl( _Function&& f
567  , _Tuple&& t
568  , std::index_sequence<_I...> )
569  {
570  if constexpr (!std::is_void_v<function_result_t<_Function>>)
571  return std::forward<_Function>(f)(std::get<_I>(std::forward<_Tuple>(t))...);
572  else
573  return std::forward<_Function>(f)(std::get<_I>(std::forward<_Tuple>(t))...), std::tuple<>{};
574  }
575  }
576 
577  // Convert tuple `t' of values into a list of arguments
578  // and invoke function `f' with those arguments.
579  template <class _Function, class _Tuple>
580  constexpr decltype(auto) apply(_Function&& f, _Tuple&& t)
581  {
582  return detail::apply_impl( std::forward<_Function>(f)
583  , std::forward<_Tuple>(t)
584  , std::make_index_sequence<std::tuple_size<std::decay_t<_Tuple>>::value>{} );
585  }
586 
587  // Convert tuple `t' of values into a list of arguments
588  // and invoke function `f' with those arguments.
589  template <class _Function, class _Tuple, typename... _Args>
590  constexpr decltype(auto) apply(_Function&& f, Result<_Args...>&& r, _Tuple&& t)
591  {
592  return detail::apply_impl( std::forward<_Function>(f)
593  , std::move(r)
594  , std::forward<_Tuple>(t)
595  , std::make_index_sequence<std::tuple_size<std::decay_t<_Tuple>>::value>{} );
596  }
597 
598  // Convert tuple `t' of values into a list of arguments
599  // and invoke function `f' with those arguments.
600  template <class _Function, class _Tuple>
601  constexpr decltype(auto) apply(_Function&& f, const Error* e, _Tuple&& t)
602  {
603  return detail::apply_impl( std::forward<_Function>(f)
604  , e
605  , std::forward<_Tuple>(t)
606  , std::make_index_sequence<std::tuple_size<std::decay_t<_Tuple>>::value>{} );
607  }
608 }
609 
610 #endif /* SDBUS_CXX_TYPETRAITS_H_ */
Definition: TypeTraits.h:82
Definition: TypeTraits.h:87
Definition: TypeTraits.h:76
Definition: TypeTraits.h:70
Definition: Types.h:53
Definition: Error.h:42
Definition: Types.h:152
Definition: TypeTraits.h:497
Definition: TypeTraits.h:391
Definition: Message.h:46
Definition: TypeTraits.h:365
Definition: Types.h:199
Definition: MethodResult.h:49
Definition: TypeTraits.h:73
Definition: TypeTraits.h:350
Definition: Types.h:173
Definition: TypeTraits.h:506
Definition: TypeTraits.h:79
Definition: TypeTraits.h:488
Definition: AdaptorInterfaces.h:36