17namespace sharg::detail
69 template <
typename option_type,
typename val
idator_t>
82 template <
typename val
idator_t>
95 template <
typename option_type,
typename val
idator_t>
133 void add_subsection(
std::string const &,
bool const)
135 void add_line(
std::string const &,
bool,
bool const)
142 template <
typename id_type>
172 template <
typename iterator_type,
typename id_type>
173 static iterator_type
find_option_id(iterator_type begin_it, iterator_type end_it, id_type
const &
id)
188 return current_arg.
substr(0, full_id.
size()) == full_id;
193 return current_arg.
substr(0, full_id.
size()) == full_id &&
194 (current_arg.
size() == full_id.
size()
195 || current_arg[full_id.
size()] ==
'=');
215 return {
"--" + long_id};
224 return {
'-', short_id};
234 if (short_id ==
'\0')
236 else if (long_id.
empty())
263 if (arg[0] ==
'-' && arg.size() > 1 && arg[1] !=
'-')
265 auto pos = arg.find(short_id);
267 if (pos != std::string::npos)
288 template <
typename option_t>
295 if (stream.fail() || !stream.eof())
308 template <named_enumeration option_t>
311 auto map = sharg::enumeration_names<option_t>;
313 if (
auto it = map.find(in); it == map.end())
320 key_value_pairs.
end(),
321 [](
auto pair1,
auto pair2)
323 if constexpr (std::totally_ordered<option_t>)
325 if (pair1.second != pair2.second)
326 return pair1.second < pair2.second;
329 return pair1.first < pair2.first;
333 for (
auto const & [key, value] : key_value_pairs)
335 result.replace(result.size() - 2, 2,
"]");
339 throw user_input_error{
"You have chosen an invalid input value: " + in +
". Please use one of: " + keys};
353 return option_parse_result::success;
369 template <detail::is_container_option container_option_t,
typename format_parse_t = format_parse>
370 requires requires (format_parse_t fp,
371 typename container_option_t::value_type & container_value,
379 typename container_option_t::value_type tmp{};
381 auto res = parse_option_value(tmp, in);
383 if (res == option_parse_result::success)
384 value.push_back(tmp);
401 template <
typename option_t>
407 if (res.ec == std::errc::result_out_of_range)
408 return option_parse_result::overflow_error;
409 else if (res.ec == std::errc::invalid_argument || res.ptr != &in[in.
size()])
410 return option_parse_result::error;
412 return option_parse_result::success;
431 else if (in ==
"true")
433 else if (in ==
"false")
436 return option_parse_result::error;
438 return option_parse_result::success;
448 template <
typename option_type>
453 std::string msg{
"Value parse failed for " + option_name +
": "};
455 if (res == option_parse_result::error)
457 throw user_input_error{msg +
"Argument " + input_value +
" could not be parsed as type "
458 + get_type_name_as_string(option_type{}) +
"."};
463 if (res == option_parse_result::overflow_error)
465 throw user_input_error{msg +
"Numeric argument " + input_value +
" is not in the valid range ["
471 assert(res == option_parse_result::success);
491 template <
typename option_type,
typename id_type>
496 if (option_it != end_of_options_it)
499 size_t id_size = (prepend_dash(
id)).size();
501 if ((*option_it).size() > id_size)
503 if ((*option_it)[id_size] ==
'=')
505 if ((*option_it).size() == id_size + 1)
507 input_value = (*option_it).
substr(id_size + 1);
511 input_value = (*option_it).
substr(id_size);
520 if (option_it == end_of_options_it)
522 input_value = *option_it;
526 auto res = parse_option_value(value, input_value);
527 throw_on_input_error<option_type>(res, prepend_dash(
id), input_value);
551 template <
typename option_type,
typename id_type>
554 auto it = find_option_id(arguments.begin(), end_of_options_it,
id);
556 if (it != end_of_options_it)
557 identify_and_retrieve_option_value(value, it,
id);
559 if (find_option_id(it, end_of_options_it,
id) != end_of_options_it)
561 +
" is no list/container but declared multiple times.");
563 return (it != end_of_options_it);
577 template <detail::is_container_option option_type,
typename id_type>
580 auto it = find_option_id(arguments.begin(), end_of_options_it,
id);
581 bool seen_at_least_once{it != end_of_options_it};
583 if (seen_at_least_once)
586 while (it != end_of_options_it)
588 identify_and_retrieve_option_value(value, it,
id);
589 it = find_option_id(it, end_of_options_it,
id);
592 return seen_at_least_once;
610 for (
auto it = arguments.begin(); it != end_of_options_it; ++it)
613 if (!arg.empty() && arg[0] ==
'-')
619 else if (arg[1] !=
'-' && arg.size() > 2)
621 throw unknown_option(
"Unknown flags " + expand_multiple_flags(arg)
622 +
". In case this is meant to be a non-option/argument/parameter, "
623 +
"please specify the start of arguments with '--'. "
624 +
"See -h/--help for program information.");
629 +
". In case this is meant to be a non-option/argument/parameter, "
630 +
"please specify the start of non-options with '--'. "
631 +
"See -h/--help for program information.");
657 throw too_many_arguments(
"Too many arguments provided. Please see -h/--help for more information.");
677 template <
typename option_type,
typename val
idator_t>
681 bool long_id_is_set{get_option_by_id(value,
config.
long_id)};
686 +
" is no list/container but specified multiple times");
688 if (short_id_is_set || long_id_is_set)
705 +
" is required but not set.");
720 value = flag_is_set(short_id) || flag_is_set(long_id) || value;
745 template <
typename option_type,
typename val
idator_type>
748 ++positional_option_count;
756 if (it == arguments.end())
757 throw too_few_arguments(
"Not enough positional arguments provided (Need at least "
759 +
"). See -h/--help for more information.");
764 assert(positional_option_count == positional_option_calls.size());
768 while (it != arguments.end())
770 auto res = parse_option_value(value, *it);
772 throw_on_input_error<option_type>(res,
id, *it);
781 ++positional_option_count;
786 auto res = parse_option_value(value, *it);
788 throw_on_input_error<option_type>(res,
id, *it);
811 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
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