27#ifndef SDBUS_CXX_TYPETRAITS_H_
28#define SDBUS_CXX_TYPETRAITS_H_
39# if __has_include(<span>)
47#include <unordered_map>
55 template <
typename... _ValueTypes>
class Struct;
59 template<
typename _T1,
typename _T2>
using DictEntry = std::pair<_T1, _T2>;
67 class PropertySetCall;
68 class PropertyGetReply;
69 template <
typename... _Results>
class Result;
71 template <
typename _T,
typename _Enable =
void>
struct signature_of;
77 using method_callback = std::function<void(MethodCall msg)>;
78 using async_reply_handler = std::function<void(MethodReply reply, std::optional<Error> error)>;
79 using signal_handler = std::function<void(Signal signal)>;
80 using message_handler = std::function<void(Message msg)>;
81 using property_set_callback = std::function<void(PropertySetCall msg)>;
82 using property_get_callback = std::function<void(PropertyGetReply& reply)>;
85 using Slot = std::unique_ptr<void, std::function<void(
void*)>>;
111 template <
class... _T>
constexpr bool always_false =
false;
114 template <
typename _T, std::
size_t _N1, std::
size_t _N2>
115 constexpr std::array<_T, _N1 + _N2> operator+(std::array<_T, _N1> lhs, std::array<_T, _N2> rhs);
118 template <
typename _T>
119 constexpr auto signature_of_v = signature_of<_T>::value;
121 template <
typename _T,
typename _Enable>
124 static constexpr bool is_valid =
false;
125 static constexpr bool is_trivial_dbus_type =
false;
127 static constexpr void* value = []
131 static_assert(always_false<_T>,
"Unsupported D-Bus type (specialize `signature_of` for your custom types)");
135 template <
typename _T>
139 template <
typename _T>
143 template <
typename _T>
147 template <
typename _T>
154 static constexpr std::array<char, 0> value{};
155 static constexpr bool is_valid =
true;
156 static constexpr bool is_trivial_dbus_type =
false;
162 static constexpr std::array value{
'b'};
163 static constexpr bool is_valid =
true;
164 static constexpr bool is_trivial_dbus_type =
true;
170 static constexpr std::array value{
'y'};
171 static constexpr bool is_valid =
true;
172 static constexpr bool is_trivial_dbus_type =
true;
178 static constexpr std::array value{
'n'};
179 static constexpr bool is_valid =
true;
180 static constexpr bool is_trivial_dbus_type =
true;
186 static constexpr std::array value{
'q'};
187 static constexpr bool is_valid =
true;
188 static constexpr bool is_trivial_dbus_type =
true;
194 static constexpr std::array value{
'i'};
195 static constexpr bool is_valid =
true;
196 static constexpr bool is_trivial_dbus_type =
true;
202 static constexpr std::array value{
'u'};
203 static constexpr bool is_valid =
true;
204 static constexpr bool is_trivial_dbus_type =
true;
210 static constexpr std::array value{
'x'};
211 static constexpr bool is_valid =
true;
212 static constexpr bool is_trivial_dbus_type =
true;
218 static constexpr std::array value{
't'};
219 static constexpr bool is_valid =
true;
220 static constexpr bool is_trivial_dbus_type =
true;
226 static constexpr std::array value{
'd'};
227 static constexpr bool is_valid =
true;
228 static constexpr bool is_trivial_dbus_type =
true;
234 static constexpr std::array value{
's'};
235 static constexpr bool is_valid =
true;
236 static constexpr bool is_trivial_dbus_type =
false;
251 template <std::
size_t _N>
255 template <std::
size_t _N>
271 template <
typename... _ValueTypes>
274 static constexpr std::array contents = (signature_of_v<_ValueTypes> + ...);
275 static constexpr std::array value = std::array{
'('} + contents + std::array{
')'};
276 static constexpr bool is_valid =
true;
277 static constexpr bool is_trivial_dbus_type =
false;
283 static constexpr std::array value{
'v'};
284 static constexpr bool is_valid =
true;
285 static constexpr bool is_trivial_dbus_type =
false;
288 template <
typename... Elements>
295 static constexpr std::array value{
'o'};
296 static constexpr bool is_valid =
true;
297 static constexpr bool is_trivial_dbus_type =
false;
303 static constexpr std::array value{
'g'};
304 static constexpr bool is_valid =
true;
305 static constexpr bool is_trivial_dbus_type =
false;
311 static constexpr std::array value{
'h'};
312 static constexpr bool is_valid =
true;
313 static constexpr bool is_trivial_dbus_type =
false;
316 template <
typename _T1,
typename _T2>
319 static constexpr std::array value = std::array{
'{'} + signature_of_v<std::tuple<_T1, _T2>> + std::array{
'}'};
320 static constexpr bool is_valid =
true;
321 static constexpr bool is_trivial_dbus_type =
false;
324 template <
typename _Element,
typename _Allocator>
327 static constexpr std::array value = std::array{
'a'} + signature_of_v<_Element>;
328 static constexpr bool is_valid =
true;
329 static constexpr bool is_trivial_dbus_type =
false;
332 template <
typename _Element, std::
size_t _Size>
338 template <
typename _Element, std::
size_t _Extent>
344 template <
typename _Enum>
345 struct signature_of<_Enum, typename std::enable_if_t<std::is_enum_v<_Enum> && !std::is_const_v<_Enum> && !std::is_volatile_v<_Enum>>>
349 template <
typename _Key,
typename _Value,
typename _Compare,
typename _Allocator>
352 static constexpr std::array contents = signature_of_v<std::tuple<_Key, _Value>>;
353 static constexpr std::array dict_entry = std::array{
'{'} + contents + std::array{
'}'};
354 static constexpr std::array value = std::array{
'a'} + dict_entry;
355 static constexpr bool is_valid =
true;
356 static constexpr bool is_trivial_dbus_type =
false;
359 template <
typename _Key,
typename _Value,
typename _Hash,
typename _KeyEqual,
typename _Allocator>
360 struct signature_of<std::unordered_map<_Key, _Value, _Hash, _KeyEqual, _Allocator>>
365 template <
typename... _Types>
368 static constexpr std::array value = (std::array<char, 0>{} + ... + signature_of_v<_Types>);
369 static constexpr bool is_valid =
false;
370 static constexpr bool is_trivial_dbus_type =
false;
374 template <
typename _T, std::
size_t _N>
375 constexpr auto as_null_terminated(std::array<_T, _N> arr)
377 return arr + std::array<_T, 1>{0};
382 template <
typename _Type>
386 template <
typename _Type>
390 template <
typename _Type>
394 template <
typename _ReturnType,
typename... _Args>
397 typedef _ReturnType result_type;
398 typedef std::tuple<_Args...> arguments_type;
399 typedef std::tuple<std::decay_t<_Args>...> decayed_arguments_type;
401 typedef _ReturnType function_type(_Args...);
403 static constexpr std::size_t arity =
sizeof...(_Args);
420 template <
size_t _Idx>
423 typedef std::tuple_element_t<_Idx, std::tuple<_Args...>> type;
426 template <
size_t _Idx>
427 using arg_t =
typename arg<_Idx>::type;
430 template <
typename _ReturnType,
typename... _Args>
433 static constexpr bool is_async =
false;
434 static constexpr bool has_error_param =
false;
437 template <
typename... _Args>
440 static constexpr bool has_error_param =
true;
443 template <
typename... _Args,
typename... _Results>
446 static constexpr bool is_async =
true;
450 template <
typename... _Args,
typename... _Results>
453 static constexpr bool is_async =
true;
457 template <
typename _ReturnType,
typename... _Args>
461 template <
typename _ClassType,
typename _ReturnType,
typename... _Args>
464 typedef _ClassType& owner_type;
467 template <
typename _ClassType,
typename _ReturnType,
typename... _Args>
470 typedef const _ClassType& owner_type;
473 template <
typename _ClassType,
typename _ReturnType,
typename... _Args>
476 typedef volatile _ClassType& owner_type;
479 template <
typename _ClassType,
typename _ReturnType,
typename... _Args>
482 typedef const volatile _ClassType& owner_type;
485 template <
typename FunctionType>
489 template <
class _Function>
492 template <
class _Function>
495 template <
typename _FunctionType>
498 template <
typename _FunctionType,
size_t _Idx>
501 template <
typename _FunctionType>
504 template <
typename _FunctionType>
507 template <
typename _Function>
513 template <
typename _Function>
514 using tuple_of_function_input_arg_types_t =
typename tuple_of_function_input_arg_types<_Function>::type;
516 template <
typename _Function>
522 template <
typename _Function>
523 using tuple_of_function_output_arg_types_t =
typename tuple_of_function_output_arg_types<_Function>::type;
525 template <
typename _Function>
528 static std::string value_as_string()
530 constexpr auto signature = as_null_terminated(signature_of_v<tuple_of_function_input_arg_types_t<_Function>>);
531 return signature.data();
535 template <
typename _Function>
538 template <
typename _Function>
541 static std::string value_as_string()
543 constexpr auto signature = as_null_terminated(signature_of_v<tuple_of_function_output_arg_types_t<_Function>>);
544 return signature.data();
548 template <
typename _Function>
554 typedef std::tuple<_Args...> type;
567 template <
typename... _Args>
568 using future_return_t =
typename future_return<_Args...>::type;
571 template <
typename,
typename>
572 constexpr bool is_one_of_variants_types =
false;
574 template <
typename... _VariantTypes,
typename _QueriedType>
575 constexpr bool is_one_of_variants_types<std::variant<_VariantTypes...>, _QueriedType>
576 = (std::is_same_v<_QueriedType, _VariantTypes> || ...);
580 template <
class _Function,
class _Tuple,
typename... _Args, std::size_t... _I>
581 constexpr decltype(
auto) apply_impl( _Function&& f
584 , std::index_sequence<_I...> )
586 return std::forward<_Function>(f)(std::move(r), std::get<_I>(std::forward<_Tuple>(t))...);
589 template <
class _Function,
class _Tuple, std::size_t... _I>
590 decltype(
auto) apply_impl( _Function&& f
591 , std::optional<Error> e
593 , std::index_sequence<_I...> )
595 return std::forward<_Function>(f)(std::move(e), std::get<_I>(std::forward<_Tuple>(t))...);
600 template <
class _Function,
class _Tuple, std::size_t... _I>
601 constexpr decltype(
auto) apply_impl( _Function&& f
603 , std::index_sequence<_I...> )
605 if constexpr (!std::is_void_v<function_result_t<_Function>>)
606 return std::forward<_Function>(f)(std::get<_I>(std::forward<_Tuple>(t))...);
608 return std::forward<_Function>(f)(std::get<_I>(std::forward<_Tuple>(t))...), std::tuple<>{};
614 template <
class _Function,
class _Tuple>
615 constexpr decltype(
auto) apply(_Function&& f, _Tuple&& t)
617 return detail::apply_impl( std::forward<_Function>(f)
618 , std::forward<_Tuple>(t)
619 , std::make_index_sequence<std::tuple_size<std::decay_t<_Tuple>>::value>{} );
624 template <
class _Function,
class _Tuple,
typename... _Args>
625 constexpr decltype(
auto) apply(_Function&& f, Result<_Args...>&& r, _Tuple&& t)
627 return detail::apply_impl( std::forward<_Function>(f)
629 , std::forward<_Tuple>(t)
630 , std::make_index_sequence<std::tuple_size<std::decay_t<_Tuple>>::value>{} );
635 template <
class _Function,
class _Tuple>
636 decltype(
auto) apply(_Function&& f, std::optional<Error> e, _Tuple&& t)
638 return detail::apply_impl( std::forward<_Function>(f)
640 , std::forward<_Tuple>(t)
641 , std::make_index_sequence<std::tuple_size<std::decay_t<_Tuple>>::value>{} );
645 template <
typename _T, std::
size_t _N1, std::
size_t _N2>
646 constexpr std::array<_T, _N1 + _N2> operator+(std::array<_T, _N1> lhs, std::array<_T, _N2> rhs)
648 std::array<_T, _N1 + _N2> result{};
649 std::size_t index = 0;
651 for (
auto& el : lhs) {
652 result[index] = std::move(el);
655 for (
auto& el : rhs) {
656 result[index] = std::move(el);
std::pair< _T1, _T2 > DictEntry
Definition Types.h:384
Definition MethodResult.h:51
Definition TypeTraits.h:97
Definition TypeTraits.h:94
Definition TypeTraits.h:107
Definition TypeTraits.h:101
Definition TypeTraits.h:91
Definition TypeTraits.h:422
Definition TypeTraits.h:396
Definition TypeTraits.h:384
Definition TypeTraits.h:553
Definition TypeTraits.h:88
Definition TypeTraits.h:540
Definition TypeTraits.h:123
Definition TypeTraits.h:518
Definition TypeTraits.h:104