7 #include "arg_router/parsing/parse_target.hpp"
8 #include "arg_router/parsing/parsing.hpp"
9 #include "arg_router/policy/policy.hpp"
10 #include "arg_router/traits.hpp"
11 #include "arg_router/utility/compile_time_optional.hpp"
12 #include "arg_router/utility/tree_recursor.hpp"
22 template <
typename... DependsPolicies>
33 constexpr
explicit dependent_t([[maybe_unused]]
const DependsPolicies&... policies) noexcept {}
47 template <
typename ProcessedTarget,
typename... Parents>
52 [[maybe_unused]]
const Parents&... parents)
const
55 using mode_type =
typename nearest_mode<Parents...>::type;
56 static_assert(!std::is_void_v<mode_type>,
"Cannot find parent mode");
57 static_assert(!processed_target.
empty,
"processed_target cannot be empty");
60 using node_targets =
typename depends_targets<depends_policies_type, mode_type>::type;
61 static_assert(cyclic_dependency_checker<node_targets, mode_type>::value,
62 "Cyclic dependency detected");
65 utility::tuple_type_iterator<node_targets>([&](
auto i) {
66 using node_target = std::tuple_element_t<i, node_targets>;
75 const auto target_index = utility::type_hash<node_target>();
76 if (processed_target->node_type() == target_index) {
80 for (
const auto& sub_target : processed_target->sub_targets()) {
81 if (sub_target.node_type() == target_index) {
87 parsing::node_token_type<node_target>()};
95 struct policy_checker {
96 constexpr
static auto value =
97 traits::has_long_name_method_v<T> || traits::has_short_name_method_v<T>;
100 static_assert((
sizeof...(DependsPolicies) > 0),
"At least one name needed for dependent");
101 static_assert(policy::is_all_policies_v<depends_policies_type>,
102 "All parameters must be policies");
103 static_assert(boost::mp11::mp_all_of<depends_policies_type, policy_checker>::value,
104 "All parameters must provide a long and/or short form name");
108 template <
typename... Parents>
114 template <
typename DependsPoliciesTuple,
typename ModeType>
115 struct depends_targets {
116 template <
typename Current,
typename... Parents>
121 using type = boost::mp11::mp_eval_if_c<
122 !(boost::mp11::mp_contains<DependsPoliciesTuple, Current>::value &&
123 (
sizeof...(Parents) > 0)),
126 std::tuple<Parents...>,
131 boost::mp11::mp_remove_if<utility::tree_type_recursor_collector_t<visitor, ModeType>,
134 static_assert(std::tuple_size_v<type> == std::tuple_size_v<DependsPoliciesTuple>,
135 "Number of found modes must match depends policy count");
136 static_assert(std::tuple_size_v<boost::mp11::mp_unique<type>> == std::tuple_size_v<type>,
137 "Node dependency list must be unique, do you have short and long "
138 "names from the same node?");
141 template <
typename DependsNodesTuple,
typename ModeType>
142 struct cyclic_dependency_checker {
145 template <std::
size_t I,
typename Nodes>
146 [[nodiscard]] constexpr
static bool check() noexcept
148 if constexpr (I >= std::tuple_size_v<Nodes>) {
151 using depends_type = std::tuple_element_t<I, Nodes>;
154 typename depends_type::policies_type>) {
155 if constexpr (boost::mp11::mp_contains<
typename depends_type::policies_type,
160 typename depends_targets<
typename depends_type::depends_policies_type,
163 return check<I + 1, boost::mp11::mp_append<Nodes, targets>>();
167 return check<I + 1, Nodes>();
171 constexpr
static bool value = check<0, DependsNodesTuple>();
182 template <
typename... DependsPolicies>
183 [[nodiscard]] constexpr
auto dependent(DependsPolicies... policies) noexcept
188 template <
typename... DependsPolicies>
189 struct is_policy<dependent_t<DependsPolicies...>> : std::true_type {
constexpr dependent_t([[maybe_unused]] const DependsPolicies &... policies) noexcept
std::tuple< std::decay_t< DependsPolicies >... > depends_policies_type
parsing::pre_parse_result pre_parse_phase([[maybe_unused]] parsing::dynamic_token_adapter &tokens, utility::compile_time_optional< ProcessedTarget > processed_target, [[maybe_unused]] parsing::parse_target &target, [[maybe_unused]] const Parents &... parents) const
constexpr static bool empty
constexpr auto has_specialisation_v
constexpr auto dependent(DependsPolicies... policies) noexcept
std::integral_constant< decltype(Value), Value > integral_constant
@ dependent_argument_missing