sdbus-c++ 1.1.0
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&>
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 {
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