1 #ifndef OOKII_COMMAND_LINE_ARGUMENT_H_
7 #define OOKII_COMMAND_LINE_ARGUMENT_H_
18 template<
typename CharType,
typename Traits,
typename Alloc>
23 template<
typename CharType,
typename Traits,
typename Alloc>
24 struct argument_storage
26 using string_type = std::basic_string<CharType, Traits, Alloc>;
28 argument_storage(string_type name)
35 string_type description;
36 std::optional<size_t> position;
37 std::vector<string_type> aliases;
38 std::vector<CharType> short_aliases;
41 bool has_long_name{
true};
42 CharType multi_value_separator{};
43 CharType short_name{};
46 template<
typename T,
typename Element,
typename CharType,
typename Traits>
47 struct typed_argument_storage
49 using converter_type = std::function<std::optional<Element>(std::basic_string_view<CharType, Traits>,
const std::locale &)>;
51 typed_argument_storage(T &value)
57 std::optional<Element> default_value;
58 converter_type converter;
61 template<
typename T,
typename CharType,
typename Traits,
typename Alloc>
62 struct action_argument_storage
64 using converter_type = std::function<std::optional<T>(std::basic_string_view<CharType, Traits>,
const std::locale &)>;
67 action_argument_storage(function_type action)
73 converter_type converter;
83 struct element_type<std::optional<T>>
106 template<
typename CharType,
typename Traits = std::
char_traits<CharType>,
typename Alloc = std::allocator<CharType>>
111 using storage_type = details::argument_storage<CharType, Traits, Alloc>;
135 return _storage.name;
146 return _storage.short_name;
154 return _storage.short_name !=
'\0';
162 return _storage.has_long_name;
200 const std::vector<string_type> &
aliases() const noexcept
202 return _storage.aliases;
215 return _storage.short_aliases;
229 return _storage.value_description;
243 return _storage.description;
256 return _storage.position;
266 return _storage.is_required;
282 return _storage.cancel_parsing;
386 : _storage{std::move(storage)}
391 if (!_storage.has_long_name)
393 if (_storage.short_name ==
'\0')
395 throw std::logic_error(
"Argument has neither a long nor a short name.");
398 _storage.name = _storage.short_name;
399 _storage.aliases.clear();
402 if (_storage.short_name ==
'\0')
404 _storage.short_aliases.clear();
409 _storage.short_name =
static_cast<CharType
>(
'\0');
410 _storage.has_long_name =
true;
411 _storage.short_aliases.clear();
430 template<
class T,
typename CharType,
typename Traits = std::
char_traits<CharType>,
typename Alloc = std::allocator<CharType>>
448 using typed_storage_type = details::typed_argument_storage<value_type, element_type, CharType, Traits>;
462 _storage{std::move(typed_storage)}
473 return details::is_switch<T>::value;
479 std::optional<element_type> converted;
480 if (_storage.converter)
481 converted = _storage.converter(value, parser.locale());
488 _storage.value = std::move(*converted);
496 return set_switch_value_core();
502 if (!this->
has_value() && _storage.default_value)
504 _storage.value = *_storage.default_value;
511 if (_storage.default_value)
513 stream << *_storage.default_value;
522 return _storage.default_value.has_value();
526 template<
typename T2 = T>
527 std::enable_if_t<details::is_switch<T2>::value,
set_value_result> set_switch_value_core()
529 _storage.value =
true;
534 template<
typename T2 = T>
535 std::enable_if_t<!details::is_switch<T2>::value,
set_value_result> set_switch_value_core()
552 template<
typename T,
typename CharType,
typename Traits = std::
char_traits<CharType>,
typename Alloc = std::allocator<CharType>>
581 _storage{std::move(typed_storage)}
588 return details::is_switch<element_type>::value;
612 _storage.value.clear();
620 std::optional<element_type> converted;
621 if (_storage.converter)
622 converted = _storage.converter(element, parser.locale());
629 _storage.value.push_back(std::move(*converted));
639 return set_switch_value_core();
645 if (!this->
has_value() && _storage.default_value)
647 _storage.value.push_back(*_storage.default_value);
654 if (_storage.default_value)
656 stream << *_storage.default_value;
665 return _storage.default_value.has_value();
669 template<
typename T2 = element_type>
670 std::enable_if_t<details::is_switch<T2>::value,
set_value_result> set_switch_value_core()
672 _storage.value.push_back(
true);
677 template<
typename T2 = element_type>
678 std::enable_if_t<!details::is_switch<T2>::value,
set_value_result> set_switch_value_core()
698 template<
class T,
typename CharType,
typename Traits = std::
char_traits<CharType>,
typename Alloc = std::allocator<CharType>>
732 _storage{std::move(typed_storage)}
743 return details::is_switch<T>::value;
749 std::optional<element_type> converted;
750 if (_storage.converter)
751 converted = _storage.converter(value, parser.locale());
759 return invoke_action(*converted, parser);
765 return set_switch_value_core(parser);
790 bool result = _storage.action(value, parser);
794 template<
typename T2 = T>
798 return invoke_action(
true, parser);
801 template<
typename T2 = T>
Class that provides information about action arguments.
Definition: command_line_argument.h:700
bool is_switch() const noexcept override
Gets a value that indicates whether the argument is a switch, which means it can be supplied without ...
Definition: command_line_argument.h:741
typename base_type::string_view_type string_view_type
The concrete type of std::basic_string_view used.
Definition: command_line_argument.h:714
details::action_argument_storage< value_type, CharType, Traits, Alloc > typed_storage_type
The concrete type of argument information storage used. For internal use.
Definition: command_line_argument.h:716
bool has_default_value() const noexcept override
Gets a value that indicates whether this argument has a default value.
Definition: command_line_argument.h:782
T value_type
The type of the argument's value, which equals T.
Definition: command_line_argument.h:705
void apply_default_value() override
Sets the variable holding the argument's value to the default value.
Definition: command_line_argument.h:769
set_value_result set_switch_value(parser_type &parser) override
Applies the implicit value for a switch argument.
Definition: command_line_argument.h:763
action_command_line_argument(const typename base_type::parser_type &parser, typename base_type::storage_type &&storage, typed_storage_type &&typed_storage)
Initializes a new instance of the command_line_argument class.
Definition: command_line_argument.h:729
set_value_result set_value(string_view_type value, parser_type &parser) override
Used to indicate that the argument has a value.
Definition: command_line_argument.h:747
base_type::stream_type & write_default_value(typename base_type::stream_type &stream) const override
Writes the default value to the specified stream.
Definition: command_line_argument.h:775
typename base_type::string_type string_type
The concrete type of std::basic_string used.
Definition: command_line_argument.h:712
typename typed_storage_type::function_type function_type
The type of the function used by this action argument.
Definition: command_line_argument.h:718
typename base_type::parser_type parser_type
The concrete type of basic_command_line_parser used.
Definition: command_line_argument.h:720
T element_type
The type of the argument's elements, which equals T.
Definition: command_line_argument.h:710
Parses command line arguments into strongly-typed values.
Definition: command_line_parser.h:106
parsing_mode mode() const noexcept
Gets the parsing mode used by this parser.
Definition: command_line_parser.h:243
const std::vector< string_type > & prefixes() const noexcept
Gets a list of all the argument name prefixes accepted by the parser.
Definition: command_line_parser.h:293
const string_type & long_prefix() const noexcept
Gets the long argument prefix.
Definition: command_line_parser.h:303
Abstract base class for regular and multi-value arguments.
Definition: command_line_argument.h:108
virtual void reset()
Resets the argument to indicate it hasn't been set.
Definition: command_line_argument.h:316
void set_value() noexcept
Used to indicate that the argument has a value.
Definition: command_line_argument.h:371
bool has_long_name() const noexcept
Gets a value that indicates whether the argument has a long name.
Definition: command_line_argument.h:160
const string_type & description() const noexcept
Gets the long description of the argument.
Definition: command_line_argument.h:241
const std::vector< string_type > & aliases() const noexcept
Gets a list of aliases that can be used instead of the argument's name.
Definition: command_line_argument.h:200
CharType short_name() const noexcept
Gets the short name of the argument, or a NULL character if it doesn't have one.
Definition: command_line_argument.h:144
const storage_type & base_storage() const
Provides access to the storage fields to derived classes.
Definition: command_line_argument.h:377
typename storage_type::string_type string_type
The concrete type of std::basic_string used.
Definition: command_line_argument.h:113
virtual bool has_default_value() const noexcept=0
Gets a value that indicates whether this argument has a default value.
virtual bool is_multi_value() const noexcept
Gets a value that indicates whether the argument can be provided more than once, collecting all the s...
Definition: command_line_argument.h:305
virtual bool is_switch() const noexcept=0
Gets a value that indicates whether the argument is a switch, which means it can be supplied without ...
const string_type & value_description() const noexcept
Gets the value description for the argument.
Definition: command_line_argument.h:227
string_view_type short_or_long_name() const
Gets the short name if the argument has one, otherwise the long name.
Definition: command_line_argument.h:169
virtual set_value_result set_value(string_view_type value, parser_type &parser)=0
Sets the argument to the specified value.
std::optional< size_t > position() const noexcept
Gets the position of the argument.
Definition: command_line_argument.h:254
const string_type & name() const noexcept
Gets the name of the argument.
Definition: command_line_argument.h:133
virtual stream_type & write_default_value(stream_type &stream) const =0
Writes the default value to the specified stream.
basic_command_line_parser< CharType, Traits, Alloc > parser_type
The concrete type of basic_command_line_parser used.
Definition: command_line_argument.h:119
bool has_value() const noexcept
Gets a value that indicates whether the argument was specified on the last invocation of basic_comman...
Definition: command_line_argument.h:290
virtual void apply_default_value()=0
Sets the variable holding the argument's value to the default value.
const std::vector< CharType > & short_aliases() const noexcept
Gets a list of short aliases that can be used instead of the argument's name.
Definition: command_line_argument.h:213
std::basic_string_view< CharType, Traits > string_view_type
The concrete type of std::basic_string_view used.
Definition: command_line_argument.h:115
command_line_argument_base(const parser_type &parser, storage_type &&storage)
Constructs a command line argument base from a command_line_argument_storage.
Definition: command_line_argument.h:385
string_type name_with_prefix(const parser_type &parser) const
Gets the argument name with the appropriate prefix.
Definition: command_line_argument.h:183
bool cancel_parsing() const noexcept
Gets a value that indicates whether supplying this argument will cancel parsing.
Definition: command_line_argument.h:280
std::basic_ostream< CharType, Traits > stream_type
The concrete type of std::basic_ostream used.
Definition: command_line_argument.h:117
details::argument_storage< CharType, Traits, Alloc > storage_type
The concrete type of argument information storage used. For internal use.
Definition: command_line_argument.h:111
bool is_required() const noexcept
Gets a value that indicates whether the argument is required.
Definition: command_line_argument.h:264
virtual set_value_result set_switch_value(parser_type &parser)=0
Applies the implicit value for a switch argument.
bool has_short_name() const noexcept
Gets a value that indicates whether the argument has a short name.
Definition: command_line_argument.h:152
Class that provides information about arguments that are not multi-value arguments.
Definition: command_line_argument.h:432
T value_type
The type of the argument's value, which equals T.
Definition: command_line_argument.h:437
details::typed_argument_storage< value_type, element_type, CharType, Traits > typed_storage_type
The concrete type of argument information storage used. For internal use.
Definition: command_line_argument.h:448
command_line_argument(const typename base_type::parser_type &parser, typename base_type::storage_type &&storage, typed_storage_type &&typed_storage)
Initializes a new instance of the command_line_argument class.
Definition: command_line_argument.h:459
typename base_type::string_type string_type
The concrete type of std::basic_string used.
Definition: command_line_argument.h:444
typename base_type::parser_type parser_type
The concrete type of basic_command_line_parser used.
Definition: command_line_argument.h:450
typename details::element_type< T >::type element_type
The type of the argument's elements, which equals T.
Definition: command_line_argument.h:442
void apply_default_value() override
Sets the variable holding the argument's value to the default value.
Definition: command_line_argument.h:500
bool is_switch() const noexcept override
Gets a value that indicates whether the argument is a switch, which means it can be supplied without ...
Definition: command_line_argument.h:471
bool has_default_value() const noexcept override
Gets a value that indicates whether this argument has a default value.
Definition: command_line_argument.h:520
typename base_type::string_view_type string_view_type
The concrete type of std::basic_string_view used.
Definition: command_line_argument.h:446
set_value_result set_switch_value([[maybe_unused]] parser_type &parser) override
Applies the implicit value for a switch argument.
Definition: command_line_argument.h:494
set_value_result set_value(string_view_type value, parser_type &parser) override
Used to indicate that the argument has a value.
Definition: command_line_argument.h:477
base_type::stream_type & write_default_value(typename base_type::stream_type &stream) const override
Writes the default value to the specified stream.
Definition: command_line_argument.h:509
Class that provides information about arguments that are not multi-value arguments.
Definition: command_line_argument.h:554
set_value_result set_value(string_view_type value, parser_type &parser) override
Used to indicate that the argument has a value.
Definition: command_line_argument.h:616
bool is_switch() const noexcept override
Gets a value that indicates whether the argument is a switch, which means it can be supplied without ...
Definition: command_line_argument.h:586
typename T::value_type element_type
The type of the argument's container's elements.
Definition: command_line_argument.h:561
typename base_type::string_type string_type
The concrete type of std::basic_string used.
Definition: command_line_argument.h:563
typename base_type::string_view_type string_view_type
The concrete type of std::basic_string_view used.
Definition: command_line_argument.h:565
void reset() override
Resets the argument to indicate it hasn't been set.
Definition: command_line_argument.h:609
typename base_type::parser_type parser_type
The concrete type of basic_command_line_parser used.
Definition: command_line_argument.h:569
details::typed_argument_storage< T, element_type, CharType, Traits > typed_storage_type
The concrete type of argument information storage used. For internal use.
Definition: command_line_argument.h:567
multi_value_command_line_argument(const typename base_type::parser_type &parser, typename base_type::storage_type &&storage, typed_storage_type &&typed_storage)
Initializes a new instance of the multi_value_command_line_argument class.
Definition: command_line_argument.h:578
T value_type
The type of the argument's container, which equals T.
Definition: command_line_argument.h:559
bool is_multi_value() const noexcept override
Gets a value that indicates whether the argument can be provided more than once, collecting all the s...
Definition: command_line_argument.h:594
set_value_result set_switch_value([[maybe_unused]] parser_type &parser) override
Applies the implicit value for a switch argument.
Definition: command_line_argument.h:637
CharType separator() const noexcept
Gets the character used to separate multiple values in a single argument value, or '\0' if no separat...
Definition: command_line_argument.h:603
void apply_default_value() override
Sets the variable holding the argument's value to the default value.
Definition: command_line_argument.h:643
bool has_default_value() const noexcept override
Gets a value that indicates whether this argument has a default value.
Definition: command_line_argument.h:663
base_type::stream_type & write_default_value(typename base_type::stream_type &stream) const override
Writes the default value to the specified stream.
Definition: command_line_argument.h:652
A pseudo-range for string tokenization.
Definition: string_helper.h:264
Provides functionality for switch arguments.
Namespace containing the core Ookii.CommandLine.Cpp types.
Definition: command_line_argument.h:16
@ long_short
Use POSIX-like rules where arguments have separate long and short names.
set_value_result
The result of attempting to set a value for an argument.
Definition: command_line_argument.h:91
@ cancel
The operation was successful, but has requested that parsing will be cancelled.
@ success
The operation was successful.
@ error
There was an error converting the value to the element type of the argument.
@ cancel_parsing
Cancel parsing immediately, disregarding the rest of the command line. Parsing will return with parse...
Provides the ookii::parsing_mode enumeration.
static std::optional< T > from_string(std::basic_string_view< CharType, Traits > value, const std::locale &loc={})
Convert a string to the specified type.
Definition: string_helper.h:217
Template used to specify the default value description for a type.
Definition: value_description.h:30