arg_router  1.4.0
C++ command line argument parsing and routing
flag.hpp
1 // Copyright (C) 2022-2023 by Camden Mannett.
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE or copy at https://www.boost.org/LICENSE_1_0.txt)
4 
5 #pragma once
6 
7 #include "arg_router/policy/default_value.hpp"
8 #include "arg_router/policy/description.hpp"
9 #include "arg_router/policy/long_name.hpp"
10 #include "arg_router/policy/min_max_count.hpp"
11 #include "arg_router/policy/short_form_expander.hpp"
12 #include "arg_router/policy/short_name.hpp"
13 #include "arg_router/tree_node.hpp"
14 #include "arg_router/utility/string_to_policy.hpp"
15 
16 namespace arg_router
17 {
28 template <typename... Policies>
29 class flag_t :
30  public tree_node<policy::default_value<bool>,
31  policy::min_max_count_t<traits::integral_constant<std::size_t{0}>,
32  traits::integral_constant<std::size_t{0}>>,
33  std::decay_t<Policies>...>
34 {
35  static_assert(policy::is_all_policies_v<std::tuple<std::decay_t<Policies>...>>,
36  "Flags must only contain policies (not other nodes)");
37 
38  using parent_type =
41  traits::integral_constant<std::size_t{0}>>,
42  std::decay_t<Policies>...>;
43 
44  static_assert(traits::has_long_name_method_v<flag_t> || traits::has_short_name_method_v<flag_t>,
45  "Flag must have a long and/or short name policy");
46  static_assert(!traits::has_display_name_method_v<flag_t>,
47  "Flag must not have a display name policy");
48  static_assert(!traits::has_none_name_method_v<flag_t>, "Flag must not have a none name policy");
49 
50 public:
51  using typename parent_type::policies_type;
52 
54  using value_type = bool;
55 
57  template <bool Flatten>
58  using help_data_type = typename parent_type::template default_leaf_help_data_type<Flatten>;
59 
64  constexpr explicit flag_t(Policies... policies) noexcept :
67  traits::integral_constant<std::size_t{0}>>{},
68  std::move(policies)...}
69  {
70  }
71 
72  template <typename Validator, bool HasTarget, typename... Parents>
73  [[nodiscard]] std::optional<parsing::parse_target> pre_parse(
74  parsing::pre_parse_data<Validator, HasTarget> pre_parse_data,
75  const Parents&... parents) const
76 
77  {
78  return parent_type::pre_parse(pre_parse_data, *this, parents...);
79  }
80 
89  template <typename... Parents>
90  value_type parse([[maybe_unused]] parsing::parse_target&& target,
91  [[maybe_unused]] const Parents&... parents) const
92  {
93  // Presence of the flag yields a constant true
94  const auto result = true;
95 
96  // Routing phase
97  using routing_policy =
98  typename parent_type::template phase_finder_t<policy::has_routing_phase_method>;
99  if constexpr (!std::is_void_v<routing_policy>) {
100  this->routing_policy::routing_phase(result);
101  }
102 
103  return result;
104  }
105 
106 private:
107  static_assert(!parent_type::template any_phases_v<value_type,
110  "Flag does not support policies with parse or validation phases "
111  "(e.g. custom_parser or min_max_value)");
112 };
113 
135 template <typename... Policies>
136 [[nodiscard]] constexpr auto flag(Policies... policies) noexcept
137 {
138  return std::apply(
139  [](auto... converted_policies) {
140  // Add the short-form expander if one of the policies implements the short name method,
141  // and if the short and long prefix are not the same
142  constexpr auto has_short_name =
143  boost::mp11::mp_any_of<std::tuple<std::decay_t<decltype(converted_policies)>...>,
145  if constexpr ((config::long_prefix != config::short_prefix) && has_short_name) {
146  return flag_t{policy::short_form_expander, std::move(converted_policies)...};
147  } else {
148  return flag_t{std::move(converted_policies)...};
149  }
150  },
155  std::move(policies)...));
156 }
157 } // namespace arg_router
value_type parse([[maybe_unused]] parsing::parse_target &&target, [[maybe_unused]] const Parents &... parents) const
Definition: flag.hpp:90
typename parent_type::template default_leaf_help_data_type< Flatten > help_data_type
Definition: flag.hpp:58
constexpr flag_t(Policies... policies) noexcept
Definition: flag.hpp:64
std::optional< parsing::parse_target > pre_parse(parsing::pre_parse_data< Validator, HasTarget > pre_parse_data, const Node &node, const Parents &... parents) const
Definition: tree_node.hpp:465
constexpr auto short_prefix
Definition: config.hpp:58
constexpr auto long_prefix
Definition: config.hpp:52
constexpr auto short_form_expander
constexpr auto is_all_policies_v
Definition: policy.hpp:53
std::integral_constant< decltype(Value), Value > integral_constant
Definition: traits.hpp:210
constexpr auto convert(Params &&... params) noexcept
constexpr auto flag(Policies... policies) noexcept
Definition: flag.hpp:136