49template <
typename val
idator_type>
50concept validator = std::copyable<std::remove_cvref_t<validator_type>> &&
56 {validator.get_help_page_message()} -> std::same_as<std::string>;
77template <
typename option_value_t>
78 requires std::is_arithmetic_v<option_value_t>
95 valid_range_str{
"[" + std::to_string(min_) +
"," + std::to_string(max_) +
"]"}
107 if (!((cmp <= max) && (cmp >= min)))
108 throw validation_error{
"Value " + std::to_string(cmp) +
" is not in range " + valid_range_str +
"."};
120 template <std::ranges::forward_range range_type>
121 requires std::is_arithmetic_v<std::ranges::range_value_t<range_type>>
124 std::for_each(range.begin(),
139 return std::string{
"Value must be in range "} + valid_range_str +
".";
174template <parsable option_value_t>
199 template <std::ranges::forward_range range_type>
200 requires std::constructible_from<option_value_type, std::ranges::range_rvalue_reference_t<range_type>>
203 std::move(rng.begin(), rng.end(), std::back_inserter(values));
214 template <
typename... option_types>
215 requires ((std::constructible_from<option_value_type, option_types> && ...))
218 (values.
emplace_back(std::forward<option_types>(opts)), ...);
231 if (!(std::find(values.
begin(), values.
end(), cmp) != values.
end()))
232 throw validation_error{detail::to_string(
"Value ", cmp,
" is not one of ", values,
".")};
243 template <std::ranges::forward_range range_type>
244 requires std::convertible_to<std::ranges::range_value_t<range_type>,
option_value_type>
248 std::ranges::end(range),
262 return detail::to_string(
"Value must be one of ", values,
".");
275template <
typename option_type,
typename... option_types>
276 requires (std::constructible_from<std::string, std::decay_t<option_types>> && ...
277 && std::constructible_from<std::string, std::decay_t<option_type>>)
281template <
typename range_type>
282 requires (std::ranges::forward_range<std::decay_t<range_type>>
283 && std::constructible_from<std::string, std::ranges::range_value_t<range_type>>)
287template <
typename option_type,
typename... option_types>
291template <
typename range_type>
292 requires (std::ranges::forward_range<std::decay_t<range_type>>)
349 template <std::ranges::forward_range range_type>
351 && !std::convertible_to<range_type, std::filesystem::path const &>)
352 void operator()(range_type
const & v)
const
354 std::for_each(v.begin(),
358 this->operator()(cmp);
378 +
" has no extension. Expected one of the "
379 "following valid extensions:"
386 if (file_path.front() ==
'.')
387 file_path.erase(0, 1);
393 auto case_insensitive_ends_with = [&](
std::string const & ext)
402 + all_extensions +
" instead!"};
418 if (
static_cast<bool>(ec))
428 if (!file.is_open() || !file.good())
441 sharg::detail::safe_filesystem_entry file_guard{path};
443 bool is_open = file.is_open();
444 bool is_good = file.good();
447 if (!is_good || !is_open)
469 size_t const suffix_length{suffix.
size()};
470 size_t const str_length{str.
size()};
472 if (suffix_length > str_length)
475 for (
size_t j = 0, s_start = str_length - suffix_length; j < suffix_length; ++j)
476 if (std::tolower(str[s_start + j]) != std::tolower(suffix[j]))
545 using file_validator_base::operator();
576 std::rethrow_exception(std::current_exception());
586 return "The input file must exist and read permissions must be granted."
703 using file_validator_base::operator();
733 std::rethrow_exception(std::current_exception());
744 if (open_mode == output_file_open_options::open_or_create)
746 return "Write permissions must be granted."
752 return "The output file must not exist already and write permissions must be granted."
802 using file_validator_base::operator();
833 std::rethrow_exception(std::current_exception());
844 return "An existing, readable path for the input directory.";
887 using file_validator_base::operator();
904 if (
static_cast<bool>(ec))
911 sharg::detail::safe_filesystem_entry dir_guard{dir};
913 dir_guard.remove_all();
928 std::rethrow_exception(std::current_exception());
939 return "A valid path for the output directory.";
989 if (!std::regex_match(cmp, rgx))
990 throw validation_error{
"Value " + cmp +
" did not match the pattern " + pattern +
"."};
1002 template <std::ranges::forward_range range_type>
1003 requires std::convertible_to<std::ranges::range_reference_t<range_type>,
std::string const &>
1006 for (
auto && entry : v)
1020 return "Value must match the pattern '" + pattern +
"'.";
1042struct default_validator
1045 using option_value_type =
std::any;
1048 template <
typename option_value_t>
1049 void operator()(option_value_t
const & )
const noexcept
1072template <val
idator val
idator1_type, val
idator val
idator2_type>
1073 requires std::common_with<typename validator1_type::option_value_type, typename validator2_type::option_value_type>
1074class validator_chain_adaptor
1078 using option_value_type =
1084 validator_chain_adaptor() =
delete;
1085 validator_chain_adaptor(validator_chain_adaptor
const & pf) =
default;
1086 validator_chain_adaptor & operator=(validator_chain_adaptor
const & pf) =
default;
1087 validator_chain_adaptor(validator_chain_adaptor &&) =
default;
1088 validator_chain_adaptor & operator=(validator_chain_adaptor &&) =
default;
1094 validator_chain_adaptor(validator1_type vali1_, validator2_type vali2_) :
1095 vali1{std::
move(vali1_)},
1096 vali2{std::
move(vali2_)}
1100 ~validator_chain_adaptor() =
default;
1111 template <
typename cmp_type>
1112 requires std::invocable<validator1_type, cmp_type const> && std::invocable<validator2_type, cmp_type const>
1113 void operator()(cmp_type
const & cmp)
const
1122 return vali1.get_help_page_message() +
" " + vali2.get_help_page_message();
1127 validator1_type vali1;
1129 validator2_type vali2;
1165template <val
idator val
idator1_type, val
idator val
idator2_type>
1166 requires std::common_with<typename std::remove_reference_t<validator1_type>::option_value_type,
1168auto operator|(validator1_type && vali1, validator2_type && vali2)
1170 return detail::validator_chain_adaptor{std::forward<validator1_type>(vali1), std::forward<validator2_type>(vali2)};
A validator that checks whether a number is inside a given range.
Definition: validators.hpp:80
std::string get_help_page_message() const
Returns a message that can be appended to the (positional) options help page info.
Definition: validators.hpp:137
void operator()(option_value_type const &cmp) const
Tests whether cmp lies inside [min, max].
Definition: validators.hpp:105
option_value_t option_value_type
The type of value that this validator invoked upon.
Definition: validators.hpp:83
arithmetic_range_validator(option_value_type const min_, option_value_type const max_)
The constructor.
Definition: validators.hpp:92
void operator()(range_type const &range) const
Tests whether every element in range lies inside [min, max].
Definition: validators.hpp:122
An abstract base class for the file and directory validators.
Definition: validators.hpp:312
file_validator_base()=default
Defaulted.
std::vector< std::string > extensions
Stores the extensions.
Definition: validators.hpp:483
void validate_readability(std::filesystem::path const &path) const
Checks if the given path is readable.
Definition: validators.hpp:411
void validate_filename(std::filesystem::path const &path) const
Validates the given filename path based on the specified extensions.
Definition: validators.hpp:368
virtual void operator()(std::filesystem::path const &path) const =0
Tests if the given path is a valid input, respectively output, file or directory.
file_validator_base & operator=(file_validator_base const &)=default
Defaulted.
std::string extensions_str
The extension range as a std:;string for pretty printing.
Definition: validators.hpp:486
virtual ~file_validator_base()=default
std::string valid_extensions_help_page_message() const
Returns the information of valid file extensions.
Definition: validators.hpp:454
bool case_insensitive_string_ends_with(std::string_view str, std::string_view suffix) const
Helper function that checks if a string is a suffix of another string. Case insensitive.
Definition: validators.hpp:467
std::string option_value_type
Type of values that are tested by validator.
Definition: validators.hpp:315
file_validator_base(file_validator_base const &)=default
Defaulted.
file_validator_base(file_validator_base &&)=default
Defaulted.
file_validator_base & operator=(file_validator_base &&)=default
Defaulted.
void validate_writeability(std::filesystem::path const &path) const
Checks if the given path is writable.
Definition: validators.hpp:438
A validator that checks if a given path is a valid output directory.
Definition: validators.hpp:867
output_directory_validator(output_directory_validator &&)=default
Defaulted.
output_directory_validator(output_directory_validator const &)=default
Defaulted.
output_directory_validator & operator=(output_directory_validator &&)=default
Defaulted.
virtual void operator()(std::filesystem::path const &dir) const override
Tests whether path is writable.
Definition: validators.hpp:897
virtual ~output_directory_validator()=default
Virtual Destructor.
output_directory_validator & operator=(output_directory_validator const &)=default
Defaulted.
output_directory_validator()=default
Defaulted.
std::string get_help_page_message() const
Returns a message that can be appended to the (positional) options help page info.
Definition: validators.hpp:937
A validator that checks if a given path is a valid output file.
Definition: validators.hpp:632
output_file_validator()=default
Defaulted.
output_file_validator(auto &&... extensions)
Constructs from a parameter pack of valid extensions.
Definition: validators.hpp:693
std::string get_help_page_message() const
Returns a message that can be appended to the (positional) options help page info.
Definition: validators.hpp:742
virtual void operator()(std::filesystem::path const &file) const override
Tests whether path is does not already exists and is writable.
Definition: validators.hpp:713
virtual ~output_file_validator()=default
Virtual Destructor.
output_file_validator(output_file_validator &&)=default
Defaulted.
output_file_validator(std::vector< std::string > const &extensions)
Constructs from a list of valid extensions.
Definition: validators.hpp:682
output_file_validator(output_file_open_options const mode, auto &&... extensions)
Constructs from a given overwrite mode and a parameter pack of valid extensions.
Definition: validators.hpp:671
output_file_validator(output_file_open_options const mode, std::vector< std::string > const &extensions)
Constructs from a given overwrite mode and a list of valid extensions.
Definition: validators.hpp:655
output_file_validator & operator=(output_file_validator const &)=default
Defaulted.
output_file_validator(output_file_validator const &)=default
Defaulted.
output_file_validator & operator=(output_file_validator &&)=default
Defaulted.
A validator that checks if a matches a regular expression pattern.
Definition: validators.hpp:965
void operator()(range_type const &v) const
Tests whether every entry in list v matches the pattern.
Definition: validators.hpp:1004
std::string get_help_page_message() const
Returns a message that can be appended to the (positional) options help page info.
Definition: validators.hpp:1018
void operator()(option_value_type const &cmp) const
Tests whether cmp lies inside values.
Definition: validators.hpp:986
regex_validator(std::string const &pattern_)
Constructing from a vector.
Definition: validators.hpp:976
Parser exception thrown when an argument could not be casted to the according type.
Definition: exceptions.hpp:183
A validator that checks whether a value is inside a list of valid values.
Definition: validators.hpp:176
void operator()(range_type const &range) const
Tests whether every element in range lies inside values.
Definition: validators.hpp:245
value_list_validator(option_type, option_types...) -> value_list_validator< option_type >
Deduction guide for a parameter pack.
value_list_validator & operator=(value_list_validator const &)=default
Defaulted.
value_list_validator(value_list_validator const &)=default
Defaulted.
option_value_t option_value_type
Type of values that are tested by validator.
Definition: validators.hpp:179
value_list_validator()=default
Defaulted.
value_list_validator(range_type rng)
Constructing from a range.
Definition: validators.hpp:201
std::string get_help_page_message() const
Returns a message that can be appended to the (positional) options help page info.
Definition: validators.hpp:260
value_list_validator(value_list_validator &&)=default
Defaulted.
void operator()(option_value_type const &cmp) const
Tests whether cmp lies inside values.
Definition: validators.hpp:229
value_list_validator(range_type &&rng) -> value_list_validator< std::string >
Deduction guide for ranges over a value type convertible to std::string.
value_list_validator(option_type, option_types...) -> value_list_validator< std::string >
Given a parameter pack of types that are convertible to std::string, delegate to value type std::stri...
~value_list_validator()=default
Defaulted.
value_list_validator & operator=(value_list_validator &&)=default
Defaulted.
value_list_validator(option_types &&... opts)
Constructing from a parameter pack.
Definition: validators.hpp:216
value_list_validator(range_type &&rng) -> value_list_validator< std::ranges::range_value_t< range_type > >
Deduction guide for ranges.
The concept for option validators passed to add_option/positional_option.
Definition: validators.hpp:50
T create_directory(T... args)
T emplace_back(T... args)
Provides parser related exceptions.
auto operator|(validator1_type &&vali1, validator2_type &&vali2)
Enables the chaining of validators.
Definition: validators.hpp:1168
T has_extension(T... args)
T is_directory(T... args)
T is_regular_file(T... args)
Provides sharg::detail::safe_filesystem_entry.
Provides sharg::detail::to_string.
output_file_open_options
Mode of an output file: Determines whether an existing file can be (silently) overwritten.
Definition: validators.hpp:597
@ create_new
Forbid overwriting the output file.
@ open_or_create
Allow to overwrite the output file.