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