7 #include "arg_router/exception.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"
26 template <
typename MinType,
typename MaxType>
29 static_assert(traits::has_value_type_v<MinType> && traits::has_value_type_v<MaxType>,
30 "MinType and MaxType must have a value_type");
31 static_assert(std::is_convertible_v<typename MinType::value_type, std::size_t> &&
32 std::is_convertible_v<typename MaxType::value_type, std::size_t>,
33 "MinType and MaxType must have a value_type that is implicitly "
34 "convertible to std::size_t");
35 static_assert(std::is_integral_v<typename MinType::value_type> &&
36 std::is_integral_v<typename MaxType::value_type>,
37 "MinType and MaxType value_types must be integrals");
38 static_assert((MinType::value >= 0) && (MaxType::value >= 0),
39 "MinType and MaxType must have a value that is a positive number");
40 static_assert(MinType::value <= MaxType::value,
41 "MinType must be less than or equal to MaxType");
45 constexpr
static auto priority = std::size_t{750};
48 [[nodiscard]] constexpr
static std::size_t
minimum_count() noexcept {
return MinType::value; }
51 [[nodiscard]] constexpr
static std::size_t
maximum_count() noexcept {
return MaxType::value; }
71 template <
typename ProcessedTarget,
typename... Parents>
76 [[maybe_unused]]
const Parents&... parents)
const
78 static_assert((
sizeof...(Parents) >= 1),
"At least one parent needed for min_max_count_t");
80 using owner_type = boost::mp11::mp_first<std::tuple<Parents...>>;
84 constexpr
auto named_offset = owner_type::is_named ? 1u : 0u;
85 constexpr
auto mn_count =
minimum_count() == std::numeric_limits<std::size_t>::max() ?
88 constexpr
auto mx_count =
maximum_count() == std::numeric_limits<std::size_t>::max() ?
92 auto num_tokens = tokens.
size();
93 if constexpr (traits::has_token_end_marker_method_v<owner_type>) {
100 if (num_tokens > mx_count) {
102 parsing::node_token_type<owner_type>()};
107 if (num_tokens < mn_count) {
109 parsing::node_token_type<owner_type>()};
113 tokens.
transfer(tokens.
begin() + std::min(mx_count - 1, num_tokens - 1));
124 template <std::
size_t MinValue, std::
size_t MaxValue>
132 template <std::
size_t Value>
141 template <std::
size_t Value>
149 template <std::
size_t Value>
153 template <
typename MinType,
typename MaxType>
154 struct is_policy<min_max_count_t<MinType, MaxType>> : std::true_type {
192 template <std::size_t MinCount,
typename... Policies>
195 template <
typename Policy>
196 struct has_min_max_t {
197 constexpr
static bool value = traits::has_minimum_count_method_v<Policy> &&
198 traits::has_maximum_count_method_v<Policy>;
201 using policies_tuple = std::tuple<std::decay_t<Policies>...>;
211 boost::mp11::mp_find_if<policies_tuple, has_min_max_t>::value !=
212 std::tuple_size_v<policies_tuple>;
217 using type = std::conditional_t<
219 boost::mp11::mp_rename<policies_tuple, tree_node>,
220 boost::mp11::mp_rename<boost::mp11::mp_push_front<policies_tuple, range_policy_type>,
std::conditional_t< has_min_max, boost::mp11::mp_rename< policies_tuple, tree_node >, boost::mp11::mp_rename< boost::mp11::mp_push_front< policies_tuple, range_policy_type >, tree_node > > type
constexpr static auto has_min_max
void transfer(iterator it)
vector< value_type > & processed()
parsing::pre_parse_result pre_parse_phase(parsing::dynamic_token_adapter &tokens, [[maybe_unused]] utility::compile_time_optional< ProcessedTarget > processed_target, [[maybe_unused]] parsing::parse_target &target, [[maybe_unused]] const Parents &... parents) const
constexpr static std::size_t maximum_count() noexcept
constexpr static std::size_t minimum_count() noexcept
constexpr static auto priority
constexpr auto min_max_count
constexpr auto fixed_count
std::integral_constant< decltype(Value), Value > integral_constant
@ minimum_count_not_reached
Minimum number of value tokens for node not reached.
@ maximum_count_exceeded
Maximum number of value tokens exceeded.