Skip to content

Commit 4c0b9d4

Browse files
authored
Merge pull request #664 from OpenVicProject/add/game-action-arg-direct-construction
Add direct construction of game action arguments
2 parents b0d2f42 + dfceef5 commit 4c0b9d4

File tree

1 file changed

+35
-4
lines changed

1 file changed

+35
-4
lines changed

src/openvic-simulation/misc/GameAction.hpp

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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

86117
FOR_EACH_GAME_ACTION(USING_ARG_TYPE)

0 commit comments

Comments
 (0)