@@ -18,16 +18,40 @@ namespace detail {
1818 template <typename ...Args>
1919 struct reduce_tuple {
2020 using type = std::tuple<Args...>;
21+ static constexpr std::integral_constant<std::size_t , sizeof ...(Args)> size {};
22+
23+ template <typename ... Args2>
24+ static constexpr type construct (Args2&&... args)
25+ requires requires { std::make_tuple (std::forward<Args2>(args)...); }
26+ {
27+ return std::make_tuple (std::forward<Args2>(args)...);
28+ }
2129 };
2230
2331 template <typename T1, typename T2>
2432 struct reduce_tuple <T1, T2> {
2533 using type = std::pair<T1, T2>;
34+ static constexpr std::integral_constant<std::size_t , 2 > size {};
35+
36+ template <typename InT1, typename InT2>
37+ static constexpr type construct (InT1&& t1, InT2&& t2)
38+ requires requires { std::make_pair (std::forward<InT1>(t1), std::forward<InT2>(t2)); }
39+ {
40+ return std::make_pair (std::forward<InT1>(t1), std::forward<InT2>(t2));
41+ }
2642 };
2743
2844 template <typename T>
2945 struct reduce_tuple <T> {
3046 using type = T;
47+ static constexpr std::integral_constant<std::size_t , 1 > size {};
48+
49+ template <typename InT>
50+ static constexpr type construct (InT&& t)
51+ requires requires { std::forward<InT>(t); }
52+ {
53+ return std::forward<InT>(t);
54+ }
3155 };
3256
3357 struct ts_op_structured_binding_passthrough {};
@@ -76,11 +100,18 @@ struct none_argument_t : type_safe::strong_typedef<none_argument_t, std::monosta
76100 : strong_typedef(static_cast <std::monostate&&>(value)) {}
77101};
78102#define USING_ARG_TYPE (name, ...) \
79- struct ARG_TYPE (name) : type_safe::strong_typedef<ARG_TYPE(name), detail::reduce_tuple<__VA_ARGS__>::type>, detail::ts_op_structured_binding_passthrough { \
103+ struct ARG_TYPE (name) \
104+ : type_safe::strong_typedef<ARG_TYPE(name), detail::reduce_tuple<__VA_ARGS__>::type>, \
105+ detail::ts_op_structured_binding_passthrough { \
80106 using strong_typedef::strong_typedef; \
81- constexpr ARG_TYPE (name)(detail::reduce_tuple<__VA_ARGS__>::type const & value) : strong_typedef (value) {} \
82- constexpr ARG_TYPE (name)(detail::reduce_tuple<__VA_ARGS__>::type && value) \
83- : strong_typedef (static_cast <detail::reduce_tuple<__VA_ARGS__>::type&&>(value)) {} \
107+ using reduce_helper_t = detail::reduce_tuple<__VA_ARGS__>; \
108+ using underlying_type = reduce_helper_t ::type; \
109+ \
110+ constexpr ARG_TYPE (name)(underlying_type const & value) : strong_typedef (value) {} \
111+ constexpr ARG_TYPE (name)(underlying_type && value) : strong_typedef (static_cast <underlying_type&&>(value)) {} \
112+ template <typename Arg1, typename ... Args> \
113+ constexpr ARG_TYPE (name)(Arg1 && arg1, Args&&... args) \
114+ : strong_typedef (reduce_helper_t::construct (std::forward<Arg1>(arg1), std::forward<Args>(args)...)) {} \
84115};
85116
86117FOR_EACH_GAME_ACTION (USING_ARG_TYPE)
0 commit comments