arg_router  1.4.0
C++ command line argument parsing and routing
alias_group.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/dependency/detail.hpp"
8 #include "arg_router/policy/multi_stage_value.hpp"
9 
14 {
33 template <typename... Params>
34 class alias_group_t : public detail::basic_one_of_t<AR_STRING("Alias Group: "), Params...>
35 {
36  using parent_type = detail::basic_one_of_t<AR_STRING("Alias Group: "), Params...>;
37 
38 public:
39  using typename parent_type::children_type;
40  using typename parent_type::policies_type;
41 
43  using value_type = boost::mp11::mp_first<typename parent_type::basic_value_type>;
44 
45  static_assert(
46  std::tuple_size_v<boost::mp11::mp_unique<typename parent_type::basic_value_type>> == 1,
47  "All children of alias_group must have the same value_type, or use "
48  "policy::no_result_value");
49 
50 private:
51  template <typename Child>
52  struct multi_stage_with_result_and_validation {
53  constexpr static auto value =
54  policy::has_multi_stage_value_v<Child> && !policy::has_no_result_value_v<Child> &&
55  Child::template any_phases_v<value_type, policy::has_validation_phase_method>;
56  };
57 
58 public:
59  // If any of the children are multi_stage_values, not no_result_value, and have a validation
60  // phase; then fail as the policy that implements needs to be moved into this node otherwise
61  // they won't be called
62  static_assert(
63  boost::mp11::mp_none_of<children_type, multi_stage_with_result_and_validation>::value,
64  "Multi-stage value supporting alias_group children (e.g. "
65  "counting_flag) cannot have a validation phase as they won't be "
66  "executed, move the implementing policies into the alias_group");
67 
69  template <bool Flatten>
71  {
72  public:
73  using label =
74  decltype(AR_STRING_SV(parent_type::display_name()){} +
75  parent_type::template default_leaf_help_data_type<Flatten>::value_suffix());
76  using description = AR_STRING("");
77  using children = typename parent_type::template //
78  children_help_data_type<Flatten>::children;
79 
80  template <typename OwnerNode, typename FilterFn>
81  [[nodiscard]] static vector<runtime_help_data> runtime_children(const OwnerNode& owner,
82  FilterFn&& f)
83  {
84  return parent_type::template children_help_data_type<Flatten>::runtime_children(
85  owner,
86  std::forward<FilterFn>(f));
87  }
88  };
89 
94  constexpr explicit alias_group_t(Params... params) noexcept : parent_type{std::move(params)...}
95  {
96  }
97 
111  template <typename Validator, bool HasTarget, typename... Parents>
112  [[nodiscard]] std::optional<parsing::parse_target> pre_parse(
114  const Parents&... parents) const
115  {
116  auto found = std::optional<parsing::parse_target>{};
118  [&](auto /*i*/, const auto& child) {
119  if (!found) {
120  found = child.pre_parse(pre_parse_data, parents...);
121  }
122  },
123  this->children());
124 
125  return found;
126  }
127 };
128 
136 template <typename... Params>
137 [[nodiscard]] constexpr auto alias_group(Params... params) noexcept
138 {
139  return alias_group_t{std::move(params)...};
140 }
141 } // namespace arg_router::dependency
std::optional< parsing::parse_target > pre_parse(parsing::pre_parse_data< Validator, HasTarget > pre_parse_data, const Parents &... parents) const
constexpr alias_group_t(Params... params) noexcept
Definition: alias_group.hpp:94
boost::mp11::mp_first< typename parent_type::basic_value_type > value_type
Definition: alias_group.hpp:43
constexpr auto alias_group(Params... params) noexcept
constexpr std::enable_if_t< traits::is_tuple_like_v< std::decay_t< Tuple > > > tuple_iterator(F &&f, Tuple &&tuple)
std::vector< T, config::allocator< T > > vector
Definition: basic_types.hpp:39