arg_router  1.4.0
C++ command line argument parsing and routing
positional_arg.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/multi_arg_base.hpp"
8 #include "arg_router/policy/description.hpp"
9 #include "arg_router/policy/display_name.hpp"
10 #include "arg_router/utility/string_to_policy.hpp"
11 
12 namespace arg_router
13 {
26 template <typename T, typename... Policies>
27 class positional_arg_t : public multi_arg_base_t<T, 0, Policies...>
28 {
29  using parent_type = multi_arg_base_t<T, 0, Policies...>;
30 
31  static_assert(traits::has_display_name_method_v<positional_arg_t>,
32  "Positional arg must have a display name policy");
33  static_assert(!traits::has_long_name_method_v<positional_arg_t>,
34  "Positional arg must not have a long name policy");
35  static_assert(!traits::has_short_name_method_v<positional_arg_t>,
36  "Positional arg must not have a short name policy");
37  static_assert(!traits::has_none_name_method_v<positional_arg_t>,
38  "Positional arg must not have a none name policy");
39 
40 public:
41  using typename parent_type::policies_type;
42 
44  using value_type = T;
45 
47  template <bool Flatten>
49  {
50  [[nodiscard]] constexpr static auto label_generator() noexcept
51  {
52  constexpr auto name_index =
53  boost::mp11::mp_find_if<policies_type, traits::has_display_name_method>::value;
54  using name_type = typename std::tuple_element_t<name_index, policies_type>::string_type;
55 
56  return AR_STRING("<"){} + name_type{} + AR_STRING("> "){} +
57  parent_type::template default_leaf_help_data_type<Flatten>::count_suffix();
58  }
59 
60  public:
61  using label = std::decay_t<decltype(label_generator())>;
62  using description =
63  typename parent_type::template default_leaf_help_data_type<Flatten>::description;
64  using children = std::tuple<>;
65  };
66 
71  constexpr explicit positional_arg_t(Policies... policies) noexcept :
72  parent_type{std::move(policies)...}
73  {
74  }
75 
76  template <typename Validator, bool HasTarget, typename... Parents>
77  [[nodiscard]] std::optional<parsing::parse_target> pre_parse(
78  parsing::pre_parse_data<Validator, HasTarget> pre_parse_data,
79  const Parents&... parents) const
80  {
81  return parent_type::pre_parse(pre_parse_data, *this, parents...);
82  }
83 
84  template <typename... Parents>
85  [[nodiscard]] value_type parse(parsing::parse_target target, const Parents&... parents) const
86  {
87  return parent_type::parse(target, *this, parents...);
88  }
89 
90 private:
91  static_assert(!parent_type::template any_phases_v<value_type, policy::has_routing_phase_method>,
92  "Positional arg does not support policies with routing phases "
93  "(e.g. router)");
94 };
95 
115 template <typename T, typename... Policies>
116 [[nodiscard]] constexpr auto positional_arg(Policies... policies) noexcept
117 {
118  return std::apply(
119  [](auto... converted_policies) {
120  return positional_arg_t<T, std::decay_t<decltype(converted_policies)>...>{
121  std::move(converted_policies)...};
122  },
126  std::move(policies)...));
127 }
128 } // namespace arg_router
value_type parse(parsing::parse_target target, const Parents &... parents) const
constexpr positional_arg_t(Policies... policies) noexcept
constexpr auto convert(Params &&... params) noexcept
constexpr auto positional_arg(Policies... policies) noexcept