SeqAn3  3.2.0-rc.1
The Modern C++ library for sequence analysis.
validators.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2022, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2022, Knut Reinert & MPI für molekulare Genetik
4 // This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
5 // shipped with this file and also available at: https://github.com/seqan/seqan3/blob/master/LICENSE.md
6 // -----------------------------------------------------------------------------------------------------
7 
13 #pragma once
14 
15 #include <algorithm>
16 #include <concepts>
17 #include <filesystem>
18 #include <fstream>
19 #include <ranges>
20 #include <regex>
21 #include <sstream>
22 
33 
34 namespace seqan3
35 {
36 
96 template <typename validator_type>
97 concept validator =
98  std::copyable<std::remove_cvref_t<validator_type>>
101 
102  {
103  validator(value)
104  } -> std::same_as<void>;
105  {
107  } -> std::same_as<std::string>;
108  };
110 
126 template <arithmetic option_value_t>
128 {
129 public:
131  using option_value_type = option_value_t;
132 
137  arithmetic_range_validator(option_value_type const min_, option_value_type const max_) : min{min_}, max{max_}
138  {}
139 
144  void operator()(option_value_type const & cmp) const
145  {
146  if (!((cmp <= max) && (cmp >= min)))
147  throw validation_error{detail::to_string("Value ", cmp, " is not in range [", min, ",", max, "].")};
148  }
149 
156  template <std::ranges::forward_range range_type>
158  void operator()(range_type const & range) const
159  {
160  std::for_each(range.begin(),
161  range.end(),
162  [&](auto cmp)
163  {
164  (*this)(cmp);
165  });
166  }
167 
170  {
171  return detail::to_string("Value must be in range [", min, ",", max, "].");
172  }
173 
174 private:
176  option_value_type min{};
177 
179  option_value_type max{};
180 };
181 
201 template <typename option_value_t>
203 {
204 public:
206  using option_value_type = option_value_t;
207 
211  value_list_validator() = default;
216  ~value_list_validator() = default;
217 
223  template <std::ranges::forward_range range_type>
224  requires std::constructible_from<option_value_type, std::ranges::range_rvalue_reference_t<range_type>>
225  value_list_validator(range_type rng)
226  {
227  values.clear();
228  std::ranges::move(std::move(rng), std::back_inserter(values));
229  }
230 
236  template <typename... option_types>
237  requires ((std::constructible_from<option_value_type, option_types> && ...))
238  value_list_validator(option_types &&... opts)
239  {
240  (values.emplace_back(std::forward<option_types>(opts)), ...);
241  }
243 
248  void operator()(option_value_type const & cmp) const
249  {
250  if (!(std::find(values.begin(), values.end(), cmp) != values.end()))
251  throw validation_error{detail::to_string("Value ", cmp, " is not one of ", std::views::all(values), ".")};
252  }
253 
259  template <std::ranges::forward_range range_type>
260  requires std::convertible_to<std::ranges::range_value_t<range_type>, option_value_type>
261  void operator()(range_type const & range) const
262  {
263  std::for_each(std::ranges::begin(range),
264  std::ranges::end(range),
265  [&](auto cmp)
266  {
267  (*this)(cmp);
268  });
269  }
270 
273  {
274  return detail::to_string("Value must be one of ", std::views::all(values), ".");
275  }
276 
277 private:
280 };
281 
287 template <typename option_type, typename... option_types>
288  requires (std::constructible_from<std::string, std::decay_t<option_types>> && ...
289  && std::constructible_from<std::string, std::decay_t<option_type>>)
290 value_list_validator(option_type, option_types...) -> value_list_validator<std::string>;
291 
293 template <typename range_type>
294  requires (std::ranges::forward_range<std::decay_t<range_type>>
295  && std::constructible_from<std::string, std::ranges::range_value_t<range_type>>)
296 value_list_validator(range_type && rng) -> value_list_validator<std::string>;
297 
299 template <typename option_type, typename... option_types>
300 value_list_validator(option_type, option_types...) -> value_list_validator<option_type>;
301 
303 template <typename range_type>
304  requires (std::ranges::forward_range<std::decay_t<range_type>>)
305 value_list_validator(range_type && rng) -> value_list_validator<std::ranges::range_value_t<range_type>>;
307 
323 {
324 public:
327 
331  file_validator_base() = default;
336  virtual ~file_validator_base() = default;
338 
346  virtual void operator()(std::filesystem::path const & path) const = 0;
347 
355  template <std::ranges::forward_range range_type>
356  requires (std::convertible_to<std::ranges::range_value_t<range_type>, std::filesystem::path const &>
357  && !std::convertible_to<range_type, std::filesystem::path const &>)
358  void operator()(range_type const & v) const
359  {
360  std::for_each(v.begin(),
361  v.end(),
362  [&](auto cmp)
363  {
364  this->operator()(cmp);
365  });
366  }
367 
368 protected:
374  void validate_filename(std::filesystem::path const & path) const
375  {
376  // If no valid extensions are given we can safely return here.
377  if (extensions.empty())
378  return;
379 
380  // Check if extension is available.
381  if (!path.has_extension())
382  throw validation_error{detail::to_string("The given filename ",
383  path.string(),
384  " has no extension. Expected"
385  " one of the following valid extensions:",
386  extensions,
387  "!")};
388 
389  std::string file_path{path.filename().string()};
390 
391  // Leading dot indicates a hidden file is not part of the extension.
392  if (file_path.front() == '.')
393  file_path.erase(0, 1);
394 
395  // Store a string_view containing all extensions for a better error message.
396  std::string const all_extensions{file_path.substr(file_path.find(".") + 1)};
397 
398  // Compares the extensions in lower case.
399  auto case_insensitive_ends_with = [&](std::string const & ext)
400  {
401  return case_insensitive_string_ends_with(file_path, ext);
402  };
403 
404  // Check if requested extension is present.
405  if (std::ranges::find_if(extensions, case_insensitive_ends_with) == extensions.end())
406  {
407  throw validation_error{detail::to_string("Expected one of the following valid extensions: ",
408  extensions,
409  "! Got ",
410  all_extensions,
411  " instead!")};
412  }
413  }
414 
421  {
422  // Check if input directory is readable.
424  {
425  std::error_code ec{};
426  std::filesystem::directory_iterator{path, ec}; // if directory iterator cannot be created, ec will be set.
427  if (static_cast<bool>(ec))
428  throw validation_error{detail::to_string("Cannot read the directory ", path, "!")};
429  }
430  else
431  {
432  // Must be a regular file.
434  throw validation_error{detail::to_string("Expected a regular file ", path, "!")};
435 
436  std::ifstream file{path};
437  if (!file.is_open() || !file.good())
438  throw validation_error{detail::to_string("Cannot read the file ", path, "!")};
439  }
440  }
441 
448  {
449  std::ofstream file{path};
450  detail::safe_filesystem_entry file_guard{path};
451 
452  bool is_open = file.is_open();
453  bool is_good = file.good();
454  file.close();
455 
456  if (!is_good || !is_open)
457  throw validation_error{detail::to_string("Cannot write ", path, "!")};
458 
459  file_guard.remove();
460  }
461 
464  {
465  if (extensions.empty())
466  return "";
467  else
468  return detail::to_string(" Valid file extensions are: [",
469  extensions | views::join_with(std::string{", "}),
470  "].");
471  }
472 
479  {
480  size_t const suffix_length{suffix.size()};
481  size_t const str_length{str.size()};
482  return suffix_length > str_length ? false
483  : std::ranges::equal(str.substr(str_length - suffix_length),
484  suffix,
485  [](char const chr1, char const chr2)
486  {
487  return std::tolower(chr1) == std::tolower(chr2);
488  });
489  }
490 
493 };
494 
519 template <typename file_t = void>
521 {
522 public:
523  static_assert(std::same_as<file_t, void> || detail::has_type_valid_formats<file_t>,
524  "Expected either a template type with a static member called valid_formats (a file type) or void.");
525 
526  // Import from base class.
528 
542  {
543  if constexpr (!std::same_as<file_t, void>)
544  file_validator_base::extensions = detail::valid_file_extensions<typename file_t::valid_formats>();
545  }
546 
551  virtual ~input_file_validator() = default;
552 
562  requires std::same_as<file_t, void>
564  {
566  }
567 
568  // Import base class constructor.
571 
572  // Import the base::operator()
573  using file_validator_base::operator();
574 
580  virtual void operator()(std::filesystem::path const & file) const override
581  {
582  try
583  {
584  if (!std::filesystem::exists(file))
585  throw validation_error{detail::to_string("The file ", file, " does not exist!")};
586 
587  // Check if file is regular and can be opened for reading.
588  validate_readability(file);
589 
590  // Check extension.
591  validate_filename(file);
592  }
593  // LCOV_EXCL_START
595  {
596  std::throw_with_nested(validation_error{"Unhandled filesystem error!"});
597  }
598  // LCOV_EXCL_STOP
599  catch (...)
600  {
602  }
603  }
604 
607  {
608  return "The input file must exist and read permissions must be granted." + valid_extensions_help_page_message();
609  }
610 };
611 
614 {
618  create_new
619 };
620 
649 template <typename file_t = void>
651 {
652 public:
653  static_assert(std::same_as<file_t, void> || detail::has_type_valid_formats<file_t>,
654  "Expected either a template type with a static member called valid_formats (a file type) or void.");
655 
656  // Import from base class.
658 
665  {}
666 
671  virtual ~output_file_validator() = default;
672 
682  mode{mode}
683  {
685  }
686 
687  // Import base constructor.
690 
700  {
701  if constexpr (!std::same_as<file_t, void>)
702  return detail::valid_file_extensions<typename file_t::valid_formats>();
703  return {};
704  }
705 
706  // Import the base::operator()
707  using file_validator_base::operator();
708 
714  virtual void operator()(std::filesystem::path const & file) const override
715  {
716  try
717  {
719  throw validation_error{detail::to_string("The file ", file, " already exists!")};
720 
721  // Check if file has any write permissions.
722  validate_writeability(file);
723 
724  validate_filename(file);
725  }
726  // LCOV_EXCL_START
728  {
729  std::throw_with_nested(validation_error{"Unhandled filesystem error!"});
730  }
731  // LCOV_EXCL_STOP
732  catch (...)
733  {
735  }
736  }
737 
740  {
742  return "Write permissions must be granted." + valid_extensions_help_page_message();
743  else // mode == create_new
744  return "The output file must not exist already and write permissions must be granted."
746  }
747 
748 private:
751 };
752 
770 {
771 public:
772  // Import from base class.
774 
783  virtual ~input_directory_validator() = default;
784 
785  // Import base constructor.
788 
789  // Import the base::operator()
790  using file_validator_base::operator();
791 
797  virtual void operator()(std::filesystem::path const & dir) const override
798  {
799  try
800  {
801  if (!std::filesystem::exists(dir))
802  throw validation_error{detail::to_string("The directory ", dir, " does not exists!")};
803 
805  throw validation_error{detail::to_string("The path ", dir, " is not a directory!")};
806 
807  // Check if directory has any read permissions.
809  }
810  // LCOV_EXCL_START
812  {
813  std::throw_with_nested(validation_error{"Unhandled filesystem error!"});
814  }
815  // LCOV_EXCL_STOP
816  catch (...)
817  {
819  }
820  }
821 
824  {
825  return detail::to_string("An existing, readable path for the input directory.");
826  }
827 };
828 
846 {
847 public:
848  // Imported from base class.
850 
859  virtual ~output_directory_validator() = default;
860 
861  // Import base constructor.
864 
865  // Import the base::operator().
866  using file_validator_base::operator();
867 
873  virtual void operator()(std::filesystem::path const & dir) const override
874  {
875  bool dir_exists = std::filesystem::exists(dir);
876  // Make sure the created dir is deleted after we are done.
877  std::error_code ec;
878  std::filesystem::create_directory(dir, ec); // does nothing and is not treated as error if path already exists.
879  // if error code was set or if dummy.txt could not be created within the output dir, throw an error.
880  if (static_cast<bool>(ec))
881  throw validation_error{detail::to_string("Cannot create directory: ", dir, "!")};
882 
883  try
884  {
885  if (!dir_exists)
886  {
887  detail::safe_filesystem_entry dir_guard{dir};
888  validate_writeability(dir / "dummy.txt");
889  dir_guard.remove_all();
890  }
891  else
892  {
893  validate_writeability(dir / "dummy.txt");
894  }
895  }
896  // LCOV_EXCL_START
898  {
899  std::throw_with_nested(validation_error{"Unhandled filesystem error!"});
900  }
901  // LCOV_EXCL_STOP
902  catch (...)
903  {
905  }
906  }
907 
910  {
911  return detail::to_string("A valid path for the output directory.");
912  }
913 };
914 
935 {
936 public:
939 
943  regex_validator(std::string const & pattern_) : pattern{pattern_}
944  {}
945 
950  void operator()(option_value_type const & cmp) const
951  {
952  std::regex rgx(pattern);
953  if (!std::regex_match(cmp, rgx))
954  throw validation_error{detail::to_string("Value ", cmp, " did not match the pattern ", pattern, ".")};
955  }
956 
963  template <std::ranges::forward_range range_type>
964  requires std::convertible_to<std::ranges::range_reference_t<range_type>, option_value_type const &>
965  void operator()(range_type const & v) const
966  {
967  for (auto && file_name : v)
968  {
969  // note: we explicitly copy/construct any reference type other than `std::string &`
970  (*this)(static_cast<option_value_type const &>(file_name));
971  }
972  }
973 
976  {
977  return detail::to_string("Value must match the pattern '", pattern, "'.");
978  }
979 
980 private:
982  std::string pattern;
983 };
984 
985 namespace detail
986 {
987 
1000 template <typename option_value_t>
1001 struct default_validator
1002 {
1004  using option_value_type = option_value_t;
1005 
1007  void operator()(option_value_t const & /*cmp*/) const noexcept
1008  {}
1009 
1012  {
1013  return "";
1014  }
1015 };
1016 
1030 template <validator validator1_type, validator validator2_type>
1031  requires std::common_with<typename validator1_type::option_value_type, typename validator2_type::option_value_type>
1032 class validator_chain_adaptor
1033 {
1034 public:
1036  using option_value_type =
1038 
1042  validator_chain_adaptor() = delete;
1043  validator_chain_adaptor(validator_chain_adaptor const & pf) = default;
1044  validator_chain_adaptor & operator=(validator_chain_adaptor const & pf) = default;
1045  validator_chain_adaptor(validator_chain_adaptor &&) = default;
1046  validator_chain_adaptor & operator=(validator_chain_adaptor &&) = default;
1047 
1052  validator_chain_adaptor(validator1_type vali1_, validator2_type vali2_) :
1053  vali1{std::move(vali1_)},
1054  vali2{std::move(vali2_)}
1055  {}
1056 
1058  ~validator_chain_adaptor() = default;
1060 
1069  template <typename cmp_type>
1070  requires std::invocable<validator1_type, cmp_type const> && std::invocable<validator2_type, cmp_type const>
1071  void operator()(cmp_type const & cmp) const
1072  {
1073  vali1(cmp);
1074  vali2(cmp);
1075  }
1076 
1079  {
1080  return detail::to_string(vali1.get_help_page_message(), " ", vali2.get_help_page_message());
1081  }
1082 
1083 private:
1085  validator1_type vali1;
1087  validator2_type vali2;
1088 };
1089 
1090 } // namespace detail
1091 
1121 template <validator validator1_type, validator validator2_type>
1122  requires std::common_with<typename std::remove_reference_t<validator1_type>::option_value_type,
1124 auto operator|(validator1_type && vali1, validator2_type && vali2)
1125 {
1126  return detail::validator_chain_adaptor{std::forward<validator1_type>(vali1), std::forward<validator2_type>(vali2)};
1127 }
1128 
1129 } // namespace seqan3
T back_inserter(T... args)
Provides various type traits on generic types.
T begin(T... args)
A validator that checks whether a number is inside a given range.
Definition: validators.hpp:128
requires arithmetic< std::ranges::range_value_t< range_type > > void operator()(range_type const &range) const
Tests whether every element in range lies inside [min, max].
Definition: validators.hpp:158
void operator()(option_value_type const &cmp) const
Tests whether cmp lies inside [min, max].
Definition: validators.hpp:144
option_value_t option_value_type
The type of value that this validator invoked upon.
Definition: validators.hpp:131
std::string get_help_page_message() const
Returns a message that can be appended to the (positional) options help page info.
Definition: validators.hpp:169
arithmetic_range_validator(option_value_type const min_, option_value_type const max_)
The constructor.
Definition: validators.hpp:137
An abstract base class for the file and directory validators.
Definition: validators.hpp:323
file_validator_base & operator=(file_validator_base &&)=default
Defaulted.
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:478
void validate_filename(std::filesystem::path const &path) const
Validates the given filename path based on the specified extensions.
Definition: validators.hpp:374
file_validator_base & operator=(file_validator_base const &)=default
Defaulted.
std::string valid_extensions_help_page_message() const
Returns the information of valid file extensions.
Definition: validators.hpp:463
virtual void operator()(std::filesystem::path const &path) const =0
Tests if the given path is a valid input, respectively output, file or directory.
std::string option_value_type
Type of values that are tested by validator.
Definition: validators.hpp:326
file_validator_base(file_validator_base &&)=default
Defaulted.
void validate_readability(std::filesystem::path const &path) const
Checks if the given path is readable.
Definition: validators.hpp:420
file_validator_base()=default
Defaulted.
requires(std::convertible_to< std::ranges::range_value_t< range_type >, std::filesystem::path const & > &&!std::convertible_to< range_type, std::filesystem::path const & >) void operator()(range_type const &v) const
Tests whether every path in list v passes validation. See operator()(option_value_type const & value)...
Definition: validators.hpp:356
file_validator_base(file_validator_base const &)=default
Defaulted.
std::vector< std::string > extensions
Stores the extensions.
Definition: validators.hpp:492
virtual ~file_validator_base()=default
void validate_writeability(std::filesystem::path const &path) const
Checks if the given path is writable.
Definition: validators.hpp:447
A validator that checks if a given path is a valid input directory.
Definition: validators.hpp:770
input_directory_validator(input_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:823
input_directory_validator & operator=(input_directory_validator &&)=default
Defaulted.
input_directory_validator()=default
Defaulted.
input_directory_validator & operator=(input_directory_validator const &)=default
Defaulted.
input_directory_validator(input_directory_validator const &)=default
Defaulted.
virtual void operator()(std::filesystem::path const &dir) const override
Tests whether path is an existing directory and is readable.
Definition: validators.hpp:797
virtual ~input_directory_validator()=default
Virtual Destructor.
A validator that checks if a given path is a valid input file.
Definition: validators.hpp:521
input_file_validator(input_file_validator const &)=default
Defaulted.
virtual ~input_file_validator()=default
Virtual destructor.
std::string get_help_page_message() const
Returns a message that can be appended to the (positional) options help page info.
Definition: validators.hpp:606
input_file_validator(std::vector< std::string > extensions) requires std
Constructs from a given collection of valid extensions.
Definition: validators.hpp:561
input_file_validator(input_file_validator &&)=default
Defaulted.
input_file_validator & operator=(input_file_validator &&)=default
Defaulted.
virtual void operator()(std::filesystem::path const &file) const override
Tests whether path is an existing regular file and is readable.
Definition: validators.hpp:580
input_file_validator()
Default constructor.
Definition: validators.hpp:541
input_file_validator & operator=(input_file_validator const &)=default
Defaulted.
A validator that checks if a given path is a valid output directory.
Definition: validators.hpp:846
output_directory_validator()=default
Defaulted.
output_directory_validator & operator=(output_directory_validator const &)=default
Defaulted.
virtual ~output_directory_validator()=default
Virtual Destructor.
output_directory_validator(output_directory_validator &&)=default
Defaulted.
output_directory_validator(output_directory_validator const &)=default
Defaulted.
virtual void operator()(std::filesystem::path const &dir) const override
Tests whether path is writable.
Definition: validators.hpp:873
output_directory_validator & operator=(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:909
A validator that checks if a given path is a valid output file.
Definition: validators.hpp:651
output_file_validator(output_file_validator &&)=default
Defaulted.
output_file_validator(output_file_validator const &)=default
Defaulted.
output_file_validator & operator=(output_file_validator const &)=default
Defaulted.
virtual void operator()(std::filesystem::path const &file) const override
Tests whether path is does not already exists and is writable.
Definition: validators.hpp:714
static std::vector< std::string > default_extensions()
The default extensions of file_t.
Definition: validators.hpp:699
output_file_validator()
Default constructor.
Definition: validators.hpp:664
output_file_validator & operator=(output_file_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:739
virtual ~output_file_validator()=default
Virtual Destructor.
output_file_validator(output_file_open_options const mode, std::vector< std::string > extensions=default_extensions())
Constructs from a given overwrite mode and a list of valid extensions.
Definition: validators.hpp:679
A validator that checks if a matches a regular expression pattern.
Definition: validators.hpp:935
std::string get_help_page_message() const
Returns a message that can be appended to the (positional) options help page info.
Definition: validators.hpp:975
void operator()(option_value_type const &cmp) const
Tests whether cmp lies inside values.
Definition: validators.hpp:950
requires std::convertible_to< std::ranges::range_reference_t< range_type >, option_value_type const & > void operator()(range_type const &v) const
Tests whether every filename in list v matches the pattern.
Definition: validators.hpp:965
std::string option_value_type
Type of values that are tested by validator.
Definition: validators.hpp:938
regex_validator(std::string const &pattern_)
Constructing from a vector.
Definition: validators.hpp:943
Argument parser exception thrown when an argument could not be casted to the according type.
Definition: exceptions.hpp:131
A validator that checks whether a value is inside a list of valid values.
Definition: validators.hpp:203
requires(std::constructible_from< std::string, std::decay_t< option_types >> &&... &&std::constructible_from< std::string, std::decay_t< option_type >>) value_list_validator(option_type
Type deduction guides.
requires((std::constructible_from< option_value_type, option_types > &&...)) value_list_validator(option_types &&... opts)
Constructing from a parameter pack.
Definition: validators.hpp:237
value_list_validator()=default
Defaulted.
requires std::constructible_from< option_value_type, std::ranges::range_rvalue_reference_t< range_type > > value_list_validator(range_type rng)
Constructing from a range.
Definition: validators.hpp:225
void operator()(option_value_type const &cmp) const
Tests whether cmp lies inside values.
Definition: validators.hpp:248
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:206
std::string get_help_page_message() const
Returns a message that can be appended to the (positional) options help page info.
Definition: validators.hpp:272
value_list_validator & operator=(value_list_validator &&)=default
Defaulted.
value_list_validator(value_list_validator &&)=default
Defaulted.
~value_list_validator()=default
Defaulted.
requires std::convertible_to< std::ranges::range_value_t< range_type >, option_value_type > void operator()(range_type const &range) const
Tests whether every element in range lies inside values.
Definition: validators.hpp:261
value_list_validator & operator=(value_list_validator const &)=default
Defaulted.
T clear(T... args)
The <concepts> header from C++20's standard library.
T create_directory(T... args)
T current_exception(T... args)
T emplace_back(T... args)
T end(T... args)
Provides parser related exceptions.
T exists(T... args)
T filename(T... args)
T find(T... args)
T for_each(T... args)
requires requires
The rank_type of the semi-alphabet; defined as the return type of seqan3::to_rank....
Definition: alphabet/concept.hpp:164
requires std::common_with< typename std::remove_reference_t< validator1_type >::option_value_type, typename std::remove_reference_t< validator2_type >::option_value_type > auto operator|(validator1_type &&vali1, validator2_type &&vali2)
Enables the chaining of validators.
Definition: validators.hpp:1124
constexpr ptrdiff_t find_if
Get the index of the first type in a pack that satisfies the given predicate.
Definition: type_pack/traits.hpp:205
constexpr auto join_with
A view adaptor that represents view consisting of the sequence obtained from flattening a view of ran...
Definition: join_with.hpp:531
T has_extension(T... args)
A type that satisfies std::is_arithmetic_v<t>.
The concept for option validators passed to add_option/positional_option.
void operator()(option_value_type const &cmp) const
Validates the value 'cmp' and throws a seqan3::validation_error on failure.
std::string get_help_page_message() const
Returns a message that can be appended to the (positional) options help page info.
using option_value_type
The type of value on which the validator is called on.
Provides various utility functions.
T is_directory(T... args)
T is_regular_file(T... args)
Provides seqan3::views::join_with.
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
output_file_open_options
Mode of an output file: Determines whether an existing file can be (silently) overwritten.
Definition: validators.hpp:614
@ create_new
Forbid overwriting the output file.
@ open_or_create
Allow to overwrite the output file.
SeqAn specific customisations in the standard namespace.
Provides seqan3::debug_stream and related types.
The <ranges> header from C++20's standard library.
T regex_match(T... args)
T rethrow_exception(T... args)
Provides seqan3::detail::safe_filesystem_entry.
T size(T... args)
T substr(T... args)
T throw_with_nested(T... args)
Auxiliary for pretty printing of exception messages.
Provides traits for seqan3::type_list.
Provides various traits for template packs.
Provides concepts that do not have equivalents in C++20.