arg_router  1.4.0
C++ command line argument parsing and routing
root_wrapper.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 #ifndef AR_ENABLE_CPP20_STRINGS
8 
9 # include "arg_router/basic_types.hpp"
10 # include "arg_router/utility/tuple_iterator.hpp"
11 
12 # include <variant>
13 
16 namespace arg_router::multi_lang
17 {
66 template <typename Fn, typename... SupportedISOLanguageCodes>
68 {
69  constexpr static auto num_supported_codes = sizeof...(SupportedISOLanguageCodes);
70  static_assert(num_supported_codes > 1, "Must be more than one language provided");
71 
72  using supported_codes = std::tuple<SupportedISOLanguageCodes...>;
73  static_assert(num_supported_codes == std::tuple_size_v<boost::mp11::mp_unique<supported_codes>>,
74  "Supported ISO language codes must be unique");
75 
76  template <std::size_t... I>
77  constexpr static auto indicies_to_variant(std::index_sequence<I...>) -> std::variant<
78  std::decay_t<decltype(std::declval<Fn>()(traits::integral_constant<I>{}))>...>;
79 
80  using root_variant_t =
81  decltype(indicies_to_variant(std::make_index_sequence<num_supported_codes>{}));
82  using supported_iso_languages = std::tuple<SupportedISOLanguageCodes...>;
83 
84 public:
91  [[deprecated("Superceded by multi_lang::root_t, will be removed in v2")]] //
92  explicit root_wrapper_t(std::string_view iso_language, Fn&& f)
93  {
94  utility::tuple_type_iterator<boost::mp11::mp_iota_c<num_supported_codes>>([&](auto I) {
95  if (root_ ||
96  (iso_language != std::tuple_element_t<I, supported_iso_languages>::get())) {
97  return;
98  }
99 
100  root_.emplace(root_variant_t{f(I)});
101  });
102 
103  // No match, so fall back to the default (the first language)
104  if (!root_) {
105  root_.emplace(root_variant_t{f(traits::integral_constant<std::size_t{0}>{})});
106  }
107  }
108 
114  void parse(int argc, char** argv) const
115  {
116  std::visit([&](const auto& root) { root.parse(argc, argv); }, *root_);
117  }
118 
123  void help(std::ostream& stream) const
124  {
125  std::visit([&](const auto& root) { root.help(stream); }, *root_);
126  }
127 
132  [[nodiscard]] string help() const
133  {
134  return std::visit([](const auto& root) { root.help(); }, *root_);
135  }
136 
137 private:
138  // Only optional due to the delayed initialisation
139  std::optional<root_variant_t> root_;
140 };
141 
151 template <typename... SupportedISOLanguageCodes, typename Fn>
152 [[nodiscard, deprecated("Superceded by multi_lang::root, will be removed in v2")]] //
153 auto root_wrapper(std::string_view iso_language, Fn&& f)
154 {
155  return root_wrapper_t<Fn, SupportedISOLanguageCodes...>{iso_language, std::forward<Fn>(f)};
156 }
157 } // namespace arg_router::multi_lang
158 
159 #endif
root_wrapper_t(std::string_view iso_language, Fn &&f)
void parse(int argc, char **argv) const
void help(std::ostream &stream) const
auto root(std::string_view language_id, const RootFactory &f)
Definition: root.hpp:221
auto root_wrapper(std::string_view iso_language, Fn &&f)
std::integral_constant< decltype(Value), Value > integral_constant
Definition: traits.hpp:210