CLI11  2.1.0
Option.hpp
Go to the documentation of this file.
1 // Copyright (c) 2017-2021, 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 // [CLI11:public_includes:set]
10 #include <algorithm>
11 #include <functional>
12 #include <memory>
13 #include <set>
14 #include <string>
15 #include <tuple>
16 #include <utility>
17 #include <vector>
18 // [CLI11:public_includes:end]
19 
20 #include "Error.hpp"
21 #include "Macros.hpp"
22 #include "Split.hpp"
23 #include "StringTools.hpp"
24 #include "Validators.hpp"
25 
26 namespace CLI {
27 // [CLI11:option_hpp:verbatim]
28 
29 using results_t = std::vector<std::string>;
31 using callback_t = std::function<bool(const results_t &)>;
32 
33 class Option;
34 class App;
35 
36 using Option_p = std::unique_ptr<Option>;
38 enum class MultiOptionPolicy : char {
39  Throw,
40  TakeLast,
41  TakeFirst,
42  Join,
43  TakeAll
44 };
45 
48 template <typename CRTP> class OptionBase {
49  friend App;
50 
51  protected:
53  std::string group_ = std::string("Options");
54 
56  bool required_{false};
57 
59  bool ignore_case_{false};
60 
62  bool ignore_underscore_{false};
63 
65  bool configurable_{true};
66 
69 
71  char delimiter_{'\0'};
72 
75 
78 
80  template <typename T> void copy_to(T *other) const {
81  other->group(group_);
82  other->required(required_);
83  other->ignore_case(ignore_case_);
84  other->ignore_underscore(ignore_underscore_);
85  other->configurable(configurable_);
86  other->disable_flag_override(disable_flag_override_);
87  other->delimiter(delimiter_);
88  other->always_capture_default(always_capture_default_);
89  other->multi_option_policy(multi_option_policy_);
90  }
91 
92  public:
93  // setters
94 
96  CRTP *group(const std::string &name) {
98  throw IncorrectConstruction("Group names may not contain newlines or null characters");
99  }
100  group_ = name;
101  return static_cast<CRTP *>(this);
102  }
103 
105  CRTP *required(bool value = true) {
106  required_ = value;
107  return static_cast<CRTP *>(this);
108  }
109 
111  CRTP *mandatory(bool value = true) { return required(value); }
112 
113  CRTP *always_capture_default(bool value = true) {
114  always_capture_default_ = value;
115  return static_cast<CRTP *>(this);
116  }
117 
118  // Getters
119 
121  const std::string &get_group() const { return group_; }
122 
124  bool get_required() const { return required_; }
125 
127  bool get_ignore_case() const { return ignore_case_; }
128 
130  bool get_ignore_underscore() const { return ignore_underscore_; }
131 
133  bool get_configurable() const { return configurable_; }
134 
137 
139  char get_delimiter() const { return delimiter_; }
140 
143 
146 
147  // Shortcuts for multi option policy
148 
150  CRTP *take_last() {
151  auto self = static_cast<CRTP *>(this);
152  self->multi_option_policy(MultiOptionPolicy::TakeLast);
153  return self;
154  }
155 
157  CRTP *take_first() {
158  auto self = static_cast<CRTP *>(this);
159  self->multi_option_policy(MultiOptionPolicy::TakeFirst);
160  return self;
161  }
162 
164  CRTP *take_all() {
165  auto self = static_cast<CRTP *>(this);
166  self->multi_option_policy(MultiOptionPolicy::TakeAll);
167  return self;
168  }
169 
171  CRTP *join() {
172  auto self = static_cast<CRTP *>(this);
173  self->multi_option_policy(MultiOptionPolicy::Join);
174  return self;
175  }
176 
178  CRTP *join(char delim) {
179  auto self = static_cast<CRTP *>(this);
180  self->delimiter_ = delim;
181  self->multi_option_policy(MultiOptionPolicy::Join);
182  return self;
183  }
184 
186  CRTP *configurable(bool value = true) {
187  configurable_ = value;
188  return static_cast<CRTP *>(this);
189  }
190 
192  CRTP *delimiter(char value = '\0') {
193  delimiter_ = value;
194  return static_cast<CRTP *>(this);
195  }
196 };
197 
200 class OptionDefaults : public OptionBase<OptionDefaults> {
201  public:
202  OptionDefaults() = default;
203 
204  // Methods here need a different implementation if they are Option vs. OptionDefault
205 
208  multi_option_policy_ = value;
209  return this;
210  }
211 
213  OptionDefaults *ignore_case(bool value = true) {
214  ignore_case_ = value;
215  return this;
216  }
217 
219  OptionDefaults *ignore_underscore(bool value = true) {
220  ignore_underscore_ = value;
221  return this;
222  }
223 
225  OptionDefaults *disable_flag_override(bool value = true) {
226  disable_flag_override_ = value;
227  return this;
228  }
229 
231  OptionDefaults *delimiter(char value = '\0') {
232  delimiter_ = value;
233  return this;
234  }
235 };
236 
237 class Option : public OptionBase<Option> {
238  friend App;
239 
240  protected:
243 
245  std::vector<std::string> snames_{};
246 
248  std::vector<std::string> lnames_{};
249 
252  std::vector<std::pair<std::string, std::string>> default_flag_values_{};
253 
255  std::vector<std::string> fnames_{};
256 
258  std::string pname_{};
259 
261  std::string envname_{};
262 
266 
268  std::string description_{};
269 
271  std::string default_str_{};
272 
274  std::string option_text_{};
275 
279  std::function<std::string()> type_name_{[]() { return std::string(); }};
280 
282  std::function<std::string()> default_function_{};
283 
287 
293 
298 
300  std::vector<Validator> validators_{};
301 
303  std::set<Option *> needs_{};
304 
306  std::set<Option *> excludes_{};
307 
311 
313  App *parent_{nullptr};
314 
317 
321 
327  enum class option_state : char {
328  parsing = 0,
329  validated = 2,
330  reduced = 4,
331  callback_run = 6,
332  };
336  bool allow_extra_args_{false};
338  bool flag_like_{false};
342  bool inject_separator_{false};
344  bool trigger_on_result_{false};
346  bool force_callback_{false};
348 
350  Option(std::string option_name, std::string option_description, callback_t callback, App *parent)
351  : description_(std::move(option_description)), parent_(parent), callback_(std::move(callback)) {
352  std::tie(snames_, lnames_, pname_) = detail::get_names(detail::split_names(option_name));
353  }
354 
355  public:
358 
359  Option(const Option &) = delete;
360  Option &operator=(const Option &) = delete;
361 
363  std::size_t count() const { return results_.size(); }
364 
366  bool empty() const { return results_.empty(); }
367 
369  explicit operator bool() const { return !empty() || force_callback_; }
370 
372  void clear() {
373  results_.clear();
375  }
376 
380 
382  Option *expected(int value) {
383  if(value < 0) {
384  expected_min_ = -value;
387  }
388  allow_extra_args_ = true;
389  flag_like_ = false;
390  } else if(value == detail::expected_max_vector_size) {
391  expected_min_ = 1;
393  allow_extra_args_ = true;
394  flag_like_ = false;
395  } else {
396  expected_min_ = value;
397  expected_max_ = value;
398  flag_like_ = (expected_min_ == 0);
399  }
400  return this;
401  }
402 
404  Option *expected(int value_min, int value_max) {
405  if(value_min < 0) {
406  value_min = -value_min;
407  }
408 
409  if(value_max < 0) {
411  }
412  if(value_max < value_min) {
413  expected_min_ = value_max;
414  expected_max_ = value_min;
415  } else {
416  expected_max_ = value_max;
417  expected_min_ = value_min;
418  }
419 
420  return this;
421  }
424  Option *allow_extra_args(bool value = true) {
425  allow_extra_args_ = value;
426  return this;
427  }
429  bool get_allow_extra_args() const { return allow_extra_args_; }
431  Option *trigger_on_parse(bool value = true) {
432  trigger_on_result_ = value;
433  return this;
434  }
436  bool get_trigger_on_parse() const { return trigger_on_result_; }
437 
439  Option *force_callback(bool value = true) {
440  force_callback_ = value;
441  return this;
442  }
444  bool get_force_callback() const { return force_callback_; }
445 
448  Option *run_callback_for_default(bool value = true) {
450  return this;
451  }
454 
456  Option *check(Validator validator, const std::string &validator_name = "") {
457  validator.non_modifying();
458  validators_.push_back(std::move(validator));
459  if(!validator_name.empty())
460  validators_.back().name(validator_name);
461  return this;
462  }
463 
465  Option *check(std::function<std::string(const std::string &)> Validator,
466  std::string Validator_description = "",
467  std::string Validator_name = "") {
468  validators_.emplace_back(Validator, std::move(Validator_description), std::move(Validator_name));
469  validators_.back().non_modifying();
470  return this;
471  }
472 
474  Option *transform(Validator Validator, const std::string &Validator_name = "") {
475  validators_.insert(validators_.begin(), std::move(Validator));
476  if(!Validator_name.empty())
477  validators_.front().name(Validator_name);
478  return this;
479  }
480 
482  Option *transform(const std::function<std::string(std::string)> &func,
483  std::string transform_description = "",
484  std::string transform_name = "") {
485  validators_.insert(validators_.begin(),
486  Validator(
487  [func](std::string &val) {
488  val = func(val);
489  return std::string{};
490  },
491  std::move(transform_description),
492  std::move(transform_name)));
493 
494  return this;
495  }
496 
498  Option *each(const std::function<void(std::string)> &func) {
499  validators_.emplace_back(
500  [func](std::string &inout) {
501  func(inout);
502  return std::string{};
503  },
504  std::string{});
505  return this;
506  }
508  Validator *get_validator(const std::string &Validator_name = "") {
509  for(auto &Validator : validators_) {
510  if(Validator_name == Validator.get_name()) {
511  return &Validator;
512  }
513  }
514  if((Validator_name.empty()) && (!validators_.empty())) {
515  return &(validators_.front());
516  }
517  throw OptionNotFound(std::string{"Validator "} + Validator_name + " Not Found");
518  }
519 
521  Validator *get_validator(int index) {
522  // This is an signed int so that it is not equivalent to a pointer.
523  if(index >= 0 && index < static_cast<int>(validators_.size())) {
524  return &(validators_[static_cast<decltype(validators_)::size_type>(index)]);
525  }
526  throw OptionNotFound("Validator index is not valid");
527  }
528 
530  Option *needs(Option *opt) {
531  if(opt != this) {
532  needs_.insert(opt);
533  }
534  return this;
535  }
536 
538  template <typename T = App> Option *needs(std::string opt_name) {
539  auto opt = static_cast<T *>(parent_)->get_option_no_throw(opt_name);
540  if(opt == nullptr) {
541  throw IncorrectConstruction::MissingOption(opt_name);
542  }
543  return needs(opt);
544  }
545 
547  template <typename A, typename B, typename... ARG> Option *needs(A opt, B opt1, ARG... args) {
548  needs(opt);
549  return needs(opt1, args...);
550  }
551 
553  bool remove_needs(Option *opt) {
554  auto iterator = std::find(std::begin(needs_), std::end(needs_), opt);
555 
556  if(iterator == std::end(needs_)) {
557  return false;
558  }
559  needs_.erase(iterator);
560  return true;
561  }
562 
565  if(opt == this) {
566  throw(IncorrectConstruction("and option cannot exclude itself"));
567  }
568  excludes_.insert(opt);
569 
570  // Help text should be symmetric - excluding a should exclude b
571  opt->excludes_.insert(this);
572 
573  // Ignoring the insert return value, excluding twice is now allowed.
574  // (Mostly to allow both directions to be excluded by user, even though the library does it for you.)
575 
576  return this;
577  }
578 
580  template <typename T = App> Option *excludes(std::string opt_name) {
581  auto opt = static_cast<T *>(parent_)->get_option_no_throw(opt_name);
582  if(opt == nullptr) {
583  throw IncorrectConstruction::MissingOption(opt_name);
584  }
585  return excludes(opt);
586  }
587 
589  template <typename A, typename B, typename... ARG> Option *excludes(A opt, B opt1, ARG... args) {
590  excludes(opt);
591  return excludes(opt1, args...);
592  }
593 
595  bool remove_excludes(Option *opt) {
596  auto iterator = std::find(std::begin(excludes_), std::end(excludes_), opt);
597 
598  if(iterator == std::end(excludes_)) {
599  return false;
600  }
601  excludes_.erase(iterator);
602  return true;
603  }
604 
606  Option *envname(std::string name) {
607  envname_ = std::move(name);
608  return this;
609  }
610 
615  template <typename T = App> Option *ignore_case(bool value = true) {
616  if(!ignore_case_ && value) {
617  ignore_case_ = value;
618  auto *parent = static_cast<T *>(parent_);
619  for(const Option_p &opt : parent->options_) {
620  if(opt.get() == this) {
621  continue;
622  }
623  auto &omatch = opt->matching_name(*this);
624  if(!omatch.empty()) {
625  ignore_case_ = false;
626  throw OptionAlreadyAdded("adding ignore case caused a name conflict with " + omatch);
627  }
628  }
629  } else {
630  ignore_case_ = value;
631  }
632  return this;
633  }
634 
639  template <typename T = App> Option *ignore_underscore(bool value = true) {
640 
641  if(!ignore_underscore_ && value) {
642  ignore_underscore_ = value;
643  auto *parent = static_cast<T *>(parent_);
644  for(const Option_p &opt : parent->options_) {
645  if(opt.get() == this) {
646  continue;
647  }
648  auto &omatch = opt->matching_name(*this);
649  if(!omatch.empty()) {
650  ignore_underscore_ = false;
651  throw OptionAlreadyAdded("adding ignore underscore caused a name conflict with " + omatch);
652  }
653  }
654  } else {
655  ignore_underscore_ = value;
656  }
657  return this;
658  }
659 
662  if(value != multi_option_policy_) {
664  expected_min_ > 1) { // this bizarre condition is to maintain backwards compatibility
665  // with the previous behavior of expected_ with vectors
667  }
668  multi_option_policy_ = value;
670  }
671  return this;
672  }
673 
675  Option *disable_flag_override(bool value = true) {
676  disable_flag_override_ = value;
677  return this;
678  }
682 
684  int get_type_size() const { return type_size_min_; }
685 
687  int get_type_size_min() const { return type_size_min_; }
689  int get_type_size_max() const { return type_size_max_; }
690 
692  int get_inject_separator() const { return inject_separator_; }
693 
695  std::string get_envname() const { return envname_; }
696 
698  std::set<Option *> get_needs() const { return needs_; }
699 
701  std::set<Option *> get_excludes() const { return excludes_; }
702 
704  std::string get_default_str() const { return default_str_; }
705 
707  callback_t get_callback() const { return callback_; }
708 
710  const std::vector<std::string> &get_lnames() const { return lnames_; }
711 
713  const std::vector<std::string> &get_snames() const { return snames_; }
714 
716  const std::vector<std::string> &get_fnames() const { return fnames_; }
718  const std::string &get_single_name() const {
719  if(!lnames_.empty()) {
720  return lnames_[0];
721  }
722  if(!pname_.empty()) {
723  return pname_;
724  }
725  if(!snames_.empty()) {
726  return snames_[0];
727  }
728  return envname_;
729  }
731  int get_expected() const { return expected_min_; }
732 
734  int get_expected_min() const { return expected_min_; }
736  int get_expected_max() const { return expected_max_; }
737 
740 
743  int t = type_size_max_;
745  }
747  int get_items_expected() const { return get_items_expected_min(); }
748 
750  bool get_positional() const { return pname_.length() > 0; }
751 
753  bool nonpositional() const { return (snames_.size() + lnames_.size()) > 0; }
754 
756  bool has_description() const { return description_.length() > 0; }
757 
759  const std::string &get_description() const { return description_; }
760 
762  Option *description(std::string option_description) {
763  description_ = std::move(option_description);
764  return this;
765  }
766 
767  Option *option_text(std::string text) {
768  option_text_ = std::move(text);
769  return this;
770  }
771 
772  const std::string &get_option_text() const { return option_text_; }
773 
777 
782  std::string get_name(bool positional = false,
783  bool all_options = false
784  ) const {
785  if(get_group().empty())
786  return {}; // Hidden
787 
788  if(all_options) {
789 
790  std::vector<std::string> name_list;
791 
793  if((positional && (!pname_.empty())) || (snames_.empty() && lnames_.empty())) {
794  name_list.push_back(pname_);
795  }
796  if((get_items_expected() == 0) && (!fnames_.empty())) {
797  for(const std::string &sname : snames_) {
798  name_list.push_back("-" + sname);
799  if(check_fname(sname)) {
800  name_list.back() += "{" + get_flag_value(sname, "") + "}";
801  }
802  }
803 
804  for(const std::string &lname : lnames_) {
805  name_list.push_back("--" + lname);
806  if(check_fname(lname)) {
807  name_list.back() += "{" + get_flag_value(lname, "") + "}";
808  }
809  }
810  } else {
811  for(const std::string &sname : snames_)
812  name_list.push_back("-" + sname);
813 
814  for(const std::string &lname : lnames_)
815  name_list.push_back("--" + lname);
816  }
817 
818  return detail::join(name_list);
819  }
820 
821  // This returns the positional name no matter what
822  if(positional)
823  return pname_;
824 
825  // Prefer long name
826  if(!lnames_.empty())
827  return std::string(2, '-') + lnames_[0];
828 
829  // Or short name if no long name
830  if(!snames_.empty())
831  return std::string(1, '-') + snames_[0];
832 
833  // If positional is the only name, it's okay to use that
834  return pname_;
835  }
836 
840 
842  void run_callback() {
843  if(force_callback_ && results_.empty()) {
845  }
847  _validate_results(results_);
849  }
850 
852  _reduce_results(proc_results_, results_);
854  }
857  if(!(callback_)) {
858  return;
859  }
860  const results_t &send_results = proc_results_.empty() ? results_ : proc_results_;
861  bool local_result = callback_(send_results);
862 
863  if(!local_result)
865  }
866  }
867 
869  const std::string &matching_name(const Option &other) const {
870  static const std::string estring;
871  for(const std::string &sname : snames_)
872  if(other.check_sname(sname))
873  return sname;
874  for(const std::string &lname : lnames_)
875  if(other.check_lname(lname))
876  return lname;
877 
878  if(ignore_case_ ||
879  ignore_underscore_) { // We need to do the inverse, in case we are ignore_case or ignore underscore
880  for(const std::string &sname : other.snames_)
881  if(check_sname(sname))
882  return sname;
883  for(const std::string &lname : other.lnames_)
884  if(check_lname(lname))
885  return lname;
886  }
887  return estring;
888  }
890  bool operator==(const Option &other) const { return !matching_name(other).empty(); }
891 
893  bool check_name(const std::string &name) const {
894 
895  if(name.length() > 2 && name[0] == '-' && name[1] == '-')
896  return check_lname(name.substr(2));
897  if(name.length() > 1 && name.front() == '-')
898  return check_sname(name.substr(1));
899  if(!pname_.empty()) {
900  std::string local_pname = pname_;
901  std::string local_name = name;
902  if(ignore_underscore_) {
903  local_pname = detail::remove_underscore(local_pname);
904  local_name = detail::remove_underscore(local_name);
905  }
906  if(ignore_case_) {
907  local_pname = detail::to_lower(local_pname);
908  local_name = detail::to_lower(local_name);
909  }
910  if(local_name == local_pname) {
911  return true;
912  }
913  }
914 
915  if(!envname_.empty()) {
916  // this needs to be the original since envname_ shouldn't match on case insensitivity
917  return (name == envname_);
918  }
919  return false;
920  }
921 
923  bool check_sname(std::string name) const {
924  return (detail::find_member(std::move(name), snames_, ignore_case_) >= 0);
925  }
926 
928  bool check_lname(std::string name) const {
929  return (detail::find_member(std::move(name), lnames_, ignore_case_, ignore_underscore_) >= 0);
930  }
931 
933  bool check_fname(std::string name) const {
934  if(fnames_.empty()) {
935  return false;
936  }
937  return (detail::find_member(std::move(name), fnames_, ignore_case_, ignore_underscore_) >= 0);
938  }
939 
942  std::string get_flag_value(const std::string &name, std::string input_value) const {
943  static const std::string trueString{"true"};
944  static const std::string falseString{"false"};
945  static const std::string emptyString{"{}"};
946  // check for disable flag override_
948  if(!((input_value.empty()) || (input_value == emptyString))) {
949  auto default_ind = detail::find_member(name, fnames_, ignore_case_, ignore_underscore_);
950  if(default_ind >= 0) {
951  // We can static cast this to std::size_t because it is more than 0 in this block
952  if(default_flag_values_[static_cast<std::size_t>(default_ind)].second != input_value) {
953  throw(ArgumentMismatch::FlagOverride(name));
954  }
955  } else {
956  if(input_value != trueString) {
957  throw(ArgumentMismatch::FlagOverride(name));
958  }
959  }
960  }
961  }
963  if((input_value.empty()) || (input_value == emptyString)) {
964  if(flag_like_) {
965  return (ind < 0) ? trueString : default_flag_values_[static_cast<std::size_t>(ind)].second;
966  } else {
967  return (ind < 0) ? default_str_ : default_flag_values_[static_cast<std::size_t>(ind)].second;
968  }
969  }
970  if(ind < 0) {
971  return input_value;
972  }
973  if(default_flag_values_[static_cast<std::size_t>(ind)].second == falseString) {
974  try {
975  auto val = detail::to_flag_value(input_value);
976  return (val == 1) ? falseString : (val == (-1) ? trueString : std::to_string(-val));
977  } catch(const std::invalid_argument &) {
978  return input_value;
979  }
980  } else {
981  return input_value;
982  }
983  }
984 
986  Option *add_result(std::string s) {
987  _add_result(std::move(s), results_);
989  return this;
990  }
991 
993  Option *add_result(std::string s, int &results_added) {
994  results_added = _add_result(std::move(s), results_);
996  return this;
997  }
998 
1000  Option *add_result(std::vector<std::string> s) {
1002  for(auto &str : s) {
1003  _add_result(std::move(str), results_);
1004  }
1005  return this;
1006  }
1007 
1009  const results_t &results() const { return results_; }
1010 
1013  results_t res = proc_results_.empty() ? results_ : proc_results_;
1016  res = results_;
1017  _validate_results(res);
1018  }
1019  if(!res.empty()) {
1020  results_t extra;
1021  _reduce_results(extra, res);
1022  if(!extra.empty()) {
1023  res = std::move(extra);
1024  }
1025  }
1026  }
1027  return res;
1028  }
1029 
1031  template <typename T> void results(T &output) const {
1032  bool retval;
1033  if(current_option_state_ >= option_state::reduced || (results_.size() == 1 && validators_.empty())) {
1034  const results_t &res = (proc_results_.empty()) ? results_ : proc_results_;
1035  retval = detail::lexical_conversion<T, T>(res, output);
1036  } else {
1037  results_t res;
1038  if(results_.empty()) {
1039  if(!default_str_.empty()) {
1040  // _add_results takes an rvalue only
1041  _add_result(std::string(default_str_), res);
1042  _validate_results(res);
1043  results_t extra;
1044  _reduce_results(extra, res);
1045  if(!extra.empty()) {
1046  res = std::move(extra);
1047  }
1048  } else {
1049  res.emplace_back();
1050  }
1051  } else {
1052  res = reduced_results();
1053  }
1054  retval = detail::lexical_conversion<T, T>(res, output);
1055  }
1056  if(!retval) {
1057  throw ConversionError(get_name(), results_);
1058  }
1059  }
1060 
1062  template <typename T> T as() const {
1063  T output;
1064  results(output);
1065  return output;
1066  }
1067 
1070 
1074 
1076  Option *type_name_fn(std::function<std::string()> typefun) {
1077  type_name_ = std::move(typefun);
1078  return this;
1079  }
1080 
1082  Option *type_name(std::string typeval) {
1083  type_name_fn([typeval]() { return typeval; });
1084  return this;
1085  }
1086 
1088  Option *type_size(int option_type_size) {
1089  if(option_type_size < 0) {
1090  // this section is included for backwards compatibility
1091  type_size_max_ = -option_type_size;
1092  type_size_min_ = -option_type_size;
1094  } else {
1095  type_size_max_ = option_type_size;
1097  type_size_min_ = option_type_size;
1098  } else {
1099  inject_separator_ = true;
1100  }
1101  if(type_size_max_ == 0)
1102  required_ = false;
1103  }
1104  return this;
1105  }
1107  Option *type_size(int option_type_size_min, int option_type_size_max) {
1108  if(option_type_size_min < 0 || option_type_size_max < 0) {
1109  // this section is included for backwards compatibility
1111  option_type_size_min = (std::abs)(option_type_size_min);
1112  option_type_size_max = (std::abs)(option_type_size_max);
1113  }
1114 
1115  if(option_type_size_min > option_type_size_max) {
1116  type_size_max_ = option_type_size_min;
1117  type_size_min_ = option_type_size_max;
1118  } else {
1119  type_size_min_ = option_type_size_min;
1120  type_size_max_ = option_type_size_max;
1121  }
1122  if(type_size_max_ == 0) {
1123  required_ = false;
1124  }
1126  inject_separator_ = true;
1127  }
1128  return this;
1129  }
1130 
1132  void inject_separator(bool value = true) { inject_separator_ = value; }
1133 
1135  Option *default_function(const std::function<std::string()> &func) {
1136  default_function_ = func;
1137  return this;
1138  }
1139 
1142  if(default_function_) {
1144  }
1145  return this;
1146  }
1147 
1149  Option *default_str(std::string val) {
1150  default_str_ = std::move(val);
1151  return this;
1152  }
1153 
1156  template <typename X> Option *default_val(const X &val) {
1157  std::string val_str = detail::to_string(val);
1158  auto old_option_state = current_option_state_;
1159  results_t old_results{std::move(results_)};
1160  results_.clear();
1161  try {
1162  add_result(val_str);
1163  // if trigger_on_result_ is set the callback already ran
1165  run_callback(); // run callback sets the state we need to reset it again
1167  } else {
1168  _validate_results(results_);
1169  current_option_state_ = old_option_state;
1170  }
1171  } catch(const CLI::Error &) {
1172  // this should be done
1173  results_ = std::move(old_results);
1174  current_option_state_ = old_option_state;
1175  throw;
1176  }
1177  results_ = std::move(old_results);
1178  default_str_ = std::move(val_str);
1179  return this;
1180  }
1181 
1183  std::string get_type_name() const {
1184  std::string full_type_name = type_name_();
1185  if(!validators_.empty()) {
1186  for(auto &Validator : validators_) {
1187  std::string vtype = Validator.get_description();
1188  if(!vtype.empty()) {
1189  full_type_name += ":" + vtype;
1190  }
1191  }
1192  }
1193  return full_type_name;
1194  }
1195 
1196  private:
1198  void _validate_results(results_t &res) const {
1199  // Run the Validators (can change the string)
1200  if(!validators_.empty()) {
1201  if(type_size_max_ > 1) { // in this context index refers to the index in the type
1202  int index = 0;
1203  if(get_items_expected_max() < static_cast<int>(res.size()) &&
1205  // create a negative index for the earliest ones
1206  index = get_items_expected_max() - static_cast<int>(res.size());
1207  }
1208 
1209  for(std::string &result : res) {
1210  if(detail::is_separator(result) && type_size_max_ != type_size_min_ && index >= 0) {
1211  index = 0; // reset index for variable size chunks
1212  continue;
1213  }
1214  auto err_msg = _validate(result, (index >= 0) ? (index % type_size_max_) : index);
1215  if(!err_msg.empty())
1216  throw ValidationError(get_name(), err_msg);
1217  ++index;
1218  }
1219  } else {
1220  int index = 0;
1221  if(expected_max_ < static_cast<int>(res.size()) &&
1223  // create a negative index for the earliest ones
1224  index = expected_max_ - static_cast<int>(res.size());
1225  }
1226  for(std::string &result : res) {
1227  auto err_msg = _validate(result, index);
1228  ++index;
1229  if(!err_msg.empty())
1230  throw ValidationError(get_name(), err_msg);
1231  }
1232  }
1233  }
1234  }
1235 
1239  void _reduce_results(results_t &res, const results_t &original) const {
1240 
1241  // max num items expected or length of vector, always at least 1
1242  // Only valid for a trimming policy
1243 
1244  res.clear();
1245  // Operation depends on the policy setting
1246  switch(multi_option_policy_) {
1248  break;
1250  // Allow multi-option sizes (including 0)
1251  std::size_t trim_size = std::min<std::size_t>(
1252  static_cast<std::size_t>(std::max<int>(get_items_expected_max(), 1)), original.size());
1253  if(original.size() != trim_size) {
1254  res.assign(original.end() - static_cast<results_t::difference_type>(trim_size), original.end());
1255  }
1256  } break;
1258  std::size_t trim_size = std::min<std::size_t>(
1259  static_cast<std::size_t>(std::max<int>(get_items_expected_max(), 1)), original.size());
1260  if(original.size() != trim_size) {
1261  res.assign(original.begin(), original.begin() + static_cast<results_t::difference_type>(trim_size));
1262  }
1263  } break;
1265  if(results_.size() > 1) {
1266  res.push_back(detail::join(original, std::string(1, (delimiter_ == '\0') ? '\n' : delimiter_)));
1267  }
1268  break;
1270  default: {
1271  auto num_min = static_cast<std::size_t>(get_items_expected_min());
1272  auto num_max = static_cast<std::size_t>(get_items_expected_max());
1273  if(num_min == 0) {
1274  num_min = 1;
1275  }
1276  if(num_max == 0) {
1277  num_max = 1;
1278  }
1279  if(original.size() < num_min) {
1280  throw ArgumentMismatch::AtLeast(get_name(), static_cast<int>(num_min), original.size());
1281  }
1282  if(original.size() > num_max) {
1283  throw ArgumentMismatch::AtMost(get_name(), static_cast<int>(num_max), original.size());
1284  }
1285  break;
1286  }
1287  }
1288  }
1289 
1290  // Run a result through the Validators
1291  std::string _validate(std::string &result, int index) const {
1292  std::string err_msg;
1293  if(result.empty() && expected_min_ == 0) {
1294  // an empty with nothing expected is allowed
1295  return err_msg;
1296  }
1297  for(const auto &vali : validators_) {
1298  auto v = vali.get_application_index();
1299  if(v == -1 || v == index) {
1300  try {
1301  err_msg = vali(result);
1302  } catch(const ValidationError &err) {
1303  err_msg = err.what();
1304  }
1305  if(!err_msg.empty())
1306  break;
1307  }
1308  }
1309 
1310  return err_msg;
1311  }
1312 
1314  int _add_result(std::string &&result, std::vector<std::string> &res) const {
1315  int result_count = 0;
1316  if(allow_extra_args_ && !result.empty() && result.front() == '[' &&
1317  result.back() == ']') { // this is now a vector string likely from the default or user entry
1318  result.pop_back();
1319 
1320  for(auto &var : CLI::detail::split(result.substr(1), ',')) {
1321  if(!var.empty()) {
1322  result_count += _add_result(std::move(var), res);
1323  }
1324  }
1325  return result_count;
1326  }
1327  if(delimiter_ == '\0') {
1328  res.push_back(std::move(result));
1329  ++result_count;
1330  } else {
1331  if((result.find_first_of(delimiter_) != std::string::npos)) {
1332  for(const auto &var : CLI::detail::split(result, delimiter_)) {
1333  if(!var.empty()) {
1334  res.push_back(var);
1335  ++result_count;
1336  }
1337  }
1338  } else {
1339  res.push_back(std::move(result));
1340  ++result_count;
1341  }
1342  }
1343  return result_count;
1344  }
1345 }; // namespace CLI
1346 
1347 // [CLI11:option_hpp:end]
1348 } // namespace CLI
Creates a command line program, with very few defaults.
Definition: App.hpp:69
Thrown when conversion call back fails, such as when an int fails to coerce to a string.
Definition: Error.hpp:196
All errors derive from this one.
Definition: Error.hpp:70
Thrown when an option is set to conflicting values (non-vector and multi args, for example)
Definition: Error.hpp:93
Thrown when an option already exists.
Definition: Error.hpp:135
Definition: Option.hpp:48
bool get_disable_flag_override() const
The status of configurable.
Definition: Option.hpp:136
bool get_ignore_case() const
The status of ignore case.
Definition: Option.hpp:127
bool get_configurable() const
The status of configurable.
Definition: Option.hpp:133
bool always_capture_default_
Automatically capture default value.
Definition: Option.hpp:74
MultiOptionPolicy multi_option_policy_
Policy for handling multiple arguments beyond the expected Max.
Definition: Option.hpp:77
bool get_ignore_underscore() const
The status of ignore_underscore.
Definition: Option.hpp:130
const std::string & get_group() const
Get the group of this option.
Definition: Option.hpp:121
CRTP * required(bool value=true)
Set the option as required.
Definition: Option.hpp:105
CRTP * join()
Set the multi option policy to join.
Definition: Option.hpp:171
CRTP * always_capture_default(bool value=true)
Definition: Option.hpp:113
CRTP * group(const std::string &name)
Changes the group membership.
Definition: Option.hpp:96
CRTP * take_all()
Set the multi option policy to take all arguments.
Definition: Option.hpp:164
bool ignore_case_
Ignore the case when matching (option, not value)
Definition: Option.hpp:59
MultiOptionPolicy get_multi_option_policy() const
The status of the multi option policy.
Definition: Option.hpp:145
CRTP * mandatory(bool value=true)
Support Plumbum term.
Definition: Option.hpp:111
bool configurable_
Allow this option to be given in a configuration file.
Definition: Option.hpp:65
CRTP * take_last()
Set the multi option policy to take last.
Definition: Option.hpp:150
bool get_required() const
True if this is a required option.
Definition: Option.hpp:124
bool disable_flag_override_
Disable overriding flag values with '=value'.
Definition: Option.hpp:68
bool required_
True if this is a required option.
Definition: Option.hpp:56
CRTP * take_first()
Set the multi option policy to take last.
Definition: Option.hpp:157
char delimiter_
Specify a delimiter character for vector arguments.
Definition: Option.hpp:71
bool get_always_capture_default() const
Return true if this will automatically capture the default value for help printing.
Definition: Option.hpp:142
std::string group_
The group membership.
Definition: Option.hpp:53
char get_delimiter() const
Get the current delimiter char.
Definition: Option.hpp:139
CRTP * join(char delim)
Set the multi option policy to join with a specific delimiter.
Definition: Option.hpp:178
CRTP * delimiter(char value='\0')
Allow in a configuration file.
Definition: Option.hpp:192
bool ignore_underscore_
Ignore underscores when matching (option, not value)
Definition: Option.hpp:62
void copy_to(T *other) const
Copy the contents to another similar class (one based on OptionBase)
Definition: Option.hpp:80
CRTP * configurable(bool value=true)
Allow in a configuration file.
Definition: Option.hpp:186
Definition: Option.hpp:200
OptionDefaults * delimiter(char value='\0')
set a delimiter character to split up single arguments to treat as multiple inputs
Definition: Option.hpp:231
OptionDefaults * disable_flag_override(bool value=true)
Disable overriding flag values with an '=' segment.
Definition: Option.hpp:225
OptionDefaults * ignore_underscore(bool value=true)
Ignore underscores in the option name.
Definition: Option.hpp:219
OptionDefaults()=default
OptionDefaults * ignore_case(bool value=true)
Ignore the case of the option name.
Definition: Option.hpp:213
OptionDefaults * multi_option_policy(MultiOptionPolicy value=MultiOptionPolicy::Throw)
Take the last argument if given multiple times.
Definition: Option.hpp:207
Thrown when counting a non-existent option.
Definition: Error.hpp:340
Definition: Option.hpp:237
Option * option_text(std::string text)
Definition: Option.hpp:767
Option * type_name_fn(std::function< std::string()> typefun)
Set the type function to run when displayed on this option.
Definition: Option.hpp:1076
int get_type_size_max() const
The maximum number of arguments the option expects.
Definition: Option.hpp:689
Option * trigger_on_parse(bool value=true)
Set the value of trigger_on_parse which specifies that the option callback should be triggered on eve...
Definition: Option.hpp:431
std::size_t count() const
Count the total number of times an option was passed.
Definition: Option.hpp:363
std::string default_str_
A human readable default value, either manually set, captured, or captured by default.
Definition: Option.hpp:271
bool run_callback_for_default_
Control option to run the callback to set the default.
Definition: Option.hpp:340
int get_expected_min() const
The number of times the option expects to be included.
Definition: Option.hpp:734
bool get_run_callback_for_default() const
Get the current value of run_callback_for_default.
Definition: Option.hpp:453
std::function< std::string()> type_name_
Definition: Option.hpp:279
int get_expected_max() const
The max number of times the option expects to be included.
Definition: Option.hpp:736
option_state
enumeration for the option state machine
Definition: Option.hpp:327
@ reduced
a subset of results has been generated
@ callback_run
the callback has been executed
@ validated
the results have been validated
@ parsing
The option is currently collecting parsed results.
option_state current_option_state_
Whether the callback has run (needed for INI parsing)
Definition: Option.hpp:334
std::string option_text_
If given, replace the text that describes the option type and usage in the help text.
Definition: Option.hpp:274
int type_size_min_
The minimum number of arguments an option should be expecting.
Definition: Option.hpp:292
bool get_trigger_on_parse() const
The status of trigger on parse.
Definition: Option.hpp:436
Option * needs(Option *opt)
Sets required options.
Definition: Option.hpp:530
int get_expected() const
The number of times the option expects to be included.
Definition: Option.hpp:731
std::string pname_
A positional name.
Definition: Option.hpp:258
results_t reduced_results() const
Get a copy of the results.
Definition: Option.hpp:1012
int expected_min_
The minimum number of expected values.
Definition: Option.hpp:295
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:350
Option * default_function(const std::function< std::string()> &func)
Set a capture function for the default. Mostly used by App.
Definition: Option.hpp:1135
Option * add_result(std::vector< std::string > s)
Puts a result at the end.
Definition: Option.hpp:1000
int get_type_size_min() const
The minimum number of arguments the option expects.
Definition: Option.hpp:687
std::string get_default_str() const
The default value (for help printing)
Definition: Option.hpp:704
std::set< Option * > needs_
A list of options that are required with this option.
Definition: Option.hpp:303
Option * run_callback_for_default(bool value=true)
Definition: Option.hpp:448
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:595
Option * type_size(int option_type_size_min, int option_type_size_max)
Set a custom option type size range.
Definition: Option.hpp:1107
const std::vector< std::string > & get_lnames() const
Get the long names.
Definition: Option.hpp:710
Option * default_str(std::string val)
Set the default value string representation (does not change the contained value)
Definition: Option.hpp:1149
Option * transform(Validator Validator, const std::string &Validator_name="")
Adds a transforming Validator with a built in type name.
Definition: Option.hpp:474
Option * default_val(const X &val)
Definition: Option.hpp:1156
bool trigger_on_result_
flag indicating that the option should trigger the validation and callback chain on each result when ...
Definition: Option.hpp:344
bool flag_like_
Specify that the option should act like a flag vs regular option.
Definition: Option.hpp:338
bool check_lname(std::string name) const
Requires "--" to be removed from string.
Definition: Option.hpp:928
Option * type_size(int option_type_size)
Set a custom option size.
Definition: Option.hpp:1088
std::set< Option * > excludes_
A list of options that are excluded with this option.
Definition: Option.hpp:306
Validator * get_validator(int index)
Get a Validator by index NOTE: this may not be the order of definition.
Definition: Option.hpp:521
std::set< Option * > get_needs() const
The set of options needed.
Definition: Option.hpp:698
bool force_callback_
flag indicating that the option should force the callback regardless if any results present
Definition: Option.hpp:346
bool check_fname(std::string name) const
Requires "--" to be removed from string.
Definition: Option.hpp:933
std::string get_flag_value(const std::string &name, std::string input_value) const
Definition: Option.hpp:942
std::vector< std::string > fnames_
a list of flag names with specified default values;
Definition: Option.hpp:255
const std::vector< std::string > & get_fnames() const
Get the flag names with specified default values.
Definition: Option.hpp:716
const results_t & results() const
Get the current complete results set.
Definition: Option.hpp:1009
Option * force_callback(bool value=true)
Set the value of force_callback.
Definition: Option.hpp:439
bool has_description() const
True if option has description.
Definition: Option.hpp:756
bool check_name(const std::string &name) const
Check a name. Requires "-" or "--" for short / long, supports positional name.
Definition: Option.hpp:893
Option(const Option &)=delete
bool get_force_callback() const
The status of force_callback.
Definition: Option.hpp:444
Option * excludes(A opt, B opt1, ARG... args)
Any number supported, any mix of string and Opt.
Definition: Option.hpp:589
bool get_allow_extra_args() const
Get the current value of allow extra args.
Definition: Option.hpp:429
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:993
std::vector< std::string > snames_
A list of the short names (-a) without the leading dashes.
Definition: Option.hpp:245
results_t proc_results_
results after reduction
Definition: Option.hpp:325
Option * add_result(std::string s)
Puts a result at the end.
Definition: Option.hpp:986
void inject_separator(bool value=true)
Set the value of the separator injection flag.
Definition: Option.hpp:1132
const std::string & get_single_name() const
Get a single name for the option, first of lname, pname, sname, envname.
Definition: Option.hpp:718
int get_type_size() const
The number of arguments the option expects.
Definition: Option.hpp:684
callback_t get_callback() const
Get the callback function.
Definition: Option.hpp:707
std::string get_type_name() const
Get the full typename for this option.
Definition: Option.hpp:1183
App * parent_
link back up to the parent App for fallthrough
Definition: Option.hpp:313
bool nonpositional() const
True if option has at least one non-positional name.
Definition: Option.hpp:753
Option * excludes(Option *opt)
Sets excluded options.
Definition: Option.hpp:564
int expected_max_
The maximum number of expected values.
Definition: Option.hpp:297
std::string get_envname() const
The environment variable associated to this value.
Definition: Option.hpp:695
Option * capture_default_str()
Capture the default value from the original value (if it can be captured)
Definition: Option.hpp:1141
const std::string & matching_name(const Option &other) const
If options share any of the same names, find it.
Definition: Option.hpp:869
int get_items_expected_max() const
Get the maximum number of items expected to be returned and used for the callback.
Definition: Option.hpp:742
Option * envname(std::string name)
Sets environment variable to read if no option given.
Definition: Option.hpp:606
int get_inject_separator() const
Return the inject_separator flag.
Definition: Option.hpp:692
Option * allow_extra_args(bool value=true)
Definition: Option.hpp:424
Option * multi_option_policy(MultiOptionPolicy value=MultiOptionPolicy::Throw)
Take the last argument if given multiple times (or another policy)
Definition: Option.hpp:661
std::string description_
The description for help strings.
Definition: Option.hpp:268
Option * ignore_case(bool value=true)
Definition: Option.hpp:615
bool inject_separator_
flag indicating a separator needs to be injected after each argument call
Definition: Option.hpp:342
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:553
bool get_callback_run() const
See if the callback has been run already.
Definition: Option.hpp:1069
T as() const
Return the results as the specified type.
Definition: Option.hpp:1062
void run_callback()
Process the callback.
Definition: Option.hpp:842
callback_t callback_
Options store a callback to do all the work.
Definition: Option.hpp:316
Option * needs(std::string opt_name)
Can find a string if needed.
Definition: Option.hpp:538
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:782
Option & operator=(const Option &)=delete
void clear()
Clear the parsed results (mostly for testing)
Definition: Option.hpp:372
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:465
Option * description(std::string option_description)
Set the description.
Definition: Option.hpp:762
Option * disable_flag_override(bool value=true)
Disable flag overrides values, e.g. –flag=is not allowed.
Definition: Option.hpp:675
Option * needs(A opt, B opt1, ARG... args)
Any number supported, any mix of string and Opt.
Definition: Option.hpp:547
void results(T &output) const
Get the results as a specified type.
Definition: Option.hpp:1031
Option * expected(int value_min, int value_max)
Set the range of expected arguments.
Definition: Option.hpp:404
const std::vector< std::string > & get_snames() const
Get the short names.
Definition: Option.hpp:713
bool get_positional() const
True if the argument can be given directly.
Definition: Option.hpp:750
std::string envname_
If given, check the environment for this option.
Definition: Option.hpp:261
std::function< std::string()> default_function_
Run this function to capture a default (ignore if empty)
Definition: Option.hpp:282
const std::string & get_option_text() const
Definition: Option.hpp:772
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:482
bool check_sname(std::string name) const
Requires "-" to be removed from string.
Definition: Option.hpp:923
Validator * get_validator(const std::string &Validator_name="")
Get a named Validator.
Definition: Option.hpp:508
std::vector< std::pair< std::string, std::string > > default_flag_values_
Definition: Option.hpp:252
std::vector< Validator > validators_
A list of Validators to run on each value parsed.
Definition: Option.hpp:300
const std::string & get_description() const
Get the description.
Definition: Option.hpp:759
int type_size_max_
Definition: Option.hpp:290
bool allow_extra_args_
Specify that extra args beyond type_size_max should be allowed.
Definition: Option.hpp:336
Option * type_name(std::string typeval)
Set a custom option typestring.
Definition: Option.hpp:1082
std::vector< std::string > lnames_
A list of the long names (--long) without the leading dashes.
Definition: Option.hpp:248
Option * excludes(std::string opt_name)
Can find a string if needed.
Definition: Option.hpp:580
bool operator==(const Option &other) const
If options share any of the same names, they are equal (not counting positional)
Definition: Option.hpp:890
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:498
std::set< Option * > get_excludes() const
The set of options excluded.
Definition: Option.hpp:701
Option * check(Validator validator, const std::string &validator_name="")
Adds a Validator with a built in type name.
Definition: Option.hpp:456
Option * ignore_underscore(bool value=true)
Definition: Option.hpp:639
results_t results_
complete Results of parsing
Definition: Option.hpp:323
bool empty() const
True if the option was not passed.
Definition: Option.hpp:366
Option * expected(int value)
Set the number of expected arguments.
Definition: Option.hpp:382
int get_items_expected_min() const
The total min number of expected string values to be used.
Definition: Option.hpp:739
int get_items_expected() const
The total min number of expected string values to be used.
Definition: Option.hpp:747
Some validators that are provided.
Definition: Validators.hpp:77
std::string get_description() const
Generate type description information for the Validator.
Definition: Validators.hpp:141
const std::string & get_name() const
Get the name of the Validator.
Definition: Validators.hpp:159
Validator & non_modifying(bool no_modify=true)
Specify whether the Validator can be modifying or not.
Definition: Validators.hpp:173
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:269
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:107
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:304
std::string remove_underscore(std::string str)
remove underscores from a string
Definition: StringTools.hpp:267
bool is_separator(const std::string &str)
check if a string is a container segment separator (empty or "%%")
Definition: StringTools.hpp:248
constexpr int expected_max_vector_size
Definition: StringTools.hpp:43
std::vector< std::string > split(const std::string &s, char delim)
Split a string by a delim.
Definition: StringTools.hpp:46
std::string join(const T &v, std::string delim=",")
Simple function to join a string.
Definition: StringTools.hpp:63
std::vector< std::string > split_names(std::string current)
Definition: Split.hpp:67
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:645
bool valid_alias_name_string(const std::string &str)
Verify an app name.
Definition: StringTools.hpp:242
std::string to_lower(std::string str)
Return a lower case version of a string.
Definition: StringTools.hpp:259
std::int64_t to_flag_value(std::string val)
Convert a flag into an integer value typically binary flags.
Definition: TypeTools.hpp:815
Definition: App.hpp:34
std::unique_ptr< Option > Option_p
Definition: Option.hpp:36
std::vector< std::string > results_t
Definition: Option.hpp:29
MultiOptionPolicy
Enumeration of the multiOption Policy selection.
Definition: Option.hpp:38
@ TakeAll
just get all the passed argument regardless
@ TakeFirst
take only the first Expected number of arguments
@ Throw
Throw an error if any extra arguments were given.
@ TakeLast
take only the last Expected number of arguments
@ Join
merge all the arguments together into a single string via the delimiter character default(' ')
std::function< bool(const results_t &)> callback_t
callback function definition
Definition: Option.hpp:31