18namespace sharg::detail
70 template <
typename option_type,
typename val
idator_t>
83 template <
typename val
idator_t>
96 template <
typename option_type,
typename val
idator_t>
134 void add_subsection(
std::string const &,
bool const)
136 void add_line(
std::string const &,
bool,
bool const)
163 template <
typename iterator_type>
166 bool const short_id_empty{
id.empty_short_id()};
167 bool const long_id_empty{
id.empty_long_id()};
169 if (short_id_empty && long_id_empty)
177 tmp.remove_suffix(1u);
185 if (!short_id_empty && current_arg.starts_with(short_id))
189 if (!long_id_empty && (current_arg == long_id_space || current_arg.
starts_with(long_id_equals)))
213 return {
"--" + long_id};
222 return {
'-', short_id};
232 if (short_id ==
'\0')
234 else if (long_id.
empty())
261 if (arg[0] ==
'-' && arg.size() > 1 && arg[1] !=
'-')
263 auto pos = arg.find(short_id);
265 if (pos != std::string::npos)
286 template <
typename option_t>
293 if (stream.fail() || !stream.eof())
306 template <named_enumeration option_t>
309 auto map = sharg::enumeration_names<option_t>;
311 if (
auto it = map.find(in); it == map.end())
318 key_value_pairs.
end(),
319 [](
auto pair1,
auto pair2)
321 if constexpr (std::totally_ordered<option_t>)
323 if (pair1.second != pair2.second)
324 return pair1.second < pair2.second;
327 return pair1.first < pair2.first;
331 for (
auto const & [key, value] : key_value_pairs)
333 result.
replace(result.size() - 2, 2,
"]");
337 throw user_input_error{
"You have chosen an invalid input value: " + in +
". Please use one of: " + keys};
351 return option_parse_result::success;
367 template <detail::is_container_option container_option_t,
typename format_parse_t = format_parse>
368 requires requires (format_parse_t fp,
369 typename container_option_t::value_type & container_value,
377 typename container_option_t::value_type tmp{};
379 auto res = parse_option_value(tmp, in);
381 if (res == option_parse_result::success)
382 value.push_back(tmp);
399 template <
typename option_t>
405 if (res.ec == std::errc::result_out_of_range)
406 return option_parse_result::overflow_error;
407 else if (res.ec == std::errc::invalid_argument || res.ptr != in.
data() + in.
size())
408 return option_parse_result::error;
410 return option_parse_result::success;
425 if (in ==
"0" || in ==
"false")
427 else if (in ==
"1" || in ==
"true")
430 return option_parse_result::error;
432 return option_parse_result::success;
442 template <
typename option_type>
447 std::string msg{
"Value parse failed for " + option_name +
": "};
449 if (res == option_parse_result::error)
451 throw user_input_error{msg +
"Argument " + input_value +
" could not be parsed as type "
452 + get_type_name_as_string<option_type>() +
"."};
457 if (res == option_parse_result::overflow_error)
459 throw user_input_error{msg +
"Numeric argument " + input_value +
" is not in the valid range ["
465 assert(res == option_parse_result::success);
485 template <
typename option_type,
typename id_type>
490 if (option_it != end_of_options_it)
493 size_t id_size = (prepend_dash(
id)).size();
495 if ((*option_it).size() > id_size)
497 if ((*option_it)[id_size] ==
'=')
499 if ((*option_it).size() == id_size + 1)
501 input_value = (*option_it).
substr(id_size + 1);
505 input_value = (*option_it).
substr(id_size);
514 if (option_it == end_of_options_it)
516 input_value = *option_it;
520 auto res = parse_option_value(value, input_value);
521 throw_on_input_error<option_type>(res, prepend_dash(
id), input_value);
545 template <
typename option_type,
typename id_type>
548 auto it = find_option_id(arguments.begin(), end_of_options_it,
id);
550 if (it != end_of_options_it)
551 identify_and_retrieve_option_value(value, it,
id);
553 if (find_option_id(it, end_of_options_it,
id) != end_of_options_it)
555 +
" is no list/container but declared multiple times.");
557 return (it != end_of_options_it);
571 template <detail::is_container_option option_type,
typename id_type>
574 auto it = find_option_id(arguments.begin(), end_of_options_it,
id);
575 bool seen_at_least_once{it != end_of_options_it};
577 if (seen_at_least_once)
580 while (it != end_of_options_it)
582 identify_and_retrieve_option_value(value, it,
id);
583 it = find_option_id(it, end_of_options_it,
id);
586 return seen_at_least_once;
604 for (
auto it = arguments.begin(); it != end_of_options_it; ++it)
607 if (!arg.empty() && arg[0] ==
'-')
613 else if (arg[1] !=
'-' && arg.size() > 2)
615 throw unknown_option(
"Unknown flags " + expand_multiple_flags(arg)
616 +
". In case this is meant to be a non-option/argument/parameter, "
617 +
"please specify the start of arguments with '--'. "
618 +
"See -h/--help for program information.");
623 +
". In case this is meant to be a non-option/argument/parameter, "
624 +
"please specify the start of non-options with '--'. "
625 +
"See -h/--help for program information.");
651 throw too_many_arguments(
"Too many arguments provided. Please see -h/--help for more information.");
671 template <
typename option_type,
typename val
idator_t>
675 bool long_id_is_set{get_option_by_id(value,
config.
long_id)};
680 +
" is no list/container but specified multiple times");
682 if (short_id_is_set || long_id_is_set)
699 +
" is required but not set.");
714 value = flag_is_set(short_id) || flag_is_set(long_id) || value;
739 template <
typename option_type,
typename val
idator_type>
742 ++positional_option_count;
750 if (it == arguments.end())
751 throw too_few_arguments(
"Not enough positional arguments provided (Need at least "
753 +
"). See -h/--help for more information.");
758 assert(positional_option_count == positional_option_calls.size());
762 while (it != arguments.end())
764 auto res = parse_option_value(value, *it);
766 throw_on_input_error<option_type>(res,
id, *it);
775 ++positional_option_count;
780 auto res = parse_option_value(value, *it);
782 throw_on_input_error<option_type>(res,
id, *it);
805 unsigned positional_option_count{0};
The <charconv> header from C++17's standard library.
Parser exception thrown when a non-list option is declared multiple times.
Definition exceptions.hpp:140
Parser exception thrown when a required option is missing.
Definition exceptions.hpp:120
Parser exception thrown when too few arguments are provided.
Definition exceptions.hpp:100
Parser exception thrown when too many arguments are provided.
Definition exceptions.hpp:80
Parser exception thrown when encountering unknown option.
Definition exceptions.hpp:60
Parser exception thrown when an argument could not be casted to the according type.
Definition exceptions.hpp:180
Provides helper concepts.
Whether the option type is considered to be a container.
Definition detail/concept.hpp:38
Concept for types that can be parsed from a std::istream via the stream operator.
Definition concept.hpp:37
The concept for option validators passed to add_option/positional_option.
Definition validators.hpp:49
Provides sharg::detail::id_pair.
Option struct that is passed to the sharg::parser::add_option() function.
Definition config.hpp:43
std::string long_id
The long identifier for the option (e.g. "age", making the option callable via --age).
Definition config.hpp:62
bool required
Whether the option is required.
Definition config.hpp:129
validator_t validator
A sharg::validator that verifies the value after parsing (callable).
Definition config.hpp:135
char short_id
The short identifier for the option (e.g. 'a', making the option callable via -a).
Definition config.hpp:53
A simple struct to store a short and a long identifier for an option.
Definition id_pair.hpp:25