arg_router  1.4.0
C++ command line argument parsing and routing
token_end_marker.hpp
1 // Copyright (C) 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/parsing/parsing.hpp"
8 #include "arg_router/policy/multi_stage_value.hpp"
9 
10 namespace arg_router::policy
11 {
29 template <typename S>
31 {
32 public:
34  using string_type = S;
35 
37  constexpr static auto priority = std::size_t{760};
38 
43  constexpr explicit token_end_marker_t([[maybe_unused]] S str = {}) noexcept {}
44 
49  [[nodiscard]] constexpr static std::string_view token_end_marker() noexcept { return S::get(); }
50 
63  template <typename ProcessedTarget, typename... Parents>
66  [[maybe_unused]] utility::compile_time_optional<ProcessedTarget> processed_target,
67  [[maybe_unused]] parsing::parse_target& target,
68  [[maybe_unused]] const Parents&... parents) const
69  {
70  static_assert((sizeof...(Parents) >= 1),
71  "At least one parent needed for token_end_marker_t");
72 
73  using owner_type = boost::mp11::mp_first<std::tuple<Parents...>>;
74 
75  constexpr auto has_count = traits::has_minimum_count_method_v<owner_type> &&
76  traits::has_maximum_count_method_v<owner_type>;
77  static_assert(has_count, "Token end marker can only be used in variable list length nodes");
78 
79  if constexpr (has_count) {
80  static_assert((owner_type::minimum_count() != owner_type::maximum_count()) &&
81  !policy::has_multi_stage_value_v<owner_type>,
82  "Token end marker can only be used in variable list length nodes");
83  }
84 
85  // Transfer the tokens up to the end marker. If not found then the whole token list is
86  // used. If found, the token is removed as it should be in the parsed results
87  const auto it = std::find_if(tokens.begin() + (owner_type::is_named ? 1 : 0),
88  tokens.end(),
89  [](auto&& token) { return token.name == token_end_marker(); });
90  tokens.transfer(it);
91  tokens.erase(it);
92 
94  }
95 
96 private:
97  static_assert(utility::utf8::count(token_end_marker()) > 0,
98  "Token end markers must not be an empty string");
100  "Token end markers cannot contain whitespace");
101 };
102 
107 template <typename S>
109 
110 template <typename S>
111 struct is_policy<token_end_marker_t<S>> : std::true_type {
112 };
113 } // namespace arg_router::policy
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 token_end_marker_t([[maybe_unused]] S str={}) noexcept
constexpr static std::string_view token_end_marker() noexcept
constexpr auto token_end_marker
constexpr bool contains_whitespace(std::string_view str) noexcept
Definition: utf8.hpp:304
constexpr std::size_t count(std::string_view str) noexcept
Definition: utf8.hpp:278