diff --git a/common/arch/sdl/joy.cpp b/common/arch/sdl/joy.cpp index 2db27a793..98888345b 100644 --- a/common/arch/sdl/joy.cpp +++ b/common/arch/sdl/joy.cpp @@ -23,6 +23,7 @@ #include "compiler-range_for.h" #if MAX_JOYSTICKS +#include "compiler-integer_sequence.h" #include "compiler-type_traits.h" namespace { @@ -56,6 +57,50 @@ public: } }; +#ifndef DXX_USE_SIZE_SORTED_TUPLE +#define DXX_USE_SIZE_SORTED_TUPLE (__cplusplus > 201103L) +#endif + +#if DXX_USE_SIZE_SORTED_TUPLE +template +auto d_split_tuple(T &&t, index_sequence, index_sequence) -> + std::pair< + std::tuple::type...>, + std::tuple::type...> + >; + +template +class d_size_sorted; + +/* Given an input tuple T, define a public member `type` with the same + * members as T, but sorted such that sizeof(Ti) <= sizeof(Tj) for all i + * <= j. + */ +template +class d_size_sorted> +{ + using split_tuple = decltype(d_split_tuple( + std::declval>(), + make_tree_index_sequence(), + make_tree_index_sequence<(1 + sizeof...(Ts)) / 2>() + )); + using first_type = typename split_tuple::first_type; + using second_type = typename split_tuple::second_type; +public: + using type = typename tt::conditional<(sizeof(first_type) < sizeof(second_type)), + decltype(std::tuple_cat(std::declval(), std::declval())), + decltype(std::tuple_cat(std::declval(), std::declval())) + >::type; +}; + +template +class d_size_sorted> +{ +public: + using type = std::tuple; +}; +#endif + template class ignore_empty {}; @@ -74,6 +119,17 @@ class d_physical_joystick VERB(axis_map) \ VERB(axis_value) \ +#if DXX_USE_SIZE_SORTED_TUPLE + template + using tuple_type = typename d_size_sorted>::type; +#define define_getter(N) \ + auto N() -> decltype(std::get(t)) \ + { \ + return std::get(t); \ + } +#else + template + using tuple_type = std::tuple; enum { #define define_enum(V) tuple_item_##V, @@ -85,13 +141,14 @@ class d_physical_joystick { \ return std::get(t); \ } +#endif using tuple_member_type_handle = std::unique_ptr; //Note: Descent expects hats to be buttons, so these are indices into Joystick.buttons struct tuple_member_type_hat_map : array {}; struct tuple_member_type_button_map : array {}; struct tuple_member_type_axis_map : array {}; struct tuple_member_type_axis_value : array {}; - std::tuple< + tuple_type< tuple_member_type_handle, maybe_empty_array, maybe_empty_array,