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>;
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)>;
85 using Slot = std::unique_ptr<void, std::function<void(
void*)>>;
88 struct return_slot_t {
explicit return_slot_t() =
default; };
91 struct floating_slot_t {
explicit floating_slot_t() =
default; };
94 struct adopt_message_t {
explicit adopt_message_t() =
default; };
97 struct adopt_fd_t {
explicit adopt_fd_t() =
default; };
101 struct dont_run_event_loop_thread_t {
explicit dont_run_event_loop_thread_t() =
default; };
104 struct with_future_t {
explicit with_future_t() =
default; };
107 struct dont_expect_reply_t {
explicit dont_expect_reply_t() =
default; };
110 struct embed_variant_t {
explicit embed_variant_t() =
default; };
114 template <
class... _T>
constexpr bool always_false =
false;
117 template <
typename _T, std::
size_t _N1, std::
size_t _N2>
118 constexpr std::array<_T, _N1 + _N2> operator+(std::array<_T, _N1> lhs, std::array<_T, _N2> rhs);
121 template <
typename _T>
122 constexpr auto signature_of_v = signature_of<_T>::value;
124 template <
typename _T,
typename _Enable>
127 static constexpr bool is_valid =
false;
128 static constexpr bool is_trivial_dbus_type =
false;
130 static constexpr void* value = []
134 static_assert(always_false<_T>,
"Unsupported D-Bus type (specialize `signature_of` for your custom types)");
138 template <
typename _T>
142 template <
typename _T>
146 template <
typename _T>
150 template <
typename _T>
154 template <
typename _T>
161 static constexpr std::array<char, 0> value{};
162 static constexpr bool is_valid =
true;
163 static constexpr bool is_trivial_dbus_type =
false;
169 static constexpr std::array value{
'b'};
170 static constexpr bool is_valid =
true;
171 static constexpr bool is_trivial_dbus_type =
true;
177 static constexpr std::array value{
'y'};
178 static constexpr bool is_valid =
true;
179 static constexpr bool is_trivial_dbus_type =
true;
185 static constexpr std::array value{
'n'};
186 static constexpr bool is_valid =
true;
187 static constexpr bool is_trivial_dbus_type =
true;
193 static constexpr std::array value{
'q'};
194 static constexpr bool is_valid =
true;
195 static constexpr bool is_trivial_dbus_type =
true;
201 static constexpr std::array value{
'i'};
202 static constexpr bool is_valid =
true;
203 static constexpr bool is_trivial_dbus_type =
true;
209 static constexpr std::array value{
'u'};
210 static constexpr bool is_valid =
true;
211 static constexpr bool is_trivial_dbus_type =
true;
217 static constexpr std::array value{
'x'};
218 static constexpr bool is_valid =
true;
219 static constexpr bool is_trivial_dbus_type =
true;
225 static constexpr std::array value{
't'};
226 static constexpr bool is_valid =
true;
227 static constexpr bool is_trivial_dbus_type =
true;
233 static constexpr std::array value{
'd'};
234 static constexpr bool is_valid =
true;
235 static constexpr bool is_trivial_dbus_type =
true;
241 static constexpr std::array value{
's'};
242 static constexpr bool is_valid =
true;
243 static constexpr bool is_trivial_dbus_type =
false;
258 template <std::
size_t _N>
262 template <std::
size_t _N>
278 template <
typename... _ValueTypes>
281 static constexpr std::array contents = (signature_of_v<_ValueTypes> + ...);
282 static constexpr std::array value = std::array{
'('} + contents + std::array{
')'};
283 static constexpr char type_value{
'r'};
284 static constexpr bool is_valid =
true;
285 static constexpr bool is_trivial_dbus_type =
false;
291 static constexpr std::array value{
'v'};
292 static constexpr bool is_valid =
true;
293 static constexpr bool is_trivial_dbus_type =
false;
296 template <
typename... Elements>
303 static constexpr std::array value{
'o'};
304 static constexpr bool is_valid =
true;
305 static constexpr bool is_trivial_dbus_type =
false;
311 static constexpr std::array value{
'g'};
312 static constexpr bool is_valid =
true;
313 static constexpr bool is_trivial_dbus_type =
false;
319 static constexpr std::array value{
'h'};
320 static constexpr bool is_valid =
true;
321 static constexpr bool is_trivial_dbus_type =
false;
324 template <
typename _T1,
typename _T2>
327 static constexpr std::array value = std::array{
'{'} + signature_of_v<std::tuple<_T1, _T2>> + std::array{
'}'};
328 static constexpr char type_value{
'e'};
329 static constexpr bool is_valid =
true;
330 static constexpr bool is_trivial_dbus_type =
false;
333 template <
typename _Element,
typename _Allocator>
336 static constexpr std::array value = std::array{
'a'} + signature_of_v<_Element>;
337 static constexpr bool is_valid =
true;
338 static constexpr bool is_trivial_dbus_type =
false;
341 template <
typename _Element, std::
size_t _Size>
347 template <
typename _Element, std::
size_t _Extent>
353 template <
typename _Enum>
354 struct signature_of<_Enum, typename std::enable_if_t<std::is_enum_v<_Enum> && !std::is_const_v<_Enum> && !std::is_volatile_v<_Enum>>>
358 template <
typename _Key,
typename _Value,
typename _Compare,
typename _Allocator>
361 static constexpr std::array value = std::array{
'a'} + signature_of_v<DictEntry<_Key, _Value>>;
362 static constexpr bool is_valid =
true;
363 static constexpr bool is_trivial_dbus_type =
false;
366 template <
typename _Key,
typename _Value,
typename _Hash,
typename _KeyEqual,
typename _Allocator>
367 struct signature_of<std::unordered_map<_Key, _Value, _Hash, _KeyEqual, _Allocator>>
372 template <
typename... _Types>
375 static constexpr std::array value = (std::array<char, 0>{} + ... + signature_of_v<_Types>);
376 static constexpr bool is_valid =
false;
377 static constexpr bool is_trivial_dbus_type =
false;
381 template <
typename _T, std::
size_t _N>
382 constexpr auto as_null_terminated(std::array<_T, _N> arr)
384 return arr + std::array<_T, 1>{0};
389 template <
typename _Type>
393 template <
typename _Type>
397 template <
typename _Type>
401 template <
typename _ReturnType,
typename... _Args>
404 typedef _ReturnType result_type;
405 typedef std::tuple<_Args...> arguments_type;
406 typedef std::tuple<std::decay_t<_Args>...> decayed_arguments_type;
408 typedef _ReturnType function_type(_Args...);
410 static constexpr std::size_t arity =
sizeof...(_Args);
427 template <
size_t _Idx>
430 typedef std::tuple_element_t<_Idx, std::tuple<_Args...>> type;
433 template <
size_t _Idx>
434 using arg_t =
typename arg<_Idx>::type;
437 template <
typename _ReturnType,
typename... _Args>
440 static constexpr bool is_async =
false;
441 static constexpr bool has_error_param =
false;
444 template <
typename... _Args>
447 static constexpr bool has_error_param =
true;
450 template <
typename... _Args,
typename... _Results>
453 static constexpr bool is_async =
true;
454 using async_result_t =
Result<_Results...>;
457 template <
typename... _Args,
typename... _Results>
460 static constexpr bool is_async =
true;
461 using async_result_t =
Result<_Results...>;
464 template <
typename _ReturnType,
typename... _Args>
468 template <
typename _ClassType,
typename _ReturnType,
typename... _Args>
471 typedef _ClassType& owner_type;
474 template <
typename _ClassType,
typename _ReturnType,
typename... _Args>
477 typedef const _ClassType& owner_type;
480 template <
typename _ClassType,
typename _ReturnType,
typename... _Args>
483 typedef volatile _ClassType& owner_type;
486 template <
typename _ClassType,
typename _ReturnType,
typename... _Args>
489 typedef const volatile _ClassType& owner_type;
492 template <
typename FunctionType>
496 template <
class _Function>
499 template <
class _Function>
502 template <
typename _FunctionType>
505 template <
typename _FunctionType,
size_t _Idx>
508 template <
typename _FunctionType>
511 template <
typename _FunctionType>
514 template <
typename _Function>
520 template <
typename _Function>
521 using tuple_of_function_input_arg_types_t =
typename tuple_of_function_input_arg_types<_Function>::type;
523 template <
typename _Function>
529 template <
typename _Function>
530 using tuple_of_function_output_arg_types_t =
typename tuple_of_function_output_arg_types<_Function>::type;
532 template <
typename _Function>
535 static std::string value_as_string()
537 constexpr auto signature = as_null_terminated(signature_of_v<tuple_of_function_input_arg_types_t<_Function>>);
538 return signature.data();
542 template <
typename _Function>
543 inline auto signature_of_function_input_arguments_v = signature_of_function_input_arguments<_Function>::value_as_string();
545 template <
typename _Function>
548 static std::string value_as_string()
550 constexpr auto signature = as_null_terminated(signature_of_v<tuple_of_function_output_arg_types_t<_Function>>);
551 return signature.data();
555 template <
typename _Function>
556 inline auto signature_of_function_output_arguments_v = signature_of_function_output_arguments<_Function>::value_as_string();
561 typedef std::tuple<_Args...> type;
574 template <
typename... _Args>
575 using future_return_t =
typename future_return<_Args...>::type;
578 template <
typename,
typename>
579 constexpr bool is_one_of_variants_types =
false;
581 template <
typename... _VariantTypes,
typename _QueriedType>
582 constexpr bool is_one_of_variants_types<std::variant<_VariantTypes...>, _QueriedType>
583 = (std::is_same_v<_QueriedType, _VariantTypes> || ...);
587 template <
typename _Struct>
590 explicit as_dictionary(
const _Struct& s) : m_struct(s) {}
591 const _Struct& m_struct;
594 template <
typename _Type>
595 const _Type& as_dictionary_if_struct(
const _Type&
object)
604 template <
typename _Struct>
605 constexpr auto strict_dict_as_struct_deserialization_v =
true;
612 template <
typename _Struct>
613 constexpr auto nested_struct_as_dict_serialization_v =
false;
617 template <
class _Function,
class _Tuple,
typename... _Args, std::size_t... _I>
618 constexpr decltype(
auto) apply_impl( _Function&& f
619 , Result<_Args...>&& r
621 , std::index_sequence<_I...> )
623 return std::forward<_Function>(f)(std::move(r), std::get<_I>(std::forward<_Tuple>(t))...);
626 template <
class _Function,
class _Tuple, std::size_t... _I>
627 decltype(
auto) apply_impl( _Function&& f
628 , std::optional<Error> e
630 , std::index_sequence<_I...> )
632 return std::forward<_Function>(f)(std::move(e), std::get<_I>(std::forward<_Tuple>(t))...);
637 template <
class _Function,
class _Tuple, std::size_t... _I>
638 constexpr decltype(
auto) apply_impl( _Function&& f
640 , std::index_sequence<_I...> )
642 if constexpr (!std::is_void_v<function_result_t<_Function>>)
643 return std::forward<_Function>(f)(std::get<_I>(std::forward<_Tuple>(t))...);
645 return std::forward<_Function>(f)(std::get<_I>(std::forward<_Tuple>(t))...), std::tuple<>{};
651 template <
class _Function,
class _Tuple>
652 constexpr decltype(
auto) apply(_Function&& f, _Tuple&& t)
654 return detail::apply_impl( std::forward<_Function>(f)
655 , std::forward<_Tuple>(t)
656 , std::make_index_sequence<std::tuple_size<std::decay_t<_Tuple>>::value>{} );
661 template <
class _Function,
class _Tuple,
typename... _Args>
662 constexpr decltype(
auto) apply(_Function&& f,
Result<_Args...>&& r, _Tuple&& t)
664 return detail::apply_impl( std::forward<_Function>(f)
666 , std::forward<_Tuple>(t)
667 , std::make_index_sequence<std::tuple_size<std::decay_t<_Tuple>>::value>{} );
672 template <
class _Function,
class _Tuple>
673 decltype(
auto) apply(_Function&& f, std::optional<Error> e, _Tuple&& t)
675 return detail::apply_impl( std::forward<_Function>(f)
677 , std::forward<_Tuple>(t)
678 , std::make_index_sequence<std::tuple_size<std::decay_t<_Tuple>>::value>{} );
682 template <
typename _T, std::
size_t _N1, std::
size_t _N2>
683 constexpr std::array<_T, _N1 + _N2> operator+(std::array<_T, _N1> lhs, std::array<_T, _N2> rhs)
685 std::array<_T, _N1 + _N2> result{};
686 std::size_t index = 0;
688 for (
auto& el : lhs) {
689 result[index] = std::move(el);
692 for (
auto& el : rhs) {
693 result[index] = std::move(el);
std::pair< _T1, _T2 > DictEntry
Definition Types.h:402
Definition MethodResult.h:51
Definition TypeTraits.h:97
Definition TypeTraits.h:94
Definition TypeTraits.h:107
Definition TypeTraits.h:101
Definition TypeTraits.h:110
Definition TypeTraits.h:91
Definition TypeTraits.h:429
Definition TypeTraits.h:403
Definition TypeTraits.h:391
Definition TypeTraits.h:560
Definition TypeTraits.h:88
Definition TypeTraits.h:547
Definition TypeTraits.h:126
Definition TypeTraits.h:525
Definition TypeTraits.h:104