sdbus-c++ 0.8.3
High-level C++ D-Bus library based on systemd D-Bus implementation
Loading...
Searching...
No Matches
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
39namespace 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
54namespace 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>
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>
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>
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 {
501 return aggregate_signature<tuple_of_function_input_arg_types_t<_Function>>::str();
502 }
503 };
504
505 template <typename _Function>
507 {
508 static const std::string str()
509 {
510 return aggregate_signature<tuple_of_function_output_arg_types_t<_Function>>::str();
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_ */
Definition Error.h:44
Definition Types.h:153
Definition MethodResult.h:50
Definition Types.h:171
Definition Types.h:111
Definition Types.h:197
Definition Types.h:54
Definition TypeTraits.h:478
Definition TypeTraits.h:368
Definition TypeTraits.h:342
Definition TypeTraits.h:328
Definition TypeTraits.h:64
Definition TypeTraits.h:460