CLI11  1.9.1
Option.hpp
Go to the documentation of this file.
1 // Copyright (c) 2017-2020, University of Cincinnati, developed by Henry Schreiner
2 // under NSF AWARD 1414736 and by the respective contributors.
3 // All rights reserved.
4 //
5 // SPDX-License-Identifier: BSD-3-Clause
6 
7 #pragma once
8 
9 #include <algorithm>
10 #include <functional>
11 #include <memory>
12 #include <set>
13 #include <string>
14 #include <tuple>
15 #include <utility>
16 #include <vector>
17 
18 #include "Error.hpp"
19 #include "Macros.hpp"
20 #include "Split.hpp"
21 #include "StringTools.hpp"
22 #include "Validators.hpp"
23 
24 namespace CLI {
25 
26 using results_t = std::vector<std::string>;
28 using callback_t = std::function<bool(const results_t &)>;
29 
30 class Option;
31 class App;
32 
33 using Option_p = std::unique_ptr<Option>;
35 enum class MultiOptionPolicy : char {
36  Throw,
37  TakeLast,
38  TakeFirst,
39  Join,
40  TakeAll
41 };
42 
45 template <typename CRTP> class OptionBase {
46  friend App;
47 
48  protected:
50  std::string group_ = std::string("Options");
51 
53  bool required_{false};
54 
56  bool ignore_case_{false};
57 
59  bool ignore_underscore_{false};
60 
62  bool configurable_{true};
63 
66 
68  char delimiter_{'\0'};
69 
72 
75 
77  template <typename T> void copy_to(T *other) const {
78  other->group(group_);
79  other->required(required_);
80  other->ignore_case(ignore_case_);
81  other->ignore_underscore(ignore_underscore_);
82  other->configurable(configurable_);
83  other->disable_flag_override(disable_flag_override_);
84  other->delimiter(delimiter_);
85  other->always_capture_default(always_capture_default_);
86  other->multi_option_policy(multi_option_policy_);
87  }
88 
89  public:
90  // setters
91 
93  CRTP *group(const std::string &name) {
94  group_ = name;
95  return static_cast<CRTP *>(this);
96  }
97 
99  CRTP *required(bool value = true) {
100  required_ = value;
101  return static_cast<CRTP *>(this);
102  }
103 
105  CRTP *mandatory(bool value = true) { return required(value); }
106 
107  CRTP *always_capture_default(bool value = true) {
108  always_capture_default_ = value;
109  return static_cast<CRTP *>(this);
110  }
111 
112  // Getters
113 
115  const std::string &get_group() const { return group_; }
116 
118  bool get_required() const { return required_; }
119 
121  bool get_ignore_case() const { return ignore_case_; }
122 
124  bool get_ignore_underscore() const { return ignore_underscore_; }
125 
127  bool get_configurable() const { return configurable_; }
128 
131 
133  char get_delimiter() const { return delimiter_; }
134 
137 
140 
141  // Shortcuts for multi option policy
142 
144  CRTP *take_last() {
145  auto self = static_cast<CRTP *>(this);
147  return self;
148  }
149 
151  CRTP *take_first() {
152  auto self = static_cast<CRTP *>(this);
154  return self;
155  }
156 
158  CRTP *take_all() {
159  auto self = static_cast<CRTP *>(this);
161  return self;
162  }
163 
165  CRTP *join() {
166  auto self = static_cast<CRTP *>(this);
168  return self;
169  }
170 
172  CRTP *join(char delim) {
173  auto self = static_cast<CRTP *>(this);
174  self->delimiter_ = delim;
175  self->multi_option_policy(MultiOptionPolicy::Join);
176  return self;
177  }
178 
180  CRTP *configurable(bool value = true) {
181  configurable_ = value;
182  return static_cast<CRTP *>(this);
183  }
184 
186  CRTP *delimiter(char value = '\0') {
187  delimiter_ = value;
188  return static_cast<CRTP *>(this);
189  }
190 };
191 
194 class OptionDefaults : public OptionBase<OptionDefaults> {
195  public:
196  OptionDefaults() = default;
197 
198  // Methods here need a different implementation if they are Option vs. OptionDefault
199 
202  multi_option_policy_ = value;
203  return this;
204  }
205 
207  OptionDefaults *ignore_case(bool value = true) {
208  ignore_case_ = value;
209  return this;
210  }
211 
213  OptionDefaults *ignore_underscore(bool value = true) {
214  ignore_underscore_ = value;
215  return this;
216  }
217 
219  OptionDefaults *disable_flag_override(bool value = true) {
220  disable_flag_override_ = value;
221  return this;
222  }
223 
225  OptionDefaults *delimiter(char value = '\0') {
226  delimiter_ = value;
227  return this;
228  }
229 };
230 
231 class Option : public OptionBase<Option> {
232  friend App;
233 
234  protected:
237 
239  std::vector<std::string> snames_{};
240 
242  std::vector<std::string> lnames_{};
243 
246  std::vector<std::pair<std::string, std::string>> default_flag_values_{};
247 
249  std::vector<std::string> fnames_{};
250 
252  std::string pname_{};
253 
255  std::string envname_{};
256 
260 
262  std::string description_{};
263 
265  std::string default_str_{};
266 
270  std::function<std::string()> type_name_{[]() { return std::string(); }};
271 
273  std::function<std::string()> default_function_{};
274 
278 
284 
289 
291  std::vector<Validator> validators_{};
292 
294  std::set<Option *> needs_{};
295 
297  std::set<Option *> excludes_{};
298 
302 
304  App *parent_{nullptr};
305 
308 
312 
318  enum class option_state {
319  parsing = 0,
320  validated = 2,
321  reduced = 4,
322  callback_run = 6,
323  };
327  bool allow_extra_args_{false};
329  bool flag_like_{false};
333 
335  Option(std::string option_name, std::string option_description, callback_t callback, App *parent)
336  : description_(std::move(option_description)), parent_(parent), callback_(std::move(callback)) {
337  std::tie(snames_, lnames_, pname_) = detail::get_names(detail::split_names(option_name));
338  }
339 
340  public:
343 
344  Option(const Option &) = delete;
345  Option &operator=(const Option &) = delete;
346 
348  std::size_t count() const { return results_.size(); }
349 
351  bool empty() const { return results_.empty(); }
352 
354  explicit operator bool() const { return !empty(); }
355 
357  void clear() {
358  results_.clear();
360  }
361 
365 
367  Option *expected(int value) {
368  if(value < 0) {
369  expected_min_ = -value;
372  }
373  allow_extra_args_ = true;
374  flag_like_ = false;
375  } else if(value == detail::expected_max_vector_size) {
376  expected_min_ = 1;
378  allow_extra_args_ = true;
379  flag_like_ = false;
380  } else {
381  expected_min_ = value;
382  expected_max_ = value;
383  flag_like_ = (expected_min_ == 0);
384  }
385  return this;
386  }
387 
389  Option *expected(int value_min, int value_max) {
390  if(value_min < 0) {
391  value_min = -value_min;
392  }
393 
394  if(value_max < 0) {
396  }
397  if(value_max < value_min) {
398  expected_min_ = value_max;
399  expected_max_ = value_min;
400  } else {
401  expected_max_ = value_max;
402  expected_min_ = value_min;
403  }
404 
405  return this;
406  }
409  Option *allow_extra_args(bool value = true) {
410  allow_extra_args_ = value;
411  return this;
412  }
414  bool get_allow_extra_args() const { return allow_extra_args_; }
415 
418  Option *run_callback_for_default(bool value = true) {
420  return this;
421  }
424 
426  Option *check(Validator validator, const std::string &validator_name = "") {
427  validator.non_modifying();
428  validators_.push_back(std::move(validator));
429  if(!validator_name.empty())
430  validators_.back().name(validator_name);
431  return this;
432  }
433 
435  Option *check(std::function<std::string(const std::string &)> Validator,
436  std::string Validator_description = "",
437  std::string Validator_name = "") {
438  validators_.emplace_back(Validator, std::move(Validator_description), std::move(Validator_name));
439  validators_.back().non_modifying();
440  return this;
441  }
442 
444  Option *transform(Validator Validator, const std::string &Validator_name = "") {
445  validators_.insert(validators_.begin(), std::move(Validator));
446  if(!Validator_name.empty())
447  validators_.front().name(Validator_name);
448  return this;
449  }
450 
452  Option *transform(const std::function<std::string(std::string)> &func,
453  std::string transform_description = "",
454  std::string transform_name = "") {
455  validators_.insert(validators_.begin(),
456  Validator(
457  [func](std::string &val) {
458  val = func(val);
459  return std::string{};
460  },
461  std::move(transform_description),
462  std::move(transform_name)));
463 
464  return this;
465  }
466 
468  Option *each(const std::function<void(std::string)> &func) {
469  validators_.emplace_back(
470  [func](std::string &inout) {
471  func(inout);
472  return std::string{};
473  },
474  std::string{});
475  return this;
476  }
478  Validator *get_validator(const std::string &Validator_name = "") {
479  for(auto &Validator : validators_) {
480  if(Validator_name == Validator.get_name()) {
481  return &Validator;
482  }
483  }
484  if((Validator_name.empty()) && (!validators_.empty())) {
485  return &(validators_.front());
486  }
487  throw OptionNotFound(std::string{"Validator "} + Validator_name + " Not Found");
488  }
489 
491  Validator *get_validator(int index) {
492  // This is an signed int so that it is not equivalent to a pointer.
493  if(index >= 0 && index < static_cast<int>(validators_.size())) {
494  return &(validators_[static_cast<decltype(validators_)::size_type>(index)]);
495  }
496  throw OptionNotFound("Validator index is not valid");
497  }
498 
500  Option *needs(Option *opt) {
501  if(opt != this) {
502  needs_.insert(opt);
503  }
504  return this;
505  }
506 
508  template <typename T = App> Option *needs(std::string opt_name) {
509  auto opt = static_cast<T *>(parent_)->get_option_no_throw(opt_name);
510  if(opt == nullptr) {
511  throw IncorrectConstruction::MissingOption(opt_name);
512  }
513  return needs(opt);
514  }
515 
517  template <typename A, typename B, typename... ARG> Option *needs(A opt, B opt1, ARG... args) {
518  needs(opt);
519  return needs(opt1, args...);
520  }
521 
523  bool remove_needs(Option *opt) {
524  auto iterator = std::find(std::begin(needs_), std::end(needs_), opt);
525 
526  if(iterator == std::end(needs_)) {
527  return false;
528  }
529  needs_.erase(iterator);
530  return true;
531  }
532 
535  if(opt == this) {
536  throw(IncorrectConstruction("and option cannot exclude itself"));
537  }
538  excludes_.insert(opt);
539 
540  // Help text should be symmetric - excluding a should exclude b
541  opt->excludes_.insert(this);
542 
543  // Ignoring the insert return value, excluding twice is now allowed.
544  // (Mostly to allow both directions to be excluded by user, even though the library does it for you.)
545 
546  return this;
547  }
548 
550  template <typename T = App> Option *excludes(std::string opt_name) {
551  auto opt = static_cast<T *>(parent_)->get_option_no_throw(opt_name);
552  if(opt == nullptr) {
553  throw IncorrectConstruction::MissingOption(opt_name);
554  }
555  return excludes(opt);
556  }
557 
559  template <typename A, typename B, typename... ARG> Option *excludes(A opt, B opt1, ARG... args) {
560  excludes(opt);
561  return excludes(opt1, args...);
562  }
563 
565  bool remove_excludes(Option *opt) {
566  auto iterator = std::find(std::begin(excludes_), std::end(excludes_), opt);
567 
568  if(iterator == std::end(excludes_)) {
569  return false;
570  }
571  excludes_.erase(iterator);
572  return true;
573  }
574 
576  Option *envname(std::string name) {
577  envname_ = std::move(name);
578  return this;
579  }
580 
585  template <typename T = App> Option *ignore_case(bool value = true) {
586  if(!ignore_case_ && value) {
587  ignore_case_ = value;
588  auto *parent = static_cast<T *>(parent_);
589  for(const Option_p &opt : parent->options_) {
590  if(opt.get() == this) {
591  continue;
592  }
593  auto &omatch = opt->matching_name(*this);
594  if(!omatch.empty()) {
595  ignore_case_ = false;
596  throw OptionAlreadyAdded("adding ignore case caused a name conflict with " + omatch);
597  }
598  }
599  } else {
600  ignore_case_ = value;
601  }
602  return this;
603  }
604 
609  template <typename T = App> Option *ignore_underscore(bool value = true) {
610 
611  if(!ignore_underscore_ && value) {
612  ignore_underscore_ = value;
613  auto *parent = static_cast<T *>(parent_);
614  for(const Option_p &opt : parent->options_) {
615  if(opt.get() == this) {
616  continue;
617  }
618  auto &omatch = opt->matching_name(*this);
619  if(!omatch.empty()) {
620  ignore_underscore_ = false;
621  throw OptionAlreadyAdded("adding ignore underscore caused a name conflict with " + omatch);
622  }
623  }
624  } else {
625  ignore_underscore_ = value;
626  }
627  return this;
628  }
629 
632  if(value != multi_option_policy_) {
634  expected_min_ > 1) { // this bizarre condition is to maintain backwards compatibility
635  // with the previous behavior of expected_ with vectors
637  }
638  multi_option_policy_ = value;
640  }
641  return this;
642  }
643 
645  Option *disable_flag_override(bool value = true) {
646  disable_flag_override_ = value;
647  return this;
648  }
652 
654  int get_type_size() const { return type_size_min_; }
655 
657  int get_type_size_min() const { return type_size_min_; }
659  int get_type_size_max() const { return type_size_max_; }
660 
662  std::string get_envname() const { return envname_; }
663 
665  std::set<Option *> get_needs() const { return needs_; }
666 
668  std::set<Option *> get_excludes() const { return excludes_; }
669 
671  std::string get_default_str() const { return default_str_; }
672 
674  callback_t get_callback() const { return callback_; }
675 
677  const std::vector<std::string> &get_lnames() const { return lnames_; }
678 
680  const std::vector<std::string> &get_snames() const { return snames_; }
681 
683  const std::vector<std::string> &get_fnames() const { return fnames_; }
684 
686  int get_expected() const { return expected_min_; }
687 
689  int get_expected_min() const { return expected_min_; }
691  int get_expected_max() const { return expected_max_; }
692 
695 
698  int t = type_size_max_;
700  }
702  int get_items_expected() const { return get_items_expected_min(); }
703 
705  bool get_positional() const { return pname_.length() > 0; }
706 
708  bool nonpositional() const { return (snames_.size() + lnames_.size()) > 0; }
709 
711  bool has_description() const { return description_.length() > 0; }
712 
714  const std::string &get_description() const { return description_; }
715 
717  Option *description(std::string option_description) {
718  description_ = std::move(option_description);
719  return this;
720  }
721 
725 
730  std::string get_name(bool positional = false,
731  bool all_options = false
732  ) const {
733  if(get_group().empty())
734  return {}; // Hidden
735 
736  if(all_options) {
737 
738  std::vector<std::string> name_list;
739 
741  if((positional && (!pname_.empty())) || (snames_.empty() && lnames_.empty())) {
742  name_list.push_back(pname_);
743  }
744  if((get_items_expected() == 0) && (!fnames_.empty())) {
745  for(const std::string &sname : snames_) {
746  name_list.push_back("-" + sname);
747  if(check_fname(sname)) {
748  name_list.back() += "{" + get_flag_value(sname, "") + "}";
749  }
750  }
751 
752  for(const std::string &lname : lnames_) {
753  name_list.push_back("--" + lname);
754  if(check_fname(lname)) {
755  name_list.back() += "{" + get_flag_value(lname, "") + "}";
756  }
757  }
758  } else {
759  for(const std::string &sname : snames_)
760  name_list.push_back("-" + sname);
761 
762  for(const std::string &lname : lnames_)
763  name_list.push_back("--" + lname);
764  }
765 
766  return detail::join(name_list);
767  }
768 
769  // This returns the positional name no matter what
770  if(positional)
771  return pname_;
772 
773  // Prefer long name
774  if(!lnames_.empty())
775  return std::string(2, '-') + lnames_[0];
776 
777  // Or short name if no long name
778  if(!snames_.empty())
779  return std::string(1, '-') + snames_[0];
780 
781  // If positional is the only name, it's okay to use that
782  return pname_;
783  }
784 
788 
790  void run_callback() {
791 
793  _validate_results(results_);
795  }
796 
798  _reduce_results(proc_results_, results_);
800  }
803  if(!(callback_)) {
804  return;
805  }
806  const results_t &send_results = proc_results_.empty() ? results_ : proc_results_;
807  bool local_result = callback_(send_results);
808 
809  if(!local_result)
811  }
812  }
813 
815  const std::string &matching_name(const Option &other) const {
816  static const std::string estring;
817  for(const std::string &sname : snames_)
818  if(other.check_sname(sname))
819  return sname;
820  for(const std::string &lname : lnames_)
821  if(other.check_lname(lname))
822  return lname;
823 
824  if(ignore_case_ ||
825  ignore_underscore_) { // We need to do the inverse, in case we are ignore_case or ignore underscore
826  for(const std::string &sname : other.snames_)
827  if(check_sname(sname))
828  return sname;
829  for(const std::string &lname : other.lnames_)
830  if(check_lname(lname))
831  return lname;
832  }
833  return estring;
834  }
836  bool operator==(const Option &other) const { return !matching_name(other).empty(); }
837 
839  bool check_name(std::string name) const {
840 
841  if(name.length() > 2 && name[0] == '-' && name[1] == '-')
842  return check_lname(name.substr(2));
843  if(name.length() > 1 && name.front() == '-')
844  return check_sname(name.substr(1));
845 
846  std::string local_pname = pname_;
847  if(ignore_underscore_) {
848  local_pname = detail::remove_underscore(local_pname);
849  name = detail::remove_underscore(name);
850  }
851  if(ignore_case_) {
852  local_pname = detail::to_lower(local_pname);
853  name = detail::to_lower(name);
854  }
855  return name == local_pname;
856  }
857 
859  bool check_sname(std::string name) const {
860  return (detail::find_member(std::move(name), snames_, ignore_case_) >= 0);
861  }
862 
864  bool check_lname(std::string name) const {
865  return (detail::find_member(std::move(name), lnames_, ignore_case_, ignore_underscore_) >= 0);
866  }
867 
869  bool check_fname(std::string name) const {
870  if(fnames_.empty()) {
871  return false;
872  }
873  return (detail::find_member(std::move(name), fnames_, ignore_case_, ignore_underscore_) >= 0);
874  }
875 
878  std::string get_flag_value(const std::string &name, std::string input_value) const {
879  static const std::string trueString{"true"};
880  static const std::string falseString{"false"};
881  static const std::string emptyString{"{}"};
882  // check for disable flag override_
884  if(!((input_value.empty()) || (input_value == emptyString))) {
885  auto default_ind = detail::find_member(name, fnames_, ignore_case_, ignore_underscore_);
886  if(default_ind >= 0) {
887  // We can static cast this to std::size_t because it is more than 0 in this block
888  if(default_flag_values_[static_cast<std::size_t>(default_ind)].second != input_value) {
889  throw(ArgumentMismatch::FlagOverride(name));
890  }
891  } else {
892  if(input_value != trueString) {
893  throw(ArgumentMismatch::FlagOverride(name));
894  }
895  }
896  }
897  }
899  if((input_value.empty()) || (input_value == emptyString)) {
900  if(flag_like_) {
901  return (ind < 0) ? trueString : default_flag_values_[static_cast<std::size_t>(ind)].second;
902  } else {
903  return (ind < 0) ? default_str_ : default_flag_values_[static_cast<std::size_t>(ind)].second;
904  }
905  }
906  if(ind < 0) {
907  return input_value;
908  }
909  if(default_flag_values_[static_cast<std::size_t>(ind)].second == falseString) {
910  try {
911  auto val = detail::to_flag_value(input_value);
912  return (val == 1) ? falseString : (val == (-1) ? trueString : std::to_string(-val));
913  } catch(const std::invalid_argument &) {
914  return input_value;
915  }
916  } else {
917  return input_value;
918  }
919  }
920 
922  Option *add_result(std::string s) {
923  _add_result(std::move(s), results_);
925  return this;
926  }
927 
929  Option *add_result(std::string s, int &results_added) {
930  results_added = _add_result(std::move(s), results_);
932  return this;
933  }
934 
936  Option *add_result(std::vector<std::string> s) {
937  for(auto &str : s) {
938  _add_result(std::move(str), results_);
939  }
941  return this;
942  }
943 
945  results_t results() const { return results_; }
946 
949  results_t res = proc_results_.empty() ? results_ : proc_results_;
952  res = results_;
953  _validate_results(res);
954  }
955  if(!res.empty()) {
956  results_t extra;
957  _reduce_results(extra, res);
958  if(!extra.empty()) {
959  res = std::move(extra);
960  }
961  }
962  }
963  return res;
964  }
965 
967  template <typename T, enable_if_t<!std::is_const<T>::value, detail::enabler> = detail::dummy>
968  void results(T &output) const {
969  bool retval;
970  if(current_option_state_ >= option_state::reduced || (results_.size() == 1 && validators_.empty())) {
971  const results_t &res = (proc_results_.empty()) ? results_ : proc_results_;
972  retval = detail::lexical_conversion<T, T>(res, output);
973  } else {
974  results_t res;
975  if(results_.empty()) {
976  if(!default_str_.empty()) {
977  // _add_results takes an rvalue only
978  _add_result(std::string(default_str_), res);
979  _validate_results(res);
980  results_t extra;
981  _reduce_results(extra, res);
982  if(!extra.empty()) {
983  res = std::move(extra);
984  }
985  } else {
986  res.emplace_back();
987  }
988  } else {
989  res = reduced_results();
990  }
991  retval = detail::lexical_conversion<T, T>(res, output);
992  }
993  if(!retval) {
995  }
996  }
997 
999  template <typename T> T as() const {
1000  T output;
1001  results(output);
1002  return output;
1003  }
1004 
1007 
1011 
1013  Option *type_name_fn(std::function<std::string()> typefun) {
1014  type_name_ = std::move(typefun);
1015  return this;
1016  }
1017 
1019  Option *type_name(std::string typeval) {
1020  type_name_fn([typeval]() { return typeval; });
1021  return this;
1022  }
1023 
1025  Option *type_size(int option_type_size) {
1026  if(option_type_size < 0) {
1027  // this section is included for backwards compatibility
1028  type_size_max_ = -option_type_size;
1029  type_size_min_ = -option_type_size;
1031  } else {
1032  type_size_max_ = option_type_size;
1034  type_size_min_ = option_type_size;
1035  }
1036  if(type_size_max_ == 0)
1037  required_ = false;
1038  }
1039  return this;
1040  }
1042  Option *type_size(int option_type_size_min, int option_type_size_max) {
1043  if(option_type_size_min < 0 || option_type_size_max < 0) {
1044  // this section is included for backwards compatibility
1046  option_type_size_min = (std::abs)(option_type_size_min);
1047  option_type_size_max = (std::abs)(option_type_size_max);
1048  }
1049 
1050  if(option_type_size_min > option_type_size_max) {
1051  type_size_max_ = option_type_size_min;
1052  type_size_min_ = option_type_size_max;
1053  } else {
1054  type_size_min_ = option_type_size_min;
1055  type_size_max_ = option_type_size_max;
1056  }
1057  if(type_size_max_ == 0) {
1058  required_ = false;
1059  }
1060  return this;
1061  }
1062 
1064  Option *default_function(const std::function<std::string()> &func) {
1065  default_function_ = func;
1066  return this;
1067  }
1068 
1071  if(default_function_) {
1073  }
1074  return this;
1075  }
1076 
1078  Option *default_str(std::string val) {
1079  default_str_ = std::move(val);
1080  return this;
1081  }
1082 
1085  template <typename X> Option *default_val(const X &val) {
1086  std::string val_str = detail::to_string(val);
1087  auto old_option_state = current_option_state_;
1088  results_t old_results{std::move(results_)};
1089  results_.clear();
1090  try {
1091  add_result(val_str);
1093  run_callback(); // run callback sets the state we need to reset it again
1095  } else {
1096  _validate_results(results_);
1097  current_option_state_ = old_option_state;
1098  }
1099  } catch(const CLI::Error &) {
1100  // this should be done
1101  results_ = std::move(old_results);
1102  current_option_state_ = old_option_state;
1103  throw;
1104  }
1105  results_ = std::move(old_results);
1106  default_str_ = std::move(val_str);
1107  return this;
1108  }
1109 
1111  std::string get_type_name() const {
1112  std::string full_type_name = type_name_();
1113  if(!validators_.empty()) {
1114  for(auto &Validator : validators_) {
1115  std::string vtype = Validator.get_description();
1116  if(!vtype.empty()) {
1117  full_type_name += ":" + vtype;
1118  }
1119  }
1120  }
1121  return full_type_name;
1122  }
1123 
1124  private:
1126  void _validate_results(results_t &res) const {
1127  // Run the Validators (can change the string)
1128  if(!validators_.empty()) {
1129  if(type_size_max_ > 1) { // in this context index refers to the index in the type
1130  int index = 0;
1131  if(get_items_expected_max() < static_cast<int>(res.size()) &&
1133  // create a negative index for the earliest ones
1134  index = get_items_expected_max() - static_cast<int>(res.size());
1135  }
1136 
1137  for(std::string &result : res) {
1138  if(result.empty() && type_size_max_ != type_size_min_ && index >= 0) {
1139  index = 0; // reset index for variable size chunks
1140  continue;
1141  }
1142  auto err_msg = _validate(result, (index >= 0) ? (index % type_size_max_) : index);
1143  if(!err_msg.empty())
1144  throw ValidationError(get_name(), err_msg);
1145  ++index;
1146  }
1147  } else {
1148  int index = 0;
1149  if(expected_max_ < static_cast<int>(res.size()) &&
1151  // create a negative index for the earliest ones
1152  index = expected_max_ - static_cast<int>(res.size());
1153  }
1154  for(std::string &result : res) {
1155  auto err_msg = _validate(result, index);
1156  ++index;
1157  if(!err_msg.empty())
1158  throw ValidationError(get_name(), err_msg);
1159  }
1160  }
1161  }
1162  }
1163 
1167  void _reduce_results(results_t &res, const results_t &original) const {
1168 
1169  // max num items expected or length of vector, always at least 1
1170  // Only valid for a trimming policy
1171 
1172  res.clear();
1173  // Operation depends on the policy setting
1174  switch(multi_option_policy_) {
1176  break;
1178  // Allow multi-option sizes (including 0)
1179  std::size_t trim_size = std::min<std::size_t>(
1180  static_cast<std::size_t>(std::max<int>(get_items_expected_max(), 1)), original.size());
1181  if(original.size() != trim_size) {
1182  res.assign(original.end() - static_cast<results_t::difference_type>(trim_size), original.end());
1183  }
1184  } break;
1186  std::size_t trim_size = std::min<std::size_t>(
1187  static_cast<std::size_t>(std::max<int>(get_items_expected_max(), 1)), original.size());
1188  if(original.size() != trim_size) {
1189  res.assign(original.begin(), original.begin() + static_cast<results_t::difference_type>(trim_size));
1190  }
1191  } break;
1193  if(results_.size() > 1) {
1194  res.push_back(detail::join(original, std::string(1, (delimiter_ == '\0') ? '\n' : delimiter_)));
1195  }
1196  break;
1198  default: {
1199  auto num_min = static_cast<std::size_t>(get_items_expected_min());
1200  auto num_max = static_cast<std::size_t>(get_items_expected_max());
1201  if(num_min == 0) {
1202  num_min = 1;
1203  }
1204  if(num_max == 0) {
1205  num_max = 1;
1206  }
1207  if(original.size() < num_min) {
1208  throw ArgumentMismatch::AtLeast(get_name(), static_cast<int>(num_min), original.size());
1209  }
1210  if(original.size() > num_max) {
1211  throw ArgumentMismatch::AtMost(get_name(), static_cast<int>(num_max), original.size());
1212  }
1213  break;
1214  }
1215  }
1216  }
1217 
1218  // Run a result through the Validators
1219  std::string _validate(std::string &result, int index) const {
1220  std::string err_msg;
1221  if(result.empty() && expected_min_ == 0) {
1222  // an empty with nothing expected is allowed
1223  return err_msg;
1224  }
1225  for(const auto &vali : validators_) {
1226  auto v = vali.get_application_index();
1227  if(v == -1 || v == index) {
1228  try {
1229  err_msg = vali(result);
1230  } catch(const ValidationError &err) {
1231  err_msg = err.what();
1232  }
1233  if(!err_msg.empty())
1234  break;
1235  }
1236  }
1237 
1238  return err_msg;
1239  }
1240 
1242  int _add_result(std::string &&result, std::vector<std::string> &res) const {
1243  int result_count = 0;
1244  if(allow_extra_args_ && !result.empty() && result.front() == '[' &&
1245  result.back() == ']') { // this is now a vector string likely from the default or user entry
1246  result.pop_back();
1247 
1248  for(auto &var : CLI::detail::split(result.substr(1), ',')) {
1249  if(!var.empty()) {
1250  result_count += _add_result(std::move(var), res);
1251  }
1252  }
1253  return result_count;
1254  }
1255  if(delimiter_ == '\0') {
1256  res.push_back(std::move(result));
1257  ++result_count;
1258  } else {
1259  if((result.find_first_of(delimiter_) != std::string::npos)) {
1260  for(const auto &var : CLI::detail::split(result, delimiter_)) {
1261  if(!var.empty()) {
1262  res.push_back(var);
1263  ++result_count;
1264  }
1265  }
1266  } else {
1267  res.push_back(std::move(result));
1268  ++result_count;
1269  }
1270  }
1271  return result_count;
1272  }
1273 }; // namespace CLI
1274 
1275 } // namespace CLI
CLI::OptionBase::get_ignore_case
bool get_ignore_case() const
The status of ignore case.
Definition: Option.hpp:121
CLI::Option::operator==
bool operator==(const Option &other) const
If options share any of the same names, they are equal (not counting positional)
Definition: Option.hpp:836
CLI::Option::transform
Option * transform(Validator Validator, const std::string &Validator_name="")
Adds a transforming Validator with a built in type name.
Definition: Option.hpp:444
CLI::OptionBase::get_always_capture_default
bool get_always_capture_default() const
Return true if this will automatically capture the default value for help printing.
Definition: Option.hpp:136
CLI::OptionBase::group
CRTP * group(const std::string &name)
Changes the group membership.
Definition: Option.hpp:93
CLI::Option::default_str_
std::string default_str_
A human readable default value, either manually set, captured, or captured by default.
Definition: Option.hpp:265
CLI::Option::reduced_results
results_t reduced_results() const
Get a copy of the results.
Definition: Option.hpp:948
CLI::Option::check_name
bool check_name(std::string name) const
Check a name. Requires "-" or "--" for short / long, supports positional name.
Definition: Option.hpp:839
CLI::Option::ignore_case
Option * ignore_case(bool value=true)
Definition: Option.hpp:585
CLI::Validator::get_description
std::string get_description() const
Generate type description information for the Validator.
Definition: Validators.hpp:138
CLI::Option::get_envname
std::string get_envname() const
The environment variable associated to this value.
Definition: Option.hpp:662
CLI::Option::disable_flag_override
Option * disable_flag_override(bool value=true)
Disable flag overrides values, e.g. –flag=is not allowed.
Definition: Option.hpp:645
CLI::Option::get_default_str
std::string get_default_str() const
The default value (for help printing)
Definition: Option.hpp:671
CLI::OptionBase::get_required
bool get_required() const
True if this is a required option.
Definition: Option.hpp:118
CLI::OptionBase::get_disable_flag_override
bool get_disable_flag_override() const
The status of configurable.
Definition: Option.hpp:130
CLI::Option::Option
Option(const Option &)=delete
CLI::OptionBase::take_all
CRTP * take_all()
Set the multi option policy to take all arguments.
Definition: Option.hpp:158
CLI::detail::enabler
enabler
Simple empty scoped class.
Definition: TypeTools.hpp:26
CLI::OptionBase::delimiter_
char delimiter_
Specify a delimiter character for vector arguments.
Definition: Option.hpp:68
CLI::detail::expected_max_vector_size
constexpr int expected_max_vector_size
Definition: StringTools.hpp:39
CLI::Option::get_needs
std::set< Option * > get_needs() const
The set of options needed.
Definition: Option.hpp:665
CLI::Option::add_result
Option * add_result(std::vector< std::string > s)
Puts a result at the end.
Definition: Option.hpp:936
CLI::Option::default_function
Option * default_function(const std::function< std::string()> &func)
Set a capture function for the default. Mostly used by App.
Definition: Option.hpp:1064
CLI::OptionBase::join
CRTP * join(char delim)
Set the multi option policy to join with a specific delimiter.
Definition: Option.hpp:172
CLI::Option::pname_
std::string pname_
A positional name.
Definition: Option.hpp:252
CLI::Validator
Some validators that are provided.
Definition: Validators.hpp:74
CLI::OptionDefaults::ignore_underscore
OptionDefaults * ignore_underscore(bool value=true)
Ignore underscores in the option name.
Definition: Option.hpp:213
Error.hpp
CLI::Option::get_lnames
const std::vector< std::string > & get_lnames() const
Get the long names.
Definition: Option.hpp:677
CLI::Option::option_state::validated
@ validated
the results have been validated
CLI::Option::default_flag_values_
std::vector< std::pair< std::string, std::string > > default_flag_values_
Definition: Option.hpp:246
CLI::detail::split
std::vector< std::string > split(const std::string &s, char delim)
Split a string by a delim.
Definition: StringTools.hpp:42
CLI::Option::expected_min_
int expected_min_
The minimum number of expected values.
Definition: Option.hpp:286
CLI::Option::transform
Option * transform(const std::function< std::string(std::string)> &func, std::string transform_description="", std::string transform_name="")
Adds a Validator-like function that can change result.
Definition: Option.hpp:452
CLI::Option::description
Option * description(std::string option_description)
Set the description.
Definition: Option.hpp:717
CLI::Option::flag_like_
bool flag_like_
Specify that the option should act like a flag vs regular option.
Definition: Option.hpp:329
CLI::Option::fnames_
std::vector< std::string > fnames_
a list of flag names with specified default values;
Definition: Option.hpp:249
CLI::Option::get_type_size_max
int get_type_size_max() const
The maximum number of arguments the option expects.
Definition: Option.hpp:659
CLI::Option::snames_
std::vector< std::string > snames_
A list of the short names (-a) without the leading dashes.
Definition: Option.hpp:239
CLI::Option::results
results_t results() const
Get a copy of the results.
Definition: Option.hpp:945
CLI::Option::get_type_size_min
int get_type_size_min() const
The minimum number of arguments the option expects.
Definition: Option.hpp:657
CLI::Option::each
Option * each(const std::function< void(std::string)> &func)
Adds a user supplied function to run on each item passed in (communicate though lambda capture)
Definition: Option.hpp:468
CLI::OptionBase::multi_option_policy_
MultiOptionPolicy multi_option_policy_
Policy for handling multiple arguments beyond the expected Max.
Definition: Option.hpp:74
CLI::Option::get_positional
bool get_positional() const
True if the argument can be given directly.
Definition: Option.hpp:705
CLI::OptionBase::get_configurable
bool get_configurable() const
The status of configurable.
Definition: Option.hpp:127
CLI::Option::run_callback_for_default_
bool run_callback_for_default_
Control option to run the callback to set the default.
Definition: Option.hpp:331
CLI::Option::get_items_expected_max
int get_items_expected_max() const
Get the maximum number of items expected to be returned and used for the callback.
Definition: Option.hpp:697
CLI::MultiOptionPolicy::TakeLast
@ TakeLast
take only the last Expected number of arguments
CLI::Option::count
std::size_t count() const
Count the total number of times an option was passed.
Definition: Option.hpp:348
CLI::Option::option_state::reduced
@ reduced
a subset of results has been generated
CLI::Option::results_
results_t results_
complete Results of parsing
Definition: Option.hpp:314
CLI::Option::parent_
App * parent_
Remember the parent app.
Definition: Option.hpp:304
CLI::Option::needs_
std::set< Option * > needs_
A list of options that are required with this option.
Definition: Option.hpp:294
CLI::Option::type_size
Option * type_size(int option_type_size)
Set a custom option size.
Definition: Option.hpp:1025
CLI::Option::get_name
std::string get_name(bool positional=false, bool all_options=false) const
Gets a comma separated list of names. Will include / prefer the positional name if positional is true...
Definition: Option.hpp:730
CLI::Option::expected
Option * expected(int value)
Set the number of expected arguments.
Definition: Option.hpp:367
CLI::MultiOptionPolicy::Join
@ Join
merge all the arguments together into a single string via the delimiter character default(' ')
CLI::Option::has_description
bool has_description() const
True if option has description.
Definition: Option.hpp:711
CLI::Option::get_expected_max
int get_expected_max() const
The max number of times the option expects to be included.
Definition: Option.hpp:691
CLI::ConversionError
Thrown when conversion call back fails, such as when an int fails to coerce to a string.
Definition: Error.hpp:186
CLI::detail::join
std::string join(const T &v, std::string delim=",")
Simple function to join a string.
Definition: StringTools.hpp:59
CLI::Option::type_size_min_
int type_size_min_
The minimum number of arguments an option should be expecting.
Definition: Option.hpp:283
CLI::Option::check_fname
bool check_fname(std::string name) const
Requires "--" to be removed from string.
Definition: Option.hpp:869
CLI::Option::envname
Option * envname(std::string name)
Sets environment variable to read if no option given.
Definition: Option.hpp:576
CLI::OptionBase::take_first
CRTP * take_first()
Set the multi option policy to take last.
Definition: Option.hpp:151
CLI::Validator::get_name
const std::string & get_name() const
Get the name of the Validator.
Definition: Validators.hpp:156
CLI::Option::option_state::parsing
@ parsing
The option is currently collecting parsed results.
CLI::Option::excludes_
std::set< Option * > excludes_
A list of options that are excluded with this option.
Definition: Option.hpp:297
CLI::Option::excludes
Option * excludes(Option *opt)
Sets excluded options.
Definition: Option.hpp:534
CLI::MultiOptionPolicy
MultiOptionPolicy
Enumeration of the multiOption Policy selection.
Definition: Option.hpp:35
CLI::OptionBase::always_capture_default_
bool always_capture_default_
Automatically capture default value.
Definition: Option.hpp:71
CLI::Option::callback_
callback_t callback_
Options store a callback to do all the work.
Definition: Option.hpp:307
CLI::OptionDefaults::OptionDefaults
OptionDefaults()=default
CLI::detail::to_string
auto to_string(T &&value) -> decltype(std::forward< T >(value))
Convert an object to a string (directly forward if this can become a string)
Definition: TypeTools.hpp:226
CLI::Option::envname_
std::string envname_
If given, check the environment for this option.
Definition: Option.hpp:255
CLI::Option::get_validator
Validator * get_validator(const std::string &Validator_name="")
Get a named Validator.
Definition: Option.hpp:478
CLI::MultiOptionPolicy::TakeAll
@ TakeAll
just get all the passed argument regardless
CLI
Definition: App.hpp:32
CLI::Option::nonpositional
bool nonpositional() const
True if option has at least one non-positional name.
Definition: Option.hpp:708
CLI::Option::needs
Option * needs(Option *opt)
Sets required options.
Definition: Option.hpp:500
CLI::OptionBase::copy_to
void copy_to(T *other) const
Copy the contents to another similar class (one based on OptionBase)
Definition: Option.hpp:77
CLI::detail::dummy
constexpr enabler dummy
An instance to use in EnableIf.
Definition: TypeTools.hpp:29
CLI::Option::needs
Option * needs(std::string opt_name)
Can find a string if needed.
Definition: Option.hpp:508
CLI::Option::type_name_
std::function< std::string()> type_name_
Definition: Option.hpp:270
CLI::Option::add_result
Option * add_result(std::string s, int &results_added)
Puts a result at the end and get a count of the number of arguments actually added.
Definition: Option.hpp:929
CLI::Option::get_snames
const std::vector< std::string > & get_snames() const
Get the short names.
Definition: Option.hpp:680
CLI::OptionBase::delimiter
CRTP * delimiter(char value='\0')
Allow in a configuration file.
Definition: Option.hpp:186
CLI::Option::check
Option * check(Validator validator, const std::string &validator_name="")
Adds a Validator with a built in type name.
Definition: Option.hpp:426
CLI::detail::find_member
std::ptrdiff_t find_member(std::string name, const std::vector< std::string > names, bool ignore_case=false, bool ignore_underscore=false)
Check if a string is a member of a list of strings and optionally ignore case or ignore underscores.
Definition: StringTools.hpp:244
CLI::Option::needs
Option * needs(A opt, B opt1, ARG... args)
Any number supported, any mix of string and Opt.
Definition: Option.hpp:517
CLI::Option::allow_extra_args_
bool allow_extra_args_
Specify that extra args beyond type_size_max should be allowed.
Definition: Option.hpp:327
CLI::Option::remove_excludes
bool remove_excludes(Option *opt)
Remove needs link from an option. Returns true if the option really was in the needs list.
Definition: Option.hpp:565
CLI::OptionBase
Definition: Option.hpp:45
CLI::Option::expected_max_
int expected_max_
The maximum number of expected values.
Definition: Option.hpp:288
Validators.hpp
CLI::Error
All errors derive from this one.
Definition: Error.hpp:67
CLI::OptionBase::configurable_
bool configurable_
Allow this option to be given in a configuration file.
Definition: Option.hpp:62
CLI::OptionDefaults::multi_option_policy
OptionDefaults * multi_option_policy(MultiOptionPolicy value=MultiOptionPolicy::Throw)
Take the last argument if given multiple times.
Definition: Option.hpp:201
CLI::OptionAlreadyAdded
Thrown when an option already exists.
Definition: Error.hpp:132
CLI::Option::default_val
Option * default_val(const X &val)
Definition: Option.hpp:1085
CLI::Option::type_size
Option * type_size(int option_type_size_min, int option_type_size_max)
Set a custom option type size range.
Definition: Option.hpp:1042
CLI::Option::get_flag_value
std::string get_flag_value(const std::string &name, std::string input_value) const
Definition: Option.hpp:878
CLI::OptionBase::join
CRTP * join()
Set the multi option policy to join.
Definition: Option.hpp:165
CLI::Option::type_name_fn
Option * type_name_fn(std::function< std::string()> typefun)
Set the type function to run when displayed on this option.
Definition: Option.hpp:1013
CLI::detail::get_names
std::tuple< std::vector< std::string >, std::vector< std::string >, std::string > get_names(const std::vector< std::string > &input)
Get a vector of short names, one of long names, and a single name.
Definition: Split.hpp:103
CLI::callback_t
std::function< bool(const results_t &)> callback_t
callback function definition
Definition: Option.hpp:28
CLI::Option
Definition: Option.hpp:231
CLI::detail::to_lower
std::string to_lower(std::string str)
Return a lower case version of a string.
Definition: StringTools.hpp:199
CLI::Option::validators_
std::vector< Validator > validators_
A list of Validators to run on each value parsed.
Definition: Option.hpp:291
CLI::Option::type_size_max_
int type_size_max_
Definition: Option.hpp:281
CLI::Option::excludes
Option * excludes(std::string opt_name)
Can find a string if needed.
Definition: Option.hpp:550
CLI::Option::type_name
Option * type_name(std::string typeval)
Set a custom option typestring.
Definition: Option.hpp:1019
CLI::MultiOptionPolicy::TakeFirst
@ TakeFirst
take only the first Expected number of arguments
CLI::Option::multi_option_policy
Option * multi_option_policy(MultiOptionPolicy value=MultiOptionPolicy::Throw)
Take the last argument if given multiple times (or another policy)
Definition: Option.hpp:631
CLI::MultiOptionPolicy::Throw
@ Throw
Throw an error if any extra arguments were given.
CLI::Option::get_items_expected
int get_items_expected() const
The total min number of expected string values to be used.
Definition: Option.hpp:702
CLI::detail::remove_underscore
std::string remove_underscore(std::string str)
remove underscores from a string
Definition: StringTools.hpp:207
CLI::Option::excludes
Option * excludes(A opt, B opt1, ARG... args)
Any number supported, any mix of string and Opt.
Definition: Option.hpp:559
CLI::detail::to_flag_value
std::int64_t to_flag_value(std::string val)
Convert a flag into an integer value typically binary flags.
Definition: TypeTools.hpp:564
CLI::Option::run_callback_for_default
Option * run_callback_for_default(bool value=true)
Definition: Option.hpp:418
CLI::Option::proc_results_
results_t proc_results_
results after reduction
Definition: Option.hpp:316
CLI::Option::expected
Option * expected(int value_min, int value_max)
Set the range of expected arguments.
Definition: Option.hpp:389
CLI::OptionBase::get_multi_option_policy
MultiOptionPolicy get_multi_option_policy() const
The status of the multi option policy.
Definition: Option.hpp:139
CLI::OptionBase::group_
std::string group_
The group membership.
Definition: Option.hpp:50
CLI::Option::get_description
const std::string & get_description() const
Get the description.
Definition: Option.hpp:714
StringTools.hpp
CLI::Option::get_callback_run
bool get_callback_run() const
See if the callback has been run already.
Definition: Option.hpp:1006
CLI::OptionBase::take_last
CRTP * take_last()
Set the multi option policy to take last.
Definition: Option.hpp:144
CLI::Option::results
void results(T &output) const
Get the results as a specified type.
Definition: Option.hpp:968
CLI::OptionDefaults::ignore_case
OptionDefaults * ignore_case(bool value=true)
Ignore the case of the option name.
Definition: Option.hpp:207
Macros.hpp
CLI::results_t
std::vector< std::string > results_t
Definition: Option.hpp:26
CLI::Option::Option
Option(std::string option_name, std::string option_description, callback_t callback, App *parent)
Making an option by hand is not defined, it must be made by the App class.
Definition: Option.hpp:335
CLI::App
Creates a command line program, with very few defaults.
Definition: App.hpp:66
CLI::Option::get_type_size
int get_type_size() const
The number of arguments the option expects.
Definition: Option.hpp:654
CLI::Option::matching_name
const std::string & matching_name(const Option &other) const
If options share any of the same names, find it.
Definition: Option.hpp:815
CLI::Option::check_sname
bool check_sname(std::string name) const
Requires "-" to be removed from string.
Definition: Option.hpp:859
CLI::OptionBase::required_
bool required_
True if this is a required option.
Definition: Option.hpp:53
CLI::Option::capture_default_str
Option * capture_default_str()
Capture the default value from the original value (if it can be captured)
Definition: Option.hpp:1070
CLI::Option::as
T as() const
Return the results as the specified type.
Definition: Option.hpp:999
CLI::Option::default_function_
std::function< std::string()> default_function_
Run this function to capture a default (ignore if empty)
Definition: Option.hpp:273
CLI::OptionDefaults
Definition: Option.hpp:194
Split.hpp
CLI::OptionBase::disable_flag_override_
bool disable_flag_override_
Disable overriding flag values with '=value'.
Definition: Option.hpp:65
CLI::OptionBase::get_group
const std::string & get_group() const
Get the group of this option.
Definition: Option.hpp:115
CLI::Option::get_fnames
const std::vector< std::string > & get_fnames() const
Get the flag names with specified default values.
Definition: Option.hpp:683
CLI::OptionBase::configurable
CRTP * configurable(bool value=true)
Allow in a configuration file.
Definition: Option.hpp:180
CLI::Option::ignore_underscore
Option * ignore_underscore(bool value=true)
Definition: Option.hpp:609
CLI::Option::option_state
option_state
enumeration for the option state machine
Definition: Option.hpp:318
CLI::Option::default_str
Option * default_str(std::string val)
Set the default value string representation (does not change the contained value)
Definition: Option.hpp:1078
CLI::Option_p
std::unique_ptr< Option > Option_p
Definition: Option.hpp:33
CLI::Option::get_type_name
std::string get_type_name() const
Get the full typename for this option.
Definition: Option.hpp:1111
CLI::OptionBase::always_capture_default
CRTP * always_capture_default(bool value=true)
Definition: Option.hpp:107
CLI::Option::get_validator
Validator * get_validator(int index)
Get a Validator by index NOTE: this may not be the order of definition.
Definition: Option.hpp:491
CLI::Option::empty
bool empty() const
True if the option was not passed.
Definition: Option.hpp:351
CLI::Option::get_items_expected_min
int get_items_expected_min() const
The total min number of expected string values to be used.
Definition: Option.hpp:694
CLI::Option::get_expected
int get_expected() const
The number of times the option expects to be included.
Definition: Option.hpp:686
CLI::Validator::non_modifying
Validator & non_modifying(bool no_modify=true)
Specify whether the Validator can be modifying or not.
Definition: Validators.hpp:170
CLI::Option::get_excludes
std::set< Option * > get_excludes() const
The set of options excluded.
Definition: Option.hpp:668
CLI::detail::checked_multiply
std::enable_if< std::is_integral< T >::value, bool >::type checked_multiply(T &a, T b)
Performs a *= b; if it doesn't cause integer overflow. Returns false otherwise.
Definition: Validators.hpp:669
CLI::OptionDefaults::delimiter
OptionDefaults * delimiter(char value='\0')
set a delimiter character to split up single arguments to treat as multiple inputs
Definition: Option.hpp:225
CLI::Option::get_allow_extra_args
bool get_allow_extra_args() const
Get the current value of allow extra args.
Definition: Option.hpp:414
CLI::Option::option_state::callback_run
@ callback_run
the callback has been executed
CLI::Option::current_option_state_
option_state current_option_state_
Whether the callback has run (needed for INI parsing)
Definition: Option.hpp:325
CLI::Option::check
Option * check(std::function< std::string(const std::string &)> Validator, std::string Validator_description="", std::string Validator_name="")
Adds a Validator. Takes a const string& and returns an error message (empty if conversion/check is ok...
Definition: Option.hpp:435
CLI::OptionBase::get_delimiter
char get_delimiter() const
Get the current delimiter char.
Definition: Option.hpp:133
CLI::Option::description_
std::string description_
The description for help strings.
Definition: Option.hpp:262
CLI::OptionNotFound
Thrown when counting a non-existent option.
Definition: Error.hpp:330
CLI::OptionBase::mandatory
CRTP * mandatory(bool value=true)
Support Plumbum term.
Definition: Option.hpp:105
CLI::Option::get_expected_min
int get_expected_min() const
The number of times the option expects to be included.
Definition: Option.hpp:689
CLI::OptionBase::required
CRTP * required(bool value=true)
Set the option as required.
Definition: Option.hpp:99
CLI::Option::clear
void clear()
Clear the parsed results (mostly for testing)
Definition: Option.hpp:357
CLI::detail::split_names
std::vector< std::string > split_names(std::string current)
Definition: Split.hpp:63
CLI::ExitCodes::ValidationError
@ ValidationError
CLI::Option::operator=
Option & operator=(const Option &)=delete
CLI::Option::add_result
Option * add_result(std::string s)
Puts a result at the end.
Definition: Option.hpp:922
CLI::OptionDefaults::disable_flag_override
OptionDefaults * disable_flag_override(bool value=true)
Disable overriding flag values with an '=' segment.
Definition: Option.hpp:219
CLI::Option::lnames_
std::vector< std::string > lnames_
A list of the long names (--long) without the leading dashes.
Definition: Option.hpp:242
CLI::Option::check_lname
bool check_lname(std::string name) const
Requires "--" to be removed from string.
Definition: Option.hpp:864
CLI::OptionBase::ignore_underscore_
bool ignore_underscore_
Ignore underscores when matching (option, not value)
Definition: Option.hpp:59
CLI::OptionBase::ignore_case_
bool ignore_case_
Ignore the case when matching (option, not value)
Definition: Option.hpp:56
CLI::Option::run_callback
void run_callback()
Process the callback.
Definition: Option.hpp:790
CLI::Option::get_run_callback_for_default
bool get_run_callback_for_default() const
Get the current value of run_callback_for_default.
Definition: Option.hpp:423
CLI::Option::remove_needs
bool remove_needs(Option *opt)
Remove needs link from an option. Returns true if the option really was in the needs list.
Definition: Option.hpp:523
CLI::Option::get_callback
callback_t get_callback() const
Get the callback function.
Definition: Option.hpp:674
CLI::IncorrectConstruction
Thrown when an option is set to conflicting values (non-vector and multi args, for example)
Definition: Error.hpp:90
CLI::Option::allow_extra_args
Option * allow_extra_args(bool value=true)
Definition: Option.hpp:409
CLI::OptionBase::get_ignore_underscore
bool get_ignore_underscore() const
The status of ignore_underscore.
Definition: Option.hpp:124