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; };
113 struct with_awaitable_t {
explicit with_awaitable_t() =
default; };
117 template <
class... T>
constexpr bool always_false =
false;
120 template <
typename T, std::
size_t N1, std::
size_t N2>
121 constexpr std::array<T, N1 + N2> operator+(std::array<T, N1> lhs, std::array<T, N2> rhs);
124 template <
typename T>
125 constexpr auto signature_of_v = signature_of<T>::value;
127 template <
typename T,
typename Enable>
130 static constexpr bool is_valid =
false;
131 static constexpr bool is_trivial_dbus_type =
false;
133 static constexpr void* value = []
137 static_assert(always_false<T>,
"Unsupported D-Bus type (specialize `signature_of` for your custom types)");
141 template <
typename T>
145 template <
typename T>
149 template <
typename T>
153 template <
typename T>
157 template <
typename T>
164 static constexpr std::array<char, 0> value{};
165 static constexpr bool is_valid =
true;
166 static constexpr bool is_trivial_dbus_type =
false;
172 static constexpr std::array value{
'b'};
173 static constexpr bool is_valid =
true;
174 static constexpr bool is_trivial_dbus_type =
true;
180 static constexpr std::array value{
'y'};
181 static constexpr bool is_valid =
true;
182 static constexpr bool is_trivial_dbus_type =
true;
188 static constexpr std::array value{
'n'};
189 static constexpr bool is_valid =
true;
190 static constexpr bool is_trivial_dbus_type =
true;
196 static constexpr std::array value{
'q'};
197 static constexpr bool is_valid =
true;
198 static constexpr bool is_trivial_dbus_type =
true;
204 static constexpr std::array value{
'i'};
205 static constexpr bool is_valid =
true;
206 static constexpr bool is_trivial_dbus_type =
true;
212 static constexpr std::array value{
'u'};
213 static constexpr bool is_valid =
true;
214 static constexpr bool is_trivial_dbus_type =
true;
220 static constexpr std::array value{
'x'};
221 static constexpr bool is_valid =
true;
222 static constexpr bool is_trivial_dbus_type =
true;
228 static constexpr std::array value{
't'};
229 static constexpr bool is_valid =
true;
230 static constexpr bool is_trivial_dbus_type =
true;
236 static constexpr std::array value{
'd'};
237 static constexpr bool is_valid =
true;
238 static constexpr bool is_trivial_dbus_type =
true;
244 static constexpr std::array value{
's'};
245 static constexpr bool is_valid =
true;
246 static constexpr bool is_trivial_dbus_type =
false;
261 template <std::
size_t N>
265 template <std::
size_t N>
281 template <
typename... ValueTypes>
284 static constexpr std::array contents = (signature_of_v<ValueTypes> + ...);
285 static constexpr std::array value = std::array{
'('} + contents + std::array{
')'};
286 static constexpr char type_value{
'r'};
287 static constexpr bool is_valid =
true;
288 static constexpr bool is_trivial_dbus_type =
false;
294 static constexpr std::array value{
'v'};
295 static constexpr bool is_valid =
true;
296 static constexpr bool is_trivial_dbus_type =
false;
299 template <
typename... Elements>
306 static constexpr std::array value{
'o'};
307 static constexpr bool is_valid =
true;
308 static constexpr bool is_trivial_dbus_type =
false;
314 static constexpr std::array value{
'g'};
315 static constexpr bool is_valid =
true;
316 static constexpr bool is_trivial_dbus_type =
false;
322 static constexpr std::array value{
'h'};
323 static constexpr bool is_valid =
true;
324 static constexpr bool is_trivial_dbus_type =
false;
327 template <
typename T1,
typename T2>
330 static constexpr std::array value = std::array{
'{'} + signature_of_v<std::tuple<T1, T2>> + std::array{
'}'};
331 static constexpr char type_value{
'e'};
332 static constexpr bool is_valid =
true;
333 static constexpr bool is_trivial_dbus_type =
false;
336 template <
typename Element,
typename Allocator>
339 static constexpr std::array value = std::array{
'a'} + signature_of_v<Element>;
340 static constexpr bool is_valid =
true;
341 static constexpr bool is_trivial_dbus_type =
false;
344 template <
typename Element, std::
size_t Size>
350 template <
typename Element, std::
size_t Extent>
356 template <
typename Enum>
357 struct signature_of<Enum, std::enable_if_t<std::is_enum_v<Enum> && !std::is_const_v<Enum> && !std::is_volatile_v<Enum>>>
361 template <
typename Key,
typename Value,
typename Compare,
typename Allocator>
364 static constexpr std::array value = std::array{
'a'} + signature_of_v<DictEntry<Key, Value>>;
365 static constexpr bool is_valid =
true;
366 static constexpr bool is_trivial_dbus_type =
false;
369 template <
typename Key,
typename Value,
typename Hash,
typename KeyEqual,
typename Allocator>
370 struct signature_of<std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>>
375 template <
typename... Types>
378 static constexpr std::array value = (std::array<char, 0>{} + ... + signature_of_v<Types>);
379 static constexpr bool is_valid =
false;
380 static constexpr bool is_trivial_dbus_type =
false;
384 template <
typename T, std::
size_t N>
385 constexpr auto as_null_terminated(std::array<T, N> arr)
387 return arr + std::array<T, 1>{0};
392 template <
typename Type>
396 template <
typename Type>
400 template <
typename Type>
404 template <
typename ReturnType,
typename... Args>
407 using result_type = ReturnType;
408 using arguments_type = std::tuple<Args...>;
409 using decayed_arguments_type = std::tuple<std::decay_t<Args>...>;
411 using function_type = ReturnType (Args...);
413 static constexpr std::size_t arity =
sizeof...(Args);
430 template <
size_t Idx>
433 using type = std::tuple_element_t<Idx, std::tuple<Args...>>;
436 template <
size_t Idx>
437 using arg_t =
typename arg<Idx>::type;
440 template <
typename ReturnType,
typename... Args>
443 static constexpr bool is_async =
false;
444 static constexpr bool has_error_param =
false;
447 template <
typename... Args>
450 static constexpr bool has_error_param =
true;
453 template <
typename... Args>
456 static constexpr bool has_error_param =
true;
459 template <
typename... Args>
462 static constexpr bool has_error_param =
true;
465 template <
typename... Args,
typename... Results>
468 static constexpr bool is_async =
true;
469 using async_result_t =
Result<Results...>;
472 template <
typename... Args,
typename... Results>
475 static constexpr bool is_async =
true;
476 using async_result_t =
Result<Results...>;
479 template <
typename ReturnType,
typename... Args>
483 template <
typename ClassType,
typename ReturnType,
typename... Args>
486 using owner_type = ClassType &;
489 template <
typename ClassType,
typename ReturnType,
typename... Args>
492 using owner_type =
const ClassType &;
495 template <
typename ClassType,
typename ReturnType,
typename... Args>
498 using owner_type =
volatile ClassType &;
501 template <
typename ClassType,
typename ReturnType,
typename... Args>
504 using owner_type =
const volatile ClassType &;
507 template <
typename FunctionType>
511 template <
class Function>
514 template <
class Function>
517 template <
typename FunctionType>
520 template <
typename FunctionType,
size_t Idx>
523 template <
typename FunctionType>
526 template <
typename FunctionType>
529 template <
typename Function>
535 template <
typename Function>
536 using tuple_of_function_input_arg_types_t =
typename tuple_of_function_input_arg_types<Function>::type;
538 template <
typename Function>
544 template <
typename Function>
545 using tuple_of_function_output_arg_types_t =
typename tuple_of_function_output_arg_types<Function>::type;
547 template <
typename Function>
550 static std::string value_as_string()
552 constexpr auto signature = as_null_terminated(signature_of_v<tuple_of_function_input_arg_types_t<Function>>);
553 return signature.data();
557 template <
typename Function>
558 inline const auto signature_of_function_input_arguments_v = signature_of_function_input_arguments<Function>::value_as_string();
560 template <
typename Function>
563 static std::string value_as_string()
565 constexpr auto signature = as_null_terminated(signature_of_v<tuple_of_function_output_arg_types_t<Function>>);
566 return signature.data();
570 template <
typename Function>
571 inline const auto signature_of_function_output_arguments_v = signature_of_function_output_arguments<Function>::value_as_string();
576 using type = std::tuple<Args...>;
589 template <
typename... Args>
590 using future_return_t =
typename future_return<Args...>::type;
594 template <
typename... Args>
595 using awaitable_return_t =
typename future_return<Args...>::type;
598 template <
typename,
typename>
599 constexpr bool is_one_of_variants_types =
false;
601 template <
typename... VariantTypes,
typename QueriedType>
602 constexpr bool is_one_of_variants_types<std::variant<VariantTypes...>, QueriedType>
603 = (std::is_same_v<QueriedType, VariantTypes> || ...);
607 template <
typename Struct>
610 explicit as_dictionary(
const Struct& strct) : m_struct(strct) {}
614 template <
typename Type>
615 const Type& as_dictionary_if_struct(
const Type&
object)
624 template <
typename Struct>
625 constexpr auto strict_dict_as_struct_deserialization_v =
true;
632 template <
typename Struct>
633 constexpr auto nested_struct_as_dict_serialization_v =
false;
637 template <
class Function,
class Tuple,
typename... Args, std::size_t... I>
638 constexpr decltype(
auto) apply_impl( Function&& fun
639 , Result<Args...>&& res
641 , std::index_sequence<I...> )
643 return std::forward<Function>(fun)(std::move(res), std::get<I>(std::forward<Tuple>(tuple))...);
646 template <
class Function,
class Tuple, std::size_t... I>
647 decltype(
auto) apply_impl( Function&& fun
648 , std::optional<Error> err
650 , std::index_sequence<I...> )
652 return std::forward<Function>(fun)(std::move(err), std::get<I>(std::forward<Tuple>(tuple))...);
657 template <
class Function,
class Tuple, std::size_t... I>
658 constexpr decltype(
auto) apply_impl( Function&& fun
660 , std::index_sequence<I...> )
662 if constexpr (!std::is_void_v<function_result_t<Function>>)
663 return std::forward<Function>(fun)(std::get<I>(std::forward<Tuple>(tuple))...);
665 return std::forward<Function>(fun)(std::get<I>(std::forward<Tuple>(tuple))...), std::tuple<>{};
671 template <
class Function,
class Tuple>
672 constexpr decltype(
auto) apply(Function&& fun, Tuple&& tuple)
674 return detail::apply_impl( std::forward<Function>(fun)
675 , std::forward<Tuple>(tuple)
676 , std::make_index_sequence<std::tuple_size_v<std::decay_t<Tuple>>>{} );
681 template <
class Function,
class Tuple,
typename... Args>
682 constexpr decltype(
auto) apply(Function&& fun,
Result<Args...>&& res, Tuple&& tuple)
684 return detail::apply_impl( std::forward<Function>(fun)
686 , std::forward<Tuple>(tuple)
687 , std::make_index_sequence<std::tuple_size_v<std::decay_t<Tuple>>>{} );
692 template <
class Function,
class Tuple>
693 decltype(
auto) apply(Function&& fun, std::optional<Error> err, Tuple&& tuple)
695 return detail::apply_impl( std::forward<Function>(fun)
697 , std::forward<Tuple>(tuple)
698 , std::make_index_sequence<std::tuple_size_v<std::decay_t<Tuple>>>{} );
702 template <
typename T, std::
size_t N1, std::
size_t N2>
703 constexpr std::array<T, N1 + N2> operator+(std::array<T, N1> lhs, std::array<T, N2> rhs)
705 std::array<T, N1 + N2> result{};
707 std::move(lhs.begin(), lhs.end(), result.begin());
708 std::move(rhs.begin(), rhs.end(), result.begin() + N1);
std::pair< T1, T2 > DictEntry
Definition Types.h:415
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:432
Definition TypeTraits.h:406
Definition TypeTraits.h:394
Definition TypeTraits.h:575
Definition TypeTraits.h:88
Definition TypeTraits.h:562
Definition TypeTraits.h:129
Definition TypeTraits.h:540
Definition TypeTraits.h:113
Definition TypeTraits.h:104