sdbus-c++  1.1.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 <tuple>
37 
38 // Forward declarations
39 namespace sdbus {
40  class Variant;
41  template <typename... _ValueTypes> class Struct;
42  class ObjectPath;
43  class Signature;
44  class 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  static constexpr bool has_error_param = false;
382  };
383 
384  template <typename... _Args>
385  struct function_traits<void(const Error*, _Args...)>
386  : public function_traits_base<void, _Args...>
387  {
388  static constexpr bool has_error_param = true;
389  };
390 
391  template <typename... _Args, typename... _Results>
392  struct function_traits<void(Result<_Results...>, _Args...)>
393  : public function_traits_base<std::tuple<_Results...>, _Args...>
394  {
395  static constexpr bool is_async = true;
396  using async_result_t = Result<_Results...>;
397  };
398 
399  template <typename... _Args, typename... _Results>
400  struct function_traits<void(Result<_Results...>&&, _Args...)>
401  : public function_traits_base<std::tuple<_Results...>, _Args...>
402  {
403  static constexpr bool is_async = true;
404  using async_result_t = Result<_Results...>;
405  };
406 
407  template <typename _ReturnType, typename... _Args>
408  struct function_traits<_ReturnType(*)(_Args...)>
409  : public function_traits<_ReturnType(_Args...)>
410  {};
411 
412  template <typename _ClassType, typename _ReturnType, typename... _Args>
413  struct function_traits<_ReturnType(_ClassType::*)(_Args...)>
414  : public function_traits<_ReturnType(_Args...)>
415  {
416  typedef _ClassType& owner_type;
417  };
418 
419  template <typename _ClassType, typename _ReturnType, typename... _Args>
420  struct function_traits<_ReturnType(_ClassType::*)(_Args...) const>
421  : public function_traits<_ReturnType(_Args...)>
422  {
423  typedef const _ClassType& owner_type;
424  };
425 
426  template <typename _ClassType, typename _ReturnType, typename... _Args>
427  struct function_traits<_ReturnType(_ClassType::*)(_Args...) volatile>
428  : public function_traits<_ReturnType(_Args...)>
429  {
430  typedef volatile _ClassType& owner_type;
431  };
432 
433  template <typename _ClassType, typename _ReturnType, typename... _Args>
434  struct function_traits<_ReturnType(_ClassType::*)(_Args...) const volatile>
435  : public function_traits<_ReturnType(_Args...)>
436  {
437  typedef const volatile _ClassType& owner_type;
438  };
439 
440  template <typename FunctionType>
441  struct function_traits<std::function<FunctionType>>
442  : public function_traits<FunctionType>
443  {};
444 
445  template <class _Function>
446  constexpr auto is_async_method_v = function_traits<_Function>::is_async;
447 
448  template <class _Function>
449  constexpr auto has_error_param_v = function_traits<_Function>::has_error_param;
450 
451  template <typename _FunctionType>
452  using function_arguments_t = typename function_traits<_FunctionType>::arguments_type;
453 
454  template <typename _FunctionType, size_t _Idx>
455  using function_argument_t = typename function_traits<_FunctionType>::template arg_t<_Idx>;
456 
457  template <typename _FunctionType>
458  constexpr auto function_argument_count_v = function_traits<_FunctionType>::arity;
459 
460  template <typename _FunctionType>
461  using function_result_t = typename function_traits<_FunctionType>::result_type;
462 
463  template <typename _Function>
465  {
467  };
468 
469  template <typename _Function>
470  using tuple_of_function_input_arg_types_t = typename tuple_of_function_input_arg_types<_Function>::type;
471 
472  template <typename _Function>
474  {
475  typedef typename function_traits<_Function>::result_type type;
476  };
477 
478  template <typename _Function>
479  using tuple_of_function_output_arg_types_t = typename tuple_of_function_output_arg_types<_Function>::type;
480 
481  template <typename _Type>
483  {
484  static const std::string str()
485  {
486  return signature_of<std::decay_t<_Type>>::str();
487  }
488  };
489 
490  template <typename... _Types>
491  struct aggregate_signature<std::tuple<_Types...>>
492  {
493  static const std::string str()
494  {
495  std::string signature;
496  (void)(signature += ... += signature_of<std::decay_t<_Types>>::str());
497  return signature;
498  }
499  };
500 
501  template <typename _Function>
503  {
504  static const std::string str()
505  {
507  }
508  };
509 
510  template <typename _Function>
512  {
513  static const std::string str()
514  {
516  }
517  };
518 
519  namespace detail
520  {
521  template <class _Function, class _Tuple, typename... _Args, std::size_t... _I>
522  constexpr decltype(auto) apply_impl( _Function&& f
523  , Result<_Args...>&& r
524  , _Tuple&& t
525  , std::index_sequence<_I...> )
526  {
527  return std::forward<_Function>(f)(std::move(r), std::get<_I>(std::forward<_Tuple>(t))...);
528  }
529 
530  template <class _Function, class _Tuple, std::size_t... _I>
531  constexpr decltype(auto) apply_impl( _Function&& f
532  , const Error* e
533  , _Tuple&& t
534  , std::index_sequence<_I...> )
535  {
536  return std::forward<_Function>(f)(e, std::get<_I>(std::forward<_Tuple>(t))...);
537  }
538 
539  // For non-void returning functions, apply_impl simply returns function return value (a tuple of values).
540  // For void-returning functions, apply_impl returns an empty tuple.
541  template <class _Function, class _Tuple, std::size_t... _I>
542  constexpr decltype(auto) apply_impl( _Function&& f
543  , _Tuple&& t
544  , std::index_sequence<_I...> )
545  {
546  if constexpr (!std::is_void_v<function_result_t<_Function>>)
547  return std::forward<_Function>(f)(std::get<_I>(std::forward<_Tuple>(t))...);
548  else
549  return std::forward<_Function>(f)(std::get<_I>(std::forward<_Tuple>(t))...), std::tuple<>{};
550  }
551  }
552 
553  // Convert tuple `t' of values into a list of arguments
554  // and invoke function `f' with those arguments.
555  template <class _Function, class _Tuple>
556  constexpr decltype(auto) apply(_Function&& f, _Tuple&& t)
557  {
558  return detail::apply_impl( std::forward<_Function>(f)
559  , std::forward<_Tuple>(t)
560  , std::make_index_sequence<std::tuple_size<std::decay_t<_Tuple>>::value>{} );
561  }
562 
563  // Convert tuple `t' of values into a list of arguments
564  // and invoke function `f' with those arguments.
565  template <class _Function, class _Tuple, typename... _Args>
566  constexpr decltype(auto) apply(_Function&& f, Result<_Args...>&& r, _Tuple&& t)
567  {
568  return detail::apply_impl( std::forward<_Function>(f)
569  , std::move(r)
570  , std::forward<_Tuple>(t)
571  , std::make_index_sequence<std::tuple_size<std::decay_t<_Tuple>>::value>{} );
572  }
573 
574  // Convert tuple `t' of values into a list of arguments
575  // and invoke function `f' with those arguments.
576  template <class _Function, class _Tuple>
577  constexpr decltype(auto) apply(_Function&& f, const Error* e, _Tuple&& t)
578  {
579  return detail::apply_impl( std::forward<_Function>(f)
580  , e
581  , std::forward<_Tuple>(t)
582  , std::make_index_sequence<std::tuple_size<std::decay_t<_Tuple>>::value>{} );
583  }
584 }
585 
586 #endif /* SDBUS_CXX_TYPETRAITS_H_ */
Definition: Error.h:44
Definition: Types.h:153
Definition: MethodResult.h:50
Definition: Types.h:172
Definition: Types.h:111
Definition: Types.h:199
Definition: Types.h:54
Definition: TypeTraits.h:483
Definition: TypeTraits.h:368
Definition: TypeTraits.h:342
Definition: TypeTraits.h:328
Definition: TypeTraits.h:64
Definition: TypeTraits.h:465
Definition: TypeTraits.h:474