arg_router  1.4.0
C++ command line argument parsing and routing
exception_translator.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/exception.hpp"
8 #include "arg_router/policy/policy.hpp"
9 #include "arg_router/utility/tuple_iterator.hpp"
10 
11 #include <boost/lexical_cast.hpp>
12 
29 namespace arg_router::policy
30 {
31 template <typename TranslationType,
32  typename FallbackTranslationType = default_error_code_translations>
33 class exception_translator_t
34 {
35  template <typename T>
36  using get_translations = typename T::error_code_translations;
37 
38  template <typename T>
39  using get_translations_or_default =
40  boost::mp11::mp_eval_if_c<!traits::has_error_code_translations_type_v<T>, //
41  std::tuple<>,
42  get_translations,
43  T>;
44 
45  using translations =
46  boost::mp11::mp_append<get_translations_or_default<TranslationType>,
47  get_translations_or_default<FallbackTranslationType>>;
48 
49 public:
55  [[noreturn]] static void translate_exception(const multi_lang_exception& e)
56  {
57  utility::tuple_type_iterator<translations>([&](auto i) {
58  using entry_type = std::tuple_element_t<i, translations>;
59 
60  constexpr auto this_ec = boost::mp11::mp_front<entry_type>::value;
61  using this_msg = boost::mp11::mp_back<entry_type>;
62 
63  if (this_ec == e.ec()) {
64  throw parse_exception{utility::exception_formatter<this_msg>{}, e.tokens()};
65  }
66  });
67 
68  const auto ec = static_cast<std::underlying_type_t<error_code>>(e.ec());
69 
70  // We use boost::lexical_cast here instead of std::to_string as arg_router::string may have
71  // a non-std::allocator allocator type
72  // NOLINTNEXTLINE(boost-use-to-string)
73  throw parse_exception{"Untranslated error code (" + boost::lexical_cast<string>(ec) + ")",
74  e.tokens()};
75  }
76 };
77 
85 template <typename TranslationType,
86  typename FallbackTranslationType = default_error_code_translations>
87 constexpr auto exception_translator =
88  exception_translator_t<TranslationType, FallbackTranslationType>{};
89 
90 template <typename TranslationType, typename FallbackTranslationType>
91 struct is_policy<exception_translator_t<TranslationType, FallbackTranslationType>> :
92  std::true_type {
93 };
94 } // namespace arg_router::policy
constexpr auto exception_translator