Scarab  v3.5.1
Project 8 C++ Utility Library
CLI11.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 // CLI11: Version 1.8.0
4 // Originally designed by Henry Schreiner
5 // https://github.com/CLIUtils/CLI11
6 //
7 // This is a standalone header file generated by MakeSingleHeader.py in CLI11/scripts
8 // from: v1.8.0
9 //
10 // From LICENSE:
11 //
12 // CLI11 1.8 Copyright (c) 2017-2019 University of Cincinnati, developed by Henry
13 // Schreiner under NSF AWARD 1414736. All rights reserved.
14 //
15 // Redistribution and use in source and binary forms of CLI11, with or without
16 // modification, are permitted provided that the following conditions are met:
17 //
18 // 1. Redistributions of source code must retain the above copyright notice, this
19 // list of conditions and the following disclaimer.
20 // 2. Redistributions in binary form must reproduce the above copyright notice,
21 // this list of conditions and the following disclaimer in the documentation
22 // and/or other materials provided with the distribution.
23 // 3. Neither the name of the copyright holder nor the names of its contributors
24 // may be used to endorse or promote products derived from this software without
25 // specific prior written permission.
26 //
27 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
28 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
29 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
30 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
31 // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
32 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
33 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
34 // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 
38 
39 // Standard combined includes:
40 
41 #include <algorithm>
42 #include <cmath>
43 #include <deque>
44 #include <exception>
45 #include <fstream>
46 #include <functional>
47 #include <iomanip>
48 #include <iostream>
49 #include <istream>
50 #include <iterator>
51 #include <locale>
52 #include <map>
53 #include <memory>
54 #include <numeric>
55 #include <set>
56 #include <sstream>
57 #include <stdexcept>
58 #include <string>
59 #include <sys/stat.h>
60 #include <sys/types.h>
61 #include <tuple>
62 #include <type_traits>
63 #include <utility>
64 #include <vector>
65 
66 
67 // Verbatim copy from CLI/Version.hpp:
68 
69 
70 #define CLI11_VERSION_MAJOR 1
71 #define CLI11_VERSION_MINOR 8
72 #define CLI11_VERSION_PATCH 0
73 #define CLI11_VERSION "1.8.0"
74 
75 
76 
77 
78 // Verbatim copy from CLI/Macros.hpp:
79 
80 
81 // The following version macro is very similar to the one in PyBind11
82 #if !(defined(_MSC_VER) && __cplusplus == 199711L) && !defined(__INTEL_COMPILER)
83 #if __cplusplus >= 201402L
84 #define CLI11_CPP14
85 #if __cplusplus >= 201703L
86 #define CLI11_CPP17
87 #if __cplusplus > 201703L
88 #define CLI11_CPP20
89 #endif
90 #endif
91 #endif
92 #elif defined(_MSC_VER) && __cplusplus == 199711L
93 // MSVC sets _MSVC_LANG rather than __cplusplus (supposedly until the standard is fully implemented)
94 // Unless you use the /Zc:__cplusplus flag on Visual Studio 2017 15.7 Preview 3 or newer
95 #if _MSVC_LANG >= 201402L
96 #define CLI11_CPP14
97 #if _MSVC_LANG > 201402L && _MSC_VER >= 1910
98 #define CLI11_CPP17
99 #if __MSVC_LANG > 201703L && _MSC_VER >= 1910
100 #define CLI11_CPP20
101 #endif
102 #endif
103 #endif
104 #endif
105 
106 #if defined(CLI11_CPP14)
107 #define CLI11_DEPRECATED(reason) [[deprecated(reason)]]
108 #elif defined(_MSC_VER)
109 #define CLI11_DEPRECATED(reason) __declspec(deprecated(reason))
110 #else
111 #define CLI11_DEPRECATED(reason) __attribute__((deprecated(reason)))
112 #endif
113 
114 
115 
116 
117 // Verbatim copy from CLI/Optional.hpp:
118 
119 
120 // You can explicitly enable or disable support
121 // by defining to 1 or 0. Extra check here to ensure it's in the stdlib too.
122 // We nest the check for __has_include and it's usage
123 #ifndef CLI11_STD_OPTIONAL
124 #ifdef __has_include
125 #if defined(CLI11_CPP17) && __has_include(<optional>)
126 #define CLI11_STD_OPTIONAL 1
127 #else
128 #define CLI11_STD_OPTIONAL 0
129 #endif
130 #else
131 #define CLI11_STD_OPTIONAL 0
132 #endif
133 #endif
134 
135 #ifndef CLI11_EXPERIMENTAL_OPTIONAL
136 #define CLI11_EXPERIMENTAL_OPTIONAL 0
137 #endif
138 
139 #ifndef CLI11_BOOST_OPTIONAL
140 #define CLI11_BOOST_OPTIONAL 0
141 #endif
142 
143 #if CLI11_BOOST_OPTIONAL
144 #include <boost/version.hpp>
145 #if BOOST_VERSION < 106100
146 #error "This boost::optional version is not supported, use 1.61 or better"
147 #endif
148 #endif
149 
150 #if CLI11_STD_OPTIONAL
151 #include <optional>
152 #endif
153 #if CLI11_EXPERIMENTAL_OPTIONAL
154 #include <experimental/optional>
155 #endif
156 #if CLI11_BOOST_OPTIONAL
157 #include <boost/optional.hpp>
158 #include <boost/optional/optional_io.hpp>
159 #endif
160 
161 
162 // From CLI/Version.hpp:
163 
164 
165 
166 // From CLI/Macros.hpp:
167 
168 
169 
170 // From CLI/Optional.hpp:
171 
172 namespace CLI {
173 
174 #if CLI11_STD_OPTIONAL
175 template <typename T> std::istream &operator>>(std::istream &in, std::optional<T> &val) {
176  T v;
177  in >> v;
178  val = v;
179  return in;
180 }
181 #endif
182 
183 #if CLI11_EXPERIMENTAL_OPTIONAL
184 template <typename T> std::istream &operator>>(std::istream &in, std::experimental::optional<T> &val) {
185  T v;
186  in >> v;
187  val = v;
188  return in;
189 }
190 #endif
191 
192 #if CLI11_BOOST_OPTIONAL
193 template <typename T> std::istream &operator>>(std::istream &in, boost::optional<T> &val) {
194  T v;
195  in >> v;
196  val = v;
197  return in;
198 }
199 #endif
200 
201 // Export the best optional to the CLI namespace
202 #if CLI11_STD_OPTIONAL
203 using std::optional;
204 #elif CLI11_EXPERIMENTAL_OPTIONAL
205 using std::experimental::optional;
206 #elif CLI11_BOOST_OPTIONAL
207 using boost::optional;
208 #endif
209 
210 // This is true if any optional is found
211 #if CLI11_STD_OPTIONAL || CLI11_EXPERIMENTAL_OPTIONAL || CLI11_BOOST_OPTIONAL
212 #define CLI11_OPTIONAL 1
213 #endif
214 
215 } // namespace CLI
216 
217 // From CLI/StringTools.hpp:
218 
219 namespace CLI {
220 
223 namespace enums {
224 
226 template <typename T, typename = typename std::enable_if<std::is_enum<T>::value>::type>
227 std::ostream &operator<<(std::ostream &in, const T &item) {
228  // make sure this is out of the detail namespace otherwise it won't be found when needed
230 }
231 
233 template <typename T, typename = typename std::enable_if<std::is_enum<T>::value>::type>
234 std::istream &operator>>(std::istream &in, T &item) {
236  in >> i;
237  item = static_cast<T>(i);
238  return in;
239 }
240 } // namespace enums
241 
243 using namespace enums;
244 
245 namespace detail {
246 
247 // Based on http://stackoverflow.com/questions/236129/split-a-string-in-c
249 inline std::vector<std::string> split(const std::string &s, char delim) {
250  std::vector<std::string> elems;
251  // Check to see if empty string, give consistent result
252  if(s.empty())
253  elems.emplace_back();
254  else {
255  std::stringstream ss;
256  ss.str(s);
257  std::string item;
258  while(std::getline(ss, item, delim)) {
259  elems.push_back(item);
260  }
261  }
262  return elems;
263 }
265 template <typename T> inline std::string as_string(const T &v) {
266  std::ostringstream s;
267  s << v;
268  return s.str();
269 }
270 // if the data type is already a string just forward it
271 template <typename T, typename = typename std::enable_if<std::is_constructible<std::string, T>::value>::type>
272 inline auto as_string(T &&v) -> decltype(std::forward<T>(v)) {
273  return std::forward<T>(v);
274 }
275 
277 template <typename T> std::string join(const T &v, std::string delim = ",") {
278  std::ostringstream s;
279  auto beg = std::begin(v);
280  auto end = std::end(v);
281  if(beg != end)
282  s << *beg++;
283  while(beg != end) {
284  s << delim << *beg++;
285  }
286  return s.str();
287 }
288 
290 template <typename T,
291  typename Callable,
292  typename = typename std::enable_if<!std::is_constructible<std::string, Callable>::value>::type>
293 std::string join(const T &v, Callable func, std::string delim = ",") {
294  std::ostringstream s;
295  auto beg = std::begin(v);
296  auto end = std::end(v);
297  if(beg != end)
298  s << func(*beg++);
299  while(beg != end) {
300  s << delim << func(*beg++);
301  }
302  return s.str();
303 }
304 
306 template <typename T> std::string rjoin(const T &v, std::string delim = ",") {
307  std::ostringstream s;
308  for(size_t start = 0; start < v.size(); start++) {
309  if(start > 0)
310  s << delim;
311  s << v[v.size() - start - 1];
312  }
313  return s.str();
314 }
315 
316 // Based roughly on http://stackoverflow.com/questions/25829143/c-trim-whitespace-from-a-string
317 
319 inline std::string &ltrim(std::string &str) {
320  auto it = std::find_if(str.begin(), str.end(), [](char ch) { return !std::isspace<char>(ch, std::locale()); });
321  str.erase(str.begin(), it);
322  return str;
323 }
324 
326 inline std::string &ltrim(std::string &str, const std::string &filter) {
327  auto it = std::find_if(str.begin(), str.end(), [&filter](char ch) { return filter.find(ch) == std::string::npos; });
328  str.erase(str.begin(), it);
329  return str;
330 }
331 
333 inline std::string &rtrim(std::string &str) {
334  auto it = std::find_if(str.rbegin(), str.rend(), [](char ch) { return !std::isspace<char>(ch, std::locale()); });
335  str.erase(it.base(), str.end());
336  return str;
337 }
338 
340 inline std::string &rtrim(std::string &str, const std::string &filter) {
341  auto it =
342  std::find_if(str.rbegin(), str.rend(), [&filter](char ch) { return filter.find(ch) == std::string::npos; });
343  str.erase(it.base(), str.end());
344  return str;
345 }
346 
348 inline std::string &trim(std::string &str) { return ltrim(rtrim(str)); }
349 
351 inline std::string &trim(std::string &str, const std::string filter) { return ltrim(rtrim(str, filter), filter); }
352 
354 inline std::string trim_copy(const std::string &str) {
355  std::string s = str;
356  return trim(s);
357 }
358 
360 inline std::string trim_copy(const std::string &str, const std::string &filter) {
361  std::string s = str;
362  return trim(s, filter);
363 }
365 inline std::ostream &format_help(std::ostream &out, std::string name, std::string description, size_t wid) {
366  name = " " + name;
367  out << std::setw(static_cast<int>(wid)) << std::left << name;
368  if(!description.empty()) {
369  if(name.length() >= wid)
370  out << "\n" << std::setw(static_cast<int>(wid)) << "";
371  for(const char c : description) {
372  out.put(c);
373  if(c == '\n') {
374  out << std::setw(static_cast<int>(wid)) << "";
375  }
376  }
377  }
378  out << "\n";
379  return out;
380 }
381 
383 template <typename T> bool valid_first_char(T c) {
384  return std::isalnum(c, std::locale()) || c == '_' || c == '?' || c == '@';
385 }
386 
388 template <typename T> bool valid_later_char(T c) { return valid_first_char(c) || c == '.' || c == '-'; }
389 
391 inline bool valid_name_string(const std::string &str) {
392  if(str.empty() || !valid_first_char(str[0]))
393  return false;
394  for(auto c : str.substr(1))
395  if(!valid_later_char(c))
396  return false;
397  return true;
398 }
399 
401 inline bool isalpha(const std::string &str) {
402  return std::all_of(str.begin(), str.end(), [](char c) { return std::isalpha(c, std::locale()); });
403 }
404 
406 inline std::string to_lower(std::string str) {
407  std::transform(std::begin(str), std::end(str), std::begin(str), [](const std::string::value_type &x) {
408  return std::tolower(x, std::locale());
409  });
410  return str;
411 }
412 
414 inline std::string remove_underscore(std::string str) {
415  str.erase(std::remove(std::begin(str), std::end(str), '_'), std::end(str));
416  return str;
417 }
418 
420 inline std::string find_and_replace(std::string str, std::string from, std::string to) {
421 
422  size_t start_pos = 0;
423 
424  while((start_pos = str.find(from, start_pos)) != std::string::npos) {
425  str.replace(start_pos, from.length(), to);
426  start_pos += to.length();
427  }
428 
429  return str;
430 }
431 
433 inline bool has_default_flag_values(const std::string &flags) {
434  return (flags.find_first_of("{!") != std::string::npos);
435 }
436 
437 inline void remove_default_flag_values(std::string &flags) {
438  auto loc = flags.find_first_of('{');
439  while(loc != std::string::npos) {
440  auto finish = flags.find_first_of("},", loc + 1);
441  if((finish != std::string::npos) && (flags[finish] == '}')) {
442  flags.erase(flags.begin() + static_cast<std::ptrdiff_t>(loc),
443  flags.begin() + static_cast<std::ptrdiff_t>(finish) + 1);
444  }
445  loc = flags.find_first_of('{', loc + 1);
446  }
447  flags.erase(std::remove(flags.begin(), flags.end(), '!'), flags.end());
448 }
449 
451 inline std::ptrdiff_t find_member(std::string name,
452  const std::vector<std::string> names,
453  bool ignore_case = false,
454  bool ignore_underscore = false) {
455  auto it = std::end(names);
456  if(ignore_case) {
457  if(ignore_underscore) {
459  it = std::find_if(std::begin(names), std::end(names), [&name](std::string local_name) {
460  return detail::to_lower(detail::remove_underscore(local_name)) == name;
461  });
462  } else {
463  name = detail::to_lower(name);
464  it = std::find_if(std::begin(names), std::end(names), [&name](std::string local_name) {
465  return detail::to_lower(local_name) == name;
466  });
467  }
468 
469  } else if(ignore_underscore) {
470  name = detail::remove_underscore(name);
471  it = std::find_if(std::begin(names), std::end(names), [&name](std::string local_name) {
472  return detail::remove_underscore(local_name) == name;
473  });
474  } else
475  it = std::find(std::begin(names), std::end(names), name);
476 
477  return (it != std::end(names)) ? (it - std::begin(names)) : (-1);
478 }
479 
482 template <typename Callable> inline std::string find_and_modify(std::string str, std::string trigger, Callable modify) {
483  size_t start_pos = 0;
484  while((start_pos = str.find(trigger, start_pos)) != std::string::npos) {
485  start_pos = modify(str, start_pos);
486  }
487  return str;
488 }
489 
492 inline std::vector<std::string> split_up(std::string str) {
493 
494  const std::string delims("\'\"`");
495  auto find_ws = [](char ch) { return std::isspace<char>(ch, std::locale()); };
496  trim(str);
497 
498  std::vector<std::string> output;
499  bool embeddedQuote = false;
500  char keyChar = ' ';
501  while(!str.empty()) {
502  if(delims.find_first_of(str[0]) != std::string::npos) {
503  keyChar = str[0];
504  auto end = str.find_first_of(keyChar, 1);
505  while((end != std::string::npos) && (str[end - 1] == '\\')) { // deal with escaped quotes
506  end = str.find_first_of(keyChar, end + 1);
507  embeddedQuote = true;
508  }
509  if(end != std::string::npos) {
510  output.push_back(str.substr(1, end - 1));
511  str = str.substr(end + 1);
512  } else {
513  output.push_back(str.substr(1));
514  str = "";
515  }
516  } else {
517  auto it = std::find_if(std::begin(str), std::end(str), find_ws);
518  if(it != std::end(str)) {
519  std::string value = std::string(str.begin(), it);
520  output.push_back(value);
521  str = std::string(it, str.end());
522  } else {
523  output.push_back(str);
524  str = "";
525  }
526  }
527  // transform any embedded quotes into the regular character
528  if(embeddedQuote) {
529  output.back() = find_and_replace(output.back(), std::string("\\") + keyChar, std::string(1, keyChar));
530  embeddedQuote = false;
531  }
532  trim(str);
533  }
534  return output;
535 }
536 
541 inline std::string fix_newlines(std::string leader, std::string input) {
542  std::string::size_type n = 0;
543  while(n != std::string::npos && n < input.size()) {
544  n = input.find('\n', n);
545  if(n != std::string::npos) {
546  input = input.substr(0, n + 1) + leader + input.substr(n + 1);
547  n += leader.size();
548  }
549  }
550  return input;
551 }
552 
557 inline size_t escape_detect(std::string &str, size_t offset) {
558  auto next = str[offset + 1];
559  if((next == '\"') || (next == '\'') || (next == '`')) {
560  auto astart = str.find_last_of("-/ \"\'`", offset - 1);
561  if(astart != std::string::npos) {
562  if(str[astart] == ((str[offset] == '=') ? '-' : '/'))
563  str[offset] = ' '; // interpret this as a space so the split_up works properly
564  }
565  }
566  return offset + 1;
567 }
568 
570 inline std::string &add_quotes_if_needed(std::string &str) {
571  if((str.front() != '"' && str.front() != '\'') || str.front() != str.back()) {
572  char quote = str.find('"') < str.find('\'') ? '\'' : '"';
573  if(str.find(' ') != std::string::npos) {
574  str.insert(0, 1, quote);
575  str.append(1, quote);
576  }
577  }
578  return str;
579 }
580 
581 } // namespace detail
582 
583 } // namespace CLI
584 
585 // From CLI/Error.hpp:
586 
587 namespace CLI {
588 
589 // Use one of these on all error classes.
590 // These are temporary and are undef'd at the end of this file.
591 #define CLI11_ERROR_DEF(parent, name) \
592  protected: \
593  name(std::string ename, std::string msg, int exit_code) : parent(std::move(ename), std::move(msg), exit_code) {} \
594  name(std::string ename, std::string msg, ExitCodes exit_code) \
595  : parent(std::move(ename), std::move(msg), exit_code) {} \
596  \
597  public: \
598  name(std::string msg, ExitCodes exit_code) : parent(#name, std::move(msg), exit_code) {} \
599  name(std::string msg, int exit_code) : parent(#name, std::move(msg), exit_code) {}
600 
601 // This is added after the one above if a class is used directly and builds its own message
602 #define CLI11_ERROR_SIMPLE(name) \
603  explicit name(std::string msg) : name(#name, msg, ExitCodes::name) {}
604 
607 enum class ExitCodes {
608  Success = 0,
609  IncorrectConstruction = 100,
612  FileError,
618  ExtrasError,
619  ConfigError,
620  InvalidError,
624  BaseClass = 127
625 };
626 
627 // Error definitions
628 
634 
636 class Error : public std::runtime_error {
638  std::string error_name{"Error"};
639 
640  public:
641  int get_exit_code() const { return actual_exit_code; }
642 
643  std::string get_name() const { return error_name; }
644 
645  Error(std::string name, std::string msg, int exit_code = static_cast<int>(ExitCodes::BaseClass))
646  : runtime_error(msg), actual_exit_code(exit_code), error_name(std::move(name)) {}
647 
648  Error(std::string name, std::string msg, ExitCodes exit_code) : Error(name, msg, static_cast<int>(exit_code)) {}
649 };
650 
651 // Note: Using Error::Error constructors does not work on GCC 4.7
652 
654 class ConstructionError : public Error {
656 };
657 
662  static IncorrectConstruction PositionalFlag(std::string name) {
663  return IncorrectConstruction(name + ": Flags cannot be positional");
664  }
665  static IncorrectConstruction Set0Opt(std::string name) {
666  return IncorrectConstruction(name + ": Cannot set 0 expected, use a flag instead");
667  }
668  static IncorrectConstruction SetFlag(std::string name) {
669  return IncorrectConstruction(name + ": Cannot set an expected number for flags");
670  }
671  static IncorrectConstruction ChangeNotVector(std::string name) {
672  return IncorrectConstruction(name + ": You can only change the expected arguments for vectors");
673  }
674  static IncorrectConstruction AfterMultiOpt(std::string name) {
675  return IncorrectConstruction(
676  name + ": You can't change expected arguments after you've changed the multi option policy!");
677  }
678  static IncorrectConstruction MissingOption(std::string name) {
679  return IncorrectConstruction("Option " + name + " is not defined");
680  }
681  static IncorrectConstruction MultiOptionPolicy(std::string name) {
682  return IncorrectConstruction(name + ": multi_option_policy only works for flags and exact value options");
683  }
684 };
685 
690  static BadNameString OneCharName(std::string name) { return BadNameString("Invalid one char name: " + name); }
691  static BadNameString BadLongName(std::string name) { return BadNameString("Bad long name: " + name); }
692  static BadNameString DashesOnly(std::string name) {
693  return BadNameString("Must have a name, not just dashes: " + name);
694  }
695  static BadNameString MultiPositionalNames(std::string name) {
696  return BadNameString("Only one positional name allowed, remove: " + name);
697  }
698 };
699 
703  explicit OptionAlreadyAdded(std::string name)
704  : OptionAlreadyAdded(name + " is already added", ExitCodes::OptionAlreadyAdded) {}
705  static OptionAlreadyAdded Requires(std::string name, std::string other) {
706  return OptionAlreadyAdded(name + " requires " + other, ExitCodes::OptionAlreadyAdded);
707  }
708  static OptionAlreadyAdded Excludes(std::string name, std::string other) {
709  return OptionAlreadyAdded(name + " excludes " + other, ExitCodes::OptionAlreadyAdded);
710  }
711 };
712 
713 // Parsing errors
714 
716 class ParseError : public Error {
718 };
719 
720 // Not really "errors"
721 
723 class Success : public ParseError {
725  Success() : Success("Successfully completed, should be caught and quit", ExitCodes::Success) {}
726 };
727 
729 class CallForHelp : public ParseError {
731  CallForHelp() : CallForHelp("This should be caught in your main function, see examples", ExitCodes::Success) {}
732 };
733 
735 class CallForAllHelp : public ParseError {
738  : CallForAllHelp("This should be caught in your main function, see examples", ExitCodes::Success) {}
739 };
740 
742 class RuntimeError : public ParseError {
744  explicit RuntimeError(int exit_code = 1) : RuntimeError("Runtime error", exit_code) {}
745 };
746 
748 class FileError : public ParseError {
751  static FileError Missing(std::string name) { return FileError(name + " was not readable (missing?)"); }
752 };
753 
755 class ConversionError : public ParseError {
758  ConversionError(std::string member, std::string name)
759  : ConversionError("The value " + member + " is not an allowed value for " + name) {}
760  ConversionError(std::string name, std::vector<std::string> results)
761  : ConversionError("Could not convert: " + name + " = " + detail::join(results)) {}
762  static ConversionError TooManyInputsFlag(std::string name) {
763  return ConversionError(name + ": too many inputs for a flag");
764  }
765  static ConversionError TrueFalse(std::string name) {
766  return ConversionError(name + ": Should be true/false or a number");
767  }
768 };
769 
771 class ValidationError : public ParseError {
774  explicit ValidationError(std::string name, std::string msg) : ValidationError(name + ": " + msg) {}
775 };
776 
778 class RequiredError : public ParseError {
780  explicit RequiredError(std::string name) : RequiredError(name + " is required", ExitCodes::RequiredError) {}
781  static RequiredError Subcommand(size_t min_subcom) {
782  if(min_subcom == 1)
783  return RequiredError("A subcommand");
784  else
785  return RequiredError("Requires at least " + std::to_string(min_subcom) + " subcommands",
787  }
788  static RequiredError Option(size_t min_option, size_t max_option, size_t used, const std::string &option_list) {
789  if((min_option == 1) && (max_option == 1) && (used == 0))
790  return RequiredError("Exactly 1 option from [" + option_list + "]");
791  else if((min_option == 1) && (max_option == 1) && (used > 1))
792  return RequiredError("Exactly 1 option from [" + option_list + "] is required and " + std::to_string(used) +
793  " were given",
795  else if((min_option == 1) && (used == 0))
796  return RequiredError("At least 1 option from [" + option_list + "]");
797  else if(used < min_option)
798  return RequiredError("Requires at least " + std::to_string(min_option) + " options used and only " +
799  std::to_string(used) + "were given from [" + option_list + "]",
801  else if(max_option == 1)
802  return RequiredError("Requires at most 1 options be given from [" + option_list + "]",
804  else
805  return RequiredError("Requires at most " + std::to_string(max_option) + " options be used and " +
806  std::to_string(used) + "were given from [" + option_list + "]",
808  }
809 };
810 
812 class ArgumentMismatch : public ParseError {
815  ArgumentMismatch(std::string name, int expected, size_t recieved)
816  : ArgumentMismatch(expected > 0 ? ("Expected exactly " + std::to_string(expected) + " arguments to " + name +
817  ", got " + std::to_string(recieved))
818  : ("Expected at least " + std::to_string(-expected) + " arguments to " + name +
819  ", got " + std::to_string(recieved)),
821 
822  static ArgumentMismatch AtLeast(std::string name, int num) {
823  return ArgumentMismatch(name + ": At least " + std::to_string(num) + " required");
824  }
825  static ArgumentMismatch TypedAtLeast(std::string name, int num, std::string type) {
826  return ArgumentMismatch(name + ": " + std::to_string(num) + " required " + type + " missing");
827  }
828  static ArgumentMismatch FlagOverride(std::string name) {
829  return ArgumentMismatch(name + " was given a disallowed flag override");
830  }
831 };
832 
834 class RequiresError : public ParseError {
836  RequiresError(std::string curname, std::string subname)
837  : RequiresError(curname + " requires " + subname, ExitCodes::RequiresError) {}
838 };
839 
841 class ExcludesError : public ParseError {
843  ExcludesError(std::string curname, std::string subname)
844  : ExcludesError(curname + " excludes " + subname, ExitCodes::ExcludesError) {}
845 };
846 
848 class ExtrasError : public ParseError {
850  explicit ExtrasError(std::vector<std::string> args)
851  : ExtrasError((args.size() > 1 ? "The following arguments were not expected: "
852  : "The following argument was not expected: ") +
853  detail::rjoin(args, " "),
855 };
856 
858 class ConfigError : public ParseError {
861  static ConfigError Extras(std::string item) { return ConfigError("INI was not able to parse " + item); }
862  static ConfigError NotConfigurable(std::string item) {
863  return ConfigError(item + ": This option is not allowed in a configuration file");
864  }
865 };
866 
868 class InvalidError : public ParseError {
870  explicit InvalidError(std::string name)
871  : InvalidError(name + ": Too many positional arguments with unlimited expected args", ExitCodes::InvalidError) {
872  }
873 };
874 
877 class HorribleError : public ParseError {
880 };
881 
882 // After parsing
883 
885 class OptionNotFound : public Error {
887  explicit OptionNotFound(std::string name) : OptionNotFound(name + " not found", ExitCodes::OptionNotFound) {}
888 };
889 
890 #undef CLI11_ERROR_DEF
891 #undef CLI11_ERROR_SIMPLE
892 
894 
895 } // namespace CLI
896 
897 // From CLI/TypeTools.hpp:
898 
899 namespace CLI {
900 
901 // Type tools
902 
903 // Utilities for type enabling
904 namespace detail {
905 // Based generally on https://rmf.io/cxx11/almost-static-if
907 enum class enabler {};
908 
910 constexpr enabler dummy = {};
911 } // namespace detail
912 
918 template <bool B, class T = void> using enable_if_t = typename std::enable_if<B, T>::type;
919 
921 template <typename... Ts> struct make_void { using type = void; };
922 
924 template <typename... Ts> using void_t = typename make_void<Ts...>::type;
925 
927 template <bool B, class T, class F> using conditional_t = typename std::conditional<B, T, F>::type;
928 
930 template <typename T> struct is_vector : std::false_type {};
931 
933 template <class T, class A> struct is_vector<std::vector<T, A>> : std::true_type {};
934 
936 template <typename T> struct is_bool : std::false_type {};
937 
939 template <> struct is_bool<bool> : std::true_type {};
940 
942 template <typename T> struct is_shared_ptr : std::false_type {};
943 
945 template <typename T> struct is_shared_ptr<std::shared_ptr<T>> : std::true_type {};
946 
948 template <typename T> struct is_shared_ptr<const std::shared_ptr<T>> : std::true_type {};
949 
951 template <typename T> struct is_copyable_ptr {
952  static bool const value = is_shared_ptr<T>::value || std::is_pointer<T>::value;
953 };
954 
956 template <typename T> struct IsMemberType { using type = T; };
957 
959 template <> struct IsMemberType<const char *> { using type = std::string; };
960 
961 namespace detail {
962 
963 // These are utilities for IsMember
964 
967 template <typename T> struct element_type {
968  using type =
969  typename std::conditional<is_copyable_ptr<T>::value, typename std::pointer_traits<T>::element_type, T>::type;
970 };
971 
974 template <typename T> struct element_value_type { using type = typename element_type<T>::type::value_type; };
975 
977 template <typename T, typename _ = void> struct pair_adaptor : std::false_type {
978  using value_type = typename T::value_type;
981 
983  template <typename Q> static auto first(Q &&pair_value) -> decltype(std::forward<Q>(pair_value)) {
984  return std::forward<Q>(pair_value);
985  }
987  template <typename Q> static auto second(Q &&pair_value) -> decltype(std::forward<Q>(pair_value)) {
988  return std::forward<Q>(pair_value);
989  }
990 };
991 
994 template <typename T>
996  T,
997  conditional_t<false, void_t<typename T::value_type::first_type, typename T::value_type::second_type>, void>>
998  : std::true_type {
999  using value_type = typename T::value_type;
1002 
1004  template <typename Q> static auto first(Q &&pair_value) -> decltype(std::get<0>(std::forward<Q>(pair_value))) {
1005  return std::get<0>(std::forward<Q>(pair_value));
1006  }
1008  template <typename Q> static auto second(Q &&pair_value) -> decltype(std::get<1>(std::forward<Q>(pair_value))) {
1009  return std::get<1>(std::forward<Q>(pair_value));
1010  }
1011 };
1012 
1013 // Check for streamability
1014 // Based on https://stackoverflow.com/questions/22758291/how-can-i-detect-if-a-type-can-be-streamed-to-an-stdostream
1015 
1016 template <typename S, typename T> class is_streamable {
1017  template <typename SS, typename TT>
1018  static auto test(int) -> decltype(std::declval<SS &>() << std::declval<TT>(), std::true_type());
1019 
1020  template <typename, typename> static auto test(...) -> std::false_type;
1021 
1022  public:
1023  static const bool value = decltype(test<S, T>(0))::value;
1024 };
1025 
1027 template <typename T, enable_if_t<std::is_constructible<std::string, T>::value, detail::enabler> = detail::dummy>
1028 auto to_string(T &&value) -> decltype(std::forward<T>(value)) {
1029  return std::forward<T>(value);
1030 }
1031 
1033 template <typename T,
1035  detail::enabler> = detail::dummy>
1036 std::string to_string(T &&value) {
1037  std::stringstream stream;
1038  stream << value;
1039  return stream.str();
1040 }
1041 
1043 template <typename T,
1044  enable_if_t<!std::is_constructible<std::string, T>::value && !is_streamable<std::stringstream, T>::value,
1045  detail::enabler> = detail::dummy>
1046 std::string to_string(T &&) {
1047  return std::string{};
1048 }
1049 
1050 // Type name print
1051 
1055 
1056 template <typename T,
1057  enable_if_t<std::is_integral<T>::value && std::is_signed<T>::value, detail::enabler> = detail::dummy>
1058 constexpr const char *type_name() {
1059  return "INT";
1060 }
1061 
1062 template <typename T,
1063  enable_if_t<std::is_integral<T>::value && std::is_unsigned<T>::value, detail::enabler> = detail::dummy>
1064 constexpr const char *type_name() {
1065  return "UINT";
1066 }
1067 
1068 template <typename T, enable_if_t<std::is_floating_point<T>::value, detail::enabler> = detail::dummy>
1069 constexpr const char *type_name() {
1070  return "FLOAT";
1071 }
1072 
1074 template <typename T, enable_if_t<is_vector<T>::value, detail::enabler> = detail::dummy>
1075 constexpr const char *type_name() {
1076  return "VECTOR";
1077 }
1079 template <typename T, enable_if_t<std::is_enum<T>::value, detail::enabler> = detail::dummy>
1080 constexpr const char *type_name() {
1081  return "ENUM";
1082 }
1083 
1085 template <typename T,
1086  enable_if_t<!std::is_floating_point<T>::value && !std::is_integral<T>::value && !is_vector<T>::value &&
1087  !std::is_enum<T>::value,
1088  detail::enabler> = detail::dummy>
1089 constexpr const char *type_name() {
1090  return "TEXT";
1091 }
1092 
1093 // Lexical cast
1094 
1096 inline int64_t to_flag_value(std::string val) {
1097  static const std::string trueString("true");
1098  static const std::string falseString("false");
1099  if(val == trueString) {
1100  return 1;
1101  }
1102  if(val == falseString) {
1103  return -1;
1104  }
1105  val = detail::to_lower(val);
1106  int64_t ret;
1107  if(val.size() == 1) {
1108  switch(val[0]) {
1109  case '0':
1110  case 'f':
1111  case 'n':
1112  case '-':
1113  ret = -1;
1114  break;
1115  case '1':
1116  case 't':
1117  case 'y':
1118  case '+':
1119  ret = 1;
1120  break;
1121  case '2':
1122  case '3':
1123  case '4':
1124  case '5':
1125  case '6':
1126  case '7':
1127  case '8':
1128  case '9':
1129  ret = val[0] - '0';
1130  break;
1131  default:
1132  throw std::invalid_argument("unrecognized character");
1133  }
1134  return ret;
1135  }
1136  if(val == trueString || val == "on" || val == "yes" || val == "enable") {
1137  ret = 1;
1138  } else if(val == falseString || val == "off" || val == "no" || val == "disable") {
1139  ret = -1;
1140  } else {
1141  ret = std::stoll(val);
1142  }
1143  return ret;
1144 }
1145 
1147 template <
1148  typename T,
1149  enable_if_t<std::is_integral<T>::value && std::is_signed<T>::value && !is_bool<T>::value && !std::is_enum<T>::value,
1150  detail::enabler> = detail::dummy>
1151 bool lexical_cast(std::string input, T &output) {
1152  try {
1153  size_t n = 0;
1154  long long output_ll = std::stoll(input, &n, 0);
1155  output = static_cast<T>(output_ll);
1156  return n == input.size() && static_cast<long long>(output) == output_ll;
1157  } catch(const std::invalid_argument &) {
1158  return false;
1159  } catch(const std::out_of_range &) {
1160  return false;
1161  }
1162 }
1163 
1165 template <typename T,
1166  enable_if_t<std::is_integral<T>::value && std::is_unsigned<T>::value && !is_bool<T>::value, detail::enabler> =
1167  detail::dummy>
1168 bool lexical_cast(std::string input, T &output) {
1169  if(!input.empty() && input.front() == '-')
1170  return false; // std::stoull happily converts negative values to junk without any errors.
1171 
1172  try {
1173  size_t n = 0;
1174  unsigned long long output_ll = std::stoull(input, &n, 0);
1175  output = static_cast<T>(output_ll);
1176  return n == input.size() && static_cast<unsigned long long>(output) == output_ll;
1177  } catch(const std::invalid_argument &) {
1178  return false;
1179  } catch(const std::out_of_range &) {
1180  return false;
1181  }
1182 }
1183 
1185 template <typename T, enable_if_t<is_bool<T>::value, detail::enabler> = detail::dummy>
1186 bool lexical_cast(std::string input, T &output) {
1187  try {
1188  auto out = to_flag_value(input);
1189  output = (out > 0);
1190  return true;
1191  } catch(const std::invalid_argument &) {
1192  return false;
1193  }
1194 }
1195 
1197 template <typename T, enable_if_t<std::is_floating_point<T>::value, detail::enabler> = detail::dummy>
1198 bool lexical_cast(std::string input, T &output) {
1199  try {
1200  size_t n = 0;
1201  output = static_cast<T>(std::stold(input, &n));
1202  return n == input.size();
1203  } catch(const std::invalid_argument &) {
1204  return false;
1205  } catch(const std::out_of_range &) {
1206  return false;
1207  }
1208 }
1209 
1211 template <typename T,
1212  enable_if_t<!std::is_floating_point<T>::value && !std::is_integral<T>::value &&
1213  std::is_assignable<T &, std::string>::value,
1214  detail::enabler> = detail::dummy>
1215 bool lexical_cast(std::string input, T &output) {
1216  output = input;
1217  return true;
1218 }
1219 
1221 template <typename T, enable_if_t<std::is_enum<T>::value, detail::enabler> = detail::dummy>
1222 bool lexical_cast(std::string input, T &output) {
1223  typename std::underlying_type<T>::type val;
1224  bool retval = detail::lexical_cast(input, val);
1225  if(!retval) {
1226  return false;
1227  }
1228  output = static_cast<T>(val);
1229  return true;
1230 }
1231 
1233 template <typename T,
1234  enable_if_t<!std::is_floating_point<T>::value && !std::is_integral<T>::value &&
1235  !std::is_assignable<T &, std::string>::value && !std::is_enum<T>::value,
1236  detail::enabler> = detail::dummy>
1237 bool lexical_cast(std::string input, T &output) {
1238  std::istringstream is;
1239 
1240  is.str(input);
1241  is >> output;
1242  return !is.fail() && !is.rdbuf()->in_avail();
1243 }
1244 
1249 template <typename T,
1250  enable_if_t<std::is_integral<T>::value && std::is_unsigned<T>::value, detail::enabler> = detail::dummy>
1251 void sum_flag_vector(const std::vector<std::string> &flags, T &output) {
1252  int64_t count{0};
1253  for(auto &flag : flags) {
1254  count += detail::to_flag_value(flag);
1255  }
1256  output = (count > 0) ? static_cast<T>(count) : T{0};
1257 }
1258 
1263 template <typename T,
1264  enable_if_t<std::is_integral<T>::value && std::is_signed<T>::value, detail::enabler> = detail::dummy>
1265 void sum_flag_vector(const std::vector<std::string> &flags, T &output) {
1266  int64_t count{0};
1267  for(auto &flag : flags) {
1268  count += detail::to_flag_value(flag);
1269  }
1270  output = static_cast<T>(count);
1271 }
1272 
1273 } // namespace detail
1274 } // namespace CLI
1275 
1276 // From CLI/Split.hpp:
1277 
1278 namespace CLI {
1279 namespace detail {
1280 
1281 // Returns false if not a short option. Otherwise, sets opt name and rest and returns true
1282 inline bool split_short(const std::string &current, std::string &name, std::string &rest) {
1283  if(current.size() > 1 && current[0] == '-' && valid_first_char(current[1])) {
1284  name = current.substr(1, 1);
1285  rest = current.substr(2);
1286  return true;
1287  } else
1288  return false;
1289 }
1290 
1291 // Returns false if not a long option. Otherwise, sets opt name and other side of = and returns true
1292 inline bool split_long(const std::string &current, std::string &name, std::string &value) {
1293  if(current.size() > 2 && current.substr(0, 2) == "--" && valid_first_char(current[2])) {
1294  auto loc = current.find_first_of('=');
1295  if(loc != std::string::npos) {
1296  name = current.substr(2, loc - 2);
1297  value = current.substr(loc + 1);
1298  } else {
1299  name = current.substr(2);
1300  value = "";
1301  }
1302  return true;
1303  } else
1304  return false;
1305 }
1306 
1307 // Returns false if not a windows style option. Otherwise, sets opt name and value and returns true
1308 inline bool split_windows_style(const std::string &current, std::string &name, std::string &value) {
1309  if(current.size() > 1 && current[0] == '/' && valid_first_char(current[1])) {
1310  auto loc = current.find_first_of(':');
1311  if(loc != std::string::npos) {
1312  name = current.substr(1, loc - 1);
1313  value = current.substr(loc + 1);
1314  } else {
1315  name = current.substr(1);
1316  value = "";
1317  }
1318  return true;
1319  } else
1320  return false;
1321 }
1322 
1323 // Splits a string into multiple long and short names
1324 inline std::vector<std::string> split_names(std::string current) {
1325  std::vector<std::string> output;
1326  size_t val;
1327  while((val = current.find(",")) != std::string::npos) {
1328  output.push_back(trim_copy(current.substr(0, val)));
1329  current = current.substr(val + 1);
1330  }
1331  output.push_back(trim_copy(current));
1332  return output;
1333 }
1334 
1336 inline std::vector<std::pair<std::string, std::string>> get_default_flag_values(const std::string &str) {
1337  std::vector<std::string> flags = split_names(str);
1338  flags.erase(std::remove_if(flags.begin(),
1339  flags.end(),
1340  [](const std::string &name) {
1341  return ((name.empty()) || (!(((name.find_first_of('{') != std::string::npos) &&
1342  (name.back() == '}')) ||
1343  (name[0] == '!'))));
1344  }),
1345  flags.end());
1346  std::vector<std::pair<std::string, std::string>> output;
1347  output.reserve(flags.size());
1348  for(auto &flag : flags) {
1349  auto def_start = flag.find_first_of('{');
1350  std::string defval = "false";
1351  if((def_start != std::string::npos) && (flag.back() == '}')) {
1352  defval = flag.substr(def_start + 1);
1353  defval.pop_back();
1354  flag.erase(def_start, std::string::npos);
1355  }
1356  flag.erase(0, flag.find_first_not_of("-!"));
1357  output.emplace_back(flag, defval);
1358  }
1359  return output;
1360 }
1361 
1363 inline std::tuple<std::vector<std::string>, std::vector<std::string>, std::string>
1364 get_names(const std::vector<std::string> &input) {
1365 
1366  std::vector<std::string> short_names;
1367  std::vector<std::string> long_names;
1368  std::string pos_name;
1369 
1370  for(std::string name : input) {
1371  if(name.length() == 0)
1372  continue;
1373  else if(name.length() > 1 && name[0] == '-' && name[1] != '-') {
1374  if(name.length() == 2 && valid_first_char(name[1]))
1375  short_names.emplace_back(1, name[1]);
1376  else
1377  throw BadNameString::OneCharName(name);
1378  } else if(name.length() > 2 && name.substr(0, 2) == "--") {
1379  name = name.substr(2);
1380  if(valid_name_string(name))
1381  long_names.push_back(name);
1382  else
1383  throw BadNameString::BadLongName(name);
1384  } else if(name == "-" || name == "--") {
1385  throw BadNameString::DashesOnly(name);
1386  } else {
1387  if(pos_name.length() > 0)
1389  pos_name = name;
1390  }
1391  }
1392 
1393  return std::tuple<std::vector<std::string>, std::vector<std::string>, std::string>(
1394  short_names, long_names, pos_name);
1395 }
1396 
1397 } // namespace detail
1398 } // namespace CLI
1399 
1400 // From CLI/ConfigFwd.hpp:
1401 
1402 namespace CLI {
1403 
1404 class App;
1405 
1406 namespace detail {
1407 
1409 inline std::string ini_join(std::vector<std::string> args) {
1410  std::ostringstream s;
1411  size_t start = 0;
1412  for(const auto &arg : args) {
1413  if(start++ > 0)
1414  s << " ";
1415 
1416  auto it = std::find_if(arg.begin(), arg.end(), [](char ch) { return std::isspace<char>(ch, std::locale()); });
1417  if(it == arg.end())
1418  s << arg;
1419  else if(arg.find_first_of('\"') == std::string::npos)
1420  s << '\"' << arg << '\"';
1421  else
1422  s << '\'' << arg << '\'';
1423  }
1424 
1425  return s.str();
1426 }
1427 
1428 } // namespace detail
1429 
1431 struct ConfigItem {
1433  std::vector<std::string> parents;
1434 
1436  std::string name;
1437 
1439  std::vector<std::string> inputs;
1440 
1442  std::string fullname() const {
1443  std::vector<std::string> tmp = parents;
1444  tmp.emplace_back(name);
1445  return detail::join(tmp, ".");
1446  }
1447 };
1448 
1450 class Config {
1451  protected:
1452  std::vector<ConfigItem> items;
1453 
1454  public:
1456  virtual std::string to_config(const App *, bool, bool, std::string) const = 0;
1457 
1459  virtual std::vector<ConfigItem> from_config(std::istream &) const = 0;
1460 
1462  virtual std::string to_flag(const ConfigItem &item) const {
1463  if(item.inputs.size() == 1) {
1464  return item.inputs.at(0);
1465  }
1467  }
1468 
1470  std::vector<ConfigItem> from_file(const std::string &name) {
1471  std::ifstream input{name};
1472  if(!input.good())
1473  throw FileError::Missing(name);
1474 
1475  return from_config(input);
1476  }
1477 
1479  virtual ~Config() = default;
1480 };
1481 
1483 class ConfigINI : public Config {
1484  public:
1485  std::string to_config(const App *, bool default_also, bool write_description, std::string prefix) const override;
1486 
1487  std::vector<ConfigItem> from_config(std::istream &input) const override {
1488  std::string line;
1489  std::string section = "default";
1490 
1491  std::vector<ConfigItem> output;
1492 
1493  while(getline(input, line)) {
1494  std::vector<std::string> items_buffer;
1495 
1496  detail::trim(line);
1497  size_t len = line.length();
1498  if(len > 1 && line[0] == '[' && line[len - 1] == ']') {
1499  section = line.substr(1, len - 2);
1500  } else if(len > 0 && line[0] != ';') {
1501  output.emplace_back();
1502  ConfigItem &out = output.back();
1503 
1504  // Find = in string, split and recombine
1505  auto pos = line.find('=');
1506  if(pos != std::string::npos) {
1507  out.name = detail::trim_copy(line.substr(0, pos));
1508  std::string item = detail::trim_copy(line.substr(pos + 1));
1509  items_buffer = detail::split_up(item);
1510  } else {
1511  out.name = detail::trim_copy(line);
1512  items_buffer = {"ON"};
1513  }
1514 
1515  if(detail::to_lower(section) != "default") {
1516  out.parents = {section};
1517  }
1518 
1519  if(out.name.find('.') != std::string::npos) {
1520  std::vector<std::string> plist = detail::split(out.name, '.');
1521  out.name = plist.back();
1522  plist.pop_back();
1523  out.parents.insert(out.parents.end(), plist.begin(), plist.end());
1524  }
1525 
1526  out.inputs.insert(std::end(out.inputs), std::begin(items_buffer), std::end(items_buffer));
1527  }
1528  }
1529  return output;
1530  }
1531 };
1532 
1533 } // namespace CLI
1534 
1535 // From CLI/Validators.hpp:
1536 
1537 namespace CLI {
1538 
1539 class Option;
1540 
1542 
1549 
1551 class Validator {
1552  protected:
1554  std::function<std::string()> desc_function_{[]() { return std::string{}; }};
1555 
1558  std::function<std::string(std::string &)> func_{[](std::string &) { return std::string{}; }};
1560  std::string name_;
1562  bool active_{true};
1564  bool non_modifying_{false};
1565 
1566  public:
1567  Validator() = default;
1569  explicit Validator(std::string validator_desc) : desc_function_([validator_desc]() { return validator_desc; }) {}
1570  // Construct Validator from basic information
1571  Validator(std::function<std::string(std::string &)> op, std::string validator_desc, std::string validator_name = "")
1572  : desc_function_([validator_desc]() { return validator_desc; }), func_(std::move(op)),
1573  name_(std::move(validator_name)) {}
1575  Validator &operation(std::function<std::string(std::string &)> op) {
1576  func_ = std::move(op);
1577  return *this;
1578  }
1581  std::string operator()(std::string &str) const {
1582  std::string retstring;
1583  if(active_) {
1584  if(non_modifying_) {
1585  std::string value = str;
1586  retstring = func_(value);
1587  } else {
1588  retstring = func_(str);
1589  }
1590  }
1591  return retstring;
1592  };
1593 
1596  std::string operator()(const std::string &str) const {
1597  std::string value = str;
1598  return (active_) ? func_(value) : std::string{};
1599  };
1600 
1602  Validator &description(std::string validator_desc) {
1603  desc_function_ = [validator_desc]() { return validator_desc; };
1604  return *this;
1605  }
1607  std::string get_description() const {
1608  if(active_) {
1609  return desc_function_();
1610  }
1611  return std::string{};
1612  }
1614  Validator &name(std::string validator_name) {
1615  name_ = std::move(validator_name);
1616  return *this;
1617  }
1619  const std::string &get_name() const { return name_; }
1621  Validator &active(bool active_val = true) {
1622  active_ = active_val;
1623  return *this;
1624  }
1625 
1627  Validator &non_modifying(bool no_modify = true) {
1628  non_modifying_ = no_modify;
1629  return *this;
1630  }
1631 
1633  bool get_active() const { return active_; }
1634 
1636  bool get_modifying() const { return !non_modifying_; }
1637 
1640  Validator operator&(const Validator &other) const {
1641  Validator newval;
1642 
1643  newval._merge_description(*this, other, " AND ");
1644 
1645  // Give references (will make a copy in lambda function)
1646  const std::function<std::string(std::string & filename)> &f1 = func_;
1647  const std::function<std::string(std::string & filename)> &f2 = other.func_;
1648 
1649  newval.func_ = [f1, f2](std::string &input) {
1650  std::string s1 = f1(input);
1651  std::string s2 = f2(input);
1652  if(!s1.empty() && !s2.empty())
1653  return std::string("(") + s1 + ") AND (" + s2 + ")";
1654  else
1655  return s1 + s2;
1656  };
1657 
1658  newval.active_ = (active_ & other.active_);
1659  return newval;
1660  }
1661 
1664  Validator operator|(const Validator &other) const {
1665  Validator newval;
1666 
1667  newval._merge_description(*this, other, " OR ");
1668 
1669  // Give references (will make a copy in lambda function)
1670  const std::function<std::string(std::string &)> &f1 = func_;
1671  const std::function<std::string(std::string &)> &f2 = other.func_;
1672 
1673  newval.func_ = [f1, f2](std::string &input) {
1674  std::string s1 = f1(input);
1675  std::string s2 = f2(input);
1676  if(s1.empty() || s2.empty())
1677  return std::string();
1678  else
1679  return std::string("(") + s1 + ") OR (" + s2 + ")";
1680  };
1681  newval.active_ = (active_ & other.active_);
1682  return newval;
1683  }
1684 
1687  Validator newval;
1688  const std::function<std::string()> &dfunc1 = desc_function_;
1689  newval.desc_function_ = [dfunc1]() {
1690  auto str = dfunc1();
1691  return (!str.empty()) ? std::string("NOT ") + str : std::string{};
1692  };
1693  // Give references (will make a copy in lambda function)
1694  const std::function<std::string(std::string & res)> &f1 = func_;
1695 
1696  newval.func_ = [f1, dfunc1](std::string &test) -> std::string {
1697  std::string s1 = f1(test);
1698  if(s1.empty()) {
1699  return std::string("check ") + dfunc1() + " succeeded improperly";
1700  } else
1701  return std::string{};
1702  };
1703  newval.active_ = active_;
1704  return newval;
1705  }
1706 
1707  private:
1708  void _merge_description(const Validator &val1, const Validator &val2, const std::string &merger) {
1709 
1710  const std::function<std::string()> &dfunc1 = val1.desc_function_;
1711  const std::function<std::string()> &dfunc2 = val2.desc_function_;
1712 
1713  desc_function_ = [=]() {
1714  std::string f1 = dfunc1();
1715  std::string f2 = dfunc2();
1716  if((f1.empty()) || (f2.empty())) {
1717  return f1 + f2;
1718  }
1719  return std::string("(") + f1 + ")" + merger + "(" + f2 + ")";
1720  };
1721  }
1722 };
1723 
1725 class CustomValidator : public Validator {
1726  public:
1727 };
1728 // The implementation of the built in validators is using the Validator class;
1729 // the user is only expected to use the const (static) versions (since there's no setup).
1730 // Therefore, this is in detail.
1731 namespace detail {
1732 
1735  public:
1737  func_ = [](std::string &filename) {
1738  struct stat buffer;
1739  bool exist = stat(filename.c_str(), &buffer) == 0;
1740  bool is_dir = (buffer.st_mode & S_IFDIR) != 0;
1741  if(!exist) {
1742  return "File does not exist: " + filename;
1743  } else if(is_dir) {
1744  return "File is actually a directory: " + filename;
1745  }
1746  return std::string();
1747  };
1748  }
1749 };
1750 
1753  public:
1755  func_ = [](std::string &filename) {
1756  struct stat buffer;
1757  bool exist = stat(filename.c_str(), &buffer) == 0;
1758  bool is_dir = (buffer.st_mode & S_IFDIR) != 0;
1759  if(!exist) {
1760  return "Directory does not exist: " + filename;
1761  } else if(!is_dir) {
1762  return "Directory is actually a file: " + filename;
1763  }
1764  return std::string();
1765  };
1766  }
1767 };
1768 
1771  public:
1772  ExistingPathValidator() : Validator("PATH(existing)") {
1773  func_ = [](std::string &filename) {
1774  struct stat buffer;
1775  bool const exist = stat(filename.c_str(), &buffer) == 0;
1776  if(!exist) {
1777  return "Path does not exist: " + filename;
1778  }
1779  return std::string();
1780  };
1781  }
1782 };
1783 
1786  public:
1787  NonexistentPathValidator() : Validator("PATH(non-existing)") {
1788  func_ = [](std::string &filename) {
1789  struct stat buffer;
1790  bool exist = stat(filename.c_str(), &buffer) == 0;
1791  if(exist) {
1792  return "Path already exists: " + filename;
1793  }
1794  return std::string();
1795  };
1796  }
1797 };
1798 
1800 class IPV4Validator : public Validator {
1801  public:
1802  IPV4Validator() : Validator("IPV4") {
1803  func_ = [](std::string &ip_addr) {
1804  auto result = CLI::detail::split(ip_addr, '.');
1805  if(result.size() != 4) {
1806  return "Invalid IPV4 address must have four parts " + ip_addr;
1807  }
1808  int num;
1809  bool retval = true;
1810  for(const auto &var : result) {
1811  retval &= detail::lexical_cast(var, num);
1812  if(!retval) {
1813  return "Failed parsing number " + var;
1814  }
1815  if(num < 0 || num > 255) {
1816  return "Each IP number must be between 0 and 255 " + var;
1817  }
1818  }
1819  return std::string();
1820  };
1821  }
1822 };
1823 
1825 class PositiveNumber : public Validator {
1826  public:
1827  PositiveNumber() : Validator("POSITIVE") {
1828  func_ = [](std::string &number_str) {
1829  int number;
1830  if(!detail::lexical_cast(number_str, number)) {
1831  return "Failed parsing number " + number_str;
1832  }
1833  if(number < 0) {
1834  return "Number less then 0 " + number_str;
1835  }
1836  return std::string();
1837  };
1838  }
1839 };
1840 
1842 class Number : public Validator {
1843  public:
1844  Number() : Validator("NUMBER") {
1845  func_ = [](std::string &number_str) {
1846  double number;
1847  if(!detail::lexical_cast(number_str, number)) {
1848  return "Failed parsing as a number " + number_str;
1849  }
1850  return std::string();
1851  };
1852  }
1853 };
1854 
1855 } // namespace detail
1856 
1857 // Static is not needed here, because global const implies static.
1858 
1861 
1864 
1867 
1870 
1873 
1876 
1879 
1881 class Range : public Validator {
1882  public:
1887  template <typename T> Range(T min, T max) {
1888  std::stringstream out;
1889  out << detail::type_name<T>() << " in [" << min << " - " << max << "]";
1890  description(out.str());
1891 
1892  func_ = [min, max](std::string &input) {
1893  T val;
1894  bool converted = detail::lexical_cast(input, val);
1895  if((!converted) || (val < min || val > max))
1896  return "Value " + input + " not in range " + std::to_string(min) + " to " + std::to_string(max);
1897 
1898  return std::string();
1899  };
1900  }
1901 
1903  template <typename T> explicit Range(T max) : Range(static_cast<T>(0), max) {}
1904 };
1905 
1907 class Bound : public Validator {
1908  public:
1913  template <typename T> Bound(T min, T max) {
1914  std::stringstream out;
1915  out << detail::type_name<T>() << " bounded to [" << min << " - " << max << "]";
1916  description(out.str());
1917 
1918  func_ = [min, max](std::string &input) {
1919  T val;
1920  bool converted = detail::lexical_cast(input, val);
1921  if(!converted) {
1922  return "Value " + input + " could not be converted";
1923  }
1924  if(val < min)
1925  input = detail::as_string(min);
1926  else if(val > max)
1927  input = detail::as_string(max);
1928 
1929  return std::string();
1930  };
1931  }
1932 
1934  template <typename T> explicit Bound(T max) : Bound(static_cast<T>(0), max) {}
1935 };
1936 
1937 namespace detail {
1938 template <typename T,
1940 auto smart_deref(T value) -> decltype(*value) {
1941  return *value;
1942 }
1943 
1944 template <
1945  typename T,
1948  return value;
1949 }
1951 template <typename T> std::string generate_set(const T &set) {
1952  using element_t = typename detail::element_type<T>::type;
1953  using iteration_type_t = typename detail::pair_adaptor<element_t>::value_type; // the type of the object pair
1954  std::string out(1, '{');
1955  out.append(detail::join(detail::smart_deref(set),
1956  [](const iteration_type_t &v) { return detail::pair_adaptor<element_t>::first(v); },
1957  ","));
1958  out.push_back('}');
1959  return out;
1960 }
1961 
1963 template <typename T> std::string generate_map(const T &map, bool key_only = false) {
1964  using element_t = typename detail::element_type<T>::type;
1965  using iteration_type_t = typename detail::pair_adaptor<element_t>::value_type; // the type of the object pair
1966  std::string out(1, '{');
1967  out.append(detail::join(detail::smart_deref(map),
1968  [key_only](const iteration_type_t &v) {
1970  if(!key_only) {
1972  }
1973  return res;
1974  },
1975  ","));
1976  out.push_back('}');
1977  return out;
1978 }
1979 
1980 template <typename> struct sfinae_true : std::true_type {};
1983 template <typename T, typename V>
1984 static auto test_find(int) -> sfinae_true<decltype(std::declval<T>().find(std::declval<V>()))>;
1985 template <typename, typename V> static auto test_find(long) -> std::false_type;
1986 
1987 template <typename T, typename V> struct has_find : decltype(test_find<T, V>(0)) {};
1988 
1990 template <typename T, typename V, enable_if_t<!has_find<T, V>::value, detail::enabler> = detail::dummy>
1991 auto search(const T &set, const V &val) -> std::pair<bool, decltype(std::begin(detail::smart_deref(set)))> {
1992  using element_t = typename detail::element_type<T>::type;
1993  auto &setref = detail::smart_deref(set);
1994  auto it = std::find_if(std::begin(setref), std::end(setref), [&val](decltype(*std::begin(setref)) v) {
1995  return (detail::pair_adaptor<element_t>::first(v) == val);
1996  });
1997  return {(it != std::end(setref)), it};
1998 }
1999 
2001 template <typename T, typename V, enable_if_t<has_find<T, V>::value, detail::enabler> = detail::dummy>
2002 auto search(const T &set, const V &val) -> std::pair<bool, decltype(std::begin(detail::smart_deref(set)))> {
2003  auto &setref = detail::smart_deref(set);
2004  auto it = setref.find(val);
2005  return {(it != std::end(setref)), it};
2006 }
2007 
2009 template <typename T, typename V>
2010 auto search(const T &set, const V &val, const std::function<V(V)> &filter_function)
2011  -> std::pair<bool, decltype(std::begin(detail::smart_deref(set)))> {
2012  using element_t = typename detail::element_type<T>::type;
2013  // do the potentially faster first search
2014  auto res = search(set, val);
2015  if((res.first) || (!(filter_function))) {
2016  return res;
2017  }
2018  // if we haven't found it do the longer linear search with all the element translations
2019  auto &setref = detail::smart_deref(set);
2020  auto it = std::find_if(std::begin(setref), std::end(setref), [&](decltype(*std::begin(setref)) v) {
2022  a = filter_function(a);
2023  return (a == val);
2024  });
2025  return {(it != std::end(setref)), it};
2026 }
2027 
2029 template <typename T> typename std::enable_if<std::is_integral<T>::value, bool>::type checked_multiply(T &a, T b) {
2030  if(a == 0 || b == 0) {
2031  a *= b;
2032  return true;
2033  }
2034  T c = a * b;
2035  if(c / a != b) {
2036  return false;
2037  }
2038  a = c;
2039  return true;
2040 }
2041 
2043 template <typename T>
2044 typename std::enable_if<std::is_floating_point<T>::value, bool>::type checked_multiply(T &a, T b) {
2045  T c = a * b;
2046  if(std::isinf(c) && !std::isinf(a) && !std::isinf(b)) {
2047  return false;
2048  }
2049  a = c;
2050  return true;
2051 }
2052 
2053 } // namespace detail
2055 class IsMember : public Validator {
2056  public:
2057  using filter_fn_t = std::function<std::string(std::string)>;
2058 
2060  template <typename T, typename... Args>
2061  explicit IsMember(std::initializer_list<T> values, Args &&... args)
2062  : IsMember(std::vector<T>(values), std::forward<Args>(args)...) {}
2063 
2065  template <typename T> explicit IsMember(T &&set) : IsMember(std::forward<T>(set), nullptr) {}
2066 
2069  template <typename T, typename F> explicit IsMember(T set, F filter_function) {
2070 
2071  // Get the type of the contained item - requires a container have ::value_type
2072  // if the type does not have first_type and second_type, these are both value_type
2073  using element_t = typename detail::element_type<T>::type; // Removes (smart) pointers if needed
2074  using item_t = typename detail::pair_adaptor<element_t>::first_type; // Is value_type if not a map
2075 
2076  using local_item_t = typename IsMemberType<item_t>::type; // This will convert bad types to good ones
2077  // (const char * to std::string)
2078 
2079  // Make a local copy of the filter function, using a std::function if not one already
2080  std::function<local_item_t(local_item_t)> filter_fn = filter_function;
2081 
2082  // This is the type name for help, it will take the current version of the set contents
2083  desc_function_ = [set]() { return detail::generate_set(detail::smart_deref(set)); };
2084 
2085  // This is the function that validates
2086  // It stores a copy of the set pointer-like, so shared_ptr will stay alive
2087  func_ = [set, filter_fn](std::string &input) {
2088  local_item_t b;
2089  if(!detail::lexical_cast(input, b)) {
2090  throw ValidationError(input); // name is added later
2091  }
2092  if(filter_fn) {
2093  b = filter_fn(b);
2094  }
2095  auto res = detail::search(set, b, filter_fn);
2096  if(res.first) {
2097  // Make sure the version in the input string is identical to the one in the set
2098  if(filter_fn) {
2100  }
2101 
2102  // Return empty error string (success)
2103  return std::string{};
2104  }
2105 
2106  // If you reach this point, the result was not found
2107  std::string out(" not in ");
2109  return out;
2110  };
2111  }
2112 
2114  template <typename T, typename... Args>
2115  IsMember(T &&set, filter_fn_t filter_fn_1, filter_fn_t filter_fn_2, Args &&... other)
2116  : IsMember(std::forward<T>(set),
2117  [filter_fn_1, filter_fn_2](std::string a) { return filter_fn_2(filter_fn_1(a)); },
2118  other...) {}
2119 };
2120 
2122 template <typename T> using TransformPairs = std::vector<std::pair<std::string, T>>;
2123 
2125 class Transformer : public Validator {
2126  public:
2127  using filter_fn_t = std::function<std::string(std::string)>;
2128 
2130  template <typename... Args>
2131  explicit Transformer(std::initializer_list<std::pair<std::string, std::string>> values, Args &&... args)
2132  : Transformer(TransformPairs<std::string>(values), std::forward<Args>(args)...) {}
2133 
2135  template <typename T> explicit Transformer(T &&mapping) : Transformer(std::forward<T>(mapping), nullptr) {}
2136 
2139  template <typename T, typename F> explicit Transformer(T mapping, F filter_function) {
2140 
2141  static_assert(detail::pair_adaptor<typename detail::element_type<T>::type>::value,
2142  "mapping must produce value pairs");
2143  // Get the type of the contained item - requires a container have ::value_type
2144  // if the type does not have first_type and second_type, these are both value_type
2145  using element_t = typename detail::element_type<T>::type; // Removes (smart) pointers if needed
2146  using item_t = typename detail::pair_adaptor<element_t>::first_type; // Is value_type if not a map
2147  using local_item_t = typename IsMemberType<item_t>::type; // This will convert bad types to good ones
2148  // (const char * to std::string)
2149 
2150  // Make a local copy of the filter function, using a std::function if not one already
2151  std::function<local_item_t(local_item_t)> filter_fn = filter_function;
2152 
2153  // This is the type name for help, it will take the current version of the set contents
2154  desc_function_ = [mapping]() { return detail::generate_map(detail::smart_deref(mapping)); };
2155 
2156  func_ = [mapping, filter_fn](std::string &input) {
2157  local_item_t b;
2158  if(!detail::lexical_cast(input, b)) {
2159  return std::string();
2160  // there is no possible way we can match anything in the mapping if we can't convert so just return
2161  }
2162  if(filter_fn) {
2163  b = filter_fn(b);
2164  }
2165  auto res = detail::search(mapping, b, filter_fn);
2166  if(res.first) {
2168  }
2169  return std::string{};
2170  };
2171  }
2172 
2174  template <typename T, typename... Args>
2175  Transformer(T &&mapping, filter_fn_t filter_fn_1, filter_fn_t filter_fn_2, Args &&... other)
2176  : Transformer(std::forward<T>(mapping),
2177  [filter_fn_1, filter_fn_2](std::string a) { return filter_fn_2(filter_fn_1(a)); },
2178  other...) {}
2179 };
2180 
2183  public:
2184  using filter_fn_t = std::function<std::string(std::string)>;
2185 
2187  template <typename... Args>
2188  explicit CheckedTransformer(std::initializer_list<std::pair<std::string, std::string>> values, Args &&... args)
2189  : CheckedTransformer(TransformPairs<std::string>(values), std::forward<Args>(args)...) {}
2190 
2192  template <typename T> explicit CheckedTransformer(T mapping) : CheckedTransformer(std::move(mapping), nullptr) {}
2193 
2196  template <typename T, typename F> explicit CheckedTransformer(T mapping, F filter_function) {
2197 
2198  static_assert(detail::pair_adaptor<typename detail::element_type<T>::type>::value,
2199  "mapping must produce value pairs");
2200  // Get the type of the contained item - requires a container have ::value_type
2201  // if the type does not have first_type and second_type, these are both value_type
2202  using element_t = typename detail::element_type<T>::type; // Removes (smart) pointers if needed
2203  using item_t = typename detail::pair_adaptor<element_t>::first_type; // Is value_type if not a map
2204  using local_item_t = typename IsMemberType<item_t>::type; // This will convert bad types to good ones
2205  // (const char * to std::string)
2206  using iteration_type_t = typename detail::pair_adaptor<element_t>::value_type; // the type of the object pair //
2207  // the type of the object pair
2208 
2209  // Make a local copy of the filter function, using a std::function if not one already
2210  std::function<local_item_t(local_item_t)> filter_fn = filter_function;
2211 
2212  auto tfunc = [mapping]() {
2213  std::string out("value in ");
2214  out += detail::generate_map(detail::smart_deref(mapping)) + " OR {";
2215  out += detail::join(
2216  detail::smart_deref(mapping),
2217  [](const iteration_type_t &v) { return detail::as_string(detail::pair_adaptor<element_t>::second(v)); },
2218  ",");
2219  out.push_back('}');
2220  return out;
2221  };
2222 
2223  desc_function_ = tfunc;
2224 
2225  func_ = [mapping, tfunc, filter_fn](std::string &input) {
2226  local_item_t b;
2227  bool converted = detail::lexical_cast(input, b);
2228  if(converted) {
2229  if(filter_fn) {
2230  b = filter_fn(b);
2231  }
2232  auto res = detail::search(mapping, b, filter_fn);
2233  if(res.first) {
2235  return std::string{};
2236  }
2237  }
2238  for(const auto &v : detail::smart_deref(mapping)) {
2240  if(output_string == input) {
2241  return std::string();
2242  }
2243  }
2244 
2245  return "Check " + input + " " + tfunc() + " FAILED";
2246  };
2247  }
2248 
2250  template <typename T, typename... Args>
2251  CheckedTransformer(T &&mapping, filter_fn_t filter_fn_1, filter_fn_t filter_fn_2, Args &&... other)
2252  : CheckedTransformer(std::forward<T>(mapping),
2253  [filter_fn_1, filter_fn_2](std::string a) { return filter_fn_2(filter_fn_1(a)); },
2254  other...) {}
2255 };
2256 
2258 inline std::string ignore_case(std::string item) { return detail::to_lower(item); }
2259 
2261 inline std::string ignore_underscore(std::string item) { return detail::remove_underscore(item); }
2262 
2264 inline std::string ignore_space(std::string item) {
2265  item.erase(std::remove(std::begin(item), std::end(item), ' '), std::end(item));
2266  item.erase(std::remove(std::begin(item), std::end(item), '\t'), std::end(item));
2267  return item;
2268 }
2269 
2281 class AsNumberWithUnit : public Validator {
2282  public:
2287  enum Options {
2288  CASE_SENSITIVE = 0,
2289  CASE_INSENSITIVE = 1,
2290  UNIT_OPTIONAL = 0,
2291  UNIT_REQUIRED = 2,
2292  DEFAULT = CASE_INSENSITIVE | UNIT_OPTIONAL
2293  };
2294 
2295  template <typename Number>
2296  explicit AsNumberWithUnit(std::map<std::string, Number> mapping,
2297  Options opts = DEFAULT,
2298  const std::string &unit_name = "UNIT") {
2299  description(generate_description<Number>(unit_name, opts));
2300  validate_mapping(mapping, opts);
2301 
2302  // transform function
2303  func_ = [mapping, opts](std::string &input) -> std::string {
2304  Number num;
2305 
2306  detail::rtrim(input);
2307  if(input.empty()) {
2308  throw ValidationError("Input is empty");
2309  }
2310 
2311  // Find split position between number and prefix
2312  auto unit_begin = input.end();
2313  while(unit_begin > input.begin() && std::isalpha(*(unit_begin - 1), std::locale())) {
2314  --unit_begin;
2315  }
2316 
2317  std::string unit{unit_begin, input.end()};
2318  input.resize(static_cast<size_t>(std::distance(input.begin(), unit_begin)));
2319  detail::trim(input);
2320 
2321  if(opts & UNIT_REQUIRED && unit.empty()) {
2322  throw ValidationError("Missing mandatory unit");
2323  }
2324  if(opts & CASE_INSENSITIVE) {
2325  unit = detail::to_lower(unit);
2326  }
2327 
2328  bool converted = detail::lexical_cast(input, num);
2329  if(!converted) {
2330  throw ValidationError("Value " + input + " could not be converted to " + detail::type_name<Number>());
2331  }
2332 
2333  if(unit.empty()) {
2334  // No need to modify input if no unit passed
2335  return {};
2336  }
2337 
2338  // find corresponding factor
2339  auto it = mapping.find(unit);
2340  if(it == mapping.end()) {
2341  throw ValidationError(unit +
2342  " unit not recognized. "
2343  "Allowed values: " +
2344  detail::generate_map(mapping, true));
2345  }
2346 
2347  // perform safe multiplication
2348  bool ok = detail::checked_multiply(num, it->second);
2349  if(!ok) {
2350  throw ValidationError(detail::as_string(num) + " multiplied by " + unit +
2351  " factor would cause number overflow. Use smaller value.");
2352  }
2353  input = detail::as_string(num);
2354 
2355  return {};
2356  };
2357  }
2358 
2359  private:
2362  template <typename Number> static void validate_mapping(std::map<std::string, Number> &mapping, Options opts) {
2363  for(auto &kv : mapping) {
2364  if(kv.first.empty()) {
2365  throw ValidationError("Unit must not be empty.");
2366  }
2367  if(!detail::isalpha(kv.first)) {
2368  throw ValidationError("Unit must contain only letters.");
2369  }
2370  }
2371 
2372  // make all units lowercase if CASE_INSENSITIVE
2373  if(opts & CASE_INSENSITIVE) {
2374  std::map<std::string, Number> lower_mapping;
2375  for(auto &kv : mapping) {
2376  auto s = detail::to_lower(kv.first);
2377  if(lower_mapping.count(s)) {
2378  throw ValidationError("Several matching lowercase unit representations are found: " + s);
2379  }
2380  lower_mapping[detail::to_lower(kv.first)] = kv.second;
2381  }
2382  mapping = std::move(lower_mapping);
2383  }
2384  }
2385 
2387  template <typename Number> static std::string generate_description(const std::string &name, Options opts) {
2388  std::stringstream out;
2389  out << detail::type_name<Number>() << ' ';
2390  if(opts & UNIT_REQUIRED) {
2391  out << name;
2392  } else {
2393  out << '[' << name << ']';
2394  }
2395  return out.str();
2396  }
2397 };
2398 
2411  public:
2412  using result_t = uint64_t;
2413 
2421  explicit AsSizeValue(bool kb_is_1000) : AsNumberWithUnit(get_mapping(kb_is_1000)) {
2422  if(kb_is_1000) {
2423  description("SIZE [b, kb(=1000b), kib(=1024b), ...]");
2424  } else {
2425  description("SIZE [b, kb(=1024b), ...]");
2426  }
2427  }
2428 
2429  private:
2431  static std::map<std::string, result_t> init_mapping(bool kb_is_1000) {
2432  std::map<std::string, result_t> m;
2433  result_t k_factor = kb_is_1000 ? 1000 : 1024;
2434  result_t ki_factor = 1024;
2435  result_t k = 1;
2436  result_t ki = 1;
2437  m["b"] = 1;
2438  for(std::string p : {"k", "m", "g", "t", "p", "e"}) {
2439  k *= k_factor;
2440  ki *= ki_factor;
2441  m[p] = k;
2442  m[p + "b"] = k;
2443  m[p + "i"] = ki;
2444  m[p + "ib"] = ki;
2445  }
2446  return m;
2447  }
2448 
2450  static std::map<std::string, result_t> get_mapping(bool kb_is_1000) {
2451  if(kb_is_1000) {
2452  static auto m = init_mapping(true);
2453  return m;
2454  } else {
2455  static auto m = init_mapping(false);
2456  return m;
2457  }
2458  }
2459 };
2460 
2461 namespace detail {
2466 inline std::pair<std::string, std::string> split_program_name(std::string commandline) {
2467  // try to determine the programName
2468  std::pair<std::string, std::string> vals;
2469  trim(commandline);
2470  auto esp = commandline.find_first_of(' ', 1);
2471  while(!ExistingFile(commandline.substr(0, esp)).empty()) {
2472  esp = commandline.find_first_of(' ', esp + 1);
2473  if(esp == std::string::npos) {
2474  // if we have reached the end and haven't found a valid file just assume the first argument is the
2475  // program name
2476  esp = commandline.find_first_of(' ', 1);
2477  break;
2478  }
2479  }
2480  vals.first = commandline.substr(0, esp);
2481  rtrim(vals.first);
2482  // strip the program name
2483  vals.second = (esp != std::string::npos) ? commandline.substr(esp + 1) : std::string{};
2484  ltrim(vals.second);
2485  return vals;
2486 }
2487 
2488 } // namespace detail
2490 
2491 } // namespace CLI
2492 
2493 // From CLI/FormatterFwd.hpp:
2494 
2495 namespace CLI {
2496 
2497 class Option;
2498 class App;
2499 
2504 
2505 enum class AppFormatMode {
2506  Normal, //< The normal, detailed help
2507  All, //< A fully expanded help
2508  Sub, //< Used when printed as part of expanded subcommand
2509 };
2510 
2516  protected:
2519 
2521  size_t column_width_{30};
2522 
2525  std::map<std::string, std::string> labels_;
2526 
2530 
2531  public:
2532  FormatterBase() = default;
2533  FormatterBase(const FormatterBase &) = default;
2534  FormatterBase(FormatterBase &&) = default;
2535 
2537  virtual ~FormatterBase() noexcept {} // NOLINT(modernize-use-equals-default)
2538 
2540  virtual std::string make_help(const App *, std::string, AppFormatMode) const = 0;
2541 
2545 
2547  void label(std::string key, std::string val) { labels_[key] = val; }
2548 
2550  void column_width(size_t val) { column_width_ = val; }
2551 
2555 
2557  std::string get_label(std::string key) const {
2558  if(labels_.find(key) == labels_.end())
2559  return key;
2560  else
2561  return labels_.at(key);
2562  }
2563 
2565  size_t get_column_width() const { return column_width_; }
2566 
2568 };
2569 
2571 class FormatterLambda final : public FormatterBase {
2572  using funct_t = std::function<std::string(const App *, std::string, AppFormatMode)>;
2573 
2576 
2577  public:
2579  explicit FormatterLambda(funct_t funct) : lambda_(std::move(funct)) {}
2580 
2582  ~FormatterLambda() noexcept override {} // NOLINT(modernize-use-equals-default)
2583 
2585  std::string make_help(const App *app, std::string name, AppFormatMode mode) const override {
2586  return lambda_(app, name, mode);
2587  }
2588 };
2589 
2592 class Formatter : public FormatterBase {
2593  public:
2594  Formatter() = default;
2595  Formatter(const Formatter &) = default;
2596  Formatter(Formatter &&) = default;
2597 
2600 
2603  virtual std::string make_group(std::string group, bool is_positional, std::vector<const Option *> opts) const;
2604 
2606  virtual std::string make_positionals(const App *app) const;
2607 
2609  std::string make_groups(const App *app, AppFormatMode mode) const;
2610 
2612  virtual std::string make_subcommands(const App *app, AppFormatMode mode) const;
2613 
2615  virtual std::string make_subcommand(const App *sub) const;
2616 
2618  virtual std::string make_expanded(const App *sub) const;
2619 
2621  virtual std::string make_footer(const App *app) const;
2622 
2624  virtual std::string make_description(const App *app) const;
2625 
2627  virtual std::string make_usage(const App *app, std::string name) const;
2628 
2630  std::string make_help(const App *, std::string, AppFormatMode) const override;
2631 
2635 
2637  virtual std::string make_option(const Option *opt, bool is_positional) const {
2638  std::stringstream out;
2640  out, make_option_name(opt, is_positional) + make_option_opts(opt), make_option_desc(opt), column_width_);
2641  return out.str();
2642  }
2643 
2645  virtual std::string make_option_name(const Option *, bool) const;
2646 
2648  virtual std::string make_option_opts(const Option *) const;
2649 
2651  virtual std::string make_option_desc(const Option *) const;
2652 
2654  virtual std::string make_option_usage(const Option *opt) const;
2655 
2657 };
2658 
2659 } // namespace CLI
2660 
2661 // From CLI/Option.hpp:
2662 
2663 namespace CLI {
2664 
2665 using results_t = std::vector<std::string>;
2666 using callback_t = std::function<bool(results_t)>;
2667 
2668 class Option;
2669 class App;
2670 
2671 using Option_p = std::unique_ptr<Option>;
2672 
2673 enum class MultiOptionPolicy : char { Throw, TakeLast, TakeFirst, Join };
2674 
2677 template <typename CRTP> class OptionBase {
2678  friend App;
2679 
2680  protected:
2682  std::string group_ = std::string("Options");
2683 
2685  bool required_{false};
2686 
2688  bool ignore_case_{false};
2689 
2691  bool ignore_underscore_{false};
2692 
2694  bool configurable_{true};
2695 
2697  bool disable_flag_override_{false};
2698 
2700  char delimiter_{'\0'};
2701 
2703  bool always_capture_default_{false};
2704 
2707 
2709  template <typename T> void copy_to(T *other) const {
2710  other->group(group_);
2711  other->required(required_);
2712  other->ignore_case(ignore_case_);
2713  other->ignore_underscore(ignore_underscore_);
2714  other->configurable(configurable_);
2715  other->disable_flag_override(disable_flag_override_);
2716  other->delimiter(delimiter_);
2717  other->always_capture_default(always_capture_default_);
2718  other->multi_option_policy(multi_option_policy_);
2719  }
2720 
2721  public:
2722  // setters
2723 
2725  CRTP *group(std::string name) {
2726  group_ = name;
2727  return static_cast<CRTP *>(this);
2728  }
2729 
2731  CRTP *required(bool value = true) {
2732  required_ = value;
2733  return static_cast<CRTP *>(this);
2734  }
2735 
2737  CRTP *mandatory(bool value = true) { return required(value); }
2738 
2739  CRTP *always_capture_default(bool value = true) {
2740  always_capture_default_ = value;
2741  return static_cast<CRTP *>(this);
2742  }
2743 
2744  // Getters
2745 
2747  const std::string &get_group() const { return group_; }
2748 
2750  bool get_required() const { return required_; }
2751 
2753  bool get_ignore_case() const { return ignore_case_; }
2754 
2756  bool get_ignore_underscore() const { return ignore_underscore_; }
2757 
2759  bool get_configurable() const { return configurable_; }
2760 
2762  bool get_disable_flag_override() const { return disable_flag_override_; }
2763 
2765  char get_delimiter() const { return delimiter_; }
2766 
2768  bool get_always_capture_default() const { return always_capture_default_; }
2769 
2771  MultiOptionPolicy get_multi_option_policy() const { return multi_option_policy_; }
2772 
2773  // Shortcuts for multi option policy
2774 
2776  CRTP *take_last() {
2777  auto self = static_cast<CRTP *>(this);
2779  return self;
2780  }
2781 
2783  CRTP *take_first() {
2784  auto self = static_cast<CRTP *>(this);
2786  return self;
2787  }
2788 
2790  CRTP *join() {
2791  auto self = static_cast<CRTP *>(this);
2793  return self;
2794  }
2795 
2797  CRTP *configurable(bool value = true) {
2798  configurable_ = value;
2799  return static_cast<CRTP *>(this);
2800  }
2801 
2803  CRTP *delimiter(char value = '\0') {
2804  delimiter_ = value;
2805  return static_cast<CRTP *>(this);
2806  }
2807 };
2808 
2811 class OptionDefaults : public OptionBase<OptionDefaults> {
2812  public:
2813  OptionDefaults() = default;
2814 
2815  // Methods here need a different implementation if they are Option vs. OptionDefault
2816 
2819  multi_option_policy_ = value;
2820  return this;
2821  }
2822 
2824  OptionDefaults *ignore_case(bool value = true) {
2825  ignore_case_ = value;
2826  return this;
2827  }
2828 
2830  OptionDefaults *ignore_underscore(bool value = true) {
2831  ignore_underscore_ = value;
2832  return this;
2833  }
2834 
2837  disable_flag_override_ = value;
2838  return this;
2839  }
2840 
2842  OptionDefaults *delimiter(char value = '\0') {
2843  delimiter_ = value;
2844  return this;
2845  }
2846 };
2847 
2848 class Option : public OptionBase<Option> {
2849  friend App;
2850 
2851  protected:
2854 
2856  std::vector<std::string> snames_;
2857 
2859  std::vector<std::string> lnames_;
2860 
2863  std::vector<std::pair<std::string, std::string>> default_flag_values_;
2864 
2866  std::vector<std::string> fnames_;
2867 
2869  std::string pname_;
2870 
2872  std::string envname_;
2873 
2877 
2879  std::string description_;
2880 
2882  std::string default_str_;
2883 
2887  std::function<std::string()> type_name_{[]() { return std::string(); }};
2888 
2890  std::function<std::string()> default_function_;
2891 
2895 
2899  int type_size_{1};
2900 
2902  int expected_{1};
2903 
2905  std::vector<Validator> validators_;
2906 
2908  std::set<Option *> needs_;
2909 
2911  std::set<Option *> excludes_;
2912 
2916 
2919 
2922 
2926 
2929 
2931  bool callback_run_{false};
2932 
2934 
2936  Option(std::string option_name,
2937  std::string option_description,
2938  std::function<bool(results_t)> callback,
2939  App *parent)
2940  : description_(std::move(option_description)), parent_(parent), callback_(std::move(callback)) {
2941  std::tie(snames_, lnames_, pname_) = detail::get_names(detail::split_names(option_name));
2942  }
2943 
2944  public:
2947 
2949  size_t count() const { return results_.size(); }
2950 
2952  size_t empty() const { return results_.empty(); }
2953 
2955  operator bool() const { return !empty(); }
2956 
2958  void clear() { results_.clear(); }
2959 
2963 
2965  Option *expected(int value) {
2966 
2967  // Break if this is a flag
2968  if(type_size_ == 0)
2969  throw IncorrectConstruction::SetFlag(get_name(true, true));
2970 
2971  // Setting 0 is not allowed
2972  else if(value == 0)
2973  throw IncorrectConstruction::Set0Opt(get_name());
2974 
2975  // No change is okay, quit now
2976  else if(expected_ == value)
2977  return this;
2978 
2979  // Type must be a vector
2980  else if(type_size_ >= 0)
2981  throw IncorrectConstruction::ChangeNotVector(get_name());
2982 
2983  // TODO: Can support multioption for non-1 values (except for join)
2984  else if(value != 1 && multi_option_policy_ != MultiOptionPolicy::Throw)
2985  throw IncorrectConstruction::AfterMultiOpt(get_name());
2986 
2987  expected_ = value;
2988  return this;
2989  }
2990 
2992  Option *check(Validator validator, std::string validator_name = "") {
2993  validator.non_modifying();
2994  validators_.push_back(std::move(validator));
2995  if(!validator_name.empty())
2996  validators_.front().name(validator_name);
2997  return this;
2998  }
2999 
3001  Option *check(std::function<std::string(const std::string &)> validator,
3002  std::string validator_description = "",
3003  std::string validator_name = "") {
3004  validators_.emplace_back(validator, std::move(validator_description), std::move(validator_name));
3005  validators_.back().non_modifying();
3006  return this;
3007  }
3008 
3010  Option *transform(Validator validator, std::string validator_name = "") {
3011  validators_.insert(validators_.begin(), std::move(validator));
3012  if(!validator_name.empty())
3013  validators_.front().name(validator_name);
3014  return this;
3015  }
3016 
3018  Option *transform(std::function<std::string(std::string)> func,
3019  std::string transform_description = "",
3020  std::string transform_name = "") {
3021  validators_.insert(validators_.begin(),
3022  Validator(
3023  [func](std::string &val) {
3024  val = func(val);
3025  return std::string{};
3026  },
3027  std::move(transform_description),
3028  std::move(transform_name)));
3029 
3030  return this;
3031  }
3032 
3034  Option *each(std::function<void(std::string)> func) {
3035  validators_.emplace_back(
3036  [func](std::string &inout) {
3037  func(inout);
3038  return std::string{};
3039  },
3040  std::string{});
3041  return this;
3042  }
3044  Validator *get_validator(const std::string &validator_name = "") {
3045  for(auto &validator : validators_) {
3046  if(validator_name == validator.get_name()) {
3047  return &validator;
3048  }
3049  }
3050  if((validator_name.empty()) && (!validators_.empty())) {
3051  return &(validators_.front());
3052  }
3053  throw OptionNotFound(std::string("Validator ") + validator_name + " Not Found");
3054  }
3057  auto tup = needs_.insert(opt);
3058  if(!tup.second)
3059  throw OptionAlreadyAdded::Requires(get_name(), opt->get_name());
3060  return this;
3061  }
3062 
3064  template <typename T = App> Option *needs(std::string opt_name) {
3065  for(const Option_p &opt : dynamic_cast<T *>(parent_)->options_)
3066  if(opt.get() != this && opt->check_name(opt_name))
3067  return needs(opt.get());
3068  throw IncorrectConstruction::MissingOption(opt_name);
3069  }
3070 
3072  template <typename A, typename B, typename... ARG> Option *needs(A opt, B opt1, ARG... args) {
3073  needs(opt);
3074  return needs(opt1, args...);
3075  }
3076 
3078  bool remove_needs(Option *opt) {
3079  auto iterator = std::find(std::begin(needs_), std::end(needs_), opt);
3080 
3081  if(iterator != std::end(needs_)) {
3082  needs_.erase(iterator);
3083  return true;
3084  } else {
3085  return false;
3086  }
3087  }
3088 
3091  excludes_.insert(opt);
3092 
3093  // Help text should be symmetric - excluding a should exclude b
3094  opt->excludes_.insert(this);
3095 
3096  // Ignoring the insert return value, excluding twice is now allowed.
3097  // (Mostly to allow both directions to be excluded by user, even though the library does it for you.)
3098 
3099  return this;
3100  }
3101 
3103  template <typename T = App> Option *excludes(std::string opt_name) {
3104  for(const Option_p &opt : dynamic_cast<T *>(parent_)->options_)
3105  if(opt.get() != this && opt->check_name(opt_name))
3106  return excludes(opt.get());
3107  throw IncorrectConstruction::MissingOption(opt_name);
3108  }
3109 
3111  template <typename A, typename B, typename... ARG> Option *excludes(A opt, B opt1, ARG... args) {
3112  excludes(opt);
3113  return excludes(opt1, args...);
3114  }
3115 
3118  auto iterator = std::find(std::begin(excludes_), std::end(excludes_), opt);
3119 
3120  if(iterator != std::end(excludes_)) {
3121  excludes_.erase(iterator);
3122  return true;
3123  } else {
3124  return false;
3125  }
3126  }
3127 
3129  Option *envname(std::string name) {
3130  envname_ = name;
3131  return this;
3132  }
3133 
3138  template <typename T = App> Option *ignore_case(bool value = true) {
3139  ignore_case_ = value;
3140  auto *parent = dynamic_cast<T *>(parent_);
3141 
3142  for(const Option_p &opt : parent->options_)
3143  if(opt.get() != this && *opt == *this)
3144  throw OptionAlreadyAdded(opt->get_name(true, true));
3145 
3146  return this;
3147  }
3148 
3153  template <typename T = App> Option *ignore_underscore(bool value = true) {
3154  ignore_underscore_ = value;
3155  auto *parent = dynamic_cast<T *>(parent_);
3156  for(const Option_p &opt : parent->options_)
3157  if(opt.get() != this && *opt == *this)
3158  throw OptionAlreadyAdded(opt->get_name(true, true));
3159 
3160  return this;
3161  }
3162 
3165 
3166  if(get_items_expected() < 0)
3167  throw IncorrectConstruction::MultiOptionPolicy(get_name());
3168  multi_option_policy_ = value;
3169  return this;
3170  }
3171 
3173  Option *disable_flag_override(bool value = true) {
3174  disable_flag_override_ = value;
3175  return this;
3176  }
3180 
3182  int get_type_size() const { return type_size_; }
3183 
3185  std::string get_envname() const { return envname_; }
3186 
3188  std::set<Option *> get_needs() const { return needs_; }
3189 
3191  std::set<Option *> get_excludes() const { return excludes_; }
3192 
3194  CLI11_DEPRECATED("Use get_default_str() instead")
3195  std::string get_defaultval() const { return default_str_; }
3196 
3198  std::string get_default_str() const { return default_str_; }
3199 
3201  callback_t get_callback() const { return callback_; }
3202 
3204  const std::vector<std::string> get_lnames() const { return lnames_; }
3205 
3207  const std::vector<std::string> get_snames() const { return snames_; }
3208 
3210  const std::vector<std::string> get_fnames() const { return fnames_; }
3211 
3213  int get_expected() const { return expected_; }
3214 
3231  int get_items_expected() const {
3232  return std::abs(type_size_ * expected_) *
3233  ((multi_option_policy_ != MultiOptionPolicy::Throw || (expected_ < 0 && type_size_ < 0) ? -1 : 1));
3234  }
3235 
3237  bool get_positional() const { return pname_.length() > 0; }
3238 
3240  bool nonpositional() const { return (snames_.size() + lnames_.size()) > 0; }
3241 
3243  bool has_description() const { return description_.length() > 0; }
3244 
3246  const std::string &get_description() const { return description_; }
3247 
3249  Option *description(std::string option_description) {
3250  description_ = std::move(option_description);
3251  return this;
3252  }
3253 
3257 
3262  std::string get_name(bool positional = false, //<[input] Show the positional name
3263  bool all_options = false //<[input] Show every option
3264  ) const {
3265 
3266  if(all_options) {
3267 
3268  std::vector<std::string> name_list;
3269 
3271  if((positional && pname_.length()) || (snames_.empty() && lnames_.empty()))
3272  name_list.push_back(pname_);
3273  if((get_items_expected() == 0) && (!fnames_.empty())) {
3274  for(const std::string &sname : snames_) {
3275  name_list.push_back("-" + sname);
3276  if(check_fname(sname)) {
3277  name_list.back() += "{" + get_flag_value(sname, "") + "}";
3278  }
3279  }
3280 
3281  for(const std::string &lname : lnames_) {
3282  name_list.push_back("--" + lname);
3283  if(check_fname(lname)) {
3284  name_list.back() += "{" + get_flag_value(lname, "") + "}";
3285  }
3286  }
3287  } else {
3288  for(const std::string &sname : snames_)
3289  name_list.push_back("-" + sname);
3290 
3291  for(const std::string &lname : lnames_)
3292  name_list.push_back("--" + lname);
3293  }
3294 
3295  return detail::join(name_list);
3296 
3297  } else {
3298 
3299  // This returns the positional name no matter what
3300  if(positional)
3301  return pname_;
3302 
3303  // Prefer long name
3304  else if(!lnames_.empty())
3305  return std::string("--") + lnames_[0];
3306 
3307  // Or short name if no long name
3308  else if(!snames_.empty())
3309  return std::string("-") + snames_[0];
3310 
3311  // If positional is the only name, it's okay to use that
3312  else
3313  return pname_;
3314  }
3315  }
3316 
3320 
3322  void run_callback() {
3323 
3324  callback_run_ = true;
3325 
3326  // Run the validators (can change the string)
3327  if(!validators_.empty()) {
3328  for(std::string &result : results_) {
3329  auto err_msg = _validate(result);
3330  if(!err_msg.empty())
3331  throw ValidationError(get_name(), err_msg);
3332  }
3333  }
3334  if(!(callback_)) {
3335  return;
3336  }
3337  bool local_result;
3338 
3339  // Num items expected or length of vector, always at least 1
3340  // Only valid for a trimming policy
3341  int trim_size =
3342  std::min<int>(std::max<int>(std::abs(get_items_expected()), 1), static_cast<int>(results_.size()));
3343 
3344  // Operation depends on the policy setting
3345  if(multi_option_policy_ == MultiOptionPolicy::TakeLast) {
3346  // Allow multi-option sizes (including 0)
3347  results_t partial_result{results_.end() - trim_size, results_.end()};
3348  local_result = !callback_(partial_result);
3349 
3350  } else if(multi_option_policy_ == MultiOptionPolicy::TakeFirst) {
3351  results_t partial_result{results_.begin(), results_.begin() + trim_size};
3352  local_result = !callback_(partial_result);
3353 
3354  } else if(multi_option_policy_ == MultiOptionPolicy::Join) {
3355  results_t partial_result = {detail::join(results_, "\n")};
3356  local_result = !callback_(partial_result);
3357 
3358  } else {
3359  // Exact number required
3360  if(get_items_expected() > 0) {
3361  if(results_.size() != static_cast<size_t>(get_items_expected()))
3362  throw ArgumentMismatch(get_name(), get_items_expected(), results_.size());
3363  // Variable length list
3364  } else if(get_items_expected() < 0) {
3365  // Require that this be a multiple of expected size and at least as many as expected
3366  if(results_.size() < static_cast<size_t>(-get_items_expected()) ||
3367  results_.size() % static_cast<size_t>(std::abs(get_type_size())) != 0u)
3368  throw ArgumentMismatch(get_name(), get_items_expected(), results_.size());
3369  }
3370  local_result = !callback_(results_);
3371  }
3372 
3373  if(local_result)
3374  throw ConversionError(get_name(), results_);
3375  }
3376 
3378  bool operator==(const Option &other) const {
3379  for(const std::string &sname : snames_)
3380  if(other.check_sname(sname))
3381  return true;
3382  for(const std::string &lname : lnames_)
3383  if(other.check_lname(lname))
3384  return true;
3385 
3386  if(ignore_case_ ||
3387  ignore_underscore_) { // We need to do the inverse, in case we are ignore_case or ignore underscore
3388  for(const std::string &sname : other.snames_)
3389  if(check_sname(sname))
3390  return true;
3391  for(const std::string &lname : other.lnames_)
3392  if(check_lname(lname))
3393  return true;
3394  }
3395  return false;
3396  }
3397 
3399  bool check_name(std::string name) const {
3400 
3401  if(name.length() > 2 && name[0] == '-' && name[1] == '-')
3402  return check_lname(name.substr(2));
3403  else if(name.length() > 1 && name.front() == '-')
3404  return check_sname(name.substr(1));
3405  else {
3406  std::string local_pname = pname_;
3407  if(ignore_underscore_) {
3408  local_pname = detail::remove_underscore(local_pname);
3409  name = detail::remove_underscore(name);
3410  }
3411  if(ignore_case_) {
3412  local_pname = detail::to_lower(local_pname);
3413  name = detail::to_lower(name);
3414  }
3415  return name == local_pname;
3416  }
3417  }
3418 
3420  bool check_sname(std::string name) const { return (detail::find_member(name, snames_, ignore_case_) >= 0); }
3421 
3423  bool check_lname(std::string name) const {
3424  return (detail::find_member(name, lnames_, ignore_case_, ignore_underscore_) >= 0);
3425  }
3426 
3428  bool check_fname(std::string name) const {
3429  if(fnames_.empty()) {
3430  return false;
3431  }
3432  return (detail::find_member(name, fnames_, ignore_case_, ignore_underscore_) >= 0);
3433  }
3434 
3435  std::string get_flag_value(std::string name, std::string input_value) const {
3436  static const std::string trueString{"true"};
3437  static const std::string falseString{"false"};
3438  static const std::string emptyString{"{}"};
3439  // check for disable flag override_
3440  if(disable_flag_override_) {
3441  if(!((input_value.empty()) || (input_value == emptyString))) {
3442  auto default_ind = detail::find_member(name, fnames_, ignore_case_, ignore_underscore_);
3443  if(default_ind >= 0) {
3444  // We can static cast this to size_t because it is more than 0 in this block
3445  if(default_flag_values_[static_cast<size_t>(default_ind)].second != input_value) {
3446  throw(ArgumentMismatch::FlagOverride(name));
3447  }
3448  } else {
3449  if(input_value != trueString) {
3450  throw(ArgumentMismatch::FlagOverride(name));
3451  }
3452  }
3453  }
3454  }
3455  auto ind = detail::find_member(name, fnames_, ignore_case_, ignore_underscore_);
3456  if((input_value.empty()) || (input_value == emptyString)) {
3457  return (ind < 0) ? trueString : default_flag_values_[static_cast<size_t>(ind)].second;
3458  }
3459  if(ind < 0) {
3460  return input_value;
3461  }
3462  if(default_flag_values_[static_cast<size_t>(ind)].second == falseString) {
3463  try {
3464  auto val = detail::to_flag_value(input_value);
3465  return (val == 1) ? falseString : (val == (-1) ? trueString : std::to_string(-val));
3466  } catch(const std::invalid_argument &) {
3467  return input_value;
3468  }
3469  } else {
3470  return input_value;
3471  }
3472  }
3473 
3475  Option *add_result(std::string s) {
3476  _add_result(std::move(s));
3477  callback_run_ = false;
3478  return this;
3479  }
3480 
3482  Option *add_result(std::string s, int &results_added) {
3483  results_added = _add_result(std::move(s));
3484  callback_run_ = false;
3485  return this;
3486  }
3487 
3489  Option *add_result(std::vector<std::string> s) {
3490  for(auto &str : s) {
3491  _add_result(std::move(str));
3492  }
3493  callback_run_ = false;
3494  return this;
3495  }
3496 
3498  std::vector<std::string> results() const { return results_; }
3499 
3501  template <typename T,
3502  enable_if_t<!is_vector<T>::value && !std::is_const<T>::value, detail::enabler> = detail::dummy>
3503  void results(T &output) const {
3504  bool retval;
3505  if(results_.empty()) {
3506  retval = detail::lexical_cast(default_str_, output);
3507  } else if(results_.size() == 1) {
3508  retval = detail::lexical_cast(results_[0], output);
3509  } else {
3510  switch(multi_option_policy_) {
3512  retval = detail::lexical_cast(results_.front(), output);
3513  break;
3515  default:
3516  retval = detail::lexical_cast(results_.back(), output);
3517  break;
3519  throw ConversionError(get_name(), results_);
3521  retval = detail::lexical_cast(detail::join(results_), output);
3522  break;
3523  }
3524  }
3525  if(!retval) {
3526  throw ConversionError(get_name(), results_);
3527  }
3528  }
3530  template <typename T> void results(std::vector<T> &output) const {
3531  output.clear();
3532  bool retval = true;
3533 
3534  for(const auto &elem : results_) {
3535  output.emplace_back();
3536  retval &= detail::lexical_cast(elem, output.back());
3537  }
3538 
3539  if(!retval) {
3540  throw ConversionError(get_name(), results_);
3541  }
3542  }
3543 
3545  template <typename T> T as() const {
3546  T output;
3547  results(output);
3548  return output;
3549  }
3550 
3552  bool get_callback_run() const { return callback_run_; }
3553 
3557 
3559  Option *type_name_fn(std::function<std::string()> typefun) {
3560  type_name_ = typefun;
3561  return this;
3562  }
3563 
3565  Option *type_name(std::string typeval) {
3566  type_name_fn([typeval]() { return typeval; });
3567  return this;
3568  }
3569 
3571  Option *type_size(int option_type_size) {
3572  type_size_ = option_type_size;
3573  if(type_size_ == 0)
3574  required_ = false;
3575  if(option_type_size < 0)
3576  expected_ = -1;
3577  return this;
3578  }
3579 
3581  Option *default_function(const std::function<std::string()> &func) {
3582  default_function_ = func;
3583  return this;
3584  }
3585 
3588  if(default_function_) {
3589  default_str_ = default_function_();
3590  }
3591  return this;
3592  }
3593 
3595  Option *default_str(std::string val) {
3596  default_str_ = val;
3597  return this;
3598  }
3599 
3601  Option *default_val(std::string val) {
3602  default_str(val);
3603  auto old_results = results_;
3604  results_ = {val};
3605  run_callback();
3606  results_ = std::move(old_results);
3607  return this;
3608  }
3609 
3611  std::string get_type_name() const {
3612  std::string full_type_name = type_name_();
3613  if(!validators_.empty()) {
3614  for(auto &validator : validators_) {
3615  std::string vtype = validator.get_description();
3616  if(!vtype.empty()) {
3617  full_type_name += ":" + vtype;
3618  }
3619  }
3620  }
3621  return full_type_name;
3622  }
3623 
3624  private:
3625  // run through the validators
3626  std::string _validate(std::string &result) {
3627  std::string err_msg;
3628  for(const auto &vali : validators_) {
3629  try {
3630  err_msg = vali(result);
3631  } catch(const ValidationError &err) {
3632  err_msg = err.what();
3633  }
3634  if(!err_msg.empty())
3635  break;
3636  }
3637  return err_msg;
3638  }
3639 
3640  int _add_result(std::string &&result) {
3641  int result_count = 0;
3642  if(delimiter_ == '\0') {
3643  results_.push_back(std::move(result));
3644  ++result_count;
3645  } else {
3646  if((result.find_first_of(delimiter_) != std::string::npos)) {
3647  for(const auto &var : CLI::detail::split(result, delimiter_)) {
3648  if(!var.empty()) {
3649  results_.push_back(var);
3650  ++result_count;
3651  }
3652  }
3653  } else {
3654  results_.push_back(std::move(result));
3655  ++result_count;
3656  }
3657  }
3658  return result_count;
3659  }
3660 };
3661 
3662 } // namespace CLI
3663 
3664 // From CLI/App.hpp:
3665 
3666 namespace CLI {
3667 
3668 #ifndef CLI11_PARSE
3669 #define CLI11_PARSE(app, argc, argv) \
3670  try { \
3671  (app).parse((argc), (argv)); \
3672  } catch(const CLI::ParseError &e) { \
3673  return (app).exit(e); \
3674  }
3675 #endif
3676 
3677 namespace detail {
3679 struct AppFriend;
3680 } // namespace detail
3681 
3682 namespace FailureMessage {
3683 std::string simple(const App *app, const Error &e);
3684 std::string help(const App *app, const Error &e);
3685 } // namespace FailureMessage
3686 
3687 class App;
3688 
3689 using App_p = std::shared_ptr<App>;
3690 
3691 class Option_group;
3693 
3696 class App {
3697  friend Option;
3698  friend detail::AppFriend;
3699 
3700  protected:
3701  // This library follows the Google style guide for member names ending in underscores
3702 
3705 
3707  std::string name_;
3708 
3710  std::string description_;
3711 
3713  bool allow_extras_{false};
3714 
3716  bool allow_config_extras_{false};
3717 
3719  bool prefix_command_{false};
3720 
3722  bool has_automatic_name_{false};
3723 
3725  bool required_{false};
3726 
3728  bool disabled_{false};
3729 
3731  bool pre_parse_called_{false};
3732 
3735  bool immediate_callback_{false};
3736 
3738  std::function<void(size_t)> pre_parse_callback_;
3739 
3741  std::function<void()> callback_;
3742 
3746 
3749 
3751  std::vector<Option_p> options_;
3752 
3756 
3758  std::string footer_;
3759 
3761  Option *help_ptr_{nullptr};
3762 
3764  Option *help_all_ptr_{nullptr};
3765 
3767  std::shared_ptr<FormatterBase> formatter_{new Formatter()};
3768 
3770  std::function<std::string(const App *, const Error &e)> failure_message_ = FailureMessage::simple;
3771 
3775 
3776  using missing_t = std::vector<std::pair<detail::Classifier, std::string>>;
3777 
3782 
3784  std::vector<Option *> parse_order_;
3785 
3787  std::vector<App *> parsed_subcommands_;
3788 
3790  std::set<App *> exclude_subcommands_;
3791 
3794  std::set<Option *> exclude_options_;
3795 
3799 
3801  std::vector<App_p> subcommands_;
3802 
3804  bool ignore_case_{false};
3805 
3807  bool ignore_underscore_{false};
3808 
3810  bool fallthrough_{false};
3811 
3813  bool allow_windows_style_options_{
3814 #ifdef _WIN32
3815  true
3816 #else
3817  false
3818 #endif
3819  };
3821  bool positionals_at_end_{false};
3822 
3824  bool disabled_by_default_{false};
3826  bool enabled_by_default_{false};
3828  bool validate_positionals_{false};
3830  App *parent_{nullptr};
3831 
3833  size_t parsed_ = 0;
3834 
3836  size_t require_subcommand_min_ = 0;
3837 
3839  size_t require_subcommand_max_ = 0;
3840 
3842  size_t require_option_min_ = 0;
3843 
3845  size_t require_option_max_ = 0;
3846 
3848  std::string group_{"Subcommands"};
3849 
3853 
3855  std::string config_name_;
3856 
3858  bool config_required_{false};
3859 
3861  Option *config_ptr_{nullptr};
3862 
3864  std::shared_ptr<Config> config_formatter_{new ConfigINI()};
3865 
3867 
3869  App(std::string app_description, std::string app_name, App *parent)
3870  : name_(std::move(app_name)), description_(std::move(app_description)), parent_(parent) {
3871  // Inherit if not from a nullptr
3872  if(parent_ != nullptr) {
3873  if(parent_->help_ptr_ != nullptr)
3874  set_help_flag(parent_->help_ptr_->get_name(false, true), parent_->help_ptr_->get_description());
3875  if(parent_->help_all_ptr_ != nullptr)
3876  set_help_all_flag(parent_->help_all_ptr_->get_name(false, true),
3877  parent_->help_all_ptr_->get_description());
3878 
3880  option_defaults_ = parent_->option_defaults_;
3881 
3882  // INHERITABLE
3883  failure_message_ = parent_->failure_message_;
3884  allow_extras_ = parent_->allow_extras_;
3885  allow_config_extras_ = parent_->allow_config_extras_;
3886  prefix_command_ = parent_->prefix_command_;
3887  immediate_callback_ = parent_->immediate_callback_;
3888  ignore_case_ = parent_->ignore_case_;
3889  ignore_underscore_ = parent_->ignore_underscore_;
3890  fallthrough_ = parent_->fallthrough_;
3891  validate_positionals_ = parent_->validate_positionals_;
3892  allow_windows_style_options_ = parent_->allow_windows_style_options_;
3893  group_ = parent_->group_;
3894  footer_ = parent_->footer_;
3895  formatter_ = parent_->formatter_;
3896  config_formatter_ = parent_->config_formatter_;
3897  require_subcommand_max_ = parent_->require_subcommand_max_;
3898  }
3899  }
3900 
3901  public:
3904 
3906  explicit App(std::string app_description = "", std::string app_name = "")
3907  : App(app_description, app_name, nullptr) {
3908  set_help_flag("-h,--help", "Print this help message and exit");
3909  }
3910 
3912  virtual ~App() = default;
3913 
3920  App *callback(std::function<void()> app_callback) {
3921  callback_ = std::move(app_callback);
3922  return this;
3923  }
3924 
3927  App *preparse_callback(std::function<void(size_t)> pp_callback) {
3928  pre_parse_callback_ = std::move(pp_callback);
3929  return this;
3930  }
3931 
3933  App *name(std::string app_name = "") {
3934  name_ = app_name;
3935  has_automatic_name_ = false;
3936  return this;
3937  }
3938 
3940  App *allow_extras(bool allow = true) {
3941  allow_extras_ = allow;
3942  return this;
3943  }
3944 
3946  App *required(bool require = true) {
3947  required_ = require;
3948  return this;
3949  }
3950 
3952  App *disabled(bool disable = true) {
3953  disabled_ = disable;
3954  return this;
3955  }
3956 
3958  App *disabled_by_default(bool disable = true) {
3959  disabled_by_default_ = disable;
3960  return this;
3961  }
3962 
3965  App *enabled_by_default(bool enable = true) {
3966  enabled_by_default_ = enable;
3967  return this;
3968  }
3969 
3971  App *immediate_callback(bool immediate = true) {
3972  immediate_callback_ = immediate;
3973  return this;
3974  }
3975 
3977  App *validate_positionals(bool validate = true) {
3978  validate_positionals_ = validate;
3979  return this;
3980  }
3981 
3984  App *allow_config_extras(bool allow = true) {
3985  allow_extras(allow);
3986  allow_config_extras_ = allow;
3987  return this;
3988  }
3989 
3991  App *prefix_command(bool allow = true) {
3992  prefix_command_ = allow;
3993  return this;
3994  }
3995 
3997  App *ignore_case(bool value = true) {
3998  ignore_case_ = value;
3999  if(parent_ != nullptr && !name_.empty()) {
4000  for(const auto &subc : parent_->subcommands_) {
4001  if(subc.get() != this && (this->check_name(subc->name_) || subc->check_name(this->name_)))
4002  throw OptionAlreadyAdded(subc->name_);
4003  }
4004  }
4005  return this;
4006  }
4007 
4009  App *allow_windows_style_options(bool value = true) {
4010  allow_windows_style_options_ = value;
4011  return this;
4012  }
4013 
4015  App *positionals_at_end(bool value = true) {
4016  positionals_at_end_ = value;
4017  return this;
4018  }
4019 
4021  App *ignore_underscore(bool value = true) {
4022  ignore_underscore_ = value;
4023  if(parent_ != nullptr && !name_.empty()) {
4024  for(const auto &subc : parent_->subcommands_) {
4025  if(subc.get() != this && (this->check_name(subc->name_) || subc->check_name(this->name_)))
4026  throw OptionAlreadyAdded(subc->name_);
4027  }
4028  }
4029  return this;
4030  }
4031 
4033  App *formatter(std::shared_ptr<FormatterBase> fmt) {
4034  formatter_ = fmt;
4035  return this;
4036  }
4037 
4039  App *formatter_fn(std::function<std::string(const App *, std::string, AppFormatMode)> fmt) {
4040  formatter_ = std::make_shared<FormatterLambda>(fmt);
4041  return this;
4042  }
4043 
4045  App *config_formatter(std::shared_ptr<Config> fmt) {
4046  config_formatter_ = fmt;
4047  return this;
4048  }
4049 
4051  bool parsed() const { return parsed_ > 0; }
4052 
4054  OptionDefaults *option_defaults() { return &option_defaults_; }
4055 
4059 
4074  Option *add_option(std::string option_name,
4075  callback_t option_callback,
4076  std::string option_description = "",
4077  bool defaulted = false,
4078  std::function<std::string()> func = {}) {
4079  Option myopt{option_name, option_description, option_callback, this};
4080 
4081  if(std::find_if(std::begin(options_), std::end(options_), [&myopt](const Option_p &v) {
4082  return *v == myopt;
4083  }) == std::end(options_)) {
4084  options_.emplace_back();
4085  Option_p &option = options_.back();
4086  option.reset(new Option(option_name, option_description, option_callback, this));
4087 
4088  // Set the default string capture function
4089  option->default_function(func);
4090 
4091  // For compatibility with CLI11 1.7 and before, capture the default string here
4092  if(defaulted)
4093  option->capture_default_str();
4094 
4095  // Transfer defaults to the new option
4096  option_defaults_.copy_to(option.get());
4097 
4098  // Don't bother to capture if we already did
4099  if(!defaulted && option->get_always_capture_default())
4100  option->capture_default_str();
4101 
4102  return option.get();
4103 
4104  } else
4105  throw OptionAlreadyAdded(myopt.get_name());
4106  }
4107 
4109  template <typename T, enable_if_t<!is_vector<T>::value & !std::is_const<T>::value, detail::enabler> = detail::dummy>
4110  Option *add_option(std::string option_name,
4111  T &variable,
4112  std::string option_description = "",
4113  bool defaulted = false) {
4114 
4115  auto fun = [&variable](CLI::results_t res) { return detail::lexical_cast(res[0], variable); };
4116 
4117  Option *opt = add_option(option_name, fun, option_description, defaulted, [&variable]() {
4118  return std::string(CLI::detail::to_string(variable));
4119  });
4120  opt->type_name(detail::type_name<T>());
4121 
4122  return opt;
4123  }
4124 
4126  template <typename T, enable_if_t<!is_vector<T>::value, detail::enabler> = detail::dummy>
4127  Option *add_option_function(std::string option_name,
4128  const std::function<void(const T &)> &func,
4129  std::string option_description = "") {
4130 
4131  auto fun = [func](CLI::results_t res) {
4132  T variable;
4133  bool result = detail::lexical_cast(res[0], variable);
4134  if(result) {
4135  func(variable);
4136  }
4137  return result;
4138  };
4139 
4140  Option *opt = add_option(option_name, std::move(fun), option_description, false);
4141  opt->type_name(detail::type_name<T>());
4142  return opt;
4143  }
4144 
4146  Option *add_option(std::string option_name) {
4147  return add_option(option_name, CLI::callback_t(), std::string{}, false);
4148  }
4149 
4151  template <typename T,
4152  enable_if_t<std::is_const<T>::value && std::is_constructible<std::string, T>::value, detail::enabler> =
4153  detail::dummy>
4154  Option *add_option(std::string option_name, T &option_description) {
4155  return add_option(option_name, CLI::callback_t(), option_description, false);
4156  }
4157 
4159  template <typename T>
4160  Option *add_option(std::string option_name,
4161  std::vector<T> &variable,
4162  std::string option_description = "",
4163  bool defaulted = false) {
4164 
4165  auto fun = [&variable](CLI::results_t res) {
4166  bool retval = true;
4167  variable.clear();
4168  variable.reserve(res.size());
4169  for(const auto &elem : res) {
4170 
4171  variable.emplace_back();
4172  retval &= detail::lexical_cast(elem, variable.back());
4173  }
4174  return (!variable.empty()) && retval;
4175  };
4176 
4177  auto default_function = [&variable]() {
4178  std::vector<std::string> defaults;
4179  defaults.resize(variable.size());
4180  std::transform(variable.begin(), variable.end(), defaults.begin(), [](T &val) {
4181  return std::string(CLI::detail::to_string(val));
4182  });
4183  return std::string("[" + detail::join(defaults) + "]");
4184  };
4185 
4186  Option *opt = add_option(option_name, fun, option_description, defaulted, default_function);
4187  opt->type_name(detail::type_name<T>())->type_size(-1);
4188 
4189  return opt;
4190  }
4191 
4193  template <typename T, enable_if_t<is_vector<T>::value, detail::enabler> = detail::dummy>
4194  Option *add_option_function(std::string option_name,
4195  const std::function<void(const T &)> &func,
4196  std::string option_description = "") {
4197 
4198  CLI::callback_t fun = [func](CLI::results_t res) {
4199  T values;
4200  bool retval = true;
4201  values.reserve(res.size());
4202  for(const auto &elem : res) {
4203  values.emplace_back();
4204  retval &= detail::lexical_cast(elem, values.back());
4205  }
4206  if(retval) {
4207  func(values);
4208  }
4209  return retval;
4210  };
4211 
4212  Option *opt = add_option(option_name, std::move(fun), std::move(option_description), false);
4213  opt->type_name(detail::type_name<T>())->type_size(-1);
4214  return opt;
4215  }
4216 
4218  Option *set_help_flag(std::string flag_name = "", const std::string &help_description = "") {
4219  // take flag_description by const reference otherwise add_flag tries to assign to help_description
4220  if(help_ptr_ != nullptr) {
4221  remove_option(help_ptr_);
4222  help_ptr_ = nullptr;
4223  }
4224 
4225  // Empty name will simply remove the help flag
4226  if(!flag_name.empty()) {
4227  help_ptr_ = add_flag(flag_name, help_description);
4228  help_ptr_->configurable(false);
4229  }
4230 
4231  return help_ptr_;
4232  }
4233 
4235  Option *set_help_all_flag(std::string help_name = "", const std::string &help_description = "") {
4236  // take flag_description by const reference otherwise add_flag tries to assign to flag_description
4237  if(help_all_ptr_ != nullptr) {
4238  remove_option(help_all_ptr_);
4239  help_all_ptr_ = nullptr;
4240  }
4241 
4242  // Empty name will simply remove the help all flag
4243  if(!help_name.empty()) {
4244  help_all_ptr_ = add_flag(help_name, help_description);
4245  help_all_ptr_->configurable(false);
4246  }
4247 
4248  return help_all_ptr_;
4249  }
4250 
4251  private:
4253  Option *_add_flag_internal(std::string flag_name, CLI::callback_t fun, std::string flag_description) {
4254  Option *opt;
4255  if(detail::has_default_flag_values(flag_name)) {
4256  // check for default values and if it has them
4257  auto flag_defaults = detail::get_default_flag_values(flag_name);
4259  opt = add_option(std::move(flag_name), std::move(fun), std::move(flag_description), false);
4260  for(const auto &fname : flag_defaults)
4261  opt->fnames_.push_back(fname.first);
4262  opt->default_flag_values_ = std::move(flag_defaults);
4263  } else {
4264  opt = add_option(std::move(flag_name), std::move(fun), std::move(flag_description), false);
4265  }
4266  // flags cannot have positional values
4267  if(opt->get_positional()) {
4268  auto pos_name = opt->get_name(true);
4269  remove_option(opt);
4270  throw IncorrectConstruction::PositionalFlag(pos_name);
4271  }
4272 
4273  opt->type_size(0);
4274  return opt;
4275  }
4276 
4277  public:
4279  Option *add_flag(std::string flag_name) { return _add_flag_internal(flag_name, CLI::callback_t(), std::string{}); }
4280 
4284  template <typename T,
4285  enable_if_t<std::is_const<T>::value && std::is_constructible<std::string, T>::value, detail::enabler> =
4286  detail::dummy>
4287  Option *add_flag(std::string flag_name, T &flag_description) {
4288  return _add_flag_internal(flag_name, CLI::callback_t(), flag_description);
4289  }
4290 
4293  template <typename T,
4295  Option *add_flag(std::string flag_name,
4296  T &flag_count,
4297  std::string flag_description = "") {
4298  flag_count = 0;
4299  CLI::callback_t fun = [&flag_count](CLI::results_t res) {
4300  try {
4301  detail::sum_flag_vector(res, flag_count);
4302  } catch(const std::invalid_argument &) {
4303  return false;
4304  }
4305  return true;
4306  };
4307  return _add_flag_internal(flag_name, std::move(fun), std::move(flag_description));
4308  }
4309 
4312  template <typename T,
4313  enable_if_t<!is_vector<T>::value && !std::is_const<T>::value &&
4314  (!std::is_integral<T>::value || is_bool<T>::value) &&
4315  !std::is_constructible<std::function<void(int)>, T>::value,
4316  detail::enabler> = detail::dummy>
4317  Option *add_flag(std::string flag_name,
4318  T &flag_result,
4319  std::string flag_description = "") {
4320 
4321  CLI::callback_t fun = [&flag_result](CLI::results_t res) {
4322  if(res.size() != 1) {
4323  return false;
4324  }
4325  return CLI::detail::lexical_cast(res[0], flag_result);
4326  };
4327  Option *opt = _add_flag_internal(flag_name, std::move(fun), std::move(flag_description));
4329  return opt;
4330  }
4331 
4333  template <typename T,
4335  Option *add_flag(std::string flag_name,
4336  std::vector<T> &flag_results,
4337  std::string flag_description = "") {
4338  CLI::callback_t fun = [&flag_results](CLI::results_t res) {
4339  bool retval = true;
4340  for(const auto &elem : res) {
4341  flag_results.emplace_back();
4342  retval &= detail::lexical_cast(elem, flag_results.back());
4343  }
4344  return retval;
4345  };
4346  return _add_flag_internal(flag_name, std::move(fun), std::move(flag_description));
4347  }
4348 
4350  Option *add_flag_callback(std::string flag_name,
4351  std::function<void(void)> function,
4352  std::string flag_description = "") {
4353 
4354  CLI::callback_t fun = [function](CLI::results_t res) {
4355  if(res.size() != 1) {
4356  return false;
4357  }
4358  bool trigger;
4359  auto result = CLI::detail::lexical_cast(res[0], trigger);
4360  if(trigger)
4361  function();
4362  return result;
4363  };
4364  Option *opt = _add_flag_internal(flag_name, std::move(fun), std::move(flag_description));
4366  return opt;
4367  }
4368 
4370  Option *add_flag_function(std::string flag_name,
4371  std::function<void(int64_t)> function,
4372  std::string flag_description = "") {
4373 
4374  CLI::callback_t fun = [function](CLI::results_t res) {
4375  int64_t flag_count = 0;
4376  detail::sum_flag_vector(res, flag_count);
4377  function(flag_count);
4378  return true;
4379  };
4380  return _add_flag_internal(flag_name, std::move(fun), std::move(flag_description));
4381  }
4382 
4383 #ifdef CLI11_CPP14
4384  Option *add_flag(std::string flag_name,
4386  std::function<void(int64_t)> function,
4387  std::string flag_description = "") {
4388  return add_flag_function(std::move(flag_name), std::move(function), std::move(flag_description));
4389  }
4390 #endif
4391 
4393  template <typename T>
4394  Option *add_set(std::string option_name,
4395  T &member,
4396  std::set<T> options,
4397  std::string option_description = "") {
4398 
4399  Option *opt = add_option(option_name, member, std::move(option_description));
4400  opt->check(IsMember{options});
4401  return opt;
4402  }
4403 
4405  template <typename T>
4406  Option *add_mutable_set(std::string option_name,
4407  T &member,
4408  const std::set<T> &options,
4409  std::string option_description = "") {
4410 
4411  Option *opt = add_option(option_name, member, std::move(option_description));
4412  opt->check(IsMember{&options});
4413  return opt;
4414  }
4415 
4417  template <typename T>
4418  Option *add_set(std::string option_name,
4419  T &member,
4420  std::set<T> options,
4421  std::string option_description,
4422  bool defaulted) {
4423 
4424  Option *opt = add_option(option_name, member, std::move(option_description), defaulted);
4425  opt->check(IsMember{options});
4426  return opt;
4427  }
4428 
4430  template <typename T>
4431  Option *add_mutable_set(std::string option_name,
4432  T &member,
4433  const std::set<T> &options,
4434  std::string option_description,
4435  bool defaulted) {
4436 
4437  Option *opt = add_option(option_name, member, std::move(option_description), defaulted);
4438  opt->check(IsMember{&options});
4439  return opt;
4440  }
4441 
4443  CLI11_DEPRECATED("Use ->transform(CLI::IsMember(..., CLI::ignore_case)) instead")
4444  Option *add_set_ignore_case(std::string option_name,
4445  std::string &member,
4446  std::set<std::string> options,
4447  std::string option_description = "") {
4448 
4449  Option *opt = add_option(option_name, member, std::move(option_description));
4450  opt->transform(IsMember{options, CLI::ignore_case});
4451  return opt;
4452  }
4453 
4456  CLI11_DEPRECATED("Use ->transform(CLI::IsMember(..., CLI::ignore_case)) with a (shared) pointer instead")
4457  Option *add_mutable_set_ignore_case(std::string option_name,
4458  std::string &member,
4459  const std::set<std::string> &options,
4460  std::string option_description = "") {
4461 
4462  Option *opt = add_option(option_name, member, std::move(option_description));
4463  opt->transform(IsMember{&options, CLI::ignore_case});
4464  return opt;
4465  }
4466 
4468  CLI11_DEPRECATED("Use ->transform(CLI::IsMember(..., CLI::ignore_case)) instead")
4469  Option *add_set_ignore_case(std::string option_name,
4470  std::string &member,
4471  std::set<std::string> options,
4472  std::string option_description,
4473  bool defaulted) {
4474 
4475  Option *opt = add_option(option_name, member, std::move(option_description), defaulted);
4476  opt->transform(IsMember{options, CLI::ignore_case});
4477  return opt;
4478  }
4479 
4482  CLI11_DEPRECATED("Use ->transform(CLI::IsMember(...)) with a (shared) pointer instead")
4483  Option *add_mutable_set_ignore_case(std::string option_name,
4484  std::string &member,
4485  const std::set<std::string> &options,
4486  std::string option_description,
4487  bool defaulted) {
4488 
4489  Option *opt = add_option(option_name, member, std::move(option_description), defaulted);
4490  opt->transform(IsMember{&options, CLI::ignore_case});
4491  return opt;
4492  }
4493 
4495  CLI11_DEPRECATED("Use ->transform(CLI::IsMember(..., CLI::ignore_underscore)) instead")
4496  Option *add_set_ignore_underscore(std::string option_name,
4497  std::string &member,
4498  std::set<std::string> options,
4499  std::string option_description = "") {
4500 
4501  Option *opt = add_option(option_name, member, std::move(option_description));
4502  opt->transform(IsMember{options, CLI::ignore_underscore});
4503  return opt;
4504  }
4505 
4508  CLI11_DEPRECATED("Use ->transform(CLI::IsMember(..., CLI::ignore_underscore)) with a (shared) pointer instead")
4509  Option *add_mutable_set_ignore_underscore(std::string option_name,
4510  std::string &member,
4511  const std::set<std::string> &options,
4512  std::string option_description = "") {
4513 
4514  Option *opt = add_option(option_name, member, std::move(option_description));
4515  opt->transform(IsMember{options, CLI::ignore_underscore});
4516  return opt;
4517  }
4518 
4520  CLI11_DEPRECATED("Use ->transform(CLI::IsMember(..., CLI::ignore_underscore)) instead")
4521  Option *add_set_ignore_underscore(std::string option_name,
4522  std::string &member,
4523  std::set<std::string> options,
4524  std::string option_description,
4525  bool defaulted) {
4526 
4527  Option *opt = add_option(option_name, member, std::move(option_description), defaulted);
4528  opt->transform(IsMember{options, CLI::ignore_underscore});
4529  return opt;
4530  }
4531 
4534  CLI11_DEPRECATED("Use ->transform(CLI::IsMember(..., CLI::ignore_underscore)) with a (shared) pointer instead")
4535  Option *add_mutable_set_ignore_underscore(std::string option_name,
4536  std::string &member,
4537  const std::set<std::string> &options,
4538  std::string option_description,
4539  bool defaulted) {
4540 
4541  Option *opt = add_option(option_name, member, std::move(option_description), defaulted);
4542  opt->transform(IsMember{&options, CLI::ignore_underscore});
4543  return opt;
4544  }
4545 
4547  CLI11_DEPRECATED("Use ->transform(CLI::IsMember(..., CLI::ignore_case, CLI::ignore_underscore)) instead")
4548  Option *add_set_ignore_case_underscore(std::string option_name,
4549  std::string &member,
4550  std::set<std::string> options,
4551  std::string option_description = "") {
4552 
4553  Option *opt = add_option(option_name, member, std::move(option_description));
4555  return opt;
4556  }
4557 
4561  "Use ->transform(CLI::IsMember(..., CLI::ignore_case, CLI::ignore_underscore)) with a (shared) pointer instead")
4562  Option *add_mutable_set_ignore_case_underscore(std::string option_name,
4563  std::string &member,
4564  const std::set<std::string> &options,
4565  std::string option_description = "") {
4566 
4567  Option *opt = add_option(option_name, member, std::move(option_description));
4569  return opt;
4570  }
4571 
4573  CLI11_DEPRECATED("Use ->transform(CLI::IsMember(..., CLI::ignore_case, CLI::ignore_underscore)) instead")
4574  Option *add_set_ignore_case_underscore(std::string option_name,
4575  std::string &member,
4576  std::set<std::string> options,
4577  std::string option_description,
4578  bool defaulted) {
4579 
4580  Option *opt = add_option(option_name, member, std::move(option_description), defaulted);
4582  return opt;
4583  }
4584 
4588  "Use ->transform(CLI::IsMember(..., CLI::ignore_case, CLI::ignore_underscore)) with a (shared) pointer instead")
4589  Option *add_mutable_set_ignore_case_underscore(std::string option_name,
4590  std::string &member,
4591  const std::set<std::string> &options,
4592  std::string option_description,
4593  bool defaulted) {
4594 
4595  Option *opt = add_option(option_name, member, std::move(option_description), defaulted);
4597  return opt;
4598  }
4599 
4601  template <typename T>
4602  Option *add_complex(std::string option_name,
4603  T &variable,
4604  std::string option_description = "",
4605  bool defaulted = false,
4606  std::string label = "COMPLEX") {
4607 
4608  std::string simple_name = CLI::detail::split(option_name, ',').at(0);
4609  CLI::callback_t fun = [&variable, simple_name, label](results_t res) {
4610  if(res[1].back() == 'i')
4611  res[1].pop_back();
4612  double x, y;
4613  bool worked = detail::lexical_cast(res[0], x) && detail::lexical_cast(res[1], y);
4614  if(worked)
4615  variable = T(x, y);
4616  return worked;
4617  };
4618 
4619  auto default_function = [&variable]() {
4620  std::stringstream out;
4621  out << variable;
4622  return out.str();
4623  };
4624 
4625  CLI::Option *opt =
4626  add_option(option_name, std::move(fun), std::move(option_description), defaulted, default_function);
4627 
4628  opt->type_name(label)->type_size(2);
4629  return opt;
4630  }
4631 
4633  Option *set_config(std::string option_name = "",
4634  std::string default_filename = "",
4635  std::string help_message = "Read an ini file",
4636  bool config_required = false) {
4637 
4638  // Remove existing config if present
4639  if(config_ptr_ != nullptr)
4640  remove_option(config_ptr_);
4641 
4642  // Only add config if option passed
4643  if(!option_name.empty()) {
4644  config_name_ = default_filename;
4645  config_required_ = config_required;
4646  config_ptr_ = add_option(option_name, config_name_, help_message, !default_filename.empty());
4647  config_ptr_->configurable(false);
4648  }
4649 
4650  return config_ptr_;
4651  }
4652 
4654  bool remove_option(Option *opt) {
4655  // Make sure no links exist
4656  for(Option_p &op : options_) {
4657  op->remove_needs(opt);
4658  op->remove_excludes(opt);
4659  }
4660 
4661  if(help_ptr_ == opt)
4662  help_ptr_ = nullptr;
4663  if(help_all_ptr_ == opt)
4664  help_all_ptr_ = nullptr;
4665 
4666  auto iterator =
4667  std::find_if(std::begin(options_), std::end(options_), [opt](const Option_p &v) { return v.get() == opt; });
4668  if(iterator != std::end(options_)) {
4669  options_.erase(iterator);
4670  return true;
4671  }
4672  return false;
4673  }
4674 
4676  template <typename T = Option_group>
4677  T *add_option_group(std::string group_name, std::string group_description = "") {
4678  auto option_group = std::make_shared<T>(std::move(group_description), group_name, nullptr);
4679  auto ptr = option_group.get();
4680  // move to App_p for overload resolution on older gcc versions
4681  App_p app_ptr = std::dynamic_pointer_cast<App>(option_group);
4682  add_subcommand(std::move(app_ptr));
4683  return ptr;
4684  }
4685 
4689 
4691  App *add_subcommand(std::string subcommand_name = "", std::string subcommand_description = "") {
4692  CLI::App_p subcom = std::shared_ptr<App>(new App(std::move(subcommand_description), subcommand_name, this));
4693  return add_subcommand(std::move(subcom));
4694  }
4695 
4698  if(!subcom)
4699  throw IncorrectConstruction("passed App is not valid");
4700  if(!subcom->name_.empty()) {
4701  for(const auto &subc : subcommands_)
4702  if(subc->check_name(subcom->name_) || subcom->check_name(subc->name_))
4703  throw OptionAlreadyAdded(subc->name_);
4704  }
4705  subcom->parent_ = this;
4706  subcommands_.push_back(std::move(subcom));
4707  return subcommands_.back().get();
4708  }
4709 
4711  bool remove_subcommand(App *subcom) {
4712  // Make sure no links exist
4713  for(App_p &sub : subcommands_) {
4714  sub->remove_excludes(subcom);
4715  }
4716 
4717  auto iterator = std::find_if(
4718  std::begin(subcommands_), std::end(subcommands_), [subcom](const App_p &v) { return v.get() == subcom; });
4719  if(iterator != std::end(subcommands_)) {
4720  subcommands_.erase(iterator);
4721  return true;
4722  }
4723  return false;
4724  }
4727  App *get_subcommand(App *subcom) const {
4728  if(subcom == nullptr)
4729  throw OptionNotFound("nullptr passed");
4730  for(const App_p &subcomptr : subcommands_)
4731  if(subcomptr.get() == subcom)
4732  return subcom;
4733  throw OptionNotFound(subcom->get_name());
4734  }
4735 
4737  App *get_subcommand(std::string subcom) const {
4738  auto subc = _find_subcommand(subcom, false, false);
4739  if(subc == nullptr)
4740  throw OptionNotFound(subcom);
4741  return subc;
4742  }
4744  App *get_subcommand(int index = 0) const {
4745  if(index >= 0) {
4746  auto uindex = static_cast<unsigned>(index);
4747  if(uindex < subcommands_.size())
4748  return subcommands_[uindex].get();
4749  }
4750  throw OptionNotFound(std::to_string(index));
4751  }
4752 
4755  if(subcom == nullptr)
4756  throw OptionNotFound("nullptr passed");
4757  for(const App_p &subcomptr : subcommands_)
4758  if(subcomptr.get() == subcom)
4759  return subcomptr;
4760  throw OptionNotFound(subcom->get_name());
4761  }
4762 
4764  CLI::App_p get_subcommand_ptr(std::string subcom) const {
4765  for(const App_p &subcomptr : subcommands_)
4766  if(subcomptr->check_name(subcom))
4767  return subcomptr;
4768  throw OptionNotFound(subcom);
4769  }
4770 
4772  CLI::App_p get_subcommand_ptr(int index = 0) const {
4773  if(index >= 0) {
4774  auto uindex = static_cast<unsigned>(index);
4775  if(uindex < subcommands_.size())
4776  return subcommands_[uindex];
4777  }
4778  throw OptionNotFound(std::to_string(index));
4779  }
4780 
4782  App *get_option_group(std::string group_name) const {
4783  for(const App_p &app : subcommands_) {
4784  if(app->name_.empty() && app->group_ == group_name) {
4785  return app.get();
4786  }
4787  }
4788  throw OptionNotFound(group_name);
4789  }
4790 
4794  size_t count() const { return parsed_; }
4795 
4798  size_t count_all() const {
4799  size_t cnt{0};
4800  for(auto &opt : options_) {
4801  cnt += opt->count();
4802  }
4803  for(auto &sub : subcommands_) {
4804  cnt += sub->count_all();
4805  }
4806  if(!get_name().empty()) { // for named subcommands add the number of times the subcommand was called
4807  cnt += parsed_;
4808  }
4809  return cnt;
4810  }
4811 
4813  App *group(std::string group_name) {
4814  group_ = group_name;
4815  return this;
4816  }
4817 
4820  require_subcommand_min_ = 1;
4821  require_subcommand_max_ = 0;
4822  return this;
4823  }
4824 
4828  App *require_subcommand(int value) {
4829  if(value < 0) {
4830  require_subcommand_min_ = 0;
4831  require_subcommand_max_ = static_cast<size_t>(-value);
4832  } else {
4833  require_subcommand_min_ = static_cast<size_t>(value);
4834  require_subcommand_max_ = static_cast<size_t>(value);
4835  }
4836  return this;
4837  }
4838 
4841  App *require_subcommand(size_t min, size_t max) {
4842  require_subcommand_min_ = min;
4843  require_subcommand_max_ = max;
4844  return this;
4845  }
4846 
4849  require_option_min_ = 1;
4850  require_option_max_ = 0;
4851  return this;
4852  }
4853 
4857  App *require_option(int value) {
4858  if(value < 0) {
4859  require_option_min_ = 0;
4860  require_option_max_ = static_cast<size_t>(-value);
4861  } else {
4862  require_option_min_ = static_cast<size_t>(value);
4863  require_option_max_ = static_cast<size_t>(value);
4864  }
4865  return this;
4866  }
4867 
4870  App *require_option(size_t min, size_t max) {
4871  require_option_min_ = min;
4872  require_option_max_ = max;
4873  return this;
4874  }
4875 
4878  App *fallthrough(bool value = true) {
4879  fallthrough_ = value;
4880  return this;
4881  }
4882 
4885  operator bool() const { return parsed_ > 0; }
4886 
4890 
4894  virtual void pre_callback() {}
4895 
4899  //
4901  void clear() {
4902 
4903  parsed_ = 0;
4904  pre_parse_called_ = false;
4905 
4906  missing_.clear();
4907  parsed_subcommands_.clear();
4908  for(const Option_p &opt : options_) {
4909  opt->clear();
4910  }
4911  for(const App_p &subc : subcommands_) {
4912  subc->clear();
4913  }
4914  }
4915 
4918  void parse(int argc, const char *const *argv) {
4919  // If the name is not set, read from command line
4920  if(name_.empty() || has_automatic_name_) {
4921  has_automatic_name_ = true;
4922  name_ = argv[0];
4923  }
4924 
4925  std::vector<std::string> args;
4926  args.reserve(static_cast<size_t>(argc - 1));
4927  for(int i = argc - 1; i > 0; i--)
4928  args.emplace_back(argv[i]);
4929  parse(std::move(args));
4930  }
4931 
4936  void parse(std::string commandline, bool program_name_included = false) {
4937 
4938  if(program_name_included) {
4939  auto nstr = detail::split_program_name(commandline);
4940  if((name_.empty()) || (has_automatic_name_)) {
4941  has_automatic_name_ = true;
4942  name_ = nstr.first;
4943  }
4944  commandline = std::move(nstr.second);
4945  } else
4946  detail::trim(commandline);
4947  // the next section of code is to deal with quoted arguments after an '=' or ':' for windows like operations
4948  if(!commandline.empty()) {
4949  commandline = detail::find_and_modify(commandline, "=", detail::escape_detect);
4950  if(allow_windows_style_options_)
4951  commandline = detail::find_and_modify(commandline, ":", detail::escape_detect);
4952  }
4953 
4954  auto args = detail::split_up(std::move(commandline));
4955  // remove all empty strings
4956  args.erase(std::remove(args.begin(), args.end(), std::string{}), args.end());
4957  std::reverse(args.begin(), args.end());
4958 
4959  parse(std::move(args));
4960  }
4961 
4964  void parse(std::vector<std::string> &args) {
4965  // Clear if parsed
4966  if(parsed_ > 0)
4967  clear();
4968 
4969  // parsed_ is incremented in commands/subcommands,
4970  // but placed here to make sure this is cleared when
4971  // running parse after an error is thrown, even by _validate or _configure.
4972  parsed_ = 1;
4973  _validate();
4974  _configure();
4975  // set the parent as nullptr as this object should be the top now
4976  parent_ = nullptr;
4977  parsed_ = 0;
4978 
4979  _parse(args);
4980  run_callback();
4981  }
4982 
4984  void parse(std::vector<std::string> &&args) {
4985  // Clear if parsed
4986  if(parsed_ > 0)
4987  clear();
4988 
4989  // parsed_ is incremented in commands/subcommands,
4990  // but placed here to make sure this is cleared when
4991  // running parse after an error is thrown, even by _validate or _configure.
4992  parsed_ = 1;
4993  _validate();
4994  _configure();
4995  // set the parent as nullptr as this object should be the top now
4996  parent_ = nullptr;
4997  parsed_ = 0;
4998 
4999  _parse(std::move(args));
5000  run_callback();
5001  }
5002 
5004  void failure_message(std::function<std::string(const App *, const Error &e)> function) {
5005  failure_message_ = function;
5006  }
5007 
5009  int exit(const Error &e, std::ostream &out = std::cout, std::ostream &err = std::cerr) const {
5010 
5012  if(dynamic_cast<const CLI::RuntimeError *>(&e) != nullptr)
5013  return e.get_exit_code();
5014 
5015  if(dynamic_cast<const CLI::CallForHelp *>(&e) != nullptr) {
5016  out << help();
5017  return e.get_exit_code();
5018  }
5019 
5020  if(dynamic_cast<const CLI::CallForAllHelp *>(&e) != nullptr) {
5021  out << help("", AppFormatMode::All);
5022  return e.get_exit_code();
5023  }
5024 
5025  if(e.get_exit_code() != static_cast<int>(ExitCodes::Success)) {
5026  if(failure_message_)
5027  err << failure_message_(this, e) << std::flush;
5028  }
5029 
5030  return e.get_exit_code();
5031  }
5032 
5036 
5038  size_t count(std::string option_name) const { return get_option(option_name)->count(); }
5039 
5042  std::vector<App *> get_subcommands() const { return parsed_subcommands_; }
5043 
5046  std::vector<const App *> get_subcommands(const std::function<bool(const App *)> &filter) const {
5047  std::vector<const App *> subcomms(subcommands_.size());
5048  std::transform(std::begin(subcommands_), std::end(subcommands_), std::begin(subcomms), [](const App_p &v) {
5049  return v.get();
5050  });
5051 
5052  if(filter) {
5053  subcomms.erase(std::remove_if(std::begin(subcomms),
5054  std::end(subcomms),
5055  [&filter](const App *app) { return !filter(app); }),
5056  std::end(subcomms));
5057  }
5058 
5059  return subcomms;
5060  }
5061 
5064  std::vector<App *> get_subcommands(const std::function<bool(App *)> &filter) {
5065  std::vector<App *> subcomms(subcommands_.size());
5066  std::transform(std::begin(subcommands_), std::end(subcommands_), std::begin(subcomms), [](const App_p &v) {
5067  return v.get();
5068  });
5069 
5070  if(filter) {
5071  subcomms.erase(
5072  std::remove_if(std::begin(subcomms), std::end(subcomms), [&filter](App *app) { return !filter(app); }),
5073  std::end(subcomms));
5074  }
5075 
5076  return subcomms;
5077  }
5078 
5080  bool got_subcommand(App *subcom) const {
5081  // get subcom needed to verify that this was a real subcommand
5082  return get_subcommand(subcom)->parsed_ > 0;
5083  }
5084 
5086  bool got_subcommand(std::string subcommand_name) const { return get_subcommand(subcommand_name)->parsed_ > 0; }
5087 
5090  if(opt == nullptr) {
5091  throw OptionNotFound("nullptr passed");
5092  }
5093  exclude_options_.insert(opt);
5094  return this;
5095  }
5096 
5099  if((app == this) || (app == nullptr)) {
5100  throw OptionNotFound("nullptr passed");
5101  }
5102  auto res = exclude_subcommands_.insert(app);
5103  // subcommand exclusion should be symmetric
5104  if(res.second) {
5105  app->exclude_subcommands_.insert(this);
5106  }
5107  return this;
5108  }
5109 
5112  auto iterator = std::find(std::begin(exclude_options_), std::end(exclude_options_), opt);
5113  if(iterator != std::end(exclude_options_)) {
5114  exclude_options_.erase(iterator);
5115  return true;
5116  } else {
5117  return false;
5118  }
5119  }
5120 
5123  auto iterator = std::find(std::begin(exclude_subcommands_), std::end(exclude_subcommands_), app);
5124  if(iterator != std::end(exclude_subcommands_)) {
5125  auto other_app = *iterator;
5126  exclude_subcommands_.erase(iterator);
5127  other_app->remove_excludes(this);
5128  return true;
5129  } else {
5130  return false;
5131  }
5132  }
5133 
5137 
5139  App *footer(std::string footer_string) {
5140  footer_ = std::move(footer_string);
5141  return this;
5142  }
5143 
5146  std::string config_to_str(bool default_also = false, bool write_description = false) const {
5147  return config_formatter_->to_config(this, default_also, write_description, "");
5148  }
5149 
5152  std::string help(std::string prev = "", AppFormatMode mode = AppFormatMode::Normal) const {
5153  if(prev.empty())
5154  prev = get_name();
5155  else
5156  prev += " " + get_name();
5157 
5158  // Delegate to subcommand if needed
5159  auto selected_subcommands = get_subcommands();
5160  if(!selected_subcommands.empty())
5161  return selected_subcommands.at(0)->help(prev, mode);
5162  else
5163  return formatter_->make_help(this, prev, mode);
5164  }
5165 
5169 
5171  std::shared_ptr<FormatterBase> get_formatter() const { return formatter_; }
5172 
5174  std::shared_ptr<Config> get_config_formatter() const { return config_formatter_; }
5175 
5177  std::string get_description() const { return description_; }
5178 
5180  App *description(std::string app_description) {
5181  description_ = std::move(app_description);
5182  return this;
5183  }
5184 
5186  std::vector<const Option *> get_options(const std::function<bool(const Option *)> filter = {}) const {
5187  std::vector<const Option *> options(options_.size());
5188  std::transform(std::begin(options_), std::end(options_), std::begin(options), [](const Option_p &val) {
5189  return val.get();
5190  });
5191 
5192  if(filter) {
5193  options.erase(std::remove_if(std::begin(options),
5194  std::end(options),
5195  [&filter](const Option *opt) { return !filter(opt); }),
5196  std::end(options));
5197  }
5198 
5199  return options;
5200  }
5201 
5203  Option *get_option_no_throw(std::string option_name) noexcept {
5204  for(Option_p &opt : options_) {
5205  if(opt->check_name(option_name)) {
5206  return opt.get();
5207  }
5208  }
5209  for(auto &subc : subcommands_) {
5210  // also check down into nameless subcommands
5211  if(subc->get_name().empty()) {
5212  auto opt = subc->get_option_no_throw(option_name);
5213  if(opt != nullptr) {
5214  return opt;
5215  }
5216  }
5217  }
5218  return nullptr;
5219  }
5220 
5222  const Option *get_option_no_throw(std::string option_name) const noexcept {
5223  for(const Option_p &opt : options_) {
5224  if(opt->check_name(option_name)) {
5225  return opt.get();
5226  }
5227  }
5228  for(const auto &subc : subcommands_) {
5229  // also check down into nameless subcommands
5230  if(subc->get_name().empty()) {
5231  auto opt = subc->get_option_no_throw(option_name);
5232  if(opt != nullptr) {
5233  return opt;
5234  }
5235  }
5236  }
5237  return nullptr;
5238  }
5239 
5241  const Option *get_option(std::string option_name) const {
5242  auto opt = get_option_no_throw(option_name);
5243  if(opt == nullptr) {
5244  throw OptionNotFound(option_name);
5245  }
5246  return opt;
5247  }
5248 
5250  Option *get_option(std::string option_name) {
5251  auto opt = get_option_no_throw(option_name);
5252  if(opt == nullptr) {
5253  throw OptionNotFound(option_name);
5254  }
5255  return opt;
5256  }
5257 
5259  const Option *operator[](const std::string &option_name) const { return get_option(option_name); }
5260 
5262  const Option *operator[](const char *option_name) const { return get_option(option_name); }
5263 
5265  bool get_ignore_case() const { return ignore_case_; }
5266 
5268  bool get_ignore_underscore() const { return ignore_underscore_; }
5269 
5271  bool get_fallthrough() const { return fallthrough_; }
5272 
5274  bool get_allow_windows_style_options() const { return allow_windows_style_options_; }
5275 
5277  bool get_positionals_at_end() const { return positionals_at_end_; }
5278 
5280  const std::string &get_group() const { return group_; }
5281 
5283  const std::string &get_footer() const { return footer_; }
5284 
5286  size_t get_require_subcommand_min() const { return require_subcommand_min_; }
5287 
5289  size_t get_require_subcommand_max() const { return require_subcommand_max_; }
5290 
5292  size_t get_require_option_min() const { return require_option_min_; }
5293 
5295  size_t get_require_option_max() const { return require_option_max_; }
5296 
5298  bool get_prefix_command() const { return prefix_command_; }
5299 
5301  bool get_allow_extras() const { return allow_extras_; }
5302 
5304  bool get_required() const { return required_; }
5305 
5307  bool get_disabled() const { return disabled_; }
5308 
5310  bool get_immediate_callback() const { return immediate_callback_; }
5311 
5313  bool get_disabled_by_default() const { return disabled_by_default_; }
5314 
5316  bool get_enabled_by_default() const { return enabled_by_default_; }
5318  bool get_validate_positionals() const { return validate_positionals_; }
5319 
5321  bool get_allow_config_extras() const { return allow_config_extras_; }
5322 
5324  Option *get_help_ptr() { return help_ptr_; }
5325 
5327  const Option *get_help_ptr() const { return help_ptr_; }
5328 
5330  const Option *get_help_all_ptr() const { return help_all_ptr_; }
5331 
5333  Option *get_config_ptr() { return config_ptr_; }
5334 
5336  const Option *get_config_ptr() const { return config_ptr_; }
5337 
5339  App *get_parent() { return parent_; }
5340 
5342  const App *get_parent() const { return parent_; }
5343 
5345  std::string get_name() const { return name_; }
5346 
5348  std::string get_display_name() const { return (!name_.empty()) ? name_ : "[Option Group: " + get_group() + "]"; }
5349 
5351  bool check_name(std::string name_to_check) const {
5352  std::string local_name = name_;
5353  if(ignore_underscore_) {
5354  local_name = detail::remove_underscore(name_);
5355  name_to_check = detail::remove_underscore(name_to_check);
5356  }
5357  if(ignore_case_) {
5358  local_name = detail::to_lower(name_);
5359  name_to_check = detail::to_lower(name_to_check);
5360  }
5361 
5362  return local_name == name_to_check;
5363  }
5364 
5366  std::vector<std::string> get_groups() const {
5367  std::vector<std::string> groups;
5368 
5369  for(const Option_p &opt : options_) {
5370  // Add group if it is not already in there
5371  if(std::find(groups.begin(), groups.end(), opt->get_group()) == groups.end()) {
5372  groups.push_back(opt->get_group());
5373  }
5374  }
5375 
5376  return groups;
5377  }
5378 
5380  const std::vector<Option *> &parse_order() const { return parse_order_; }
5381 
5383  std::vector<std::string> remaining(bool recurse = false) const {
5384  std::vector<std::string> miss_list;
5385  for(const std::pair<detail::Classifier, std::string> &miss : missing_) {
5386  miss_list.push_back(std::get<1>(miss));
5387  }
5388  // Get from a subcommand that may allow extras
5389  if(recurse) {
5390  if(!allow_extras_) {
5391  for(const auto &sub : subcommands_) {
5392  if(sub->name_.empty() && !sub->missing_.empty()) {
5393  for(const std::pair<detail::Classifier, std::string> &miss : sub->missing_) {
5394  miss_list.push_back(std::get<1>(miss));
5395  }
5396  }
5397  }
5398  }
5399  // Recurse into subcommands
5400 
5401  for(const App *sub : parsed_subcommands_) {
5402  std::vector<std::string> output = sub->remaining(recurse);
5403  std::copy(std::begin(output), std::end(output), std::back_inserter(miss_list));
5404  }
5405  }
5406  return miss_list;
5407  }
5408 
5410  std::vector<std::string> remaining_for_passthrough(bool recurse = false) const {
5411  std::vector<std::string> miss_list = remaining(recurse);
5412  std::reverse(std::begin(miss_list), std::end(miss_list));
5413  return miss_list;
5414  }
5415 
5417  size_t remaining_size(bool recurse = false) const {
5418  auto remaining_options = static_cast<size_t>(std::count_if(
5419  std::begin(missing_), std::end(missing_), [](const std::pair<detail::Classifier, std::string> &val) {
5420  return val.first != detail::Classifier::POSITIONAL_MARK;
5421  }));
5422 
5423  if(recurse) {
5424  for(const App_p &sub : subcommands_) {
5425  remaining_options += sub->remaining_size(recurse);
5426  }
5427  }
5428  return remaining_options;
5429  }
5430 
5432 
5433  protected:
5438  void _validate() const {
5439  auto pcount = std::count_if(std::begin(options_), std::end(options_), [](const Option_p &opt) {
5440  return opt->get_items_expected() < 0 && opt->get_positional();
5441  });
5442  if(pcount > 1)
5443  throw InvalidError(name_);
5444 
5445  size_t nameless_subs{0};
5446  for(const App_p &app : subcommands_) {
5447  app->_validate();
5448  if(app->get_name().empty())
5449  ++nameless_subs;
5450  }
5451 
5452  if(require_option_min_ > 0) {
5453  if(require_option_max_ > 0) {
5454  if(require_option_max_ < require_option_min_) {
5455  throw(InvalidError("Required min options greater than required max options",
5457  }
5458  }
5459  if(require_option_min_ > (options_.size() + nameless_subs)) {
5460  throw(InvalidError("Required min options greater than number of available options",
5462  }
5463  }
5464  }
5465 
5469  void _configure() {
5470  if(disabled_by_default_) {
5471  disabled_ = true;
5472  }
5473  if(enabled_by_default_) {
5474  disabled_ = false;
5475  }
5476  for(const App_p &app : subcommands_) {
5477  if(app->has_automatic_name_) {
5478  app->name_.clear();
5479  }
5480  if(app->name_.empty()) {
5481  app->fallthrough_ = false; // make sure fallthrough_ is false to prevent infinite loop
5482  app->prefix_command_ = false;
5483  }
5484  // make sure the parent is set to be this object in preparation for parse
5485  app->parent_ = this;
5486  app->_configure();
5487  }
5488  }
5490  void run_callback() {
5491  pre_callback();
5492  // run the callbacks for the received subcommands
5493  for(App *subc : get_subcommands()) {
5494  if(!subc->immediate_callback_)
5495  subc->run_callback();
5496  }
5497  // now run callbacks for option_groups
5498  for(auto &subc : subcommands_) {
5499  if(!subc->immediate_callback_ && subc->name_.empty() && subc->count_all() > 0) {
5500  subc->run_callback();
5501  }
5502  }
5503  // finally run the main callback
5504  if(callback_ && (parsed_ > 0)) {
5505  if(!name_.empty() || count_all() > 0) {
5506  callback_();
5507  }
5508  }
5509  }
5510 
5512  bool _valid_subcommand(const std::string &current, bool ignore_used = true) const {
5513  // Don't match if max has been reached - but still check parents
5514  if(require_subcommand_max_ != 0 && parsed_subcommands_.size() >= require_subcommand_max_) {
5515  return parent_ != nullptr && parent_->_valid_subcommand(current, ignore_used);
5516  }
5517  auto com = _find_subcommand(current, true, ignore_used);
5518  if(com != nullptr) {
5519  return true;
5520  }
5521  // Check parent if exists, else return false
5522  return parent_ != nullptr && parent_->_valid_subcommand(current, ignore_used);
5523  }
5524 
5526  detail::Classifier _recognize(const std::string &current, bool ignore_used_subcommands = true) const {
5527  std::string dummy1, dummy2;
5528 
5529  if(current == "--")
5531  if(_valid_subcommand(current, ignore_used_subcommands))
5533  if(detail::split_long(current, dummy1, dummy2))
5534  return detail::Classifier::LONG;
5535  if(detail::split_short(current, dummy1, dummy2))
5537  if((allow_windows_style_options_) && (detail::split_windows_style(current, dummy1, dummy2)))
5539  if((current == "++") && !name_.empty() && parent_ != nullptr)
5541  return detail::Classifier::NONE;
5542  }
5543 
5544  // The parse function is now broken into several parts, and part of process
5545 
5547  void _process_ini() {
5548  // Process an INI file
5549  if(config_ptr_ != nullptr) {
5550  if(*config_ptr_) {
5551  config_ptr_->run_callback();
5552  config_required_ = true;
5553  }
5554  if(!config_name_.empty()) {
5555  try {
5556  std::vector<ConfigItem> values = config_formatter_->from_file(config_name_);
5557  _parse_config(values);
5558  } catch(const FileError &) {
5559  if(config_required_)
5560  throw;
5561  }
5562  }
5563  }
5564  }
5565 
5567  void _process_env() {
5568  for(const Option_p &opt : options_) {
5569  if(opt->count() == 0 && !opt->envname_.empty()) {
5570  char *buffer = nullptr;
5571  std::string ename_string;
5572 
5573 #ifdef _MSC_VER
5574  // Windows version
5575  size_t sz = 0;
5576  if(_dupenv_s(&buffer, &sz, opt->envname_.c_str()) == 0 && buffer != nullptr) {
5577  ename_string = std::string(buffer);
5578  free(buffer);
5579  }
5580 #else
5581  // This also works on Windows, but gives a warning
5582  buffer = std::getenv(opt->envname_.c_str());
5583  if(buffer != nullptr)
5584  ename_string = std::string(buffer);
5585 #endif
5586 
5587  if(!ename_string.empty()) {
5588  opt->add_result(ename_string);
5589  }
5590  }
5591  }
5592 
5593  for(App_p &sub : subcommands_) {
5594  if(sub->get_name().empty() || !sub->immediate_callback_)
5595  sub->_process_env();
5596  }
5597  }
5598 
5601 
5602  for(App_p &sub : subcommands_) {
5603  // process the priority option_groups first
5604  if(sub->get_name().empty() && sub->immediate_callback_) {
5605  if(sub->count_all() > 0) {
5606  sub->_process_callbacks();
5607  sub->run_callback();
5608  }
5609  }
5610  }
5611 
5612  for(const Option_p &opt : options_) {
5613  if(opt->count() > 0 && !opt->get_callback_run()) {
5614  opt->run_callback();
5615  }
5616  }
5617 
5618  for(App_p &sub : subcommands_) {
5619  if(!sub->immediate_callback_) {
5620  sub->_process_callbacks();
5621  }
5622  }
5623  }
5624 
5628  void _process_help_flags(bool trigger_help = false, bool trigger_all_help = false) const {
5629  const Option *help_ptr = get_help_ptr();
5630  const Option *help_all_ptr = get_help_all_ptr();
5631 
5632  if(help_ptr != nullptr && help_ptr->count() > 0)
5633  trigger_help = true;
5634  if(help_all_ptr != nullptr && help_all_ptr->count() > 0)
5635  trigger_all_help = true;
5636 
5637  // If there were parsed subcommands, call those. First subcommand wins if there are multiple ones.
5638  if(!parsed_subcommands_.empty()) {
5639  for(const App *sub : parsed_subcommands_)
5640  sub->_process_help_flags(trigger_help, trigger_all_help);
5641 
5642  // Only the final subcommand should call for help. All help wins over help.
5643  } else if(trigger_all_help) {
5644  throw CallForAllHelp();
5645  } else if(trigger_help) {
5646  throw CallForHelp();
5647  }
5648  }
5649 
5652  // check excludes
5653  bool excluded{false};
5654  std::string excluder;
5655  for(auto &opt : exclude_options_) {
5656  if(opt->count() > 0) {
5657  excluded = true;
5658  excluder = opt->get_name();
5659  }
5660  }
5661  for(auto &subc : exclude_subcommands_) {
5662  if(subc->count_all() > 0) {
5663  excluded = true;
5664  excluder = subc->get_display_name();
5665  }
5666  }
5667  if(excluded) {
5668  if(count_all() > 0) {
5669  throw ExcludesError(get_display_name(), excluder);
5670  }
5671  // if we are excluded but didn't receive anything, just return
5672  return;
5673  }
5674  size_t used_options = 0;
5675  for(const Option_p &opt : options_) {
5676 
5677  if(opt->count() != 0) {
5678  ++used_options;
5679  }
5680  // Required or partially filled
5681  if(opt->get_required() || opt->count() != 0) {
5682  // Make sure enough -N arguments parsed (+N is already handled in parsing function)
5683  if(opt->get_items_expected() < 0 && opt->count() < static_cast<size_t>(-opt->get_items_expected()))
5684  throw ArgumentMismatch::AtLeast(opt->get_name(), -opt->get_items_expected());
5685 
5686  // Required but empty
5687  if(opt->get_required() && opt->count() == 0)
5688  throw RequiredError(opt->get_name());
5689  }
5690  // Requires
5691  for(const Option *opt_req : opt->needs_)
5692  if(opt->count() > 0 && opt_req->count() == 0)
5693  throw RequiresError(opt->get_name(), opt_req->get_name());
5694  // Excludes
5695  for(const Option *opt_ex : opt->excludes_)
5696  if(opt->count() > 0 && opt_ex->count() != 0)
5697  throw ExcludesError(opt->get_name(), opt_ex->get_name());
5698  }
5699  // check for the required number of subcommands
5700  if(require_subcommand_min_ > 0) {
5701  auto selected_subcommands = get_subcommands();
5702  if(require_subcommand_min_ > selected_subcommands.size())
5703  throw RequiredError::Subcommand(require_subcommand_min_);
5704  }
5705 
5706  // Max error cannot occur, the extra subcommand will parse as an ExtrasError or a remaining item.
5707 
5708  // run this loop to check how many unnamed subcommands were actually used since they are considered options from
5709  // the perspective of an App
5710  for(App_p &sub : subcommands_) {
5711  if(sub->disabled_)
5712  continue;
5713  if(sub->name_.empty() && sub->count_all() > 0) {
5714  ++used_options;
5715  }
5716  }
5717 
5718  if(require_option_min_ > used_options || (require_option_max_ > 0 && require_option_max_ < used_options)) {
5719  auto option_list = detail::join(options_, [](const Option_p &ptr) { return ptr->get_name(false, true); });
5720  if(option_list.compare(0, 10, "-h,--help,") == 0) {
5721  option_list.erase(0, 10);
5722  }
5723  auto subc_list = get_subcommands([](App *app) { return ((app->get_name().empty()) && (!app->disabled_)); });
5724  if(!subc_list.empty()) {
5725  option_list += "," + detail::join(subc_list, [](const App *app) { return app->get_display_name(); });
5726  }
5727  throw RequiredError::Option(require_option_min_, require_option_max_, used_options, option_list);
5728  }
5729 
5730  // now process the requirements for subcommands if needed
5731  for(App_p &sub : subcommands_) {
5732  if(sub->disabled_)
5733  continue;
5734  if(sub->name_.empty() && sub->required_ == false) {
5735  if(sub->count_all() == 0) {
5736  if(require_option_min_ > 0 && require_option_min_ <= used_options) {
5737  continue;
5738  // if we have met the requirement and there is nothing in this option group skip checking
5739  // requirements
5740  }
5741  if(require_option_max_ > 0 && used_options >= require_option_min_) {
5742  continue;
5743  // if we have met the requirement and there is nothing in this option group skip checking
5744  // requirements
5745  }
5746  }
5747  }
5748  if(sub->count() > 0 || sub->name_.empty()) {
5749  sub->_process_requirements();
5750  }
5751 
5752  if(sub->required_ && sub->count_all() == 0) {
5753  throw(CLI::RequiredError(sub->get_display_name()));
5754  }
5755  }
5756  }
5757 
5759  void _process() {
5760  _process_ini();
5761  _process_env();
5762  _process_callbacks();
5763  _process_help_flags();
5764  _process_requirements();
5765  }
5766 
5769  if(!(allow_extras_ || prefix_command_)) {
5770  size_t num_left_over = remaining_size();
5771  if(num_left_over > 0) {
5772  throw ExtrasError(remaining(false));
5773  }
5774  }
5775 
5776  for(App_p &sub : subcommands_) {
5777  if(sub->count() > 0)
5778  sub->_process_extras();
5779  }
5780  }
5781 
5784  void _process_extras(std::vector<std::string> &args) {
5785  if(!(allow_extras_ || prefix_command_)) {
5786  size_t num_left_over = remaining_size();
5787  if(num_left_over > 0) {
5788  args = remaining(false);
5789  throw ExtrasError(args);
5790  }
5791  }
5792 
5793  for(App_p &sub : subcommands_) {
5794  if(sub->count() > 0)
5795  sub->_process_extras(args);
5796  }
5797  }
5798 
5801  ++parsed_;
5802  for(App_p &sub : subcommands_) {
5803  if(sub->get_name().empty())
5804  sub->increment_parsed();
5805  }
5806  }
5808  void _parse(std::vector<std::string> &args) {
5809  increment_parsed();
5810  _trigger_pre_parse(args.size());
5811  bool positional_only = false;
5812 
5813  while(!args.empty()) {
5814  if(!_parse_single(args, positional_only)) {
5815  break;
5816  }
5817  }
5818 
5819  if(parent_ == nullptr) {
5820  _process();
5821 
5822  // Throw error if any items are left over (depending on settings)
5823  _process_extras(args);
5824 
5825  // Convert missing (pairs) to extras (string only) ready for processing in another app
5826  args = remaining_for_passthrough(false);
5827  } else if(immediate_callback_) {
5828  _process_env();
5829  _process_callbacks();
5830  _process_help_flags();
5831  _process_requirements();
5832  run_callback();
5833  }
5834  }
5835 
5837  void _parse(std::vector<std::string> &&args) {
5838  // this can only be called by the top level in which case parent == nullptr by definition
5839  // operation is simplified
5840  increment_parsed();
5841  _trigger_pre_parse(args.size());
5842  bool positional_only = false;
5843 
5844  while(!args.empty()) {
5845  _parse_single(args, positional_only);
5846  }
5847  _process();
5848 
5849  // Throw error if any items are left over (depending on settings)
5850  _process_extras();
5851  }
5852 
5857  void _parse_config(std::vector<ConfigItem> &args) {
5858  for(ConfigItem item : args) {
5859  if(!_parse_single_config(item) && !allow_config_extras_)
5860  throw ConfigError::Extras(item.fullname());
5861  }
5862  }
5863 
5865  bool _parse_single_config(const ConfigItem &item, size_t level = 0) {
5866  if(level < item.parents.size()) {
5867  try {
5868  auto subcom = get_subcommand(item.parents.at(level));
5869  return subcom->_parse_single_config(item, level + 1);
5870  } catch(const OptionNotFound &) {
5871  return false;
5872  }
5873  }
5874 
5875  Option *op = get_option_no_throw("--" + item.name);
5876  if(op == nullptr) {
5877  // If the option was not present
5878  if(get_allow_config_extras())
5879  // Should we worry about classifying the extras properly?
5880  missing_.emplace_back(detail::Classifier::NONE, item.fullname());
5881  return false;
5882  }
5883 
5884  if(!op->get_configurable())
5885  throw ConfigError::NotConfigurable(item.fullname());
5886 
5887  if(op->empty()) {
5888  // Flag parsing
5889  if(op->get_type_size() == 0) {
5890  auto res = config_formatter_->to_flag(item);
5891  res = op->get_flag_value(item.name, res);
5892 
5893  op->add_result(res);
5894 
5895  } else {
5896  op->add_result(item.inputs);
5897  op->run_callback();
5898  }
5899  }
5900 
5901  return true;
5902  }
5903 
5906  bool _parse_single(std::vector<std::string> &args, bool &positional_only) {
5907  bool retval = true;
5908  detail::Classifier classifier = positional_only ? detail::Classifier::NONE : _recognize(args.back());
5909  switch(classifier) {
5911  args.pop_back();
5912  positional_only = true;
5913  if((!_has_remaining_positionals()) && (parent_ != nullptr)) {
5914  retval = false;
5915  } else {
5916  _move_to_missing(classifier, "--");
5917  }
5918  break;
5920  // treat this like a positional mark if in the parent app
5921  args.pop_back();
5922  retval = false;
5923  break;
5925  retval = _parse_subcommand(args);
5926  break;
5930  // If already parsed a subcommand, don't accept options_
5931  _parse_arg(args, classifier);
5932  break;
5934  // Probably a positional or something for a parent (sub)command
5935  retval = _parse_positional(args);
5936  if(retval && positionals_at_end_) {
5937  positional_only = true;
5938  }
5939  break;
5940 
5941  // LCOV_EXCL_START
5942  default:
5943  HorribleError("unrecognized classifier (you should not see this!)");
5944  // LCOV_EXCL_END
5945  }
5946  return retval;
5947  }
5948 
5950  size_t _count_remaining_positionals(bool required_only = false) const {
5951  size_t retval = 0;
5952  for(const Option_p &opt : options_)
5953  if(opt->get_positional() && (!required_only || opt->get_required()) && opt->get_items_expected() > 0 &&
5954  static_cast<int>(opt->count()) < opt->get_items_expected())
5955  retval = static_cast<size_t>(opt->get_items_expected()) - opt->count();
5956 
5957  return retval;
5958  }
5959 
5962  for(const Option_p &opt : options_)
5963  if(opt->get_positional() &&
5964  ((opt->get_items_expected() < 0) || ((static_cast<int>(opt->count()) < opt->get_items_expected()))))
5965  return true;
5966 
5967  return false;
5968  }
5969 
5972  bool _parse_positional(std::vector<std::string> &args) {
5973 
5974  const std::string &positional = args.back();
5975  for(const Option_p &opt : options_) {
5976  // Eat options, one by one, until done
5977  if(opt->get_positional() &&
5978  (static_cast<int>(opt->count()) < opt->get_items_expected() || opt->get_items_expected() < 0)) {
5979  if(validate_positionals_) {
5980  std::string pos = positional;
5981  pos = opt->_validate(pos);
5982  if(!pos.empty()) {
5983  continue;
5984  }
5985  }
5986  opt->add_result(positional);
5987  parse_order_.push_back(opt.get());
5988  args.pop_back();
5989  return true;
5990  }
5991  }
5992 
5993  for(auto &subc : subcommands_) {
5994  if((subc->name_.empty()) && (!subc->disabled_)) {
5995  if(subc->_parse_positional(args)) {
5996  if(!subc->pre_parse_called_) {
5997  subc->_trigger_pre_parse(args.size());
5998  }
5999  return true;
6000  }
6001  }
6002  }
6003  // let the parent deal with it if possible
6004  if(parent_ != nullptr && fallthrough_)
6005  return _get_fallthrough_parent()->_parse_positional(args);
6006 
6008  auto com = _find_subcommand(args.back(), true, false);
6009  if(com != nullptr && (require_subcommand_max_ == 0 || require_subcommand_max_ > parsed_subcommands_.size())) {
6010  args.pop_back();
6011  com->_parse(args);
6012  return true;
6013  }
6016  auto parent_app = (parent_ != nullptr) ? _get_fallthrough_parent() : this;
6017  com = parent_app->_find_subcommand(args.back(), true, false);
6018  if(com != nullptr && (com->parent_->require_subcommand_max_ == 0 ||
6019  com->parent_->require_subcommand_max_ > com->parent_->parsed_subcommands_.size())) {
6020  return false;
6021  }
6022 
6023  if(positionals_at_end_) {
6024  throw CLI::ExtrasError(args);
6025  }
6027  if(parent_ != nullptr && name_.empty()) {
6028  return false;
6029  }
6031  _move_to_missing(detail::Classifier::NONE, positional);
6032  args.pop_back();
6033  if(prefix_command_) {
6034  while(!args.empty()) {
6035  _move_to_missing(detail::Classifier::NONE, args.back());
6036  args.pop_back();
6037  }
6038  }
6039 
6040  return true;
6041  }
6042 
6045  App *_find_subcommand(const std::string &subc_name, bool ignore_disabled, bool ignore_used) const noexcept {
6046  for(const App_p &com : subcommands_) {
6047  if(com->disabled_ && ignore_disabled)
6048  continue;
6049  if(com->get_name().empty()) {
6050  auto subc = com->_find_subcommand(subc_name, ignore_disabled, ignore_used);
6051  if(subc != nullptr) {
6052  return subc;
6053  }
6054  } else if(com->check_name(subc_name)) {
6055  if((!*com) || !ignore_used)
6056  return com.get();
6057  }
6058  }
6059  return nullptr;
6060  }
6061 
6066  bool _parse_subcommand(std::vector<std::string> &args) {
6067  if(_count_remaining_positionals(/* required */ true) > 0) {
6068  _parse_positional(args);
6069  return true;
6070  }
6071  auto com = _find_subcommand(args.back(), true, true);
6072  if(com != nullptr) {
6073  args.pop_back();
6074  parsed_subcommands_.push_back(com);
6075  com->_parse(args);
6076  auto parent_app = com->parent_;
6077  while(parent_app != this) {
6078  parent_app->_trigger_pre_parse(args.size());
6079  parent_app->parsed_subcommands_.push_back(com);
6080  parent_app = parent_app->parent_;
6081  }
6082  return true;
6083  }
6084 
6085  if(parent_ == nullptr)
6086  throw HorribleError("Subcommand " + args.back() + " missing");
6087  return false;
6088  }
6089 
6092  bool _parse_arg(std::vector<std::string> &args, detail::Classifier current_type) {
6093 
6094  std::string current = args.back();
6095 
6096  std::string arg_name;
6097  std::string value;
6098  std::string rest;
6099 
6100  switch(current_type) {
6102  if(!detail::split_long(current, arg_name, value))
6103  throw HorribleError("Long parsed but missing (you should not see this):" + args.back());
6104  break;
6106  if(!detail::split_short(current, arg_name, rest))
6107  throw HorribleError("Short parsed but missing! You should not see this");
6108  break;
6110  if(!detail::split_windows_style(current, arg_name, value))
6111  throw HorribleError("windows option parsed but missing! You should not see this");
6112  break;
6116  default:
6117  throw HorribleError("parsing got called with invalid option! You should not see this");
6118  }
6119 
6120  auto op_ptr =
6121  std::find_if(std::begin(options_), std::end(options_), [arg_name, current_type](const Option_p &opt) {
6122  if(current_type == detail::Classifier::LONG)
6123  return opt->check_lname(arg_name);
6124  if(current_type == detail::Classifier::SHORT)
6125  return opt->check_sname(arg_name);
6126  // this will only get called for detail::Classifier::WINDOWS
6127  return opt->check_lname(arg_name) || opt->check_sname(arg_name);
6128  });
6129 
6130  // Option not found
6131  if(op_ptr == std::end(options_)) {
6132  for(auto &subc : subcommands_) {
6133  if(subc->name_.empty() && !subc->disabled_) {
6134  if(subc->_parse_arg(args, current_type)) {
6135  if(!subc->pre_parse_called_) {
6136  subc->_trigger_pre_parse(args.size());
6137  }
6138  return true;
6139  }
6140  }
6141  }
6142  // If a subcommand, try the master command
6143  if(parent_ != nullptr && fallthrough_)
6144  return _get_fallthrough_parent()->_parse_arg(args, current_type);
6145  // don't capture missing if this is a nameless subcommand
6146  if(parent_ != nullptr && name_.empty()) {
6147  return false;
6148  }
6149  // Otherwise, add to missing
6150  args.pop_back();
6151  _move_to_missing(current_type, current);
6152  return true;
6153  }
6154 
6155  args.pop_back();
6156 
6157  // Get a reference to the pointer to make syntax bearable
6158  Option_p &op = *op_ptr;
6159 
6160  int num = op->get_items_expected();
6161 
6162  // Make sure we always eat the minimum for unlimited vectors
6163  int collected = 0;
6164  int result_count = 0;
6165  // deal with flag like things
6166  if(num == 0) {
6167  auto res = op->get_flag_value(arg_name, value);
6168  op->add_result(res);
6169  parse_order_.push_back(op.get());
6170  }
6171  // --this=value
6172  else if(!value.empty()) {
6173  op->add_result(value, result_count);
6174  parse_order_.push_back(op.get());
6175  collected += result_count;
6176  // If exact number expected
6177  if(num > 0)
6178  num = (num >= result_count) ? num - result_count : 0;
6179 
6180  // -Trest
6181  } else if(!rest.empty()) {
6182  op->add_result(rest, result_count);
6183  parse_order_.push_back(op.get());
6184  rest = "";
6185  collected += result_count;
6186  // If exact number expected
6187  if(num > 0)
6188  num = (num >= result_count) ? num - result_count : 0;
6189  }
6190 
6191  // Unlimited vector parser
6192  if(num < 0) {
6193  while(!args.empty() && _recognize(args.back(), false) == detail::Classifier::NONE) {
6194  if(collected >= -num) {
6195  // We could break here for allow extras, but we don't
6196 
6197  // If any positionals remain, don't keep eating
6198  if(_count_remaining_positionals() > 0)
6199  break;
6200  }
6201  op->add_result(args.back(), result_count);
6202  parse_order_.push_back(op.get());
6203  args.pop_back();
6204  collected += result_count;
6205  }
6206 
6207  // Allow -- to end an unlimited list and "eat" it
6208  if(!args.empty() && _recognize(args.back()) == detail::Classifier::POSITIONAL_MARK)
6209  args.pop_back();
6210 
6211  } else {
6212  while(num > 0 && !args.empty()) {
6213  std::string current_ = args.back();
6214  args.pop_back();
6215  op->add_result(current_, result_count);
6216  parse_order_.push_back(op.get());
6217  num -= result_count;
6218  }
6219 
6220  if(num > 0) {
6221  throw ArgumentMismatch::TypedAtLeast(op->get_name(), num, op->get_type_name());
6222  }
6223  }
6224 
6225  if(!rest.empty()) {
6226  rest = "-" + rest;
6227  args.push_back(rest);
6228  }
6229  return true;
6230  }
6231 
6233  void _trigger_pre_parse(size_t remaining_args) {
6234  if(!pre_parse_called_) {
6235  pre_parse_called_ = true;
6236  if(pre_parse_callback_) {
6237  pre_parse_callback_(remaining_args);
6238  }
6239  } else if(immediate_callback_) {
6240  if(!name_.empty()) {
6241  auto pcnt = parsed_;
6242  auto extras = std::move(missing_);
6243  clear();
6244  parsed_ = pcnt;
6245  pre_parse_called_ = true;
6246  missing_ = std::move(extras);
6247  }
6248  }
6249  }
6250 
6253  if(parent_ == nullptr) {
6254  throw(HorribleError("No Valid parent"));
6255  }
6256  auto fallthrough_parent = parent_;
6257  while((fallthrough_parent->parent_ != nullptr) && (fallthrough_parent->get_name().empty())) {
6258  fallthrough_parent = fallthrough_parent->parent_;
6259  }
6260  return fallthrough_parent;
6261  }
6262 
6264  void _move_to_missing(detail::Classifier val_type, const std::string &val) {
6265  if(allow_extras_ || subcommands_.empty()) {
6266  missing_.emplace_back(val_type, val);
6267  return;
6268  }
6269  // allow extra arguments to be places in an option group if it is allowed there
6270  for(auto &subc : subcommands_) {
6271  if(subc->name_.empty() && subc->allow_extras_) {
6272  subc->missing_.emplace_back(val_type, val);
6273  return;
6274  }
6275  }
6276  // if we haven't found any place to put them yet put them in missing
6277  missing_.emplace_back(val_type, val);
6278  }
6279 
6280  public:
6282  void _move_option(Option *opt, App *app) {
6283  if(opt == nullptr) {
6284  throw OptionNotFound("the option is NULL");
6285  }
6286  // verify that the give app is actually a subcommand
6287  bool found = false;
6288  for(auto &subc : subcommands_) {
6289  if(app == subc.get()) {
6290  found = true;
6291  }
6292  }
6293  if(!found) {
6294  throw OptionNotFound("The Given app is not a subcommand");
6295  }
6296 
6297  if((help_ptr_ == opt) || (help_all_ptr_ == opt))
6298  throw OptionAlreadyAdded("cannot move help options");
6299 
6300  if(config_ptr_ == opt)
6301  throw OptionAlreadyAdded("cannot move config file options");
6302 
6303  auto iterator =
6304  std::find_if(std::begin(options_), std::end(options_), [opt](const Option_p &v) { return v.get() == opt; });
6305  if(iterator != std::end(options_)) {
6306  const auto &opt_p = *iterator;
6307  if(std::find_if(std::begin(app->options_), std::end(app->options_), [&opt_p](const Option_p &v) {
6308  return (*v == *opt_p);
6309  }) == std::end(app->options_)) {
6310  // only erase after the insertion was successful
6311  app->options_.push_back(std::move(*iterator));
6312  options_.erase(iterator);
6313  } else {
6314  throw OptionAlreadyAdded(opt->get_name());
6315  }
6316  } else {
6317  throw OptionNotFound("could not locate the given App");
6318  }
6319  }
6320 };
6321 
6323 class Option_group : public App {
6324  public:
6325  Option_group(std::string group_description, std::string group_name, App *parent)
6326  : App(std::move(group_description), "", parent) {
6327  group(group_name);
6328  // option groups should have automatic fallthrough
6329  }
6330  using App::add_option;
6333  if(get_parent() == nullptr) {
6334  throw OptionNotFound("Unable to locate the specified option");
6335  }
6336  get_parent()->_move_option(opt, this);
6337  return opt;
6338  }
6340  void add_options(Option *opt) { add_option(opt); }
6342  template <typename... Args> void add_options(Option *opt, Args... args) {
6343  add_option(opt);
6344  add_options(args...);
6345  }
6346  using App::add_subcommand;
6348  App *add_subcommand(App *subcom) {
6349  App_p subc = subcom->get_parent()->get_subcommand_ptr(subcom);
6350  subc->get_parent()->remove_subcommand(subcom);
6351  add_subcommand(std::move(subc));
6352  return subcom;
6353  }
6354 };
6356 inline void TriggerOn(App *trigger_app, App *app_to_enable) {
6357  app_to_enable->enabled_by_default(false);
6358  app_to_enable->disabled_by_default();
6359  trigger_app->preparse_callback([app_to_enable](size_t) { app_to_enable->disabled(false); });
6360 }
6361 
6363 inline void TriggerOn(App *trigger_app, std::vector<App *> apps_to_enable) {
6364  for(auto &app : apps_to_enable) {
6365  app->enabled_by_default(false);
6367  }
6368 
6369  trigger_app->preparse_callback([apps_to_enable](size_t) {
6370  for(auto &app : apps_to_enable) {
6371  app->disabled(false);
6372  }
6373  });
6374 }
6375 
6377 inline void TriggerOff(App *trigger_app, App *app_to_enable) {
6378  app_to_enable->disabled_by_default(false);
6379  app_to_enable->enabled_by_default();
6380  trigger_app->preparse_callback([app_to_enable](size_t) { app_to_enable->disabled(); });
6381 }
6382 
6384 inline void TriggerOff(App *trigger_app, std::vector<App *> apps_to_enable) {
6385  for(auto &app : apps_to_enable) {
6386  app->disabled_by_default(false);
6388  }
6389 
6390  trigger_app->preparse_callback([apps_to_enable](size_t) {
6391  for(auto &app : apps_to_enable) {
6392  app->disabled();
6393  }
6394  });
6395 }
6396 
6397 namespace FailureMessage {
6398 
6400 inline std::string simple(const App *app, const Error &e) {
6401  std::string header = std::string(e.what()) + "\n";
6402  std::vector<std::string> names;
6403 
6404  // Collect names
6405  if(app->get_help_ptr() != nullptr)
6406  names.push_back(app->get_help_ptr()->get_name());
6407 
6408  if(app->get_help_all_ptr() != nullptr)
6409  names.push_back(app->get_help_all_ptr()->get_name());
6410 
6411  // If any names found, suggest those
6412  if(!names.empty())
6413  header += "Run with " + detail::join(names, " or ") + " for more information.\n";
6414 
6415  return header;
6416 }
6417 
6419 inline std::string help(const App *app, const Error &e) {
6420  std::string header = std::string("ERROR: ") + e.get_name() + ": " + e.what() + "\n";
6421  header += app->help();
6422  return header;
6423 }
6424 
6425 } // namespace FailureMessage
6426 
6427 namespace detail {
6429 struct AppFriend {
6430 
6432  template <typename... Args>
6433  static auto parse_arg(App *app, Args &&... args) ->
6434  typename std::result_of<decltype (&App::_parse_arg)(App, Args...)>::type {
6435  return app->_parse_arg(std::forward<Args>(args)...);
6436  }
6437 
6439  template <typename... Args>
6440  static auto parse_subcommand(App *app, Args &&... args) ->
6441  typename std::result_of<decltype (&App::_parse_subcommand)(App, Args...)>::type {
6442  return app->_parse_subcommand(std::forward<Args>(args)...);
6443  }
6445  static App *get_fallthrough_parent(App *app) { return app->_get_fallthrough_parent(); }
6446 };
6447 } // namespace detail
6448 
6449 } // namespace CLI
6450 
6451 // From CLI/Config.hpp:
6452 
6453 namespace CLI {
6454 
6455 inline std::string
6456 ConfigINI::to_config(const App *app, bool default_also, bool write_description, std::string prefix) const {
6457  std::stringstream out;
6458  for(const Option *opt : app->get_options({})) {
6459 
6460  // Only process option with a long-name and configurable
6461  if(!opt->get_lnames().empty() && opt->get_configurable()) {
6462  std::string name = prefix + opt->get_lnames()[0];
6463  std::string value;
6464 
6465  // Non-flags
6466  if(opt->get_type_size() != 0) {
6467 
6468  // If the option was found on command line
6469  if(opt->count() > 0)
6470  value = detail::ini_join(opt->results());
6471 
6472  // If the option has a default and is requested by optional argument
6473  else if(default_also && !opt->get_default_str().empty())
6474  value = opt->get_default_str();
6475  // Flag, one passed
6476  } else if(opt->count() == 1) {
6477  value = "true";
6478 
6479  // Flag, multiple passed
6480  } else if(opt->count() > 1) {
6481  value = std::to_string(opt->count());
6482 
6483  // Flag, not present
6484  } else if(opt->count() == 0 && default_also) {
6485  value = "false";
6486  }
6487 
6488  if(!value.empty()) {
6489  if(write_description && opt->has_description()) {
6490  if(static_cast<int>(out.tellp()) != 0) {
6491  out << std::endl;
6492  }
6493  out << "; " << detail::fix_newlines("; ", opt->get_description()) << std::endl;
6494  }
6495 
6496  // Don't try to quote anything that is not size 1
6497  if(opt->get_items_expected() != 1)
6498  out << name << "=" << value << std::endl;
6499  else
6500  out << name << "=" << detail::add_quotes_if_needed(value) << std::endl;
6501  }
6502  }
6503  }
6504 
6505  for(const App *subcom : app->get_subcommands({}))
6506  out << to_config(subcom, default_also, write_description, prefix + subcom->get_name() + ".");
6507 
6508  return out.str();
6509 }
6510 
6511 } // namespace CLI
6512 
6513 // From CLI/Formatter.hpp:
6514 
6515 namespace CLI {
6516 
6517 inline std::string
6518 Formatter::make_group(std::string group, bool is_positional, std::vector<const Option *> opts) const {
6519  std::stringstream out;
6520 
6521  out << "\n" << group << ":\n";
6522  for(const Option *opt : opts) {
6523  out << make_option(opt, is_positional);
6524  }
6525 
6526  return out.str();
6527 }
6528 
6529 inline std::string Formatter::make_positionals(const App *app) const {
6530  std::vector<const Option *> opts =
6531  app->get_options([](const Option *opt) { return !opt->get_group().empty() && opt->get_positional(); });
6532 
6533  if(opts.empty())
6534  return std::string();
6535  else
6536  return make_group(get_label("Positionals"), true, opts);
6537 }
6538 
6539 inline std::string Formatter::make_groups(const App *app, AppFormatMode mode) const {
6540  std::stringstream out;
6541  std::vector<std::string> groups = app->get_groups();
6542 
6543  // Options
6544  for(const std::string &group : groups) {
6545  std::vector<const Option *> opts = app->get_options([app, mode, &group](const Option *opt) {
6546  return opt->get_group() == group // Must be in the right group
6547  && opt->nonpositional() // Must not be a positional
6548  && (mode != AppFormatMode::Sub // If mode is Sub, then
6549  || (app->get_help_ptr() != opt // Ignore help pointer
6550  && app->get_help_all_ptr() != opt)); // Ignore help all pointer
6551  });
6552  if(!group.empty() && !opts.empty()) {
6553  out << make_group(group, false, opts);
6554 
6555  if(group != groups.back())
6556  out << "\n";
6557  }
6558  }
6559 
6560  return out.str();
6561 }
6562 
6563 inline std::string Formatter::make_description(const App *app) const {
6564  std::string desc = app->get_description();
6565  auto min_options = app->get_require_option_min();
6566  auto max_options = app->get_require_option_max();
6567  if(app->get_required()) {
6568  desc += " REQUIRED ";
6569  }
6570  if((max_options == min_options) && (min_options > 0)) {
6571  if(min_options == 1) {
6572  desc += " \n[Exactly 1 of the following options is required]";
6573  } else {
6574  desc += " \n[Exactly " + std::to_string(min_options) + "options from the following list are required]";
6575  }
6576  } else if(max_options > 0) {
6577  if(min_options > 0) {
6578  desc += " \n[Between " + std::to_string(min_options) + " and " + std::to_string(max_options) +
6579  " of the follow options are required]";
6580  } else {
6581  desc += " \n[At most " + std::to_string(max_options) + " of the following options are allowed]";
6582  }
6583  } else if(min_options > 0) {
6584  desc += " \n[At least " + std::to_string(min_options) + " of the following options are required]";
6585  }
6586  return (!desc.empty()) ? desc + "\n" : std::string{};
6587 }
6588 
6589 inline std::string Formatter::make_usage(const App *app, std::string name) const {
6590  std::stringstream out;
6591 
6592  out << get_label("Usage") << ":" << (name.empty() ? "" : " ") << name;
6593 
6594  std::vector<std::string> groups = app->get_groups();
6595 
6596  // Print an Options badge if any options exist
6597  std::vector<const Option *> non_pos_options =
6598  app->get_options([](const Option *opt) { return opt->nonpositional(); });
6599  if(!non_pos_options.empty())
6600  out << " [" << get_label("OPTIONS") << "]";
6601 
6602  // Positionals need to be listed here
6603  std::vector<const Option *> positionals = app->get_options([](const Option *opt) { return opt->get_positional(); });
6604 
6605  // Print out positionals if any are left
6606  if(!positionals.empty()) {
6607  // Convert to help names
6608  std::vector<std::string> positional_names(positionals.size());
6609  std::transform(positionals.begin(), positionals.end(), positional_names.begin(), [this](const Option *opt) {
6610  return make_option_usage(opt);
6611  });
6612 
6613  out << " " << detail::join(positional_names, " ");
6614  }
6615 
6616  // Add a marker if subcommands are expected or optional
6617  if(!app->get_subcommands(
6618  [](const CLI::App *subc) { return ((!subc->get_disabled()) && (!subc->get_name().empty())); })
6619  .empty()) {
6620  out << " " << (app->get_require_subcommand_min() == 0 ? "[" : "")
6621  << get_label(app->get_require_subcommand_max() < 2 || app->get_require_subcommand_min() > 1 ? "SUBCOMMAND"
6622  : "SUBCOMMANDS")
6623  << (app->get_require_subcommand_min() == 0 ? "]" : "");
6624  }
6625 
6626  out << std::endl;
6627 
6628  return out.str();
6629 }
6630 
6631 inline std::string Formatter::make_footer(const App *app) const {
6632  std::string footer = app->get_footer();
6633  if(!footer.empty())
6634  return footer + "\n";
6635  else
6636  return "";
6637 }
6638 
6639 inline std::string Formatter::make_help(const App *app, std::string name, AppFormatMode mode) const {
6640 
6641  // This immediately forwards to the make_expanded method. This is done this way so that subcommands can
6642  // have overridden formatters
6643  if(mode == AppFormatMode::Sub)
6644  return make_expanded(app);
6645 
6646  std::stringstream out;
6647  if((app->get_name().empty()) && (app->get_parent() != nullptr)) {
6648  if(app->get_group() != "Subcommands") {
6649  out << app->get_group() << ':';
6650  }
6651  }
6652 
6653  out << make_description(app);
6654  out << make_usage(app, name);
6655  out << make_positionals(app);
6656  out << make_groups(app, mode);
6657  out << make_subcommands(app, mode);
6658  out << make_footer(app);
6659 
6660  return out.str();
6661 }
6662 
6663 inline std::string Formatter::make_subcommands(const App *app, AppFormatMode mode) const {
6664  std::stringstream out;
6665 
6666  std::vector<const App *> subcommands = app->get_subcommands({});
6667 
6668  // Make a list in definition order of the groups seen
6669  std::vector<std::string> subcmd_groups_seen;
6670  for(const App *com : subcommands) {
6671  if(com->get_name().empty()) {
6672  out << make_expanded(com);
6673  continue;
6674  }
6675  std::string group_key = com->get_group();
6676  if(!group_key.empty() &&
6677  std::find_if(subcmd_groups_seen.begin(), subcmd_groups_seen.end(), [&group_key](std::string a) {
6678  return detail::to_lower(a) == detail::to_lower(group_key);
6679  }) == subcmd_groups_seen.end())
6680  subcmd_groups_seen.push_back(group_key);
6681  }
6682 
6683  // For each group, filter out and print subcommands
6684  for(const std::string &group : subcmd_groups_seen) {
6685  out << "\n" << group << ":\n";
6686  std::vector<const App *> subcommands_group = app->get_subcommands(
6687  [&group](const App *sub_app) { return detail::to_lower(sub_app->get_group()) == detail::to_lower(group); });
6688  for(const App *new_com : subcommands_group) {
6689  if(new_com->get_name().empty())
6690  continue;
6691  if(mode != AppFormatMode::All) {
6692  out << make_subcommand(new_com);
6693  } else {
6694  out << new_com->help(new_com->get_name(), AppFormatMode::Sub);
6695  out << "\n";
6696  }
6697  }
6698  }
6699 
6700  return out.str();
6701 }
6702 
6703 inline std::string Formatter::make_subcommand(const App *sub) const {
6704  std::stringstream out;
6705  detail::format_help(out, sub->get_name(), sub->get_description(), column_width_);
6706  return out.str();
6707 }
6708 
6709 inline std::string Formatter::make_expanded(const App *sub) const {
6710  std::stringstream out;
6711  out << sub->get_display_name() << "\n";
6712 
6713  out << make_description(sub);
6714  out << make_positionals(sub);
6715  out << make_groups(sub, AppFormatMode::Sub);
6716  out << make_subcommands(sub, AppFormatMode::Sub);
6717 
6718  // Drop blank spaces
6719  std::string tmp = detail::find_and_replace(out.str(), "\n\n", "\n");
6720  tmp = tmp.substr(0, tmp.size() - 1); // Remove the final '\n'
6721 
6722  // Indent all but the first line (the name)
6723  return detail::find_and_replace(tmp, "\n", "\n ") + "\n";
6724 }
6725 
6726 inline std::string Formatter::make_option_name(const Option *opt, bool is_positional) const {
6727  if(is_positional)
6728  return opt->get_name(true, false);
6729  else
6730  return opt->get_name(false, true);
6731 }
6732 
6733 inline std::string Formatter::make_option_opts(const Option *opt) const {
6734  std::stringstream out;
6735 
6736  if(opt->get_type_size() != 0) {
6737  if(!opt->get_type_name().empty())
6738  out << " " << get_label(opt->get_type_name());
6739  if(!opt->get_default_str().empty())
6740  out << "=" << opt->get_default_str();
6741  if(opt->get_expected() > 1)
6742  out << " x " << opt->get_expected();
6743  if(opt->get_expected() == -1)
6744  out << " ...";
6745  if(opt->get_required())
6746  out << " " << get_label("REQUIRED");
6747  }
6748  if(!opt->get_envname().empty())
6749  out << " (" << get_label("Env") << ":" << opt->get_envname() << ")";
6750  if(!opt->get_needs().empty()) {
6751  out << " " << get_label("Needs") << ":";
6752  for(const Option *op : opt->get_needs())
6753  out << " " << op->get_name();
6754  }
6755  if(!opt->get_excludes().empty()) {
6756  out << " " << get_label("Excludes") << ":";
6757  for(const Option *op : opt->get_excludes())
6758  out << " " << op->get_name();
6759  }
6760  return out.str();
6761 }
6762 
6763 inline std::string Formatter::make_option_desc(const Option *opt) const { return opt->get_description(); }
6764 
6765 inline std::string Formatter::make_option_usage(const Option *opt) const {
6766  // Note that these are positionals usages
6767  std::stringstream out;
6768  out << make_option_name(opt, true);
6769 
6770  if(opt->get_expected() > 1)
6771  out << "(" << std::to_string(opt->get_expected()) << "x)";
6772  else if(opt->get_expected() < 0)
6773  out << "...";
6774  return opt->get_required() ? out.str() : "[" + out.str() + "]";
6775 }
6776 
6777 } // namespace CLI
6778 
size_t remaining_size(bool recurse=false) const
This returns the number of remaining options, minus the – separator.
Definition: CLI11.hpp:5417
App * get_subcommand(std::string subcom) const
Check to see if a subcommand is part of this command (text version)
Definition: CLI11.hpp:4737
std::string get_type_name() const
Get the full typename for this option.
Definition: CLI11.hpp:3611
Option * get_option_no_throw(std::string option_name) noexcept
Get an option by name (noexcept non-const version)
Definition: CLI11.hpp:5203
const Option * operator[](const char *option_name) const
Shortcut bracket operator for getting a pointer to an option.
Definition: CLI11.hpp:5262
CRTP * required(bool value=true)
Set the option as required.
Definition: CLI11.hpp:2731
std::string help(std::string prev="", AppFormatMode mode=AppFormatMode::Normal) const
Definition: CLI11.hpp:5152
Option * needs(std::string opt_name)
Can find a string if needed.
Definition: CLI11.hpp:3064
typename T::value_type value_type
Definition: CLI11.hpp:978
CLI::App_p get_subcommand_ptr(App *subcom) const
Check to see if a subcommand is part of this command and get a shared_ptr to it.
Definition: CLI11.hpp:4754
std::string & rtrim(std::string &str, const std::string &filter)
Trim anything from right of string.
Definition: CLI11.hpp:340
Definition: CLI11.hpp:172
App * footer(std::string footer_string)
Set footer.
Definition: CLI11.hpp:5139
std::function< std::string(std::string)> filter_fn_t
Definition: CLI11.hpp:2127
static auto second(Q &&pair_value) -> decltype(std::forward< Q >(pair_value))
Get the second value (really just the underlying value)
Definition: CLI11.hpp:987
Validator & operation(std::function< std::string(std::string &)> op)
Set the Validator operation function.
Definition: CLI11.hpp:1575
App * ignore_underscore(bool value=true)
Ignore underscore. Subcommands inherit value.
Definition: CLI11.hpp:4021
All errors derive from this one.
Definition: CLI11.hpp:636
CLI::App_p get_subcommand_ptr(std::string subcom) const
Check to see if a subcommand is part of this command (text version)
Definition: CLI11.hpp:4764
void _process_env()
Get envname options if not yet passed. Runs on all subcommands.
Definition: CLI11.hpp:5567
std::function< bool(results_t)> callback_t
Definition: CLI11.hpp:2666
bool got_subcommand(std::string subcommand_name) const
Check with name instead of pointer to see if subcommand was selected.
Definition: CLI11.hpp:5086
App * require_option(size_t min, size_t max)
Definition: CLI11.hpp:4870
Bound(T max)
Range of one value is 0 to value.
Definition: CLI11.hpp:1934
std::vector< std::string > fnames_
a list of flag names with specified default values;
Definition: CLI11.hpp:2866
typename std::remove_const< value_type >::type first_type
Definition: CLI11.hpp:979
Option * excludes(std::string opt_name)
Can find a string if needed.
Definition: CLI11.hpp:3103
T as() const
return the results as a particular type
Definition: CLI11.hpp:3545
const Option * get_option(std::string option_name) const
Get an option by name.
Definition: CLI11.hpp:5241
static std::map< std::string, result_t > init_mapping(bool kb_is_1000)
Get <size unit, factor> mapping.
Definition: CLI11.hpp:2431
Option * each(std::function< void(std::string)> func)
Adds a user supplied function to run on each item passed in (communicate though lambda capture) ...
Definition: CLI11.hpp:3034
Check for an non-existing path.
Definition: CLI11.hpp:1785
Range(T min, T max)
Definition: CLI11.hpp:1887
CheckedTransformer(T mapping, F filter_function)
Definition: CLI11.hpp:2196
bool allow_extras_
If true, allow extra arguments (ie, don&#39;t throw an error). INHERITABLE.
Definition: CLI11.hpp:3713
std::remove_reference< T >::type & smart_deref(T &value)
Definition: CLI11.hpp:1947
CRTP * take_last()
Set the multi option policy to take last.
Definition: CLI11.hpp:2776
std::string to_lower(std::string str)
Return a lower case version of a string.
Definition: CLI11.hpp:406
IsMember(T set, F filter_function)
Definition: CLI11.hpp:2069
std::string description_
Description of the current program/subcommand.
Definition: CLI11.hpp:3710
This converter works with INI files.
Definition: CLI11.hpp:1483
constexpr const char * type_name()
This one should not be used, since vector types print the internal type.
Definition: CLI11.hpp:1058
std::string ignore_space(std::string item)
Helper function to allow checks to ignore spaces to be passed to IsMember or Transform.
Definition: CLI11.hpp:2264
App * get_option_group(std::string group_name) const
Check to see if an option group is part of this App.
Definition: CLI11.hpp:4782
Option * excludes(Option *opt)
Sets excluded options.
Definition: CLI11.hpp:3090
Transformer(T &&mapping, filter_fn_t filter_fn_1, filter_fn_t filter_fn_2, Args &&... other)
You can pass in as many filter functions as you like, they nest.
Definition: CLI11.hpp:2175
void _process_help_flags(bool trigger_help=false, bool trigger_all_help=false) const
Definition: CLI11.hpp:5628
const detail::IPV4Validator ValidIPV4
Check for an IP4 address.
Definition: CLI11.hpp:1872
char get_delimiter() const
Get the current delimeter char.
Definition: CLI11.hpp:2765
std::string description_
The description for help strings.
Definition: CLI11.hpp:2879
bool get_callback_run() const
See if the callback has been run already.
Definition: CLI11.hpp:3552
std::unique_ptr< Option > Option_p
Definition: CLI11.hpp:2671
-h or –help on command line
Definition: CLI11.hpp:729
std::function< std::string()> default_function_
Run this function to capture a default (ignore if empty)
Definition: CLI11.hpp:2890
std::string generate_set(const T &set)
Generate a string representation of a set.
Definition: CLI11.hpp:1951
std::function< std::string(std::string &)> func_
Definition: CLI11.hpp:1558
void TriggerOff(App *trigger_app, App *app_to_enable)
Helper function to disable one option group/subcommand when another is used.
Definition: CLI11.hpp:6377
Transformer(T &&mapping)
direct map of std::string to std::string
Definition: CLI11.hpp:2135
std::string make_help(const App *app, std::string name, AppFormatMode mode) const override
This will simply call the lambda function.
Definition: CLI11.hpp:2585
virtual std::string make_subcommands(const App *app, AppFormatMode mode) const
This prints out all the subcommands.
Definition: CLI11.hpp:6663
static ArgumentMismatch FlagOverride(std::string name)
Definition: CLI11.hpp:828
App * require_option(int value)
Definition: CLI11.hpp:4857
App * require_subcommand(size_t min, size_t max)
Definition: CLI11.hpp:4841
constexpr enabler dummy
An instance to use in EnableIf.
Definition: CLI11.hpp:910
std::string make_groups(const App *app, AppFormatMode mode) const
This prints out all the groups of options.
Definition: CLI11.hpp:6539
uint64_t result_t
Definition: CLI11.hpp:2412
std::string help(const App *app, const Error &e)
Printout the full help string on error (if this fn is set, the old default for CLI11) ...
Definition: CLI11.hpp:6419
Option * add_flag(std::string flag_name, std::vector< T > &flag_results, std::string flag_description="")
Vector version to capture multiple flags.
Definition: CLI11.hpp:4335
results_t results_
Results of parsing.
Definition: CLI11.hpp:2928
Does not output a diagnostic in CLI11_PARSE, but allows to return from main() with a specific error c...
Definition: CLI11.hpp:742
bool allow_config_extras_
If true, allow extra arguments in the ini file (ie, don&#39;t throw an error). INHERITABLE.
Definition: CLI11.hpp:3716
bool get_prefix_command() const
Get the prefix command status.
Definition: CLI11.hpp:5298
std::string & ltrim(std::string &str, const std::string &filter)
Trim anything from left of string.
Definition: CLI11.hpp:326
void failure_message(std::function< std::string(const App *, const Error &e)> function)
Provide a function to print a help message. The function gets access to the App pointer and error...
Definition: CLI11.hpp:5004
std::function< std::string(std::string)> filter_fn_t
Definition: CLI11.hpp:2184
size_t get_require_option_min() const
Get the required min option value.
Definition: CLI11.hpp:5292
Class wrapping some of the accessors of Validator.
Definition: CLI11.hpp:1725
void copy_to(T *other) const
Copy the contents to another similar class (one based on OptionBase)
Definition: CLI11.hpp:2709
Transformer(std::initializer_list< std::pair< std::string, std::string >> values, Args &&... args)
This allows in-place construction.
Definition: CLI11.hpp:2131
static BadNameString BadLongName(std::string name)
Definition: CLI11.hpp:691
bool _parse_single(std::vector< std::string > &args, bool &positional_only)
Definition: CLI11.hpp:5906
std::vector< App * > parsed_subcommands_
This is a list of the subcommands collected, in order.
Definition: CLI11.hpp:3787
This class is simply to allow tests access to App&#39;s protected functions.
Definition: CLI11.hpp:6429
App * required(bool require=true)
Remove the error when extras are left over on the command line.
Definition: CLI11.hpp:3946
missing_t missing_
Definition: CLI11.hpp:3781
std::string make_help(const App *, std::string, AppFormatMode) const override
This puts everything together.
Definition: CLI11.hpp:6639
bool get_required() const
True if this is a required option.
Definition: CLI11.hpp:2750
ConversionError(std::string name, std::vector< std::string > results)
Definition: CLI11.hpp:760
bool prefix_command_
If true, return immediately on an unrecognized option (implies allow_extras) INHERITABLE.
Definition: CLI11.hpp:3719
bool get_disabled_by_default() const
Get the status of disabled by default.
Definition: CLI11.hpp:5313
CRTP * always_capture_default(bool value=true)
Definition: CLI11.hpp:2739
std::string find_and_modify(std::string str, std::string trigger, Callable modify)
Definition: CLI11.hpp:482
Validator & name(std::string validator_name)
Specify the type string.
Definition: CLI11.hpp:1614
bool remove_subcommand(App *subcom)
Removes a subcommand from the App. Takes a subcommand pointer. Returns true if found and removed...
Definition: CLI11.hpp:4711
std::shared_ptr< App > App_p
Definition: CLI11.hpp:3689
bool lexical_cast(std::string input, T &output)
Signed integers.
Definition: CLI11.hpp:1151
std::set< Option * > exclude_options_
Definition: CLI11.hpp:3794
void column_width(size_t val)
Set the column width.
Definition: CLI11.hpp:2550
std::vector< std::pair< std::string, std::string > > default_flag_values_
Definition: CLI11.hpp:2863
Produce a range (factory). Min and max are inclusive.
Definition: CLI11.hpp:1881
App * preparse_callback(std::function< void(size_t)> pp_callback)
Definition: CLI11.hpp:3927
typename make_void< Ts... >::type void_t
A copy of std::void_t from C++17 - same reasoning as enable_if_t, it does not hurt to redefine...
Definition: CLI11.hpp:924
Option * _add_flag_internal(std::string flag_name, CLI::callback_t fun, std::string flag_description)
Internal function for adding a flag.
Definition: CLI11.hpp:4253
void parse(std::vector< std::string > &args)
Definition: CLI11.hpp:4964
std::string ignore_case(std::string item)
Helper function to allow ignore_case to be passed to IsMember or Transform.
Definition: CLI11.hpp:2258
const Option * get_help_all_ptr() const
Get a pointer to the help all flag. (const)
Definition: CLI11.hpp:5330
Option * add_option(Option *opt)
Add an existing option to the Option_group.
Definition: CLI11.hpp:6332
IsMember(T &&set)
This checks to see if an item is in a set (empty function)
Definition: CLI11.hpp:2065
App * immediate_callback(bool immediate=true)
Set the subcommand callback to be executed immediately on subcommand completion.
Definition: CLI11.hpp:3971
Option * add_result(std::string s)
Puts a result at the end.
Definition: CLI11.hpp:3475
virtual std::string make_footer(const App *app) const
This prints out all the groups of options.
Definition: CLI11.hpp:6631
CheckedTransformer(std::initializer_list< std::pair< std::string, std::string >> values, Args &&... args)
This allows in-place construction.
Definition: CLI11.hpp:2188
std::vector< std::string > split_up(std::string str)
Definition: CLI11.hpp:492
bool split_short(const std::string &current, std::string &name, std::string &rest)
Definition: CLI11.hpp:1282
detail::Classifier _recognize(const std::string &current, bool ignore_used_subcommands=true) const
Selects a Classifier enum based on the type of the current argument.
Definition: CLI11.hpp:5526
Error(std::string name, std::string msg, ExitCodes exit_code)
Definition: CLI11.hpp:648
std::vector< ConfigItem > from_file(const std::string &name)
Parse a config file, throw an error (ParseError:ConfigParseError or FileError) on failure...
Definition: CLI11.hpp:1470
virtual std::string make_group(std::string group, bool is_positional, std::vector< const Option *> opts) const
Definition: CLI11.hpp:6518
Option(std::string option_name, std::string option_description, std::function< bool(results_t)> callback, App *parent)
Making an option by hand is not defined, it must be made by the App class.
Definition: CLI11.hpp:2936
bool has_automatic_name_
If set to true the name was automatically generated from the command line vs a user set name...
Definition: CLI11.hpp:3722
std::string as_string(const T &v)
simple utility to convert various types to a string
Definition: CLI11.hpp:265
std::vector< Validator > validators_
A list of validators to run on each value parsed.
Definition: CLI11.hpp:2905
bool split_windows_style(const std::string &current, std::string &name, std::string &value)
Definition: CLI11.hpp:1308
STL namespace.
size_t get_require_subcommand_min() const
Get the required min subcommand value.
Definition: CLI11.hpp:5286
bool _has_remaining_positionals() const
Count the required remaining positional arguments.
Definition: CLI11.hpp:5961
Thrown when an excludes option is present.
Definition: CLI11.hpp:841
MultiOptionPolicy
Definition: CLI11.hpp:2673
Option * help_all_ptr_
A pointer to the help all flag if there is one INHERITABLE.
Definition: CLI11.hpp:3764
Option * add_option(std::string option_name, callback_t option_callback, std::string option_description="", bool defaulted=false, std::function< std::string()> func={})
Definition: CLI11.hpp:4074
bool _parse_arg(std::vector< std::string > &args, detail::Classifier current_type)
Definition: CLI11.hpp:6092
Option * add_flag(std::string flag_name, T &flag_result, std::string flag_description="")
Definition: CLI11.hpp:4317
std::string envname_
If given, check the environment for this option.
Definition: CLI11.hpp:2872
virtual std::string make_option(const Option *opt, bool is_positional) const
This prints out an option help line, either positional or optional form.
Definition: CLI11.hpp:2637
Validate the given string is a legal ipv4 address.
Definition: CLI11.hpp:1800
const detail::NonexistentPathValidator NonexistentPath
Check for an non-existing path.
Definition: CLI11.hpp:1869
std::string _validate(std::string &result)
Definition: CLI11.hpp:3626
std::string trim_copy(const std::string &str)
Make a copy of the string and then trim it.
Definition: CLI11.hpp:354
Some validators that are provided.
Definition: CLI11.hpp:1551
bool get_positionals_at_end() const
Check the status of the allow windows style options.
Definition: CLI11.hpp:5277
bool get_required() const
Get the status of required.
Definition: CLI11.hpp:5304
App * _find_subcommand(const std::string &subc_name, bool ignore_disabled, bool ignore_used) const noexcept
Definition: CLI11.hpp:6045
Extension of App to better manage groups of options.
Definition: CLI11.hpp:6323
CLI::App app
Definition: application.hh:22
std::string type(const x_type &a_param)
Definition: typename.hh:24
static IncorrectConstruction Set0Opt(std::string name)
Definition: CLI11.hpp:665
const Option * operator[](const std::string &option_name) const
Shortcut bracket operator for getting a pointer to an option.
Definition: CLI11.hpp:5259
CRTP * group(std::string name)
Changes the group membership.
Definition: CLI11.hpp:2725
static BadNameString DashesOnly(std::string name)
Definition: CLI11.hpp:692
virtual std::string make_expanded(const App *sub) const
This prints out a subcommand in help-all.
Definition: CLI11.hpp:6709
std::vector< std::string > results_t
Definition: CLI11.hpp:2665
bool get_ignore_underscore() const
Check the status of ignore_underscore.
Definition: CLI11.hpp:5268
bool split_long(const std::string &current, std::string &name, std::string &value)
Definition: CLI11.hpp:1292
std::string get_display_name() const
Get a display name for an app.
Definition: CLI11.hpp:5348
App * get_subcommand(int index=0) const
Get a pointer to subcommand by index.
Definition: CLI11.hpp:4744
std::enable_if< std::is_integral< T >::value, bool >::type checked_multiply(T &a, T b)
Performs a *= b; if it doesn&#39;t cause integer overflow. Returns false otherwise.
Definition: CLI11.hpp:2029
Check to see if something is a vector (fail check by default)
Definition: CLI11.hpp:930
Option * type_name_fn(std::function< std::string()> typefun)
Set the type function to run when displayed on this option.
Definition: CLI11.hpp:3559
const detail::ExistingDirectoryValidator ExistingDirectory
Check for an existing directory (returns error message if check fails)
Definition: CLI11.hpp:1863
App * add_subcommand(App *subcom)
Add an existing subcommand to be a member of an option_group.
Definition: CLI11.hpp:6348
bool remove_excludes(App *app)
Removes a subcommand from this excludes list of this subcommand.
Definition: CLI11.hpp:5122
std::string default_str_
A human readable default value, either manually set, captured, or captured by default.
Definition: CLI11.hpp:2882
Option * add_mutable_set(std::string option_name, T &member, const std::set< T > &options, std::string option_description, bool defaulted)
Add set of options (with default, set can be changed afterwards - do not destroy the set) DEPRECATED...
Definition: CLI11.hpp:4431
enabler
Simple empty scoped class.
Definition: CLI11.hpp:907
std::string trim_copy(const std::string &str, const std::string &filter)
Make a copy of the string and then trim it, any filter string can be used (any char in string is filt...
Definition: CLI11.hpp:360
funct_t lambda_
The lambda to hold and run.
Definition: CLI11.hpp:2575
Adaptor for set-like structure: This just wraps a normal container in a few utilities that do almost ...
Definition: CLI11.hpp:977
static IncorrectConstruction AfterMultiOpt(std::string name)
Definition: CLI11.hpp:674
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: CLI11.hpp:451
App * name(std::string app_name="")
Set a name for the app (empty will use parser to set the name)
Definition: CLI11.hpp:3933
Holds values to load into Options.
Definition: CLI11.hpp:1431
std::vector< std::string > parents
This is the list of parents.
Definition: CLI11.hpp:1433
std::vector< const Option * > get_options(const std::function< bool(const Option *)> filter={}) const
Get the list of options (user facing function, so returns raw pointers), has optional filter function...
Definition: CLI11.hpp:5186
void TriggerOn(App *trigger_app, App *app_to_enable)
Helper function to enable one option group/subcommand when another is used.
Definition: CLI11.hpp:6356
bool get_validate_positionals() const
Get the status of validating positionals.
Definition: CLI11.hpp:5318
size_t count() const
Count the total number of times an option was passed.
Definition: CLI11.hpp:2949
typename std::enable_if< B, T >::type enable_if_t
Definition: CLI11.hpp:918
std::shared_ptr< FormatterBase > get_formatter() const
Access the formatter.
Definition: CLI11.hpp:5171
void _move_to_missing(detail::Classifier val_type, const std::string &val)
Helper function to place extra values in the most appropriate position.
Definition: CLI11.hpp:6264
bool parsed() const
Check to see if this subcommand was parsed, true only if received on command line.
Definition: CLI11.hpp:4051
bool _parse_single_config(const ConfigItem &item, size_t level=0)
Fill in a single config option.
Definition: CLI11.hpp:5865
OptionDefaults * delimiter(char value='\0')
set a delimiter character to split up single arguments to treat as multiple inputs ...
Definition: CLI11.hpp:2842
void sum_flag_vector(const std::vector< std::string > &flags, T &output)
Definition: CLI11.hpp:1251
App * positionals_at_end(bool value=true)
Specify that the positional arguments are only at the end of the sequence.
Definition: CLI11.hpp:4015
Validator & active(bool active_val=true)
Specify whether the Validator is active or not.
Definition: CLI11.hpp:1621
std::vector< std::string > get_groups() const
Get the groups available directly from this option (in order)
Definition: CLI11.hpp:5366
Verify items are in a set.
Definition: CLI11.hpp:2055
size_t _count_remaining_positionals(bool required_only=false) const
Count the required remaining positional arguments.
Definition: CLI11.hpp:5950
bool check_fname(std::string name) const
Requires "--" to be removed from string.
Definition: CLI11.hpp:3428
std::string rjoin(const T &v, std::string delim=",")
Join a string in reverse order.
Definition: CLI11.hpp:306
static RequiredError Subcommand(size_t min_subcom)
Definition: CLI11.hpp:781
bool _parse_positional(std::vector< std::string > &args)
Definition: CLI11.hpp:5972
std::function< std::string(const App *, std::string, AppFormatMode)> funct_t
Definition: CLI11.hpp:2572
const std::string & get_name() const
Get the name of the Validator.
Definition: CLI11.hpp:1619
size_t count(std::string option_name) const
Counts the number of times the given option was passed.
Definition: CLI11.hpp:5038
Option * type_size(int option_type_size)
Set a custom option size.
Definition: CLI11.hpp:3571
Option * set_config(std::string option_name="", std::string default_filename="", std::string help_message="Read an ini file", bool config_required=false)
Set a configuration ini file option, or clear it if no name passed.
Definition: CLI11.hpp:4633
std::vector< std::string > remaining_for_passthrough(bool recurse=false) const
This returns the missing options in a form ready for processing by another command line program...
Definition: CLI11.hpp:5410
Error(std::string name, std::string msg, int exit_code=static_cast< int >(ExitCodes::BaseClass))
Definition: CLI11.hpp:645
void _process_requirements()
Verify required options and cross requirements. Subcommands too (only if selected).
Definition: CLI11.hpp:5651
std::shared_ptr< Config > get_config_formatter() const
Access the config formatter.
Definition: CLI11.hpp:5174
virtual ~FormatterBase() noexcept
Adding a destructor in this form to work around bug in GCC 4.7.
Definition: CLI11.hpp:2537
Thrown when an option is set to conflicting values (non-vector and multi args, for example) ...
Definition: CLI11.hpp:659
Option * add_flag_function(std::string flag_name, std::function< void(int64_t)> function, std::string flag_description="")
Add option for callback with an integer value.
Definition: CLI11.hpp:4370
bool get_configurable() const
The status of configurable.
Definition: CLI11.hpp:2759
bool validate_positionals_
If set to true positional options are validated before assigning INHERITABLE.
Definition: CLI11.hpp:3828
Validator(std::string validator_desc)
Construct a Validator with just the description string.
Definition: CLI11.hpp:1569
std::string generate_map(const T &map, bool key_only=false)
Generate a string representation of a map.
Definition: CLI11.hpp:1963
std::vector< std::string > lnames_
A list of the long names (--a) without the leading dashes.
Definition: CLI11.hpp:2859
std::string pname_
A positional name.
Definition: CLI11.hpp:2869
Option * add_set(std::string option_name, T &member, std::set< T > options, std::string option_description="")
Add set of options (No default, temp reference, such as an inline set) DEPRECATED.
Definition: CLI11.hpp:4394
App * require_subcommand()
The argumentless form of require subcommand requires 1 or more subcommands.
Definition: CLI11.hpp:4819
#define CLI11_DEPRECATED(reason)
Definition: CLI11.hpp:111
bool remove_excludes(Option *opt)
Removes an option from the excludes list of this subcommand.
Definition: CLI11.hpp:5111
App * add_subcommand(CLI::App_p subcom)
Add a previously created app as a subcommand.
Definition: CLI11.hpp:4697
App * require_option()
The argumentless form of require option requires 1 or more options be used.
Definition: CLI11.hpp:4848
App * get_subcommand(App *subcom) const
Definition: CLI11.hpp:4727
Option * get_help_ptr()
Get a pointer to the help flag.
Definition: CLI11.hpp:5324
App * group(std::string group_name)
Changes the group membership.
Definition: CLI11.hpp:4813
CRTP * mandatory(bool value=true)
Support Plumbum term.
Definition: CLI11.hpp:2737
bool isalpha(const std::string &str)
Verify that str consists of letters only.
Definition: CLI11.hpp:401
IsMember(std::initializer_list< T > values, Args &&... args)
This allows in-place construction using an initializer list.
Definition: CLI11.hpp:2061
static IncorrectConstruction SetFlag(std::string name)
Definition: CLI11.hpp:668
std::set< Option * > get_needs() const
The set of options needed.
Definition: CLI11.hpp:3188
void parse(std::vector< std::string > &&args)
The real work is done here. Expects a reversed vector.
Definition: CLI11.hpp:4984
void parse(std::string commandline, bool program_name_included=false)
Definition: CLI11.hpp:4936
bool allow_windows_style_options_
Allow &#39;/&#39; for options for Windows like options. Defaults to true on Windows, false otherwise...
Definition: CLI11.hpp:3813
std::pair< std::string, std::string > split_program_name(std::string commandline)
Definition: CLI11.hpp:2466
std::string get_label(std::string key) const
Get the current value of a name (REQUIRED, etc.)
Definition: CLI11.hpp:2557
Option * add_option(std::string option_name, T &option_description)
Add option with description but with no variable assignment or callback.
Definition: CLI11.hpp:4154
static IncorrectConstruction MultiOptionPolicy(std::string name)
Definition: CLI11.hpp:681
Option * multi_option_policy(MultiOptionPolicy value=MultiOptionPolicy::Throw)
Take the last argument if given multiple times (or another policy)
Definition: CLI11.hpp:3164
std::string get_description() const
Get the app or subcommand description.
Definition: CLI11.hpp:5177
Check for an existing path.
Definition: CLI11.hpp:1770
Check to see if something is copyable pointer.
Definition: CLI11.hpp:951
Option * add_set(std::string option_name, T &member, std::set< T > options, std::string option_description, bool defaulted)
Add set of options (with default, static set, such as an inline set) DEPRECATED.
Definition: CLI11.hpp:4418
bool get_ignore_case() const
The status of ignore case.
Definition: CLI11.hpp:2753
std::vector< ConfigItem > from_config(std::istream &input) const override
Convert a configuration into an app.
Definition: CLI11.hpp:1487
std::vector< std::string > remaining(bool recurse=false) const
This returns the missing options from the current subcommand.
Definition: CLI11.hpp:5383
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: CLI11.hpp:3001
App * validate_positionals(bool validate=true)
Set the subcommand to validate positional arguments before assigning.
Definition: CLI11.hpp:3977
static std::string generate_description(const std::string &name, Options opts)
Generate description like this: NUMBER [UNIT].
Definition: CLI11.hpp:2387
std::string to_config(const App *, bool default_also, bool write_description, std::string prefix) const override
Convert an app into a configuration.
Definition: CLI11.hpp:6456
bool get_active() const
Get a boolean if the validator is active.
Definition: CLI11.hpp:1633
std::vector< std::string > results() const
Get a copy of the results.
Definition: CLI11.hpp:3498
size_t count_all() const
Definition: CLI11.hpp:4798
bool get_always_capture_default() const
Return true if this will automatically capture the default value for help printing.
Definition: CLI11.hpp:2768
friend Option
Definition: CLI11.hpp:3697
Thrown when too many positionals or options are found.
Definition: CLI11.hpp:848
std::vector< std::string > split_names(std::string current)
Definition: CLI11.hpp:1324
const Option * get_help_ptr() const
Get a pointer to the help flag. (const)
Definition: CLI11.hpp:5327
static IncorrectConstruction PositionalFlag(std::string name)
Definition: CLI11.hpp:662
typename std::remove_const< value_type >::type second_type
Definition: CLI11.hpp:980
bool valid_later_char(T c)
Verify following characters of an option.
Definition: CLI11.hpp:388
bool valid_name_string(const std::string &str)
Verify an option name.
Definition: CLI11.hpp:391
bool get_immediate_callback() const
Get the status of disabled.
Definition: CLI11.hpp:5310
Check for an existing file (returns error message if check fails)
Definition: CLI11.hpp:1734
std::string to_string(T &&value)
Convert an object to a string (streaming must be supported for that type)
Definition: CLI11.hpp:1036
void label(std::string key, std::string val)
Set the "REQUIRED" label.
Definition: CLI11.hpp:2547
Option * set_help_flag(std::string flag_name="", const std::string &help_description="")
Set a help flag, replace the existing one if present.
Definition: CLI11.hpp:4218
static auto test_find(long) -> std::false_type
bool get_disabled() const
Get the status of disabled.
Definition: CLI11.hpp:5307
std::set< Option * > needs_
A list of options that are required with this option.
Definition: CLI11.hpp:2908
int64_t to_flag_value(std::string val)
Convert a flag into an integer value typically binary flags.
Definition: CLI11.hpp:1096
std::string & rtrim(std::string &str)
Trim whitespace from right of string.
Definition: CLI11.hpp:333
Check for an existing directory (returns error message if check fails)
Definition: CLI11.hpp:1752
bool get_modifying() const
Get a boolean if the validator is allowed to modify the input returns true if it can modify the input...
Definition: CLI11.hpp:1636
App * callback(std::function< void()> app_callback)
Definition: CLI11.hpp:3920
App * parent_
Remember the parent app.
Definition: CLI11.hpp:2918
Creates a command line program, with very few defaults.
Definition: CLI11.hpp:3696
Option * add_flag(std::string flag_name, T &flag_count, std::string flag_description="")
Definition: CLI11.hpp:4295
bool get_fallthrough() const
Check the status of fallthrough.
Definition: CLI11.hpp:5271
virtual std::string make_positionals(const App *app) const
This prints out just the positionals "group".
Definition: CLI11.hpp:6529
Option * help_ptr_
A pointer to the help flag if there is one INHERITABLE.
Definition: CLI11.hpp:3761
OptionDefaults * disable_flag_override(bool value=true)
Disable overriding flag values with an &#39;=&#39; segment.
Definition: CLI11.hpp:2836
bool remove_option(Option *opt)
Removes an option from the App. Takes an option pointer. Returns true if found and removed...
Definition: CLI11.hpp:4654
bool valid_first_char(T c)
Verify the first character of an option.
Definition: CLI11.hpp:383
OptionDefaults * ignore_case(bool value=true)
Ignore the case of the option name.
Definition: CLI11.hpp:2824
Validator & non_modifying(bool no_modify=true)
Specify whether the Validator can be modifying or not.
Definition: CLI11.hpp:1627
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: CLI11.hpp:1364
virtual std::string make_subcommand(const App *sub) const
This prints out a subcommand.
Definition: CLI11.hpp:6703
App * formatter(std::shared_ptr< FormatterBase > fmt)
Set the help formatter.
Definition: CLI11.hpp:4033
int exit(const Error &e, std::ostream &out=std::cout, std::ostream &err=std::cerr) const
Print a nice error message and return the exit code.
Definition: CLI11.hpp:5009
Validator(std::function< std::string(std::string &)> op, std::string validator_desc, std::string validator_name="")
Definition: CLI11.hpp:1571
App * ignore_case(bool value=true)
Ignore case. Subcommands inherit value.
Definition: CLI11.hpp:3997
bool get_ignore_underscore() const
The status of ignore_underscore.
Definition: CLI11.hpp:2756
static auto first(Q &&pair_value) -> decltype(std::get< 0 >(std::forward< Q >(pair_value)))
Get the first value (really just the underlying value)
Definition: CLI11.hpp:1004
std::function< std::string(const App *, const Error &e)> failure_message_
The error message printing function INHERITABLE.
Definition: CLI11.hpp:3770
App * require_subcommand(int value)
Definition: CLI11.hpp:4828
Thrown when a requires option is missing.
Definition: CLI11.hpp:834
std::set< Option * > excludes_
A list of options that are excluded with this option.
Definition: CLI11.hpp:2911
App * disabled(bool disable=true)
Disable the subcommand or option group.
Definition: CLI11.hpp:3952
Option * envname(std::string name)
Sets environment variable to read if no option given.
Definition: CLI11.hpp:3129
int actual_exit_code
Definition: CLI11.hpp:637
void _parse(std::vector< std::string > &&args)
Internal parse function.
Definition: CLI11.hpp:5837
std::string ignore_underscore(std::string item)
Helper function to allow ignore_underscore to be passed to IsMember or Transform. ...
Definition: CLI11.hpp:2261
Option * capture_default_str()
Capture the default value from the original value (if it can be captured)
Definition: CLI11.hpp:3587
static void validate_mapping(std::map< std::string, Number > &mapping, Options opts)
Definition: CLI11.hpp:2362
static IncorrectConstruction MissingOption(std::string name)
Definition: CLI11.hpp:678
Option * add_option_function(std::string option_name, const std::function< void(const T &)> &func, std::string option_description="")
Add option for a callback of a specific type.
Definition: CLI11.hpp:4127
void clear()
Reset the parsed data.
Definition: CLI11.hpp:4901
size_t get_column_width() const
Get the current column width.
Definition: CLI11.hpp:2565
CRTP * take_first()
Set the multi option policy to take last.
Definition: CLI11.hpp:2783
std::string operator()(std::string &str) const
Definition: CLI11.hpp:1581
App(std::string app_description, std::string app_name, App *parent)
Special private constructor for subcommand.
Definition: CLI11.hpp:3869
Option * excludes(A opt, B opt1, ARG... args)
Any number supported, any mix of string and Opt.
Definition: CLI11.hpp:3111
Validate the argument is a number and greater than or equal to 0.
Definition: CLI11.hpp:1842
static IncorrectConstruction ChangeNotVector(std::string name)
Definition: CLI11.hpp:671
static OptionAlreadyAdded Requires(std::string name, std::string other)
Definition: CLI11.hpp:705
virtual std::string make_usage(const App *app, std::string name) const
This displays the usage line.
Definition: CLI11.hpp:6589
void _process()
Process callbacks and such.
Definition: CLI11.hpp:5759
Option * get_config_ptr()
Get a pointer to the config option.
Definition: CLI11.hpp:5333
void _process_callbacks()
Process callbacks. Runs on all subcommands.
Definition: CLI11.hpp:5600
Usually something like –help-all on command line.
Definition: CLI11.hpp:735
#define CLI11_ERROR_DEF(parent, name)
Definition: CLI11.hpp:591
bool get_allow_windows_style_options() const
Check the status of the allow windows style options.
Definition: CLI11.hpp:5274
bool get_allow_config_extras() const
Get the status of allow extras.
Definition: CLI11.hpp:5321
std::string get_name() const
Definition: CLI11.hpp:643
App * prefix_command(bool allow=true)
Do not parse anything after the first unrecognized option and return.
Definition: CLI11.hpp:3991
Check to see if something is a shared pointer.
Definition: CLI11.hpp:942
std::string & trim(std::string &str, const std::string filter)
Trim anything from string.
Definition: CLI11.hpp:351
std::map< std::string, std::string > labels_
The required help printout labels (user changeable) Values are Needs, Excludes, etc.
Definition: CLI11.hpp:2525
int _add_result(std::string &&result)
Definition: CLI11.hpp:3640
App * allow_config_extras(bool allow=true)
Definition: CLI11.hpp:3984
std::string footer_
Footer to put after all options in the help output INHERITABLE.
Definition: CLI11.hpp:3758
Thrown when extra values are found in an INI file.
Definition: CLI11.hpp:858
static BadNameString MultiPositionalNames(std::string name)
Definition: CLI11.hpp:695
void add_options(Option *opt)
Add an existing option to the Option_group.
Definition: CLI11.hpp:6340
void _process_extras()
Throw an error if anything is left over and should not be.
Definition: CLI11.hpp:5768
bool active_
Enable for Validator to allow it to be disabled if need be.
Definition: CLI11.hpp:1562
Thrown when validation fails before parsing.
Definition: CLI11.hpp:868
auto search(const T &set, const V &val, const std::function< V(V)> &filter_function) -> std::pair< bool, decltype(std::begin(detail::smart_deref(set)))>
A search function with a filter function.
Definition: CLI11.hpp:2010
size_t count() const
Definition: CLI11.hpp:4794
This is a specialty override for lambda functions.
Definition: CLI11.hpp:2571
void increment_parsed()
Internal function to recursively increment the parsed counter on the current app as well unnamed subc...
Definition: CLI11.hpp:5800
std::istream & operator>>(std::istream &in, T &item)
input streaming for enumerations
Definition: CLI11.hpp:234
AsSizeValue(bool kb_is_1000)
Definition: CLI11.hpp:2421
const x_value & at(const std::map< x_key, x_value > &a_map, const x_key &a_key, const x_value &a_default)
std::string get_name() const
Get the name of the current app.
Definition: CLI11.hpp:5345
virtual void pre_callback()
Definition: CLI11.hpp:4894
virtual std::string to_flag(const ConfigItem &item) const
Get a flag value.
Definition: CLI11.hpp:1462
virtual std::string make_description(const App *app) const
This displays the description line.
Definition: CLI11.hpp:6563
Option * needs(A opt, B opt1, ARG... args)
Any number supported, any mix of string and Opt.
Definition: CLI11.hpp:3072
bool get_ignore_case() const
Check the status of ignore_case.
Definition: CLI11.hpp:5265
bool has_default_flag_values(const std::string &flags)
check if the flag definitions has possible false flags
Definition: CLI11.hpp:433
Option * disable_flag_override(bool value=true)
disable flag overrides
Definition: CLI11.hpp:3173
std::string fullname() const
The list of parents and name joined by ".".
Definition: CLI11.hpp:1442
const std::string & get_group() const
Get the group of this subcommand.
Definition: CLI11.hpp:5280
std::vector< App_p > subcommands_
Storage for subcommand list.
Definition: CLI11.hpp:3801
Thrown when parsing an INI file and it is missing.
Definition: CLI11.hpp:748
Option * transform(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: CLI11.hpp:3018
size_t get_require_subcommand_max() const
Get the required max subcommand value.
Definition: CLI11.hpp:5289
Transformer(T mapping, F filter_function)
Definition: CLI11.hpp:2139
void _validate() const
Definition: CLI11.hpp:5438
std::set< App * > exclude_subcommands_
this is a list of subcommands that are exclusionary to this one
Definition: CLI11.hpp:3790
void _merge_description(const Validator &val1, const Validator &val2, const std::string &merger)
Definition: CLI11.hpp:1708
std::set< Option * > get_excludes() const
The set of options excluded.
Definition: CLI11.hpp:3191
std::ostream & operator<<(std::ostream &in, const T &item)
output streaming for enumerations
Definition: CLI11.hpp:227
static ArgumentMismatch AtLeast(std::string name, int num)
Definition: CLI11.hpp:822
void _parse(std::vector< std::string > &args)
Internal parse function.
Definition: CLI11.hpp:5808
Option_group(std::string group_description, std::string group_name, App *parent)
Definition: CLI11.hpp:6325
Option * needs(Option *opt)
Sets required options.
Definition: CLI11.hpp:3056
IsMember(T &&set, filter_fn_t filter_fn_1, filter_fn_t filter_fn_2, Args &&... other)
You can pass in as many filter functions as you like, they nest (string only currently) ...
Definition: CLI11.hpp:2115
static BadNameString OneCharName(std::string name)
Definition: CLI11.hpp:690
#define CLI11_ERROR_SIMPLE(name)
Definition: CLI11.hpp:602
Option * set_help_all_flag(std::string help_name="", const std::string &help_description="")
Set a help all flag, replaced the existing one if present.
Definition: CLI11.hpp:4235
bool operator==(const Option &other) const
If options share any of the same names, they are equal (not counting positional)
Definition: CLI11.hpp:3378
const detail::ExistingFileValidator ExistingFile
Check for existing file (returns error message if check fails)
Definition: CLI11.hpp:1860
OptionDefaults * ignore_underscore(bool value=true)
Ignore underscores in the option name.
Definition: CLI11.hpp:2830
size_t empty() const
True if the option was not passed.
Definition: CLI11.hpp:2952
void run_callback()
Process the callback.
Definition: CLI11.hpp:3322
A copy of std::void_t from C++17 (helper for C++11 and C++14)
Definition: CLI11.hpp:921
Check to see if something is bool (fail check by default)
Definition: CLI11.hpp:936
Option * add_option(std::string option_name)
Add option with no description or variable assignment.
Definition: CLI11.hpp:4146
constexpr std::chrono::duration< Rep, Period > abs(std::chrono::duration< Rep, Period > d)
Definition: date.h:1201
Option * transform(Validator validator, std::string validator_name="")
Adds a transforming validator with a built in type name.
Definition: CLI11.hpp:3010
std::ostream & format_help(std::ostream &out, std::string name, std::string description, size_t wid)
Print a two part "help" string.
Definition: CLI11.hpp:365
OptionDefaults option_defaults_
The default values for options, customizable and changeable INHERITABLE.
Definition: CLI11.hpp:3748
std::vector< std::pair< std::string, T > > TransformPairs
definition of the default transformation object
Definition: CLI11.hpp:2122
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: CLI11.hpp:3262
CRTP * delimiter(char value='\0')
Allow in a configuration file.
Definition: CLI11.hpp:2803
CRTP * configurable(bool value=true)
Allow in a configuration file.
Definition: CLI11.hpp:2797
Option * add_complex(std::string option_name, T &variable, std::string option_description="", bool defaulted=false, std::string label="COMPLEX")
Add a complex number.
Definition: CLI11.hpp:4602
bool remove_needs(Option *opt)
Remove needs link from an option. Returns true if the option really was in the needs list...
Definition: CLI11.hpp:3078
std::vector< std::string > snames_
A list of the short names (-a) without the leading dashes.
Definition: CLI11.hpp:2856
static OptionAlreadyAdded Excludes(std::string name, std::string other)
Definition: CLI11.hpp:708
bool remove_excludes(Option *opt)
Remove needs link from an option. Returns true if the option really was in the needs list...
Definition: CLI11.hpp:3117
std::string & add_quotes_if_needed(std::string &str)
Add quotes if the string contains spaces.
Definition: CLI11.hpp:570
static App * get_fallthrough_parent(App *app)
Wrap the fallthrough parent function to make sure that is working correctly.
Definition: CLI11.hpp:6445
const App * get_parent() const
Get the parent of this subcommand (or nullptr if master app) (const version)
Definition: CLI11.hpp:5342
Option * ignore_underscore(bool value=true)
Definition: CLI11.hpp:3153
std::vector< std::pair< detail::Classifier, std::string > > missing_t
Definition: CLI11.hpp:3776
std::string get_description() const
Generate type description information for the Validator.
Definition: CLI11.hpp:1607
void _process_ini()
Read and process an ini file (main app only)
Definition: CLI11.hpp:5547
Construction errors (not in parsing)
Definition: CLI11.hpp:654
const std::string & get_footer() const
Get footer.
Definition: CLI11.hpp:5283
void clear()
Clear the parsed results (mostly for testing)
Definition: CLI11.hpp:2958
static RequiredError Option(size_t min_option, size_t max_option, size_t used, const std::string &option_list)
Definition: CLI11.hpp:788
static FileError Missing(std::string name)
Definition: CLI11.hpp:751
FormatterLambda(funct_t funct)
Create a FormatterLambda with a lambda function.
Definition: CLI11.hpp:2579
bool check_sname(std::string name) const
Requires "-" to be removed from string.
Definition: CLI11.hpp:3420
App * get_parent()
Get the parent of this subcommand (or nullptr if master app)
Definition: CLI11.hpp:5339
App * enabled_by_default(bool enable=true)
Definition: CLI11.hpp:3965
std::function< void()> callback_
This is a function that runs when complete. Great for subcommands. Can throw.
Definition: CLI11.hpp:3741
typename std::conditional< is_copyable_ptr< T >::value, typename std::pointer_traits< T >::element_type, T >::type type
Definition: CLI11.hpp:969
Thrown when an option already exists.
Definition: CLI11.hpp:701
Validate the argument is a number and greater than or equal to 0.
Definition: CLI11.hpp:1825
Thrown when counting a non-existent option.
Definition: CLI11.hpp:885
virtual std::string make_option_name(const Option *, bool) const
This is the name part of an option, Default: left column.
Definition: CLI11.hpp:6726
Option * ignore_case(bool value=true)
Definition: CLI11.hpp:3138
auto parse(const std::basic_string< CharT, Traits, Alloc > &format, Parsable &tp) -> decltype(from_stream(std::declval< std::basic_istream< CharT, Traits > &>(), format.c_str(), tp), parse_manip< Parsable, CharT, Traits, Alloc >
Definition: date.h:7239
static auto second(Q &&pair_value) -> decltype(std::get< 1 >(std::forward< Q >(pair_value)))
Get the second value (really just the underlying value)
Definition: CLI11.hpp:1008
std::string find_and_replace(std::string str, std::string from, std::string to)
Find and replace a substring with another substring.
Definition: CLI11.hpp:420
bool ignore_underscore_
If true, the program should ignore underscores INHERITABLE.
Definition: CLI11.hpp:3807
bool immediate_callback_
Definition: CLI11.hpp:3735
App * formatter_fn(std::function< std::string(const App *, std::string, AppFormatMode)> fmt)
Set the help formatter.
Definition: CLI11.hpp:4039
void remove_default_flag_values(std::string &flags)
Definition: CLI11.hpp:437
typename element_type< T >::type::value_type type
Definition: CLI11.hpp:974
std::string simple(const App *app, const Error &e)
Printout a clean, simple message on error (the default in CLI11 1.5+)
Definition: CLI11.hpp:6400
This can be specialized to override the type deduction for IsMember.
Definition: CLI11.hpp:956
size_t require_subcommand_max_
Max number of subcommands allowed (parsing stops after this number). 0 is unlimited INHERITABLE...
Definition: CLI11.hpp:3839
std::string get_flag_value(std::string name, std::string input_value) const
Definition: CLI11.hpp:3435
Translate named items to other or a value set.
Definition: CLI11.hpp:2125
bool _parse_subcommand(std::vector< std::string > &args)
Definition: CLI11.hpp:6066
int get_type_size() const
The number of arguments the option expects.
Definition: CLI11.hpp:3182
This class provides a converter for configuration files.
Definition: CLI11.hpp:1450
OptionDefaults * option_defaults()
Get the OptionDefault object, to set option defaults.
Definition: CLI11.hpp:4054
CRTP * join()
Set the multi option policy to take last.
Definition: CLI11.hpp:2790
This is a successful completion on parsing, supposed to exit.
Definition: CLI11.hpp:723
App * config_formatter(std::shared_ptr< Config > fmt)
Set the config formatter.
Definition: CLI11.hpp:4045
return os str()
auto search(const T &set, const V &val) -> std::pair< bool, decltype(std::begin(detail::smart_deref(set)))>
A search function.
Definition: CLI11.hpp:1991
std::vector< App * > get_subcommands(const std::function< bool(App *)> &filter)
Definition: CLI11.hpp:5064
std::string fix_newlines(std::string leader, std::string input)
Definition: CLI11.hpp:541
bool _valid_subcommand(const std::string &current, bool ignore_used=true) const
Check to see if a subcommand is valid. Give up immediately if subcommand max has been reached...
Definition: CLI11.hpp:5512
Option * default_function(const std::function< std::string()> &func)
Set a capture function for the default. Mostly used by App.
Definition: CLI11.hpp:3581
friend App
Definition: CLI11.hpp:2849
bool fallthrough_
Allow subcommand fallthrough, so that parent commands can collect commands after subcommand. INHERITABLE.
Definition: CLI11.hpp:3810
CheckedTransformer(T &&mapping, filter_fn_t filter_fn_1, filter_fn_t filter_fn_2, Args &&... other)
You can pass in as many filter functions as you like, they nest.
Definition: CLI11.hpp:2251
std::string join(const T &v, Callable func, std::string delim=",")
Simple function to join a string from processed elements.
Definition: CLI11.hpp:293
bool get_enabled_by_default() const
Get the status of disabled by default.
Definition: CLI11.hpp:5316
std::vector< std::pair< std::string, std::string > > get_default_flag_values(const std::string &str)
extract default flag values either {def} or starting with a !
Definition: CLI11.hpp:1336
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: CLI11.hpp:3482
App * allow_windows_style_options(bool value=true)
Allow windows style options, such as /opt. First matching short or long name used. Subcommands inherit value.
Definition: CLI11.hpp:4009
static ArgumentMismatch TypedAtLeast(std::string name, int num, std::string type)
Definition: CLI11.hpp:825
static ConversionError TooManyInputsFlag(std::string name)
Definition: CLI11.hpp:762
bool ignore_case_
If true, the program name is not case sensitive INHERITABLE.
Definition: CLI11.hpp:3804
const Option * get_option_no_throw(std::string option_name) const noexcept
Get an option by name (noexcept const version)
Definition: CLI11.hpp:5222
void _move_option(Option *opt, App *app)
function that could be used by subclasses of App to shift options around into subcommands ...
Definition: CLI11.hpp:6282
const detail::Number Number
Check for a number.
Definition: CLI11.hpp:1878
Option * add_option(std::string option_name, T &variable, std::string option_description="", bool defaulted=false)
Add option for non-vectors (duplicate copy needed without defaulted to avoid iostream << value) ...
Definition: CLI11.hpp:4110
OptionDefaults * multi_option_policy(MultiOptionPolicy value=MultiOptionPolicy::Throw)
Take the last argument if given multiple times.
Definition: CLI11.hpp:2818
std::vector< Option * > parse_order_
This is a list of pointers to options with the original parse order.
Definition: CLI11.hpp:3784
callback_t callback_
Options store a callback to do all the work.
Definition: CLI11.hpp:2921
size_t escape_detect(std::string &str, size_t offset)
Definition: CLI11.hpp:557
std::vector< ConfigItem > items
Definition: CLI11.hpp:1452
bool check_lname(std::string name) const
Requires "--" to be removed from string.
Definition: CLI11.hpp:3423
Option * add_result(std::vector< std::string > s)
Puts a result at the end.
Definition: CLI11.hpp:3489
Thrown on construction of a bad name.
Definition: CLI11.hpp:687
std::string group_
The group membership INHERITABLE.
Definition: CLI11.hpp:3848
bool disabled_
If set to true the subcommand is disabled and cannot be used, ignored for main app.
Definition: CLI11.hpp:3728
App(std::string app_description="", std::string app_name="")
Create a new program. Pass in the same arguments as main(), along with a help string.
Definition: CLI11.hpp:3906
std::enable_if< std::is_floating_point< T >::value, bool >::type checked_multiply(T &a, T b)
Performs a *= b; if it doesn&#39;t equal infinity. Returns false otherwise.
Definition: CLI11.hpp:2044
Bound(T min, T max)
Definition: CLI11.hpp:1913
bool got_subcommand(App *subcom) const
Check to see if given subcommand was selected.
Definition: CLI11.hpp:5080
std::string name_
The name for search purposes of the Validator.
Definition: CLI11.hpp:1560
void run_callback()
Internal function to run (App) callback, bottom up.
Definition: CLI11.hpp:5490
Validator operator!() const
Create a validator that fails when a given validator succeeds.
Definition: CLI11.hpp:1686
App * parent_
A pointer to the parent if this is a subcommand.
Definition: CLI11.hpp:3830
void _parse_config(std::vector< ConfigItem > &args)
Definition: CLI11.hpp:5857
void add_options(Option *opt, Args... args)
Add a bunch of options to the group.
Definition: CLI11.hpp:6342
static ConfigError NotConfigurable(std::string item)
Definition: CLI11.hpp:862
void _configure()
Definition: CLI11.hpp:5469
App * _get_fallthrough_parent()
Get the appropriate parent to fallthrough to which is the first one that has a name or the main app...
Definition: CLI11.hpp:6252
auto as_string(T &&v) -> decltype(std::forward< T >(v))
Definition: CLI11.hpp:272
Option * default_val(std::string val)
Set the default value string representation and evaluate into the bound value.
Definition: CLI11.hpp:3601
App * disabled_by_default(bool disable=true)
Set the subcommand to be disabled by default, so on clear(), at the start of each parse it is disable...
Definition: CLI11.hpp:3958
static ConfigError Extras(std::string item)
Definition: CLI11.hpp:861
Option * add_option(std::string option_name, std::vector< T > &variable, std::string option_description="", bool defaulted=false)
Add option for vectors.
Definition: CLI11.hpp:4160
auto smart_deref(T value) -> decltype(*value)
Definition: CLI11.hpp:1940
std::string config_to_str(bool default_also=false, bool write_description=false) const
Definition: CLI11.hpp:5146
bool get_allow_extras() const
Get the status of allow extras.
Definition: CLI11.hpp:5301
Anything that can error in Parse.
Definition: CLI11.hpp:716
App * fallthrough(bool value=true)
Definition: CLI11.hpp:4878
virtual std::string make_option_desc(const Option *) const
This is the description. Default: Right column, on new line if left column too large.
Definition: CLI11.hpp:6763
void _process_extras(std::vector< std::string > &args)
Definition: CLI11.hpp:5784
AsNumberWithUnit(std::map< std::string, Number > mapping, Options opts=DEFAULT, const std::string &unit_name="UNIT")
Definition: CLI11.hpp:2296
Option * add_flag(std::string flag_name)
Add a flag with no description or variable assignment.
Definition: CLI11.hpp:4279
std::shared_ptr< FormatterBase > formatter_
This is the formatter for help printing. Default provided. INHERITABLE (same pointer) ...
Definition: CLI11.hpp:3767
const detail::PositiveNumber PositiveNumber
Check for a positive number.
Definition: CLI11.hpp:1875
MultiOptionPolicy get_multi_option_policy() const
The status of the multi option policy.
Definition: CLI11.hpp:2771
Validator * get_validator(const std::string &validator_name="")
Get a named Validator.
Definition: CLI11.hpp:3044
const Option * get_config_ptr() const
Get a pointer to the config option. (const)
Definition: CLI11.hpp:5336
App * add_subcommand(std::string subcommand_name="", std::string subcommand_description="")
Add a subcommand. Inherits INHERITABLE and OptionDefaults, and help flag.
Definition: CLI11.hpp:4691
std::string operator()(const std::string &str) const
Definition: CLI11.hpp:1596
Option * add_flag_callback(std::string flag_name, std::function< void(void)> function, std::string flag_description="")
Add option for callback that is triggered with a true flag and takes no arguments.
Definition: CLI11.hpp:4350
size_t get_require_option_max() const
Get the required max option value.
Definition: CLI11.hpp:5295
const std::string & get_group() const
Get the group of this option.
Definition: CLI11.hpp:2747
std::function< std::string()> desc_function_
This is the description function, if empty the description_ will be used.
Definition: CLI11.hpp:1554
Option * add_mutable_set(std::string option_name, T &member, const std::set< T > &options, std::string option_description="")
Add set of options (No default, set can be changed afterwards - do not destroy the set) DEPRECATED...
Definition: CLI11.hpp:4406
translate named items to other or a value set
Definition: CLI11.hpp:2182
void parse(int argc, const char *const *argv)
Definition: CLI11.hpp:4918
std::string remove_underscore(std::string str)
remove underscores from a string
Definition: CLI11.hpp:414
virtual std::string make_option_opts(const Option *) const
This is the options part of the name, Default: combined into left column.
Definition: CLI11.hpp:6733
bool check_name(std::string name) const
Check a name. Requires "-" or "--" for short / long, supports positional name.
Definition: CLI11.hpp:3399
App * allow_extras(bool allow=true)
Remove the error when extras are left over on the command line.
Definition: CLI11.hpp:3940
Option * default_str(std::string val)
Set the default value string representation (does not change the contained value) ...
Definition: CLI11.hpp:3595
bool get_disable_flag_override() const
The status of configurable.
Definition: CLI11.hpp:2762
Thrown when the wrong number of arguments has been received.
Definition: CLI11.hpp:812
Option * check(Validator validator, std::string validator_name="")
Adds a Validator with a built in type name.
Definition: CLI11.hpp:2992
Thrown when conversion call back fails, such as when an int fails to coerce to a string.
Definition: CLI11.hpp:755
Range(T max)
Range of one value is 0 to value.
Definition: CLI11.hpp:1903
std::string name_
Subcommand name or program name (from parser if name is empty)
Definition: CLI11.hpp:3707
AppFormatMode
Definition: CLI11.hpp:2505
std::string name
This is the name.
Definition: CLI11.hpp:1436
static auto parse_subcommand(App *app, Args &&... args) -> typename std::result_of< decltype(&App::_parse_subcommand)(App, Args...)>::type
Wrap _parse_subcommand, perfectly forward arguments and return.
Definition: CLI11.hpp:6440
App * excludes(Option *opt)
Sets excluded options for the subcommand.
Definition: CLI11.hpp:5089
virtual std::string make_option_usage(const Option *opt) const
This is used to print the name on the USAGE line.
Definition: CLI11.hpp:6765
Option * get_option(std::string option_name)
Get an option by name (non-const version)
Definition: CLI11.hpp:5250
ExitCodes
Definition: CLI11.hpp:607
std::vector< std::string > split(const std::string &s, char delim)
Split a string by a delim.
Definition: CLI11.hpp:249
std::string & trim(std::string &str)
Trim whitespace from string.
Definition: CLI11.hpp:348
Option * type_name(std::string typeval)
Set a custom option typestring.
Definition: CLI11.hpp:3565
bool check_name(std::string name_to_check) const
Check the name, case insensitive and underscore insensitive if set.
Definition: CLI11.hpp:5351
static auto first(Q &&pair_value) -> decltype(std::forward< Q >(pair_value))
Get the first value (really just the underlying value)
Definition: CLI11.hpp:983
~FormatterLambda() noexcept override
Adding a destructor (mostly to make GCC 4.7 happy)
Definition: CLI11.hpp:2582
std::string config_name_
The name of the connected config file.
Definition: CLI11.hpp:3855
Produce a bounded range (factory). Min and max are inclusive.
Definition: CLI11.hpp:1907
std::vector< App * > get_subcommands() const
Definition: CLI11.hpp:5042
typename std::conditional< B, T, F >::type conditional_t
A copy of std::conditional_t from C++14 - same reasoning as enable_if_t, it does not hurt to redefine...
Definition: CLI11.hpp:927
T * add_option_group(std::string group_name, std::string group_description="")
creates an option group as part of the given app
Definition: CLI11.hpp:4677
Validator operator|(const Validator &other) const
Definition: CLI11.hpp:1664
static std::map< std::string, result_t > get_mapping(bool kb_is_1000)
Cache calculated mapping.
Definition: CLI11.hpp:2450
std::function< std::string(std::string)> filter_fn_t
Definition: CLI11.hpp:2057
Validator & description(std::string validator_desc)
Specify the type string.
Definition: CLI11.hpp:1602
std::string join(const T &v, std::string delim=",")
Simple function to join a string.
Definition: CLI11.hpp:277
std::shared_ptr< Config > config_formatter_
This is the formatter for help printing. Default provided. INHERITABLE (same pointer) ...
Definition: CLI11.hpp:3864
App * description(std::string app_description)
Set the description of the app.
Definition: CLI11.hpp:5180
const detail::ExistingPathValidator ExistingPath
Check for an existing path.
Definition: CLI11.hpp:1866
std::string ini_join(std::vector< std::string > args)
Comma separated join, adds quotes if needed.
Definition: CLI11.hpp:1409
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: CLI11.hpp:1028
std::string get_envname() const
The environment variable associated to this value.
Definition: CLI11.hpp:3185
std::vector< const App * > get_subcommands(const std::function< bool(const App *)> &filter) const
Definition: CLI11.hpp:5046
CheckedTransformer(T mapping)
direct map of std::string to std::string
Definition: CLI11.hpp:2192
const std::vector< Option * > & parse_order() const
This gets a vector of pointers with the original parse order.
Definition: CLI11.hpp:5380
Thrown when a required option is missing.
Definition: CLI11.hpp:778
App * excludes(App *app)
Sets excluded subcommands for the subcommand.
Definition: CLI11.hpp:5098
void results(T &output) const
get the results as a particular type
Definition: CLI11.hpp:3503
static auto parse_arg(App *app, Args &&... args) -> typename std::result_of< decltype(&App::_parse_arg)(App, Args...)>::type
Wrap _parse_short, perfectly forward arguments and return.
Definition: CLI11.hpp:6433
void _trigger_pre_parse(size_t remaining_args)
Trigger the pre_parse callback if needed.
Definition: CLI11.hpp:6233
void results(std::vector< T > &output) const
get the results as a vector of a particular type
Definition: CLI11.hpp:3530
CLI::App_p get_subcommand_ptr(int index=0) const
Get an owning pointer to subcommand by index.
Definition: CLI11.hpp:4772
Option * add_flag(std::string flag_name, T &flag_description)
Definition: CLI11.hpp:4287
std::vector< std::string > inputs
Listing of inputs.
Definition: CLI11.hpp:1439
std::function< void(size_t)> pre_parse_callback_
This is a function that runs prior to the start of parsing.
Definition: CLI11.hpp:3738
int get_exit_code() const
Definition: CLI11.hpp:641
static ConversionError TrueFalse(std::string name)
Definition: CLI11.hpp:765
Option * expected(int value)
Set the number of expected arguments (Flags don&#39;t use this)
Definition: CLI11.hpp:2965
std::vector< Option_p > options_
The list of options, stored locally.
Definition: CLI11.hpp:3751
Thrown when validation of results fails.
Definition: CLI11.hpp:771