Commit 3006f82bf62377efd1f49318c35f0b5281e732c7

Authored by Henry Fredrick Schreiner
Committed by Henry Schreiner
1 parent 94b70c8f

Making validators run before and with a reference

include/CLI/Option.hpp
... ... @@ -148,7 +148,7 @@ class Option : public OptionBase<Option> {
148 148 bool changeable_{false};
149 149  
150 150 /// A list of validators to run on each value parsed
151   - std::vector<std::function<bool(std::string)>> validators_;
  151 + std::vector<std::function<bool(std::string &)>> validators_;
152 152  
153 153 /// A list of options that are required with this option
154 154 std::set<Option *> requires_;
... ... @@ -220,7 +220,7 @@ class Option : public OptionBase&lt;Option&gt; {
220 220 }
221 221  
222 222 /// Adds a validator
223   - Option *check(std::function<bool(std::string)> validator) {
  223 + Option *check(std::function<bool(std::string &)> validator) {
224 224  
225 225 validators_.push_back(validator);
226 226 return this;
... ... @@ -417,7 +417,16 @@ class Option : public OptionBase&lt;Option&gt; {
417 417 ///@{
418 418  
419 419 /// Process the callback
420   - void run_callback() const {
  420 + void run_callback() {
  421 +
  422 + // Run the validators (can change the string)
  423 + if(!validators_.empty()) {
  424 + for(std::string &result : results_)
  425 + for(const std::function<bool(std::string &)> &vali : validators_)
  426 + if(!vali(result))
  427 + throw ValidationError("Failed validation: " + get_name() + "=" + result);
  428 + }
  429 +
421 430 bool local_result;
422 431 // If take_last, only operate on the final item
423 432 if(last_) {
... ... @@ -429,13 +438,6 @@ class Option : public OptionBase&lt;Option&gt; {
429 438  
430 439 if(local_result)
431 440 throw ConversionError("Could not convert: " + get_name() + "=" + detail::join(results_));
432   -
433   - if(!validators_.empty()) {
434   - for(const std::string &result : results_)
435   - for(const std::function<bool(std::string)> &vali : validators_)
436   - if(!vali(result))
437   - throw ValidationError("Failed validation: " + get_name() + "=" + result);
438   - }
439 441 }
440 442  
441 443 /// If options share any of the same names, they are equal (not counting positional)
... ...
include/CLI/Validators.hpp
... ... @@ -23,7 +23,7 @@ namespace CLI {
23 23 /// @{
24 24  
25 25 /// Check for an existing file
26   -inline bool ExistingFile(std::string filename) {
  26 +inline bool ExistingFile(const std::string &filename) {
27 27 struct stat buffer;
28 28 bool exist = stat(filename.c_str(), &buffer) == 0;
29 29 bool is_dir = (buffer.st_mode & S_IFDIR) != 0;
... ... @@ -39,7 +39,7 @@ inline bool ExistingFile(std::string filename) {
39 39 }
40 40  
41 41 /// Check for an existing directory
42   -inline bool ExistingDirectory(std::string filename) {
  42 +inline bool ExistingDirectory(const std::string &filename) {
43 43 struct stat buffer;
44 44 bool exist = stat(filename.c_str(), &buffer) == 0;
45 45 bool is_dir = (buffer.st_mode & S_IFDIR) != 0;
... ... @@ -55,7 +55,7 @@ inline bool ExistingDirectory(std::string filename) {
55 55 }
56 56  
57 57 /// Check for a non-existing path
58   -inline bool NonexistentPath(std::string filename) {
  58 +inline bool NonexistentPath(const std::string &filename) {
59 59 struct stat buffer;
60 60 bool exist = stat(filename.c_str(), &buffer) == 0;
61 61 if(!exist) {
... ... @@ -67,7 +67,7 @@ inline bool NonexistentPath(std::string filename) {
67 67 }
68 68  
69 69 /// Produce a range validator function
70   -template <typename T> std::function<bool(std::string)> Range(T min, T max) {
  70 +template <typename T> std::function<bool(const std::string &)> Range(T min, T max) {
71 71 return [min, max](std::string input) {
72 72 T val;
73 73 detail::lexical_cast(input, val);
... ... @@ -76,7 +76,7 @@ template &lt;typename T&gt; std::function&lt;bool(std::string)&gt; Range(T min, T max) {
76 76 }
77 77  
78 78 /// Range of one value is 0 to value
79   -template <typename T> std::function<bool(std::string)> Range(T max) { return Range(static_cast<T>(0), max); }
  79 +template <typename T> std::function<bool(const std::string &)> Range(T max) { return Range(static_cast<T>(0), max); }
80 80  
81 81 /// @}
82 82  
... ...