1 #pragma once
2 
3 // CLI11: Version 1.6.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.6.0
9 //
10 // From LICENSE:
11 //
12 // CLI11 1.5 Copyright (c) 2017-2018 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 <deque>
43 #include <exception>
44 #include <fstream>
45 #include <functional>
46 #include <iomanip>
47 #include <iostream>
48 #include <istream>
49 #include <iterator>
50 #include <locale>
51 #include <map>
52 #include <memory>
53 #include <numeric>
54 #include <set>
55 #include <sstream>
56 #include <stdexcept>
57 #include <string>
58 #include <sys/stat.h>
59 #include <sys/types.h>
60 #include <tuple>
61 #include <type_traits>
62 #include <utility>
63 #include <vector>
64 
65 
66 // Verbatim copy from CLI/Version.hpp:
67 
68 
69 #define CLI11_VERSION_MAJOR 1
70 #define CLI11_VERSION_MINOR 6
71 #define CLI11_VERSION_PATCH 0
72 #define CLI11_VERSION "1.6.0"
73 
74 
75 
76 
77 // Verbatim copy from CLI/Macros.hpp:
78 
79 
80 // The following version macro is very similar to the one in PyBind11
81 #if !(defined(_MSC_VER) && __cplusplus == 199711L) && !defined(__INTEL_COMPILER)
82 #if __cplusplus >= 201402L
83 #define CLI11_CPP14
84 #if __cplusplus >= 201703L
85 #define CLI11_CPP17
86 #if __cplusplus > 201703L
87 #define CLI11_CPP20
88 #endif
89 #endif
90 #endif
91 #elif defined(_MSC_VER) && __cplusplus == 199711L
92 // MSVC sets _MSVC_LANG rather than __cplusplus (supposedly until the standard is fully implemented)
93 // Unless you use the /Zc:__cplusplus flag on Visual Studio 2017 15.7 Preview 3 or newer
94 #if _MSVC_LANG >= 201402L
95 #define CLI11_CPP14
96 #if _MSVC_LANG > 201402L && _MSC_VER >= 1910
97 #define CLI11_CPP17
98 #if __MSVC_LANG > 201703L && _MSC_VER >= 1910
99 #define CLI11_CPP20
100 #endif
101 #endif
102 #endif
103 #endif
104 
105 #if defined(CLI11_CPP14)
106 #define CLI11_DEPRECATED(reason) [[deprecated(reason)]]
107 #elif defined(_MSC_VER)
108 #define CLI11_DEPRECATED(reason) __declspec(deprecated(reason))
109 #else
110 #define CLI11_DEPRECATED(reason) __attribute__((deprecated(reason)))
111 #endif
112 
113 
114 
115 
116 // Verbatim copy from CLI/Optional.hpp:
117 
118 #ifdef __has_include
119 
120 #if defined(CLI11_CPP17) && __has_include(<optional>) && \
121      !defined(CLI11_STD_OPTIONAL)
122 #define CLI11_STD_OPTIONAL 1
123 #endif
124 
125 #if defined(CLI11_CPP14) && __has_include(<experimental/optional>) && \
126     !defined(CLI11_EXPERIMENTAL_OPTIONAL)
127 #define CLI11_EXPERIMENTAL_OPTIONAL 1
128 #endif
129 
130 #if __has_include(<boost/optional.hpp>) && !defined(CLI11_BOOST_OPTIONAL)
131 #include <boost/version.hpp>
132 #if BOOST_VERSION >= 105800
133 #define CLI11_BOOST_OPTIONAL 1
134 #endif
135 #endif
136 
137 #endif
138 
139 #if CLI11_STD_OPTIONAL
140 #include <optional>
141 #endif
142 #if CLI11_EXPERIMENTAL_OPTIONAL
143 #include <experimental/optional>
144 #endif
145 #if CLI11_BOOST_OPTIONAL
146 #include <boost/optional.hpp>
147 #endif
148 
149 
150 // From CLI/Version.hpp:
151 
152 
153 
154 // From CLI/Macros.hpp:
155 
156 
157 
158 // From CLI/Optional.hpp:
159 
160 namespace CLI {
161 
162 #if CLI11_STD_OPTIONAL
operator >>(std::istream & in,std::optional<T> & val)163 template <typename T> std::istream &operator>>(std::istream &in, std::optional<T> &val) {
164     T v;
165     in >> v;
166     val = v;
167     return in;
168 }
169 #endif
170 
171 #if CLI11_EXPERIMENTAL_OPTIONAL
operator >>(std::istream & in,std::experimental::optional<T> & val)172 template <typename T> std::istream &operator>>(std::istream &in, std::experimental::optional<T> &val) {
173     T v;
174     in >> v;
175     val = v;
176     return in;
177 }
178 #endif
179 
180 #if CLI11_BOOST_OPTIONAL
operator >>(std::istream & in,boost::optional<T> & val)181 template <typename T> std::istream &operator>>(std::istream &in, boost::optional<T> &val) {
182     T v;
183     in >> v;
184     val = v;
185     return in;
186 }
187 #endif
188 
189 // Export the best optional to the CLI namespace
190 #if CLI11_STD_OPTIONAL
191 using std::optional;
192 #elif CLI11_EXPERIMENTAL_OPTIONAL
193 using std::experimental::optional;
194 #elif CLI11_BOOST_OPTIONAL
195 using boost::optional;
196 #endif
197 
198 // This is true if any optional is found
199 #if CLI11_STD_OPTIONAL || CLI11_EXPERIMENTAL_OPTIONAL || CLI11_BOOST_OPTIONAL
200 #define CLI11_OPTIONAL 1
201 #endif
202 
203 } // namespace CLI
204 
205 // From CLI/StringTools.hpp:
206 
207 namespace CLI {
208 namespace detail {
209 
210 // Based on http://stackoverflow.com/questions/236129/split-a-string-in-c
211 /// Split a string by a delim
split(const std::string & s,char delim)212 inline std::vector<std::string> split(const std::string &s, char delim) {
213     std::vector<std::string> elems;
214     // Check to see if empty string, give consistent result
215     if(s.empty())
216         elems.emplace_back("");
217     else {
218         std::stringstream ss;
219         ss.str(s);
220         std::string item;
221         while(std::getline(ss, item, delim)) {
222             elems.push_back(item);
223         }
224     }
225     return elems;
226 }
227 
228 /// Simple function to join a string
join(const T & v,std::string delim=",")229 template <typename T> std::string join(const T &v, std::string delim = ",") {
230     std::ostringstream s;
231     size_t start = 0;
232     for(const auto &i : v) {
233         if(start++ > 0)
234             s << delim;
235         s << i;
236     }
237     return s.str();
238 }
239 
240 /// Join a string in reverse order
rjoin(const T & v,std::string delim=",")241 template <typename T> std::string rjoin(const T &v, std::string delim = ",") {
242     std::ostringstream s;
243     for(size_t start = 0; start < v.size(); start++) {
244         if(start > 0)
245             s << delim;
246         s << v[v.size() - start - 1];
247     }
248     return s.str();
249 }
250 
251 // Based roughly on http://stackoverflow.com/questions/25829143/c-trim-whitespace-from-a-string
252 
253 /// Trim whitespace from left of string
ltrim(std::string & str)254 inline std::string &ltrim(std::string &str) {
255     auto it = std::find_if(str.begin(), str.end(), [](char ch) { return !std::isspace<char>(ch, std::locale()); });
256     str.erase(str.begin(), it);
257     return str;
258 }
259 
260 /// Trim anything from left of string
ltrim(std::string & str,const std::string & filter)261 inline std::string &ltrim(std::string &str, const std::string &filter) {
262     auto it = std::find_if(str.begin(), str.end(), [&filter](char ch) { return filter.find(ch) == std::string::npos; });
263     str.erase(str.begin(), it);
264     return str;
265 }
266 
267 /// Trim whitespace from right of string
rtrim(std::string & str)268 inline std::string &rtrim(std::string &str) {
269     auto it = std::find_if(str.rbegin(), str.rend(), [](char ch) { return !std::isspace<char>(ch, std::locale()); });
270     str.erase(it.base(), str.end());
271     return str;
272 }
273 
274 /// Trim anything from right of string
rtrim(std::string & str,const std::string & filter)275 inline std::string &rtrim(std::string &str, const std::string &filter) {
276     auto it =
277         std::find_if(str.rbegin(), str.rend(), [&filter](char ch) { return filter.find(ch) == std::string::npos; });
278     str.erase(it.base(), str.end());
279     return str;
280 }
281 
282 /// Trim whitespace from string
trim(std::string & str)283 inline std::string &trim(std::string &str) { return ltrim(rtrim(str)); }
284 
285 /// Trim anything from string
trim(std::string & str,const std::string filter)286 inline std::string &trim(std::string &str, const std::string filter) { return ltrim(rtrim(str, filter), filter); }
287 
288 /// Make a copy of the string and then trim it
trim_copy(const std::string & str)289 inline std::string trim_copy(const std::string &str) {
290     std::string s = str;
291     return trim(s);
292 }
293 
294 /// Make a copy of the string and then trim it, any filter string can be used (any char in string is filtered)
trim_copy(const std::string & str,const std::string & filter)295 inline std::string trim_copy(const std::string &str, const std::string &filter) {
296     std::string s = str;
297     return trim(s, filter);
298 }
299 /// Print a two part "help" string
format_help(std::ostream & out,std::string name,std::string description,size_t wid)300 inline std::ostream &format_help(std::ostream &out, std::string name, std::string description, size_t wid) {
301     name = "  " + name;
302     out << std::setw(static_cast<int>(wid)) << std::left << name;
303     if(!description.empty()) {
304         if(name.length() >= wid)
305             out << "\n" << std::setw(static_cast<int>(wid)) << "";
306         out << description;
307     }
308     out << "\n";
309     return out;
310 }
311 
312 /// Verify the first character of an option
valid_first_char(T c)313 template <typename T> bool valid_first_char(T c) { return std::isalpha(c, std::locale()) || c == '_'; }
314 
315 /// Verify following characters of an option
valid_later_char(T c)316 template <typename T> bool valid_later_char(T c) {
317     return std::isalnum(c, std::locale()) || c == '_' || c == '.' || c == '-';
318 }
319 
320 /// Verify an option name
valid_name_string(const std::string & str)321 inline bool valid_name_string(const std::string &str) {
322     if(str.empty() || !valid_first_char(str[0]))
323         return false;
324     for(auto c : str.substr(1))
325         if(!valid_later_char(c))
326             return false;
327     return true;
328 }
329 
330 /// Return a lower case version of a string
to_lower(std::string str)331 inline std::string to_lower(std::string str) {
332     std::transform(std::begin(str), std::end(str), std::begin(str), [](const std::string::value_type &x) {
333         return std::tolower(x, std::locale());
334     });
335     return str;
336 }
337 
338 /// Split a string '"one two" "three"' into 'one two', 'three'
split_up(std::string str)339 inline std::vector<std::string> split_up(std::string str) {
340 
341     std::vector<char> delims = {'\'', '\"'};
342     auto find_ws = [](char ch) { return std::isspace<char>(ch, std::locale()); };
343     trim(str);
344 
345     std::vector<std::string> output;
346 
347     while(!str.empty()) {
348         if(str[0] == '\'') {
349             auto end = str.find('\'', 1);
350             if(end != std::string::npos) {
351                 output.push_back(str.substr(1, end - 1));
352                 str = str.substr(end + 1);
353             } else {
354                 output.push_back(str.substr(1));
355                 str = "";
356             }
357         } else if(str[0] == '\"') {
358             auto end = str.find('\"', 1);
359             if(end != std::string::npos) {
360                 output.push_back(str.substr(1, end - 1));
361                 str = str.substr(end + 1);
362             } else {
363                 output.push_back(str.substr(1));
364                 str = "";
365             }
366 
367         } else {
368             auto it = std::find_if(std::begin(str), std::end(str), find_ws);
369             if(it != std::end(str)) {
370                 std::string value = std::string(str.begin(), it);
371                 output.push_back(value);
372                 str = std::string(it, str.end());
373             } else {
374                 output.push_back(str);
375                 str = "";
376             }
377         }
378         trim(str);
379     }
380 
381     return output;
382 }
383 
384 /// Add a leader to the beginning of all new lines (nothing is added
385 /// at the start of the first line). `"; "` would be for ini files
386 ///
387 /// Can't use Regex, or this would be a subs.
fix_newlines(std::string leader,std::string input)388 inline std::string fix_newlines(std::string leader, std::string input) {
389     std::string::size_type n = 0;
390     while(n != std::string::npos && n < input.size()) {
391         n = input.find('\n', n);
392         if(n != std::string::npos) {
393             input = input.substr(0, n + 1) + leader + input.substr(n + 1);
394             n += leader.size();
395         }
396     }
397     return input;
398 }
399 
400 } // namespace detail
401 } // namespace CLI
402 
403 // From CLI/Error.hpp:
404 
405 namespace CLI {
406 
407 // Use one of these on all error classes.
408 // These are temporary and are undef'd at the end of this file.
409 #define CLI11_ERROR_DEF(parent, name)                                                                                  \
410   protected:                                                                                                           \
411     name(std::string name, std::string msg, int exit_code) : parent(std::move(name), std::move(msg), exit_code) {}     \
412     name(std::string name, std::string msg, ExitCodes exit_code)                                                       \
413         : parent(std::move(name), std::move(msg), exit_code) {}                                                        \
414                                                                                                                        \
415   public:                                                                                                              \
416     name(std::string msg, ExitCodes exit_code) : parent(#name, std::move(msg), exit_code) {}                           \
417     name(std::string msg, int exit_code) : parent(#name, std::move(msg), exit_code) {}
418 
419 // This is added after the one above if a class is used directly and builds its own message
420 #define CLI11_ERROR_SIMPLE(name)                                                                                       \
421     explicit name(std::string msg) : name(#name, msg, ExitCodes::name) {}
422 
423 /// These codes are part of every error in CLI. They can be obtained from e using e.exit_code or as a quick shortcut,
424 /// int values from e.get_error_code().
425 enum class ExitCodes {
426     Success = 0,
427     IncorrectConstruction = 100,
428     BadNameString,
429     OptionAlreadyAdded,
430     FileError,
431     ConversionError,
432     ValidationError,
433     RequiredError,
434     RequiresError,
435     ExcludesError,
436     ExtrasError,
437     ConfigError,
438     InvalidError,
439     HorribleError,
440     OptionNotFound,
441     ArgumentMismatch,
442     BaseClass = 127
443 };
444 
445 // Error definitions
446 
447 /// @defgroup error_group Errors
448 /// @brief Errors thrown by CLI11
449 ///
450 /// These are the errors that can be thrown. Some of them, like CLI::Success, are not really errors.
451 /// @{
452 
453 /// All errors derive from this one
454 class Error : public std::runtime_error {
455     int exit_code;
456     std::string name{"Error"};
457 
458   public:
get_exit_code() const459     int get_exit_code() const { return exit_code; }
460 
get_name() const461     std::string get_name() const { return name; }
462 
Error(std::string name,std::string msg,int exit_code=static_cast<int> (ExitCodes::BaseClass))463     Error(std::string name, std::string msg, int exit_code = static_cast<int>(ExitCodes::BaseClass))
464         : runtime_error(msg), exit_code(exit_code), name(std::move(name)) {}
465 
Error(std::string name,std::string msg,ExitCodes exit_code)466     Error(std::string name, std::string msg, ExitCodes exit_code) : Error(name, msg, static_cast<int>(exit_code)) {}
467 };
468 
469 // Note: Using Error::Error constructors does not work on GCC 4.7
470 
471 /// Construction errors (not in parsing)
472 class ConstructionError : public Error {
473     CLI11_ERROR_DEF(Error, ConstructionError)
474 };
475 
476 /// Thrown when an option is set to conflicting values (non-vector and multi args, for example)
477 class IncorrectConstruction : public ConstructionError {
CLI11_ERROR_DEF(ConstructionError,IncorrectConstruction)478     CLI11_ERROR_DEF(ConstructionError, IncorrectConstruction)
479     CLI11_ERROR_SIMPLE(IncorrectConstruction)
480     static IncorrectConstruction PositionalFlag(std::string name) {
481         return IncorrectConstruction(name + ": Flags cannot be positional");
482     }
Set0Opt(std::string name)483     static IncorrectConstruction Set0Opt(std::string name) {
484         return IncorrectConstruction(name + ": Cannot set 0 expected, use a flag instead");
485     }
SetFlag(std::string name)486     static IncorrectConstruction SetFlag(std::string name) {
487         return IncorrectConstruction(name + ": Cannot set an expected number for flags");
488     }
ChangeNotVector(std::string name)489     static IncorrectConstruction ChangeNotVector(std::string name) {
490         return IncorrectConstruction(name + ": You can only change the expected arguments for vectors");
491     }
AfterMultiOpt(std::string name)492     static IncorrectConstruction AfterMultiOpt(std::string name) {
493         return IncorrectConstruction(
494             name + ": You can't change expected arguments after you've changed the multi option policy!");
495     }
MissingOption(std::string name)496     static IncorrectConstruction MissingOption(std::string name) {
497         return IncorrectConstruction("Option " + name + " is not defined");
498     }
MultiOptionPolicy(std::string name)499     static IncorrectConstruction MultiOptionPolicy(std::string name) {
500         return IncorrectConstruction(name + ": multi_option_policy only works for flags and exact value options");
501     }
502 };
503 
504 /// Thrown on construction of a bad name
505 class BadNameString : public ConstructionError {
CLI11_ERROR_DEF(ConstructionError,BadNameString)506     CLI11_ERROR_DEF(ConstructionError, BadNameString)
507     CLI11_ERROR_SIMPLE(BadNameString)
508     static BadNameString OneCharName(std::string name) { return BadNameString("Invalid one char name: " + name); }
BadLongName(std::string name)509     static BadNameString BadLongName(std::string name) { return BadNameString("Bad long name: " + name); }
DashesOnly(std::string name)510     static BadNameString DashesOnly(std::string name) {
511         return BadNameString("Must have a name, not just dashes: " + name);
512     }
MultiPositionalNames(std::string name)513     static BadNameString MultiPositionalNames(std::string name) {
514         return BadNameString("Only one positional name allowed, remove: " + name);
515     }
516 };
517 
518 /// Thrown when an option already exists
519 class OptionAlreadyAdded : public ConstructionError {
CLI11_ERROR_DEF(ConstructionError,OptionAlreadyAdded)520     CLI11_ERROR_DEF(ConstructionError, OptionAlreadyAdded)
521     explicit OptionAlreadyAdded(std::string name)
522         : OptionAlreadyAdded(name + " is already added", ExitCodes::OptionAlreadyAdded) {}
Requires(std::string name,std::string other)523     static OptionAlreadyAdded Requires(std::string name, std::string other) {
524         return OptionAlreadyAdded(name + " requires " + other, ExitCodes::OptionAlreadyAdded);
525     }
Excludes(std::string name,std::string other)526     static OptionAlreadyAdded Excludes(std::string name, std::string other) {
527         return OptionAlreadyAdded(name + " excludes " + other, ExitCodes::OptionAlreadyAdded);
528     }
529 };
530 
531 // Parsing errors
532 
533 /// Anything that can error in Parse
534 class ParseError : public Error {
535     CLI11_ERROR_DEF(Error, ParseError)
536 };
537 
538 // Not really "errors"
539 
540 /// This is a successful completion on parsing, supposed to exit
541 class Success : public ParseError {
CLI11_ERROR_DEF(ParseError,Success)542     CLI11_ERROR_DEF(ParseError, Success)
543     Success() : Success("Successfully completed, should be caught and quit", ExitCodes::Success) {}
544 };
545 
546 /// -h or --help on command line
547 class CallForHelp : public ParseError {
CLI11_ERROR_DEF(ParseError,CallForHelp)548     CLI11_ERROR_DEF(ParseError, CallForHelp)
549     CallForHelp() : CallForHelp("This should be caught in your main function, see examples", ExitCodes::Success) {}
550 };
551 
552 /// Usually somethign like --help-all on command line
553 class CallForAllHelp : public ParseError {
CLI11_ERROR_DEF(ParseError,CallForAllHelp)554     CLI11_ERROR_DEF(ParseError, CallForAllHelp)
555     CallForAllHelp()
556         : CallForAllHelp("This should be caught in your main function, see examples", ExitCodes::Success) {}
557 };
558 
559 /// Does not output a diagnostic in CLI11_PARSE, but allows to return from main() with a specific error code.
560 class RuntimeError : public ParseError {
CLI11_ERROR_DEF(ParseError,RuntimeError)561     CLI11_ERROR_DEF(ParseError, RuntimeError)
562     explicit RuntimeError(int exit_code = 1) : RuntimeError("Runtime error", exit_code) {}
563 };
564 
565 /// Thrown when parsing an INI file and it is missing
566 class FileError : public ParseError {
CLI11_ERROR_DEF(ParseError,FileError)567     CLI11_ERROR_DEF(ParseError, FileError)
568     CLI11_ERROR_SIMPLE(FileError)
569     static FileError Missing(std::string name) { return FileError(name + " was not readable (missing?)"); }
570 };
571 
572 /// Thrown when conversion call back fails, such as when an int fails to coerce to a string
573 class ConversionError : public ParseError {
CLI11_ERROR_DEF(ParseError,ConversionError)574     CLI11_ERROR_DEF(ParseError, ConversionError)
575     CLI11_ERROR_SIMPLE(ConversionError)
576     ConversionError(std::string member, std::string name)
577         : ConversionError("The value " + member + " is not an allowed value for " + name) {}
ConversionError(std::string name,std::vector<std::string> results)578     ConversionError(std::string name, std::vector<std::string> results)
579         : ConversionError("Could not convert: " + name + " = " + detail::join(results)) {}
TooManyInputsFlag(std::string name)580     static ConversionError TooManyInputsFlag(std::string name) {
581         return ConversionError(name + ": too many inputs for a flag");
582     }
TrueFalse(std::string name)583     static ConversionError TrueFalse(std::string name) {
584         return ConversionError(name + ": Should be true/false or a number");
585     }
586 };
587 
588 /// Thrown when validation of results fails
589 class ValidationError : public ParseError {
CLI11_ERROR_DEF(ParseError,ValidationError)590     CLI11_ERROR_DEF(ParseError, ValidationError)
591     CLI11_ERROR_SIMPLE(ValidationError)
592     explicit ValidationError(std::string name, std::string msg) : ValidationError(name + ": " + msg) {}
593 };
594 
595 /// Thrown when a required option is missing
596 class RequiredError : public ParseError {
CLI11_ERROR_DEF(ParseError,RequiredError)597     CLI11_ERROR_DEF(ParseError, RequiredError)
598     explicit RequiredError(std::string name) : RequiredError(name + " is required", ExitCodes::RequiredError) {}
Subcommand(size_t min_subcom)599     static RequiredError Subcommand(size_t min_subcom) {
600         if(min_subcom == 1)
601             return RequiredError("A subcommand");
602         else
603             return RequiredError("Requires at least " + std::to_string(min_subcom) + " subcommands",
604                                  ExitCodes::RequiredError);
605     }
606 };
607 
608 /// Thrown when the wrong number of arguments has been received
609 class ArgumentMismatch : public ParseError {
CLI11_ERROR_DEF(ParseError,ArgumentMismatch)610     CLI11_ERROR_DEF(ParseError, ArgumentMismatch)
611     CLI11_ERROR_SIMPLE(ArgumentMismatch)
612     ArgumentMismatch(std::string name, int expected, size_t recieved)
613         : ArgumentMismatch(expected > 0 ? ("Expected exactly " + std::to_string(expected) + " arguments to " + name +
614                                            ", got " + std::to_string(recieved))
615                                         : ("Expected at least " + std::to_string(-expected) + " arguments to " + name +
616                                            ", got " + std::to_string(recieved)),
617                            ExitCodes::ArgumentMismatch) {}
618 
AtLeast(std::string name,int num)619     static ArgumentMismatch AtLeast(std::string name, int num) {
620         return ArgumentMismatch(name + ": At least " + std::to_string(num) + " required");
621     }
TypedAtLeast(std::string name,int num,std::string type)622     static ArgumentMismatch TypedAtLeast(std::string name, int num, std::string type) {
623         return ArgumentMismatch(name + ": " + std::to_string(num) + " required " + type + " missing");
624     }
625 };
626 
627 /// Thrown when a requires option is missing
628 class RequiresError : public ParseError {
CLI11_ERROR_DEF(ParseError,RequiresError)629     CLI11_ERROR_DEF(ParseError, RequiresError)
630     RequiresError(std::string curname, std::string subname)
631         : RequiresError(curname + " requires " + subname, ExitCodes::RequiresError) {}
632 };
633 
634 /// Thrown when an excludes option is present
635 class ExcludesError : public ParseError {
CLI11_ERROR_DEF(ParseError,ExcludesError)636     CLI11_ERROR_DEF(ParseError, ExcludesError)
637     ExcludesError(std::string curname, std::string subname)
638         : ExcludesError(curname + " excludes " + subname, ExitCodes::ExcludesError) {}
639 };
640 
641 /// Thrown when too many positionals or options are found
642 class ExtrasError : public ParseError {
CLI11_ERROR_DEF(ParseError,ExtrasError)643     CLI11_ERROR_DEF(ParseError, ExtrasError)
644     explicit ExtrasError(std::vector<std::string> args)
645         : ExtrasError((args.size() > 1 ? "The following arguments were not expected: "
646                                        : "The following argument was not expected: ") +
647                           detail::rjoin(args, " "),
648                       ExitCodes::ExtrasError) {}
649 };
650 
651 /// Thrown when extra values are found in an INI file
652 class ConfigError : public ParseError {
CLI11_ERROR_DEF(ParseError,ConfigError)653     CLI11_ERROR_DEF(ParseError, ConfigError)
654     CLI11_ERROR_SIMPLE(ConfigError)
655     static ConfigError Extras(std::string item) { return ConfigError("INI was not able to parse " + item); }
NotConfigurable(std::string item)656     static ConfigError NotConfigurable(std::string item) {
657         return ConfigError(item + ": This option is not allowed in a configuration file");
658     }
659 };
660 
661 /// Thrown when validation fails before parsing
662 class InvalidError : public ParseError {
CLI11_ERROR_DEF(ParseError,InvalidError)663     CLI11_ERROR_DEF(ParseError, InvalidError)
664     explicit InvalidError(std::string name)
665         : InvalidError(name + ": Too many positional arguments with unlimited expected args", ExitCodes::InvalidError) {
666     }
667 };
668 
669 /// This is just a safety check to verify selection and parsing match - you should not ever see it
670 /// Strings are directly added to this error, but again, it should never be seen.
671 class HorribleError : public ParseError {
672     CLI11_ERROR_DEF(ParseError, HorribleError)
673     CLI11_ERROR_SIMPLE(HorribleError)
674 };
675 
676 // After parsing
677 
678 /// Thrown when counting a non-existent option
679 class OptionNotFound : public Error {
CLI11_ERROR_DEF(Error,OptionNotFound)680     CLI11_ERROR_DEF(Error, OptionNotFound)
681     explicit OptionNotFound(std::string name) : OptionNotFound(name + " not found", ExitCodes::OptionNotFound) {}
682 };
683 
684 #undef CLI11_ERROR_DEF
685 #undef CLI11_ERROR_SIMPLE
686 
687 /// @}
688 
689 } // namespace CLI
690 
691 // From CLI/TypeTools.hpp:
692 
693 namespace CLI {
694 
695 // Type tools
696 
697 // We could check to see if C++14 is being used, but it does not hurt to redefine this
698 // (even Google does this: https://github.com/google/skia/blob/master/include/private/SkTLogic.h)
699 // It is not in the std namespace anyway, so no harm done.
700 
701 template <bool B, class T = void> using enable_if_t = typename std::enable_if<B, T>::type;
702 
703 template <typename T> struct is_vector { static const bool value = false; };
704 
705 template <class T, class A> struct is_vector<std::vector<T, A>> { static bool const value = true; };
706 
707 template <typename T> struct is_bool { static const bool value = false; };
708 
709 template <> struct is_bool<bool> { static bool const value = true; };
710 
711 namespace detail {
712 // Based generally on https://rmf.io/cxx11/almost-static-if
713 /// Simple empty scoped class
714 enum class enabler {};
715 
716 /// An instance to use in EnableIf
717 constexpr enabler dummy = {};
718 
719 // Type name print
720 
721 /// Was going to be based on
722 ///  http://stackoverflow.com/questions/1055452/c-get-name-of-type-in-template
723 /// But this is cleaner and works better in this case
724 
725 template <typename T,
726           enable_if_t<std::is_integral<T>::value && std::is_signed<T>::value, detail::enabler> = detail::dummy>
type_name()727 constexpr const char *type_name() {
728     return "INT";
729 }
730 
731 template <typename T,
732           enable_if_t<std::is_integral<T>::value && std::is_unsigned<T>::value, detail::enabler> = detail::dummy>
type_name()733 constexpr const char *type_name() {
734     return "UINT";
735 }
736 
737 template <typename T, enable_if_t<std::is_floating_point<T>::value, detail::enabler> = detail::dummy>
type_name()738 constexpr const char *type_name() {
739     return "FLOAT";
740 }
741 
742 /// This one should not be used, since vector types print the internal type
743 template <typename T, enable_if_t<is_vector<T>::value, detail::enabler> = detail::dummy>
type_name()744 constexpr const char *type_name() {
745     return "VECTOR";
746 }
747 
748 template <typename T,
749           enable_if_t<!std::is_floating_point<T>::value && !std::is_integral<T>::value && !is_vector<T>::value,
750                       detail::enabler> = detail::dummy>
type_name()751 constexpr const char *type_name() {
752     return "TEXT";
753 }
754 
755 // Lexical cast
756 
757 /// Signed integers / enums
758 template <typename T,
759           enable_if_t<(std::is_integral<T>::value && std::is_signed<T>::value), detail::enabler> = detail::dummy>
lexical_cast(std::string input,T & output)760 bool lexical_cast(std::string input, T &output) {
761     try {
762         size_t n = 0;
763         long long output_ll = std::stoll(input, &n, 0);
764         output = static_cast<T>(output_ll);
765         return n == input.size() && static_cast<long long>(output) == output_ll;
766     } catch(const std::invalid_argument &) {
767         return false;
768     } catch(const std::out_of_range &) {
769         return false;
770     }
771 }
772 
773 /// Unsigned integers
774 template <typename T,
775           enable_if_t<std::is_integral<T>::value && std::is_unsigned<T>::value, detail::enabler> = detail::dummy>
lexical_cast(std::string input,T & output)776 bool lexical_cast(std::string input, T &output) {
777     if(!input.empty() && input.front() == '-')
778         return false; // std::stoull happily converts negative values to junk without any errors.
779 
780     try {
781         size_t n = 0;
782         unsigned long long output_ll = std::stoull(input, &n, 0);
783         output = static_cast<T>(output_ll);
784         return n == input.size() && static_cast<unsigned long long>(output) == output_ll;
785     } catch(const std::invalid_argument &) {
786         return false;
787     } catch(const std::out_of_range &) {
788         return false;
789     }
790 }
791 
792 /// Floats
793 template <typename T, enable_if_t<std::is_floating_point<T>::value, detail::enabler> = detail::dummy>
lexical_cast(std::string input,T & output)794 bool lexical_cast(std::string input, T &output) {
795     try {
796         size_t n = 0;
797         output = static_cast<T>(std::stold(input, &n));
798         return n == input.size();
799     } catch(const std::invalid_argument &) {
800         return false;
801     } catch(const std::out_of_range &) {
802         return false;
803     }
804 }
805 
806 /// String and similar
807 template <typename T,
808           enable_if_t<!std::is_floating_point<T>::value && !std::is_integral<T>::value &&
809                           std::is_assignable<T &, std::string>::value,
810                       detail::enabler> = detail::dummy>
lexical_cast(std::string input,T & output)811 bool lexical_cast(std::string input, T &output) {
812     output = input;
813     return true;
814 }
815 
816 /// Non-string parsable
817 template <typename T,
818           enable_if_t<!std::is_floating_point<T>::value && !std::is_integral<T>::value &&
819                           !std::is_assignable<T &, std::string>::value,
820                       detail::enabler> = detail::dummy>
lexical_cast(std::string input,T & output)821 bool lexical_cast(std::string input, T &output) {
822     std::istringstream is;
823 
824     is.str(input);
825     is >> output;
826     return !is.fail() && !is.rdbuf()->in_avail();
827 }
828 
829 } // namespace detail
830 } // namespace CLI
831 
832 // From CLI/Split.hpp:
833 
834 namespace CLI {
835 namespace detail {
836 
837 // Returns false if not a short option. Otherwise, sets opt name and rest and returns true
split_short(const std::string & current,std::string & name,std::string & rest)838 inline bool split_short(const std::string &current, std::string &name, std::string &rest) {
839     if(current.size() > 1 && current[0] == '-' && valid_first_char(current[1])) {
840         name = current.substr(1, 1);
841         rest = current.substr(2);
842         return true;
843     } else
844         return false;
845 }
846 
847 // Returns false if not a long option. Otherwise, sets opt name and other side of = and returns true
split_long(const std::string & current,std::string & name,std::string & value)848 inline bool split_long(const std::string &current, std::string &name, std::string &value) {
849     if(current.size() > 2 && current.substr(0, 2) == "--" && valid_first_char(current[2])) {
850         auto loc = current.find("=");
851         if(loc != std::string::npos) {
852             name = current.substr(2, loc - 2);
853             value = current.substr(loc + 1);
854         } else {
855             name = current.substr(2);
856             value = "";
857         }
858         return true;
859     } else
860         return false;
861 }
862 
863 // Splits a string into multiple long and short names
split_names(std::string current)864 inline std::vector<std::string> split_names(std::string current) {
865     std::vector<std::string> output;
866     size_t val;
867     while((val = current.find(",")) != std::string::npos) {
868         output.push_back(trim_copy(current.substr(0, val)));
869         current = current.substr(val + 1);
870     }
871     output.push_back(trim_copy(current));
872     return output;
873 }
874 
875 /// Get a vector of short names, one of long names, and a single name
876 inline std::tuple<std::vector<std::string>, std::vector<std::string>, std::string>
get_names(const std::vector<std::string> & input)877 get_names(const std::vector<std::string> &input) {
878 
879     std::vector<std::string> short_names;
880     std::vector<std::string> long_names;
881     std::string pos_name;
882 
883     for(std::string name : input) {
884         if(name.length() == 0)
885             continue;
886         else if(name.length() > 1 && name[0] == '-' && name[1] != '-') {
887             if(name.length() == 2 && valid_first_char(name[1]))
888                 short_names.emplace_back(1, name[1]);
889             else
890                 throw BadNameString::OneCharName(name);
891         } else if(name.length() > 2 && name.substr(0, 2) == "--") {
892             name = name.substr(2);
893             if(valid_name_string(name))
894                 long_names.push_back(name);
895             else
896                 throw BadNameString::BadLongName(name);
897         } else if(name == "-" || name == "--") {
898             throw BadNameString::DashesOnly(name);
899         } else {
900             if(pos_name.length() > 0)
901                 throw BadNameString::MultiPositionalNames(name);
902             pos_name = name;
903         }
904     }
905 
906     return std::tuple<std::vector<std::string>, std::vector<std::string>, std::string>(
907         short_names, long_names, pos_name);
908 }
909 
910 } // namespace detail
911 } // namespace CLI
912 
913 // From CLI/ConfigFwd.hpp:
914 
915 namespace CLI {
916 
917 class App;
918 
919 namespace detail {
920 
921 /// Comma separated join, adds quotes if needed
ini_join(std::vector<std::string> args)922 inline std::string ini_join(std::vector<std::string> args) {
923     std::ostringstream s;
924     size_t start = 0;
925     for(const auto &arg : args) {
926         if(start++ > 0)
927             s << " ";
928 
929         auto it = std::find_if(arg.begin(), arg.end(), [](char ch) { return std::isspace<char>(ch, std::locale()); });
930         if(it == arg.end())
931             s << arg;
932         else if(arg.find(R"(")") == std::string::npos)
933             s << R"(")" << arg << R"(")";
934         else
935             s << R"(')" << arg << R"(')";
936     }
937 
938     return s.str();
939 }
940 
941 } // namespace detail
942 
943 /// Holds values to load into Options
944 struct ConfigItem {
945     /// This is the list of parents
946     std::vector<std::string> parents;
947 
948     /// This is the name
949     std::string name;
950 
951     /// Listing of inputs
952     std::vector<std::string> inputs;
953 
954     /// The list of parents and name joined by "."
955     std::string fullname() const {
956         std::vector<std::string> tmp = parents;
957         tmp.emplace_back(name);
958         return detail::join(tmp, ".");
959     }
960 };
961 
962 /// This class provides a converter for configuration files.
963 class Config {
964   protected:
965     std::vector<ConfigItem> items;
966 
967   public:
968     /// Convert an app into a configuration
969     virtual std::string to_config(const App *, bool, bool, std::string) const = 0;
970 
971     /// Convert a configuration into an app
972     virtual std::vector<ConfigItem> from_config(std::istream &) const = 0;
973 
974     /// Convert a flag to a bool
975     virtual std::vector<std::string> to_flag(const ConfigItem &item) const {
976         if(item.inputs.size() == 1) {
977             std::string val = item.inputs.at(0);
978             val = detail::to_lower(val);
979 
980             if(val == "true" || val == "on" || val == "yes") {
981                 return std::vector<std::string>(1);
982             } else if(val == "false" || val == "off" || val == "no") {
983                 return std::vector<std::string>();
984             } else {
985                 try {
986                     size_t ui = std::stoul(val);
987                     return std::vector<std::string>(ui);
988                 } catch(const std::invalid_argument &) {
989                     throw ConversionError::TrueFalse(item.fullname());
990                 }
991             }
992         } else {
993             throw ConversionError::TooManyInputsFlag(item.fullname());
994         }
995     }
996 
997     /// Parse a config file, throw an error (ParseError:ConfigParseError or FileError) on failure
998     std::vector<ConfigItem> from_file(const std::string &name) {
999         std::ifstream input{name};
1000         if(!input.good())
1001             throw FileError::Missing(name);
1002 
1003         return from_config(input);
1004     }
1005 
1006     /// virtual destructor
1007     virtual ~Config() = default;
1008 };
1009 
1010 /// This converter works with INI files
1011 class ConfigINI : public Config {
1012   public:
1013     std::string to_config(const App *, bool default_also, bool write_description, std::string prefix) const override;
1014 
1015     std::vector<ConfigItem> from_config(std::istream &input) const override {
1016         std::string line;
1017         std::string section = "default";
1018 
1019         std::vector<ConfigItem> output;
1020 
1021         while(getline(input, line)) {
1022             std::vector<std::string> items;
1023 
1024             detail::trim(line);
1025             size_t len = line.length();
1026             if(len > 1 && line[0] == '[' && line[len - 1] == ']') {
1027                 section = line.substr(1, len - 2);
1028             } else if(len > 0 && line[0] != ';') {
1029                 output.emplace_back();
1030                 ConfigItem &out = output.back();
1031 
1032                 // Find = in string, split and recombine
1033                 auto pos = line.find('=');
1034                 if(pos != std::string::npos) {
1035                     out.name = detail::trim_copy(line.substr(0, pos));
1036                     std::string item = detail::trim_copy(line.substr(pos + 1));
1037                     items = detail::split_up(item);
1038                 } else {
1039                     out.name = detail::trim_copy(line);
1040                     items = {"ON"};
1041                 }
1042 
1043                 if(detail::to_lower(section) != "default") {
1044                     out.parents = {section};
1045                 }
1046 
1047                 if(out.name.find('.') != std::string::npos) {
1048                     std::vector<std::string> plist = detail::split(out.name, '.');
1049                     out.name = plist.back();
1050                     plist.pop_back();
1051                     out.parents.insert(out.parents.end(), plist.begin(), plist.end());
1052                 }
1053 
1054                 out.inputs.insert(std::end(out.inputs), std::begin(items), std::end(items));
1055             }
1056         }
1057         return output;
1058     }
1059 };
1060 
1061 } // namespace CLI
1062 
1063 // From CLI/Validators.hpp:
1064 
1065 namespace CLI {
1066 
1067 /// @defgroup validator_group Validators
1068 
1069 /// @brief Some validators that are provided
1070 ///
1071 /// These are simple `std::string(const std::string&)` validators that are useful. They return
1072 /// a string if the validation fails. A custom struct is provided, as well, with the same user
1073 /// semantics, but with the ability to provide a new type name.
1074 /// @{
1075 
1076 ///
1077 struct Validator {
1078     /// This is the type name, if empty the type name will not be changed
1079     std::string tname;
1080     std::function<std::string(const std::string &filename)> func;
1081 
1082     /// This is the required operator for a validator - provided to help
1083     /// users (CLI11 uses the func directly)
1084     std::string operator()(const std::string &filename) const { return func(filename); };
1085 
1086     /// Combining validators is a new validator
1087     Validator operator&(const Validator &other) const {
1088         Validator newval;
1089         newval.tname = (tname == other.tname ? tname : "");
1090 
1091         // Give references (will make a copy in lambda function)
1092         const std::function<std::string(const std::string &filename)> &f1 = func;
1093         const std::function<std::string(const std::string &filename)> &f2 = other.func;
1094 
1095         newval.func = [f1, f2](const std::string &filename) {
1096             std::string s1 = f1(filename);
1097             std::string s2 = f2(filename);
1098             if(!s1.empty() && !s2.empty())
1099                 return s1 + " & " + s2;
1100             else
1101                 return s1 + s2;
1102         };
1103         return newval;
1104     }
1105 
1106     /// Combining validators is a new validator
1107     Validator operator|(const Validator &other) const {
1108         Validator newval;
1109         newval.tname = (tname == other.tname ? tname : "");
1110 
1111         // Give references (will make a copy in lambda function)
1112         const std::function<std::string(const std::string &filename)> &f1 = func;
1113         const std::function<std::string(const std::string &filename)> &f2 = other.func;
1114 
1115         newval.func = [f1, f2](const std::string &filename) {
1116             std::string s1 = f1(filename);
1117             std::string s2 = f2(filename);
1118             if(s1.empty() || s2.empty())
1119                 return std::string();
1120             else
1121                 return s1 + " & " + s2;
1122         };
1123         return newval;
1124     }
1125 };
1126 
1127 // The implementation of the built in validators is using the Validator class;
1128 // the user is only expected to use the const (static) versions (since there's no setup).
1129 // Therefore, this is in detail.
1130 namespace detail {
1131 
1132 /// Check for an existing file (returns error message if check fails)
1133 struct ExistingFileValidator : public Validator {
1134     ExistingFileValidator() {
1135         tname = "FILE";
1136         func = [](const std::string &filename) {
1137             struct stat buffer;
1138             bool exist = stat(filename.c_str(), &buffer) == 0;
1139             bool is_dir = (buffer.st_mode & S_IFDIR) != 0;
1140             if(!exist) {
1141                 return "File does not exist: " + filename;
1142             } else if(is_dir) {
1143                 return "File is actually a directory: " + filename;
1144             }
1145             return std::string();
1146         };
1147     }
1148 };
1149 
1150 /// Check for an existing directory (returns error message if check fails)
1151 struct ExistingDirectoryValidator : public Validator {
1152     ExistingDirectoryValidator() {
1153         tname = "DIR";
1154         func = [](const std::string &filename) {
1155             struct stat buffer;
1156             bool exist = stat(filename.c_str(), &buffer) == 0;
1157             bool is_dir = (buffer.st_mode & S_IFDIR) != 0;
1158             if(!exist) {
1159                 return "Directory does not exist: " + filename;
1160             } else if(!is_dir) {
1161                 return "Directory is actually a file: " + filename;
1162             }
1163             return std::string();
1164         };
1165     }
1166 };
1167 
1168 /// Check for an existing path
1169 struct ExistingPathValidator : public Validator {
1170     ExistingPathValidator() {
1171         tname = "PATH";
1172         func = [](const std::string &filename) {
1173             struct stat buffer;
1174             bool const exist = stat(filename.c_str(), &buffer) == 0;
1175             if(!exist) {
1176                 return "Path does not exist: " + filename;
1177             }
1178             return std::string();
1179         };
1180     }
1181 };
1182 
1183 /// Check for an non-existing path
1184 struct NonexistentPathValidator : public Validator {
1185     NonexistentPathValidator() {
1186         tname = "PATH";
1187         func = [](const std::string &filename) {
1188             struct stat buffer;
1189             bool exist = stat(filename.c_str(), &buffer) == 0;
1190             if(exist) {
1191                 return "Path already exists: " + filename;
1192             }
1193             return std::string();
1194         };
1195     }
1196 };
1197 } // namespace detail
1198 
1199 // Static is not needed here, because global const implies static.
1200 
1201 /// Check for existing file (returns error message if check fails)
1202 const detail::ExistingFileValidator ExistingFile;
1203 
1204 /// Check for an existing directory (returns error message if check fails)
1205 const detail::ExistingDirectoryValidator ExistingDirectory;
1206 
1207 /// Check for an existing path
1208 const detail::ExistingPathValidator ExistingPath;
1209 
1210 /// Check for an non-existing path
1211 const detail::NonexistentPathValidator NonexistentPath;
1212 
1213 ///  Produce a range (factory). Min and max are inclusive.
1214 struct Range : public Validator {
1215     template <typename T> Range(T min, T max) {
1216         std::stringstream out;
1217         out << detail::type_name<T>() << " in [" << min << " - " << max << "]";
1218 
1219         tname = out.str();
1220         func = [min, max](std::string input) {
1221             T val;
1222             detail::lexical_cast(input, val);
1223             if(val < min || val > max)
1224                 return "Value " + input + " not in range " + std::to_string(min) + " to " + std::to_string(max);
1225 
1226             return std::string();
1227         };
1228     }
1229 
1230     /// Range of one value is 0 to value
1231     template <typename T> explicit Range(T max) : Range(static_cast<T>(0), max) {}
1232 };
1233 
1234 /// @}
1235 
1236 } // namespace CLI
1237 
1238 // From CLI/FormatterFwd.hpp:
1239 
1240 namespace CLI {
1241 
1242 class Option;
1243 class App;
1244 
1245 /// This enum signifies the type of help requested
1246 ///
1247 /// This is passed in by App; all user classes must accept this as
1248 /// the second argument.
1249 
1250 enum class AppFormatMode {
1251     Normal, //< The normal, detailed help
1252     All,    //< A fully expanded help
1253     Sub,    //< Used when printed as part of expanded subcommand
1254 };
1255 
1256 /// This is the minimum requirements to run a formatter.
1257 ///
1258 /// A user can subclass this is if they do not care at all
1259 /// about the structure in CLI::Formatter.
1260 class FormatterBase {
1261   protected:
1262     /// @name Options
1263     ///@{
1264 
1265     /// The width of the first column
1266     size_t column_width_{30};
1267 
1268     /// @brief The required help printout labels (user changeable)
1269     /// Values are Needs, Excludes, etc.
1270     std::map<std::string, std::string> labels_;
1271 
1272     ///@}
1273     /// @name Basic
1274     ///@{
1275 
1276   public:
1277     FormatterBase() = default;
1278     FormatterBase(const FormatterBase &) = default;
1279     FormatterBase(FormatterBase &&) = default;
1280     virtual ~FormatterBase() = default;
1281 
1282     /// This is the key method that puts together help
1283     virtual std::string make_help(const App *, std::string, AppFormatMode) const = 0;
1284 
1285     ///@}
1286     /// @name Setters
1287     ///@{
1288 
1289     /// Set the "REQUIRED" label
1290     void label(std::string key, std::string val) { labels_[key] = val; }
1291 
1292     /// Set the column width
1293     void column_width(size_t val) { column_width_ = val; }
1294 
1295     ///@}
1296     /// @name Getters
1297     ///@{
1298 
1299     /// Get the current value of a name (REQUIRED, etc.)
1300     std::string get_label(std::string key) const {
1301         if(labels_.find(key) == labels_.end())
1302             return key;
1303         else
1304             return labels_.at(key);
1305     }
1306 
1307     /// Get the current column width
1308     size_t get_column_width() const { return column_width_; }
1309 
1310     ///@}
1311 };
1312 
1313 /// This is a specialty override for lambda functions
1314 class FormatterLambda final : public FormatterBase {
1315     using funct_t = std::function<std::string(const App *, std::string, AppFormatMode)>;
1316 
1317     funct_t lambda_;
1318 
1319   public:
1320     explicit FormatterLambda(funct_t funct) : lambda_(std::move(funct)) {}
1321 
1322     /// This will simply call the lambda function
1323     std::string make_help(const App *app, std::string name, AppFormatMode mode) const override {
1324         return lambda_(app, name, mode);
1325     }
1326 };
1327 
1328 class Formatter : public FormatterBase {
1329   public:
1330     Formatter() = default;
1331     Formatter(const Formatter &) = default;
1332     Formatter(Formatter &&) = default;
1333 
1334     /// @name Overridables
1335     ///@{
1336 
1337     /// This prints out a group of options with title
1338     ///
1339     virtual std::string make_group(std::string group, bool is_positional, std::vector<const Option *> opts) const;
1340 
1341     /// This prints out just the positionals "group"
1342     virtual std::string make_positionals(const App *app) const;
1343 
1344     /// This prints out all the groups of options
1345     std::string make_groups(const App *app, AppFormatMode mode) const;
1346 
1347     /// This prints out all the subcommands
1348     virtual std::string make_subcommands(const App *app, AppFormatMode mode) const;
1349 
1350     /// This prints out a subcommand
1351     virtual std::string make_subcommand(const App *sub) const;
1352 
1353     /// This prints out a subcommand in help-all
1354     virtual std::string make_expanded(const App *sub) const;
1355 
1356     /// This prints out all the groups of options
1357     virtual std::string make_footer(const App *app) const;
1358 
1359     /// This displays the description line
1360     virtual std::string make_description(const App *app) const;
1361 
1362     /// This displays the usage line
1363     virtual std::string make_usage(const App *app, std::string name) const;
1364 
1365     /// This puts everything together
1366     std::string make_help(const App *, std::string, AppFormatMode) const override;
1367 
1368     ///@}
1369     /// @name Options
1370     ///@{
1371 
1372     /// This prints out an option help line, either positional or optional form
1373     virtual std::string make_option(const Option *opt, bool is_positional) const {
1374         std::stringstream out;
1375         detail::format_help(
1376             out, make_option_name(opt, is_positional) + make_option_opts(opt), make_option_desc(opt), column_width_);
1377         return out.str();
1378     }
1379 
1380     /// @brief This is the name part of an option, Default: left column
1381     virtual std::string make_option_name(const Option *, bool) const;
1382 
1383     /// @brief This is the options part of the name, Default: combined into left column
1384     virtual std::string make_option_opts(const Option *) const;
1385 
1386     /// @brief This is the description. Default: Right column, on new line if left column too large
1387     virtual std::string make_option_desc(const Option *) const;
1388 
1389     /// @brief This is used to print the name on the USAGE line
1390     virtual std::string make_option_usage(const Option *opt) const;
1391 
1392     ///@}
1393 };
1394 
1395 } // namespace CLI
1396 
1397 // From CLI/Option.hpp:
1398 
1399 namespace CLI {
1400 
1401 using results_t = std::vector<std::string>;
1402 using callback_t = std::function<bool(results_t)>;
1403 
1404 class Option;
1405 class App;
1406 
1407 using Option_p = std::unique_ptr<Option>;
1408 
1409 enum class MultiOptionPolicy { Throw, TakeLast, TakeFirst, Join };
1410 
1411 template <typename CRTP> class OptionBase {
1412     friend App;
1413 
1414   protected:
1415     /// The group membership
1416     std::string group_ = std::string("Options");
1417 
1418     /// True if this is a required option
1419     bool required_{false};
1420 
1421     /// Ignore the case when matching (option, not value)
1422     bool ignore_case_{false};
1423 
1424     /// Allow this option to be given in a configuration file
1425     bool configurable_{true};
1426 
1427     /// Policy for multiple arguments when `expected_ == 1`  (can be set on bool flags, too)
1428     MultiOptionPolicy multi_option_policy_{MultiOptionPolicy::Throw};
1429 
1430     template <typename T> void copy_to(T *other) const {
1431         other->group(group_);
1432         other->required(required_);
1433         other->ignore_case(ignore_case_);
1434         other->configurable(configurable_);
1435         other->multi_option_policy(multi_option_policy_);
1436     }
1437 
1438   public:
1439     // setters
1440 
1441     /// Changes the group membership
1442     CRTP *group(std::string name) {
1443         group_ = name;
1444         return static_cast<CRTP *>(this);
1445         ;
1446     }
1447 
1448     /// Set the option as required
1449     CRTP *required(bool value = true) {
1450         required_ = value;
1451         return static_cast<CRTP *>(this);
1452     }
1453 
1454     /// Support Plumbum term
1455     CRTP *mandatory(bool value = true) { return required(value); }
1456 
1457     // Getters
1458 
1459     /// Get the group of this option
1460     const std::string &get_group() const { return group_; }
1461 
1462     /// True if this is a required option
1463     bool get_required() const { return required_; }
1464 
1465     /// The status of ignore case
1466     bool get_ignore_case() const { return ignore_case_; }
1467 
1468     /// The status of configurable
1469     bool get_configurable() const { return configurable_; }
1470 
1471     /// The status of the multi option policy
1472     MultiOptionPolicy get_multi_option_policy() const { return multi_option_policy_; }
1473 
1474     // Shortcuts for multi option policy
1475 
1476     /// Set the multi option policy to take last
1477     CRTP *take_last() {
1478         auto self = static_cast<CRTP *>(this);
1479         self->multi_option_policy(MultiOptionPolicy::TakeLast);
1480         return self;
1481     }
1482 
1483     /// Set the multi option policy to take last
1484     CRTP *take_first() {
1485         auto self = static_cast<CRTP *>(this);
1486         self->multi_option_policy(MultiOptionPolicy::TakeFirst);
1487         return self;
1488     }
1489 
1490     /// Set the multi option policy to take last
1491     CRTP *join() {
1492         auto self = static_cast<CRTP *>(this);
1493         self->multi_option_policy(MultiOptionPolicy::Join);
1494         return self;
1495     }
1496 
1497     /// Allow in a configuration file
1498     CRTP *configurable(bool value = true) {
1499         configurable_ = value;
1500         return static_cast<CRTP *>(this);
1501     }
1502 };
1503 
1504 class OptionDefaults : public OptionBase<OptionDefaults> {
1505   public:
1506     OptionDefaults() = default;
1507 
1508     // Methods here need a different implementation if they are Option vs. OptionDefault
1509 
1510     /// Take the last argument if given multiple times
1511     OptionDefaults *multi_option_policy(MultiOptionPolicy value = MultiOptionPolicy::Throw) {
1512         multi_option_policy_ = value;
1513         return this;
1514     }
1515 
1516     /// Ignore the case of the option name
1517     OptionDefaults *ignore_case(bool value = true) {
1518         ignore_case_ = value;
1519         return this;
1520     }
1521 };
1522 
1523 class Option : public OptionBase<Option> {
1524     friend App;
1525 
1526   protected:
1527     /// @name Names
1528     ///@{
1529 
1530     /// A list of the short names (`-a`) without the leading dashes
1531     std::vector<std::string> snames_;
1532 
1533     /// A list of the long names (`--a`) without the leading dashes
1534     std::vector<std::string> lnames_;
1535 
1536     /// A positional name
1537     std::string pname_;
1538 
1539     /// If given, check the environment for this option
1540     std::string envname_;
1541 
1542     ///@}
1543     /// @name Help
1544     ///@{
1545 
1546     /// The description for help strings
1547     std::string description_;
1548 
1549     /// A human readable default value, usually only set if default is true in creation
1550     std::string defaultval_;
1551 
1552     /// A human readable type value, set when App creates this
1553     ///
1554     /// This is a lambda function so "types" can be dynamic, such as when a set prints its contents.
1555     std::function<std::string()> type_name_{[]() { return std::string(); }};
1556 
1557     /// True if this option has a default
1558     bool default_{false};
1559 
1560     ///@}
1561     /// @name Configuration
1562     ///@{
1563 
1564     /// The number of arguments that make up one option. -1=unlimited (vector-like), 0=flag, 1=normal option,
1565     /// 2=complex/pair, etc. Set only when the option is created; this is intrinsic to the type. Eventually, -2 may mean
1566     /// vector of pairs.
1567     int type_size_{1};
1568 
1569     /// The number of expected values, type_size_ must be < 0. Ignored for flag. N < 0 means at least -N values.
1570     int expected_{1};
1571 
1572     /// A list of validators to run on each value parsed
1573     std::vector<std::function<std::string(std::string &)>> validators_;
1574 
1575     /// A list of options that are required with this option
1576     std::set<Option *> requires_;
1577 
1578     /// A list of options that are excluded with this option
1579     std::set<Option *> excludes_;
1580 
1581     ///@}
1582     /// @name Other
1583     ///@{
1584 
1585     /// Remember the parent app
1586     App *parent_;
1587 
1588     /// Options store a callback to do all the work
1589     callback_t callback_;
1590 
1591     /// Options can short-circuit for help options or similar (called before parsing is validated)
1592     bool short_circuit_{false};
1593 
1594     ///@}
1595     /// @name Parsing results
1596     ///@{
1597 
1598     /// Results of parsing
1599     results_t results_;
1600 
1601     /// Whether the callback has run (needed for INI parsing)
1602     bool callback_run_{false};
1603 
1604     ///@}
1605 
1606     /// Making an option by hand is not defined, it must be made by the App class
1607     Option(
1608         std::string name, std::string description, std::function<bool(results_t)> callback, bool defaulted, App *parent)
1609         : description_(std::move(description)), default_(defaulted), parent_(parent),
1610           callback_(callback ? std::move(callback) : [](results_t) { return true; }) {
1611         std::tie(snames_, lnames_, pname_) = detail::get_names(detail::split_names(name));
1612     }
1613 
1614   public:
1615     /// @name Basic
1616     ///@{
1617 
1618     /// Count the total number of times an option was passed
1619     size_t count() const { return results_.size(); }
1620 
1621     /// True if the option was not passed
1622     size_t empty() const { return results_.empty(); }
1623 
1624     /// This class is true if option is passed.
1625     operator bool() const { return !empty(); }
1626 
1627     /// Clear the parsed results (mostly for testing)
1628     void clear() { results_.clear(); }
1629 
1630     ///@}
1631     /// @name Setting options
1632     ///@{
1633 
1634     /// Set the number of expected arguments (Flags don't use this)
1635     Option *expected(int value) {
1636         // Break if this is a flag
1637         if(type_size_ == 0)
1638             throw IncorrectConstruction::SetFlag(get_name(true, true));
1639 
1640         // Setting 0 is not allowed
1641         else if(value == 0)
1642             throw IncorrectConstruction::Set0Opt(get_name());
1643 
1644         // No change is okay, quit now
1645         else if(expected_ == value)
1646             return this;
1647 
1648         // Type must be a vector
1649         else if(type_size_ >= 0)
1650             throw IncorrectConstruction::ChangeNotVector(get_name());
1651 
1652         // TODO: Can support multioption for non-1 values (except for join)
1653         else if(value != 1 && multi_option_policy_ != MultiOptionPolicy::Throw)
1654             throw IncorrectConstruction::AfterMultiOpt(get_name());
1655 
1656         expected_ = value;
1657         return this;
1658     }
1659 
1660     /// Adds a validator with a built in type name
1661     Option *check(const Validator &validator) {
1662         validators_.emplace_back(validator.func);
1663         if(!validator.tname.empty())
1664             type_name(validator.tname);
1665         return this;
1666     }
1667 
1668     /// Adds a validator
1669     Option *check(std::function<std::string(const std::string &)> validator) {
1670         validators_.emplace_back(validator);
1671         return this;
1672     }
1673 
1674     /// Adds a validator-like function that can change result
1675     Option *transform(std::function<std::string(std::string)> func) {
1676         validators_.emplace_back([func](std::string &inout) {
1677             try {
1678                 inout = func(inout);
1679             } catch(const ValidationError &e) {
1680                 return std::string(e.what());
1681             }
1682             return std::string();
1683         });
1684         return this;
1685     }
1686 
1687     /// Adds a user supplied function to run on each item passed in (communicate though lambda capture)
1688     Option *each(std::function<void(std::string)> func) {
1689         validators_.emplace_back([func](std::string &inout) {
1690             func(inout);
1691             return std::string();
1692         });
1693         return this;
1694     }
1695 
1696     /// Sets required options
1697     Option *needs(Option *opt) {
1698         auto tup = requires_.insert(opt);
1699         if(!tup.second)
1700             throw OptionAlreadyAdded::Requires(get_name(), opt->get_name());
1701         return this;
1702     }
1703 
1704     /// Can find a string if needed
1705     template <typename T = App> Option *needs(std::string opt_name) {
1706         for(const Option_p &opt : dynamic_cast<T *>(parent_)->options_)
1707             if(opt.get() != this && opt->check_name(opt_name))
1708                 return needs(opt.get());
1709         throw IncorrectConstruction::MissingOption(opt_name);
1710     }
1711 
1712     /// Any number supported, any mix of string and Opt
1713     template <typename A, typename B, typename... ARG> Option *needs(A opt, B opt1, ARG... args) {
1714         needs(opt);
1715         return needs(opt1, args...);
1716     }
1717 
1718     /// Sets excluded options
1719     Option *excludes(Option *opt) {
1720         excludes_.insert(opt);
1721 
1722         // Help text should be symmetric - excluding a should exclude b
1723         opt->excludes_.insert(this);
1724 
1725         // Ignoring the insert return value, excluding twice is now allowed.
1726         // (Mostly to allow both directions to be excluded by user, even though the library does it for you.)
1727 
1728         return this;
1729     }
1730 
1731     /// Can find a string if needed
1732     template <typename T = App> Option *excludes(std::string opt_name) {
1733         for(const Option_p &opt : dynamic_cast<T *>(parent_)->options_)
1734             if(opt.get() != this && opt->check_name(opt_name))
1735                 return excludes(opt.get());
1736         throw IncorrectConstruction::MissingOption(opt_name);
1737     }
1738 
1739     /// Any number supported, any mix of string and Opt
1740     template <typename A, typename B, typename... ARG> Option *excludes(A opt, B opt1, ARG... args) {
1741         excludes(opt);
1742         return excludes(opt1, args...);
1743     }
1744 
1745     /// Sets environment variable to read if no option given
1746     Option *envname(std::string name) {
1747         envname_ = name;
1748         return this;
1749     }
1750 
1751     /// Ignore case
1752     ///
1753     /// The template hides the fact that we don't have the definition of App yet.
1754     /// You are never expected to add an argument to the template here.
1755     template <typename T = App> Option *ignore_case(bool value = true) {
1756         ignore_case_ = value;
1757         auto *parent = dynamic_cast<T *>(parent_);
1758 
1759         for(const Option_p &opt : parent->options_)
1760             if(opt.get() != this && *opt == *this)
1761                 throw OptionAlreadyAdded(opt->get_name(true, true));
1762 
1763         return this;
1764     }
1765 
1766     /// Take the last argument if given multiple times (or another policy)
1767     Option *multi_option_policy(MultiOptionPolicy value = MultiOptionPolicy::Throw) {
1768 
1769         if(get_items_expected() < 0)
1770             throw IncorrectConstruction::MultiOptionPolicy(get_name());
1771         multi_option_policy_ = value;
1772         return this;
1773     }
1774 
1775     /// Options with a short circuit set will run this function before parsing is finished.
1776     ///
1777     /// This is set on help functions, for example, to escape the normal validation.
1778     Option *short_circuit(bool value = true) {
1779         short_circuit_ = value;
1780         return this;
1781     }
1782 
1783     ///@}
1784     /// @name Accessors
1785     ///@{
1786 
1787     /// The number of arguments the option expects
1788     int get_type_size() const { return type_size_; }
1789 
1790     /// The environment variable associated to this value
1791     std::string get_envname() const { return envname_; }
1792 
1793     /// The set of options needed
1794     std::set<Option *> get_needs() const { return requires_; }
1795 
1796     /// The set of options excluded
1797     std::set<Option *> get_excludes() const { return excludes_; }
1798 
1799     /// The default value (for help printing)
1800     std::string get_defaultval() const { return defaultval_; }
1801 
1802     /// See if this is supposed to short circuit (skip validation, INI, etc) (Used for help flags)
1803     bool get_short_circuit() const { return short_circuit_; }
1804 
1805     /// Get the callback function
1806     callback_t get_callback() const { return callback_; }
1807 
1808     /// Get the long names
1809     const std::vector<std::string> get_lnames() const { return lnames_; }
1810 
1811     /// Get the short names
1812     const std::vector<std::string> get_snames() const { return snames_; }
1813 
1814     /// The number of times the option expects to be included
1815     int get_expected() const { return expected_; }
1816 
1817     /// \breif The total number of expected values (including the type)
1818     /// This is positive if exactly this number is expected, and negitive for at least N values
1819     ///
1820     /// v = fabs(size_type*expected)
1821     /// !MultiOptionPolicy::Throw
1822     ///           | Expected < 0  | Expected == 0 | Expected > 0
1823     /// Size < 0  |      -v       |       0       |     -v
1824     /// Size == 0 |       0       |       0       |      0
1825     /// Size > 0  |      -v       |       0       |     -v       // Expected must be 1
1826     ///
1827     /// MultiOptionPolicy::Throw
1828     ///           | Expected < 0  | Expected == 0 | Expected > 0
1829     /// Size < 0  |      -v       |       0       |      v
1830     /// Size == 0 |       0       |       0       |      0
1831     /// Size > 0  |       v       |       0       |      v      // Expected must be 1
1832     ///
1833     int get_items_expected() const {
1834         return std::abs(type_size_ * expected_) *
1835                ((multi_option_policy_ != MultiOptionPolicy::Throw || (expected_ < 0 && type_size_ < 0) ? -1 : 1));
1836     }
1837 
1838     /// True if this has a default value
1839     int get_default() const { return default_; }
1840 
1841     /// True if the argument can be given directly
1842     bool get_positional() const { return pname_.length() > 0; }
1843 
1844     /// True if option has at least one non-positional name
1845     bool nonpositional() const { return (snames_.size() + lnames_.size()) > 0; }
1846 
1847     /// True if option has description
1848     bool has_description() const { return description_.length() > 0; }
1849 
1850     /// Get the description
1851     const std::string &get_description() const { return description_; }
1852 
1853     ///@}
1854     /// @name Help tools
1855     ///@{
1856 
1857     /// \brief Gets a comma seperated list of names.
1858     /// Will include / prefer the positional name if positional is true.
1859     /// If all_options is false, pick just the most descriptive name to show.
1860     /// Use `get_name(true)` to get the positional name (replaces `get_pname`)
1861     std::string get_name(bool positional = false, //<[input] Show the positional name
1862                          bool all_options = false //<[input] Show every option
1863                          ) const {
1864 
1865         if(all_options) {
1866 
1867             std::vector<std::string> name_list;
1868 
1869             /// The all list wil never include a positional unless asked or that's the only name.
1870             if((positional && pname_.length()) || (snames_.empty() && lnames_.empty()))
1871                 name_list.push_back(pname_);
1872 
1873             for(const std::string &sname : snames_)
1874                 name_list.push_back("-" + sname);
1875 
1876             for(const std::string &lname : lnames_)
1877                 name_list.push_back("--" + lname);
1878 
1879             return detail::join(name_list);
1880 
1881         } else {
1882 
1883             // This returns the positional name no matter what
1884             if(positional)
1885                 return pname_;
1886 
1887             // Prefer long name
1888             else if(!lnames_.empty())
1889                 return std::string("--") + lnames_[0];
1890 
1891             // Or short name if no long name
1892             else if(!snames_.empty())
1893                 return std::string("-") + snames_[0];
1894 
1895             // If positional is the only name, it's okay to use that
1896             else
1897                 return pname_;
1898         }
1899     }
1900 
1901     ///@}
1902     /// @name Parser tools
1903     ///@{
1904 
1905     /// Process the callback
1906     void run_callback() {
1907 
1908         // Run the validators (can change the string)
1909         if(!validators_.empty()) {
1910             for(std::string &result : results_)
1911                 for(const std::function<std::string(std::string &)> &vali : validators_) {
1912                     std::string err_msg = vali(result);
1913                     if(!err_msg.empty())
1914                         throw ValidationError(get_name(), err_msg);
1915                 }
1916         }
1917 
1918         bool local_result;
1919 
1920         // Num items expected or length of vector, always at least 1
1921         // Only valid for a trimming policy
1922         int trim_size = std::min(std::max(std::abs(get_items_expected()), 1), static_cast<int>(results_.size()));
1923 
1924         // Operation depends on the policy setting
1925         if(multi_option_policy_ == MultiOptionPolicy::TakeLast) {
1926             // Allow multi-option sizes (including 0)
1927             results_t partial_result{results_.end() - trim_size, results_.end()};
1928             local_result = !callback_(partial_result);
1929 
1930         } else if(multi_option_policy_ == MultiOptionPolicy::TakeFirst) {
1931             results_t partial_result{results_.begin(), results_.begin() + trim_size};
1932             local_result = !callback_(partial_result);
1933 
1934         } else if(multi_option_policy_ == MultiOptionPolicy::Join) {
1935             results_t partial_result = {detail::join(results_, "\n")};
1936             local_result = !callback_(partial_result);
1937 
1938         } else {
1939             // Exact number required
1940             if(get_items_expected() > 0) {
1941                 if(results_.size() != static_cast<size_t>(get_items_expected()))
1942                     throw ArgumentMismatch(get_name(), get_items_expected(), results_.size());
1943                 // Variable length list
1944             } else if(get_items_expected() < 0) {
1945                 // Require that this be a multiple of expected size and at least as many as expected
1946                 if(results_.size() < static_cast<size_t>(-get_items_expected()) ||
1947                    results_.size() % static_cast<size_t>(std::abs(get_type_size())) != 0)
1948                     throw ArgumentMismatch(get_name(), get_items_expected(), results_.size());
1949             }
1950             local_result = !callback_(results_);
1951         }
1952 
1953         if(local_result)
1954             throw ConversionError(get_name(), results_);
1955     }
1956 
1957     /// If options share any of the same names, they are equal (not counting positional)
1958     bool operator==(const Option &other) const {
1959         for(const std::string &sname : snames_)
1960             if(other.check_sname(sname))
1961                 return true;
1962         for(const std::string &lname : lnames_)
1963             if(other.check_lname(lname))
1964                 return true;
1965         // We need to do the inverse, just in case we are ignore_case
1966         for(const std::string &sname : other.snames_)
1967             if(check_sname(sname))
1968                 return true;
1969         for(const std::string &lname : other.lnames_)
1970             if(check_lname(lname))
1971                 return true;
1972         return false;
1973     }
1974 
1975     /// Check a name. Requires "-" or "--" for short / long, supports positional name
1976     bool check_name(std::string name) const {
1977 
1978         if(name.length() > 2 && name.substr(0, 2) == "--")
1979             return check_lname(name.substr(2));
1980         else if(name.length() > 1 && name.substr(0, 1) == "-")
1981             return check_sname(name.substr(1));
1982         else {
1983             std::string local_pname = pname_;
1984             if(ignore_case_) {
1985                 local_pname = detail::to_lower(local_pname);
1986                 name = detail::to_lower(name);
1987             }
1988             return name == local_pname;
1989         }
1990     }
1991 
1992     /// Requires "-" to be removed from string
1993     bool check_sname(std::string name) const {
1994         if(ignore_case_) {
1995             name = detail::to_lower(name);
1996             return std::find_if(std::begin(snames_), std::end(snames_), [&name](std::string local_sname) {
1997                        return detail::to_lower(local_sname) == name;
1998                    }) != std::end(snames_);
1999         } else
2000             return std::find(std::begin(snames_), std::end(snames_), name) != std::end(snames_);
2001     }
2002 
2003     /// Requires "--" to be removed from string
2004     bool check_lname(std::string name) const {
2005         if(ignore_case_) {
2006             name = detail::to_lower(name);
2007             return std::find_if(std::begin(lnames_), std::end(lnames_), [&name](std::string local_sname) {
2008                        return detail::to_lower(local_sname) == name;
2009                    }) != std::end(lnames_);
2010         } else
2011             return std::find(std::begin(lnames_), std::end(lnames_), name) != std::end(lnames_);
2012     }
2013 
2014     /// Puts a result at the end
2015     Option *add_result(std::string s) {
2016         results_.push_back(s);
2017         callback_run_ = false;
2018         return this;
2019     }
2020 
2021     /// Set the results vector all at once
2022     Option *set_results(std::vector<std::string> results) {
2023         results_ = results;
2024         callback_run_ = false;
2025         return this;
2026     }
2027 
2028     /// Get a copy of the results
2029     std::vector<std::string> results() const { return results_; }
2030 
2031     /// See if the callback has been run already
2032     bool get_callback_run() const { return callback_run_; }
2033 
2034     ///@}
2035     /// @name Custom options
2036     ///@{
2037 
2038     /// Set the type function to run when displayed on this option
2039     Option *type_name_fn(std::function<std::string()> typefun) {
2040         type_name_ = typefun;
2041         return this;
2042     }
2043 
2044     /// Set a custom option typestring
2045     Option *type_name(std::string typeval) {
2046         type_name_fn([typeval]() { return typeval; });
2047         return this;
2048     }
2049 
2050     /// Provided for backward compatibility \deprecated
2051     CLI11_DEPRECATED("Please use type_name instead")
2052     Option *set_type_name(std::string typeval) { return type_name(typeval); }
2053 
2054     /// Set a custom option size
2055     Option *type_size(int type_size) {
2056         type_size_ = type_size;
2057         if(type_size_ == 0)
2058             required_ = false;
2059         if(type_size < 0)
2060             expected_ = -1;
2061         return this;
2062     }
2063 
2064     /// Set the default value string representation
2065     Option *default_str(std::string val) {
2066         defaultval_ = val;
2067         return this;
2068     }
2069 
2070     /// Set the default value string representation and evaluate
2071     Option *default_val(std::string val) {
2072         default_str(val);
2073         auto old_results = results_;
2074         results_ = {val};
2075         run_callback();
2076         results_ = std::move(old_results);
2077         return this;
2078     }
2079 
2080     /// Get the typename for this option
2081     std::string get_type_name() const { return type_name_(); }
2082 };
2083 
2084 } // namespace CLI
2085 
2086 // From CLI/App.hpp:
2087 
2088 namespace CLI {
2089 
2090 #ifndef CLI11_PARSE
2091 #define CLI11_PARSE(app, argc, argv)                                                                                   \
2092     try {                                                                                                              \
2093         (app).parse((argc), (argv));                                                                                   \
2094     } catch(const CLI::ParseError &e) {                                                                                \
2095         return (app).exit(e);                                                                                          \
2096     }
2097 #endif
2098 
2099 namespace detail {
2100 enum class Classifer { NONE, POSITIONAL_MARK, SHORT, LONG, SUBCOMMAND };
2101 struct AppFriend;
2102 } // namespace detail
2103 
2104 namespace FailureMessage {
2105 std::string simple(const App *app, const Error &e);
2106 std::string help(const App *app, const Error &e);
2107 } // namespace FailureMessage
2108 
2109 class App;
2110 
2111 using App_p = std::unique_ptr<App>;
2112 
2113 /// Creates a command line program, with very few defaults.
2114 /** To use, create a new `Program()` instance with `argc`, `argv`, and a help description. The templated
2115  *  add_option methods make it easy to prepare options. Remember to call `.start` before starting your
2116  * program, so that the options can be evaluated and the help option doesn't accidentally run your program. */
2117 class App {
2118     friend Option;
2119     friend detail::AppFriend;
2120 
2121   protected:
2122     // This library follows the Google style guide for member names ending in underscores
2123 
2124     /// @name Basics
2125     ///@{
2126 
2127     /// Subcommand name or program name (from parser if name is empty)
2128     std::string name_;
2129 
2130     /// Description of the current program/subcommand
2131     std::string description_;
2132 
2133     /// If true, allow extra arguments (ie, don't throw an error). INHERITABLE
2134     bool allow_extras_{false};
2135 
2136     /// If true, allow extra arguments in the ini file (ie, don't throw an error). INHERITABLE
2137     bool allow_config_extras_{false};
2138 
2139     ///  If true, return immediately on an unrecognised option (implies allow_extras) INHERITABLE
2140     bool prefix_command_{false};
2141 
2142     /// This is a function that runs when complete. Great for subcommands. Can throw.
2143     std::function<void()> callback_;
2144 
2145     ///@}
2146     /// @name Options
2147     ///@{
2148 
2149     /// The default values for options, customizable and changeable INHERITABLE
2150     OptionDefaults option_defaults_;
2151 
2152     /// The list of options, stored locally
2153     std::vector<Option_p> options_;
2154 
2155     ///@}
2156     /// @name Help
2157     ///@{
2158 
2159     /// Footer to put after all options in the help output INHERITABLE
2160     std::string footer_;
2161 
2162     /// A pointer to the help flag if there is one INHERITABLE
2163     Option *help_ptr_{nullptr};
2164 
2165     /// A pointer to the help all flag if there is one INHERITABLE
2166     Option *help_all_ptr_{nullptr};
2167 
2168     /// This is the formatter for help printing. Default provided. INHERITABLE (same pointer)
2169     std::shared_ptr<FormatterBase> formatter_{new Formatter()};
2170 
2171     /// The error message printing function INHERITABLE
2172     std::function<std::string(const App *, const Error &e)> failure_message_ = FailureMessage::simple;
2173 
2174     ///@}
2175     /// @name Parsing
2176     ///@{
2177 
2178     using missing_t = std::vector<std::pair<detail::Classifer, std::string>>;
2179 
2180     /// Pair of classifier, string for missing options. (extra detail is removed on returning from parse)
2181     ///
2182     /// This is faster and cleaner than storing just a list of strings and reparsing. This may contain the -- separator.
2183     missing_t missing_;
2184 
2185     /// This is a list of pointers to options with the original parse order
2186     std::vector<Option *> parse_order_;
2187 
2188     /// This is a list of the subcommands collected, in order
2189     std::vector<App *> parsed_subcommands_;
2190 
2191     ///@}
2192     /// @name Subcommands
2193     ///@{
2194 
2195     /// Storage for subcommand list
2196     std::vector<App_p> subcommands_;
2197 
2198     /// If true, the program name is not case sensitive INHERITABLE
2199     bool ignore_case_{false};
2200 
2201     /// Allow subcommand fallthrough, so that parent commands can collect commands after subcommand.  INHERITABLE
2202     bool fallthrough_{false};
2203 
2204     /// A pointer to the parent if this is a subcommand
2205     App *parent_{nullptr};
2206 
2207     /// True if this command/subcommand was parsed
2208     bool parsed_{false};
2209 
2210     /// Minimum required subcommands (not inheritable!)
2211     size_t require_subcommand_min_ = 0;
2212 
2213     /// Max number of subcommands allowed (parsing stops after this number). 0 is unlimited INHERITABLE
2214     size_t require_subcommand_max_ = 0;
2215 
2216     /// The group membership INHERITABLE
2217     std::string group_{"Subcommands"};
2218 
2219     ///@}
2220     /// @name Config
2221     ///@{
2222 
2223     /// The name of the connected config file
2224     std::string config_name_;
2225 
2226     /// True if ini is required (throws if not present), if false simply keep going.
2227     bool config_required_{false};
2228 
2229     /// Pointer to the config option
2230     Option *config_ptr_{nullptr};
2231 
2232     /// This is the formatter for help printing. Default provided. INHERITABLE (same pointer)
2233     std::shared_ptr<Config> config_formatter_{new ConfigINI()};
2234 
2235     ///@}
2236 
2237     /// Special private constructor for subcommand
2238     App(std::string description_, std::string name, App *parent)
2239         : name_(std::move(name)), description_(std::move(description_)), parent_(parent) {
2240         // Inherit if not from a nullptr
2241         if(parent_ != nullptr) {
2242             if(parent_->help_ptr_ != nullptr)
2243                 set_help_flag(parent_->help_ptr_->get_name(false, true), parent_->help_ptr_->get_description());
2244             if(parent_->help_all_ptr_ != nullptr)
2245                 set_help_all_flag(parent_->help_all_ptr_->get_name(false, true),
2246                                   parent_->help_all_ptr_->get_description());
2247 
2248             /// OptionDefaults
2249             option_defaults_ = parent_->option_defaults_;
2250 
2251             // INHERITABLE
2252             failure_message_ = parent_->failure_message_;
2253             allow_extras_ = parent_->allow_extras_;
2254             allow_config_extras_ = parent_->allow_config_extras_;
2255             prefix_command_ = parent_->prefix_command_;
2256             ignore_case_ = parent_->ignore_case_;
2257             fallthrough_ = parent_->fallthrough_;
2258             group_ = parent_->group_;
2259             footer_ = parent_->footer_;
2260             formatter_ = parent_->formatter_;
2261             config_formatter_ = parent_->config_formatter_;
2262             require_subcommand_max_ = parent_->require_subcommand_max_;
2263         }
2264     }
2265 
2266   public:
2267     /// @name Basic
2268     ///@{
2269 
2270     /// Create a new program. Pass in the same arguments as main(), along with a help string.
2271     explicit App(std::string description_ = "", std::string name = "") : App(description_, name, nullptr) {
2272         set_help_flag("-h,--help", "Print this help message and exit");
2273     }
2274 
2275     /// virtual destructor
2276     virtual ~App() = default;
2277 
2278     /// Set a callback for the end of parsing.
2279     ///
2280     /// Due to a bug in c++11,
2281     /// it is not possible to overload on std::function (fixed in c++14
2282     /// and backported to c++11 on newer compilers). Use capture by reference
2283     /// to get a pointer to App if needed.
2284     App *callback(std::function<void()> callback) {
2285         callback_ = callback;
2286         return this;
2287     }
2288 
2289     /// Set a name for the app (empty will use parser to set the name)
2290     App *name(std::string name = "") {
2291         name_ = name;
2292         return this;
2293     }
2294 
2295     /// Remove the error when extras are left over on the command line.
2296     App *allow_extras(bool allow = true) {
2297         allow_extras_ = allow;
2298         return this;
2299     }
2300 
2301     /// Remove the error when extras are left over on the command line.
2302     /// Will also call App::allow_extras().
2303     App *allow_config_extras(bool allow = true) {
2304         allow_extras(allow);
2305         allow_config_extras_ = allow;
2306         return this;
2307     }
2308 
2309     /// Do not parse anything after the first unrecognised option and return
2310     App *prefix_command(bool allow = true) {
2311         prefix_command_ = allow;
2312         return this;
2313     }
2314 
2315     /// Ignore case. Subcommand inherit value.
2316     App *ignore_case(bool value = true) {
2317         ignore_case_ = value;
2318         if(parent_ != nullptr) {
2319             for(const auto &subc : parent_->subcommands_) {
2320                 if(subc.get() != this && (this->check_name(subc->name_) || subc->check_name(this->name_)))
2321                     throw OptionAlreadyAdded(subc->name_);
2322             }
2323         }
2324         return this;
2325     }
2326 
2327     /// Set the help formatter
2328     App *formatter(std::shared_ptr<FormatterBase> fmt) {
2329         formatter_ = fmt;
2330         return this;
2331     }
2332 
2333     /// Set the help formatter
2334     App *formatter_fn(std::function<std::string(const App *, std::string, AppFormatMode)> fmt) {
2335         formatter_ = std::make_shared<FormatterLambda>(fmt);
2336         return this;
2337     }
2338 
2339     /// Set the config formatter
2340     App *config_formatter(std::shared_ptr<Config> fmt) {
2341         config_formatter_ = fmt;
2342         return this;
2343     }
2344 
2345     /// Check to see if this subcommand was parsed, true only if received on command line.
2346     bool parsed() const { return parsed_; }
2347 
2348     /// Get the OptionDefault object, to set option defaults
2349     OptionDefaults *option_defaults() { return &option_defaults_; }
2350 
2351     ///@}
2352     /// @name Adding options
2353     ///@{
2354 
2355     /// Add an option, will automatically understand the type for common types.
2356     ///
2357     /// To use, create a variable with the expected type, and pass it in after the name.
2358     /// After start is called, you can use count to see if the value was passed, and
2359     /// the value will be initialized properly. Numbers, vectors, and strings are supported.
2360     ///
2361     /// ->required(), ->default, and the validators are options,
2362     /// The positional options take an optional number of arguments.
2363     ///
2364     /// For example,
2365     ///
2366     ///     std::string filename;
2367     ///     program.add_option("filename", filename, "description of filename");
2368     ///
2369     Option *add_option(std::string name, callback_t callback, std::string description = "", bool defaulted = false) {
2370         Option myopt{name, description, callback, defaulted, this};
2371 
2372         if(std::find_if(std::begin(options_), std::end(options_), [&myopt](const Option_p &v) {
2373                return *v == myopt;
2374            }) == std::end(options_)) {
2375             options_.emplace_back();
2376             Option_p &option = options_.back();
2377             option.reset(new Option(name, description, callback, defaulted, this));
2378             option_defaults_.copy_to(option.get());
2379             return option.get();
2380         } else
2381             throw OptionAlreadyAdded(myopt.get_name());
2382     }
2383 
2384     /// Add option for non-vectors (duplicate copy needed without defaulted to avoid `iostream << value`)
2385     template <typename T, enable_if_t<!is_vector<T>::value, detail::enabler> = detail::dummy>
2386     Option *add_option(std::string name,
2387                        T &variable, ///< The variable to set
2388                        std::string description = "") {
2389 
2390         CLI::callback_t fun = [&variable](CLI::results_t res) { return detail::lexical_cast(res[0], variable); };
2391 
2392         Option *opt = add_option(name, fun, description, false);
2393         opt->type_name(detail::type_name<T>());
2394         return opt;
2395     }
2396 
2397     /// Add option for non-vectors with a default print
2398     template <typename T, enable_if_t<!is_vector<T>::value, detail::enabler> = detail::dummy>
2399     Option *add_option(std::string name,
2400                        T &variable, ///< The variable to set
2401                        std::string description,
2402                        bool defaulted) {
2403 
2404         CLI::callback_t fun = [&variable](CLI::results_t res) { return detail::lexical_cast(res[0], variable); };
2405 
2406         Option *opt = add_option(name, fun, description, defaulted);
2407         opt->type_name(detail::type_name<T>());
2408         if(defaulted) {
2409             std::stringstream out;
2410             out << variable;
2411             opt->default_str(out.str());
2412         }
2413         return opt;
2414     }
2415 
2416     /// Add option for vectors (no default)
2417     template <typename T>
2418     Option *add_option(std::string name,
2419                        std::vector<T> &variable, ///< The variable vector to set
2420                        std::string description = "") {
2421 
2422         CLI::callback_t fun = [&variable](CLI::results_t res) {
2423             bool retval = true;
2424             variable.clear();
2425             for(const auto &a : res) {
2426                 variable.emplace_back();
2427                 retval &= detail::lexical_cast(a, variable.back());
2428             }
2429             return (!variable.empty()) && retval;
2430         };
2431 
2432         Option *opt = add_option(name, fun, description, false);
2433         opt->type_name(detail::type_name<T>())->type_size(-1);
2434         return opt;
2435     }
2436 
2437     /// Add option for vectors
2438     template <typename T>
2439     Option *add_option(std::string name,
2440                        std::vector<T> &variable, ///< The variable vector to set
2441                        std::string description,
2442                        bool defaulted) {
2443 
2444         CLI::callback_t fun = [&variable](CLI::results_t res) {
2445             bool retval = true;
2446             variable.clear();
2447             for(const auto &a : res) {
2448                 variable.emplace_back();
2449                 retval &= detail::lexical_cast(a, variable.back());
2450             }
2451             return (!variable.empty()) && retval;
2452         };
2453 
2454         Option *opt = add_option(name, fun, description, defaulted);
2455         opt->type_name(detail::type_name<T>())->type_size(-1);
2456         if(defaulted)
2457             opt->default_str("[" + detail::join(variable) + "]");
2458         return opt;
2459     }
2460 
2461     /// Set a help flag, replace the existing one if present
2462     Option *set_help_flag(std::string name = "", std::string description = "") {
2463         if(help_ptr_ != nullptr) {
2464             remove_option(help_ptr_);
2465             help_ptr_ = nullptr;
2466         }
2467 
2468         // Empty name will simply remove the help flag
2469         if(!name.empty()) {
2470             help_ptr_ = add_flag_function(name, [](size_t) -> void { throw CallForHelp(); }, description);
2471             help_ptr_->short_circuit(true);
2472             help_ptr_->configurable(false);
2473         }
2474 
2475         return help_ptr_;
2476     }
2477 
2478     /// Set a help all flag, replaced the existing one if present
2479     Option *set_help_all_flag(std::string name = "", std::string description = "") {
2480         if(help_all_ptr_ != nullptr) {
2481             remove_option(help_all_ptr_);
2482             help_all_ptr_ = nullptr;
2483         }
2484 
2485         // Empty name will simply remove the help all flag
2486         if(!name.empty()) {
2487             help_all_ptr_ = add_flag_function(name, [](size_t) -> void { throw CallForAllHelp(); }, description);
2488             help_all_ptr_->short_circuit(true);
2489             help_all_ptr_->configurable(false);
2490         }
2491 
2492         return help_all_ptr_;
2493     }
2494 
2495     /// Add option for flag
2496     Option *add_flag(std::string name, std::string description = "") {
2497         CLI::callback_t fun = [](CLI::results_t) { return true; };
2498 
2499         Option *opt = add_option(name, fun, description, false);
2500         if(opt->get_positional())
2501             throw IncorrectConstruction::PositionalFlag(name);
2502         opt->type_size(0);
2503         return opt;
2504     }
2505 
2506     /// Add option for flag integer
2507     template <typename T,
2508               enable_if_t<std::is_integral<T>::value && !is_bool<T>::value, detail::enabler> = detail::dummy>
2509     Option *add_flag(std::string name,
2510                      T &count, ///< A variable holding the count
2511                      std::string description = "") {
2512 
2513         count = 0;
2514         CLI::callback_t fun = [&count](CLI::results_t res) {
2515             count = static_cast<T>(res.size());
2516             return true;
2517         };
2518 
2519         Option *opt = add_option(name, fun, description, false);
2520         if(opt->get_positional())
2521             throw IncorrectConstruction::PositionalFlag(name);
2522         opt->type_size(0);
2523         return opt;
2524     }
2525 
2526     /// Bool version - defaults to allowing multiple passings, but can be forced to one if
2527     /// `multi_option_policy(CLI::MultiOptionPolicy::Throw)` is used.
2528     template <typename T, enable_if_t<is_bool<T>::value, detail::enabler> = detail::dummy>
2529     Option *add_flag(std::string name,
2530                      T &count, ///< A variable holding true if passed
2531                      std::string description = "") {
2532 
2533         count = false;
2534         CLI::callback_t fun = [&count](CLI::results_t res) {
2535             count = true;
2536             return res.size() == 1;
2537         };
2538 
2539         Option *opt = add_option(name, fun, description, false);
2540         if(opt->get_positional())
2541             throw IncorrectConstruction::PositionalFlag(name);
2542         opt->type_size(0);
2543         opt->multi_option_policy(CLI::MultiOptionPolicy::TakeLast);
2544         return opt;
2545     }
2546 
2547     /// Add option for callback
2548     Option *add_flag_function(std::string name,
2549                               std::function<void(size_t)> function, ///< A function to call, void(size_t)
2550                               std::string description = "") {
2551 
2552         CLI::callback_t fun = [function](CLI::results_t res) {
2553             auto count = static_cast<size_t>(res.size());
2554             function(count);
2555             return true;
2556         };
2557 
2558         Option *opt = add_option(name, fun, description, false);
2559         if(opt->get_positional())
2560             throw IncorrectConstruction::PositionalFlag(name);
2561         opt->type_size(0);
2562         return opt;
2563     }
2564 
2565 #ifdef CLI11_CPP14
2566     /// Add option for callback (C++14 or better only)
2567     Option *add_flag(std::string name,
2568                      std::function<void(size_t)> function, ///< A function to call, void(size_t)
2569                      std::string description = "") {
2570         return add_flag_function(name, function, description);
2571     }
2572 #endif
2573 
2574     /// Add set of options (No default, temp refernce, such as an inline set)
2575     template <typename T>
2576     Option *add_set(std::string name,
2577                     T &member,                   ///< The selected member of the set
2578                     const std::set<T> &&options, ///< The set of possibilities
2579                     std::string description = "") {
2580 
2581         std::string simple_name = CLI::detail::split(name, ',').at(0);
2582         CLI::callback_t fun = [&member, options, simple_name](CLI::results_t res) {
2583             bool retval = detail::lexical_cast(res[0], member);
2584             if(!retval)
2585                 throw ConversionError(res[0], simple_name);
2586             return std::find(std::begin(options), std::end(options), member) != std::end(options);
2587         };
2588 
2589         Option *opt = add_option(name, fun, description, false);
2590         std::string typeval = detail::type_name<T>();
2591         typeval += " in {" + detail::join(options) + "}";
2592         opt->type_name(typeval);
2593         return opt;
2594     }
2595 
2596     /// Add set of options (No default, non-temp refernce, such as an existing set)
2597     template <typename T>
2598     Option *add_set(std::string name,
2599                     T &member,                  ///< The selected member of the set
2600                     const std::set<T> &options, ///< The set of possibilities
2601                     std::string description = "") {
2602 
2603         std::string simple_name = CLI::detail::split(name, ',').at(0);
2604         CLI::callback_t fun = [&member, &options, simple_name](CLI::results_t res) {
2605             bool retval = detail::lexical_cast(res[0], member);
2606             if(!retval)
2607                 throw ConversionError(res[0], simple_name);
2608             return std::find(std::begin(options), std::end(options), member) != std::end(options);
2609         };
2610 
2611         Option *opt = add_option(name, fun, description, false);
2612         opt->type_name_fn(
2613             [&options]() { return std::string(detail::type_name<T>()) + " in {" + detail::join(options) + "}"; });
2614 
2615         return opt;
2616     }
2617 
2618     /// Add set of options (with default, R value, such as an inline set)
2619     template <typename T>
2620     Option *add_set(std::string name,
2621                     T &member,                   ///< The selected member of the set
2622                     const std::set<T> &&options, ///< The set of posibilities
2623                     std::string description,
2624                     bool defaulted) {
2625 
2626         std::string simple_name = CLI::detail::split(name, ',').at(0);
2627         CLI::callback_t fun = [&member, options, simple_name](CLI::results_t res) {
2628             bool retval = detail::lexical_cast(res[0], member);
2629             if(!retval)
2630                 throw ConversionError(res[0], simple_name);
2631             return std::find(std::begin(options), std::end(options), member) != std::end(options);
2632         };
2633 
2634         Option *opt = add_option(name, fun, description, defaulted);
2635         std::string typeval = detail::type_name<T>();
2636         typeval += " in {" + detail::join(options) + "}";
2637         opt->type_name(typeval);
2638         if(defaulted) {
2639             std::stringstream out;
2640             out << member;
2641             opt->default_str(out.str());
2642         }
2643         return opt;
2644     }
2645 
2646     /// Add set of options (with default, L value refernce, such as an existing set)
2647     template <typename T>
2648     Option *add_set(std::string name,
2649                     T &member,                  ///< The selected member of the set
2650                     const std::set<T> &options, ///< The set of posibilities
2651                     std::string description,
2652                     bool defaulted) {
2653 
2654         std::string simple_name = CLI::detail::split(name, ',').at(0);
2655         CLI::callback_t fun = [&member, &options, simple_name](CLI::results_t res) {
2656             bool retval = detail::lexical_cast(res[0], member);
2657             if(!retval)
2658                 throw ConversionError(res[0], simple_name);
2659             return std::find(std::begin(options), std::end(options), member) != std::end(options);
2660         };
2661 
2662         Option *opt = add_option(name, fun, description, defaulted);
2663         opt->type_name_fn(
2664             [&options]() { return std::string(detail::type_name<T>()) + " in {" + detail::join(options) + "}"; });
2665         if(defaulted) {
2666             std::stringstream out;
2667             out << member;
2668             opt->default_str(out.str());
2669         }
2670         return opt;
2671     }
2672 
2673     /// Add set of options, string only, ignore case (no default, R value)
2674     Option *add_set_ignore_case(std::string name,
2675                                 std::string &member,                   ///< The selected member of the set
2676                                 const std::set<std::string> &&options, ///< The set of possibilities
2677                                 std::string description = "") {
2678 
2679         std::string simple_name = CLI::detail::split(name, ',').at(0);
2680         CLI::callback_t fun = [&member, options, simple_name](CLI::results_t res) {
2681             member = detail::to_lower(res[0]);
2682             auto iter = std::find_if(std::begin(options), std::end(options), [&member](std::string val) {
2683                 return detail::to_lower(val) == member;
2684             });
2685             if(iter == std::end(options))
2686                 throw ConversionError(member, simple_name);
2687             else {
2688                 member = *iter;
2689                 return true;
2690             }
2691         };
2692 
2693         Option *opt = add_option(name, fun, description, false);
2694         std::string typeval = detail::type_name<std::string>();
2695         typeval += " in {" + detail::join(options) + "}";
2696         opt->type_name(typeval);
2697 
2698         return opt;
2699     }
2700 
2701     /// Add set of options, string only, ignore case (no default, L value)
2702     Option *add_set_ignore_case(std::string name,
2703                                 std::string &member,                  ///< The selected member of the set
2704                                 const std::set<std::string> &options, ///< The set of possibilities
2705                                 std::string description = "") {
2706 
2707         std::string simple_name = CLI::detail::split(name, ',').at(0);
2708         CLI::callback_t fun = [&member, &options, simple_name](CLI::results_t res) {
2709             member = detail::to_lower(res[0]);
2710             auto iter = std::find_if(std::begin(options), std::end(options), [&member](std::string val) {
2711                 return detail::to_lower(val) == member;
2712             });
2713             if(iter == std::end(options))
2714                 throw ConversionError(member, simple_name);
2715             else {
2716                 member = *iter;
2717                 return true;
2718             }
2719         };
2720 
2721         Option *opt = add_option(name, fun, description, false);
2722         opt->type_name_fn([&options]() {
2723             return std::string(detail::type_name<std::string>()) + " in {" + detail::join(options) + "}";
2724         });
2725 
2726         return opt;
2727     }
2728 
2729     /// Add set of options, string only, ignore case (default, R value)
2730     Option *add_set_ignore_case(std::string name,
2731                                 std::string &member,                   ///< The selected member of the set
2732                                 const std::set<std::string> &&options, ///< The set of posibilities
2733                                 std::string description,
2734                                 bool defaulted) {
2735 
2736         std::string simple_name = CLI::detail::split(name, ',').at(0);
2737         CLI::callback_t fun = [&member, options, simple_name](CLI::results_t res) {
2738             member = detail::to_lower(res[0]);
2739             auto iter = std::find_if(std::begin(options), std::end(options), [&member](std::string val) {
2740                 return detail::to_lower(val) == member;
2741             });
2742             if(iter == std::end(options))
2743                 throw ConversionError(member, simple_name);
2744             else {
2745                 member = *iter;
2746                 return true;
2747             }
2748         };
2749 
2750         Option *opt = add_option(name, fun, description, defaulted);
2751         std::string typeval = detail::type_name<std::string>();
2752         typeval += " in {" + detail::join(options) + "}";
2753         opt->type_name(typeval);
2754         if(defaulted) {
2755             opt->default_str(member);
2756         }
2757         return opt;
2758     }
2759 
2760     /// Add set of options, string only, ignore case (default, L value)
2761     Option *add_set_ignore_case(std::string name,
2762                                 std::string &member,                  ///< The selected member of the set
2763                                 const std::set<std::string> &options, ///< The set of posibilities
2764                                 std::string description,
2765                                 bool defaulted) {
2766 
2767         std::string simple_name = CLI::detail::split(name, ',').at(0);
2768         CLI::callback_t fun = [&member, &options, simple_name](CLI::results_t res) {
2769             member = detail::to_lower(res[0]);
2770             auto iter = std::find_if(std::begin(options), std::end(options), [&member](std::string val) {
2771                 return detail::to_lower(val) == member;
2772             });
2773             if(iter == std::end(options))
2774                 throw ConversionError(member, simple_name);
2775             else {
2776                 member = *iter;
2777                 return true;
2778             }
2779         };
2780 
2781         Option *opt = add_option(name, fun, description, defaulted);
2782         opt->type_name_fn([&options]() {
2783             return std::string(detail::type_name<std::string>()) + " in {" + detail::join(options) + "}";
2784         });
2785         if(defaulted) {
2786             opt->default_str(member);
2787         }
2788         return opt;
2789     }
2790 
2791     /// Add a complex number
2792     template <typename T>
2793     Option *add_complex(std::string name,
2794                         T &variable,
2795                         std::string description = "",
2796                         bool defaulted = false,
2797                         std::string label = "COMPLEX") {
2798 
2799         std::string simple_name = CLI::detail::split(name, ',').at(0);
2800         CLI::callback_t fun = [&variable, simple_name, label](results_t res) {
2801             if(res[1].back() == 'i')
2802                 res[1].pop_back();
2803             double x, y;
2804             bool worked = detail::lexical_cast(res[0], x) && detail::lexical_cast(res[1], y);
2805             if(worked)
2806                 variable = T(x, y);
2807             return worked;
2808         };
2809 
2810         CLI::Option *opt = add_option(name, fun, description, defaulted);
2811         opt->type_name(label)->type_size(2);
2812         if(defaulted) {
2813             std::stringstream out;
2814             out << variable;
2815             opt->default_str(out.str());
2816         }
2817         return opt;
2818     }
2819 
2820     /// Set a configuration ini file option, or clear it if no name passed
2821     Option *set_config(std::string name = "",
2822                        std::string default_filename = "",
2823                        std::string help = "Read an ini file",
2824                        bool required = false) {
2825 
2826         // Remove existing config if present
2827         if(config_ptr_ != nullptr)
2828             remove_option(config_ptr_);
2829 
2830         // Only add config if option passed
2831         if(!name.empty()) {
2832             config_name_ = default_filename;
2833             config_required_ = required;
2834             config_ptr_ = add_option(name, config_name_, help, !default_filename.empty());
2835             config_ptr_->configurable(false);
2836         }
2837 
2838         return config_ptr_;
2839     }
2840 
2841     /// Removes an option from the App. Takes an option pointer. Returns true if found and removed.
2842     bool remove_option(Option *opt) {
2843         auto iterator =
2844             std::find_if(std::begin(options_), std::end(options_), [opt](const Option_p &v) { return v.get() == opt; });
2845         if(iterator != std::end(options_)) {
2846             options_.erase(iterator);
2847             return true;
2848         }
2849         return false;
2850     }
2851 
2852     ///@}
2853     /// @name Subcommmands
2854     ///@{
2855 
2856     /// Add a subcommand. Inherits INHERITABLE and OptionDefaults, and help flag
2857     App *add_subcommand(std::string name, std::string description = "") {
2858         subcommands_.emplace_back(new App(description, name, this));
2859         for(const auto &subc : subcommands_)
2860             if(subc.get() != subcommands_.back().get())
2861                 if(subc->check_name(subcommands_.back()->name_) || subcommands_.back()->check_name(subc->name_))
2862                     throw OptionAlreadyAdded(subc->name_);
2863         return subcommands_.back().get();
2864     }
2865 
2866     /// Check to see if a subcommand is part of this command (doesn't have to be in command line)
2867     App *get_subcommand(App *subcom) const {
2868         for(const App_p &subcomptr : subcommands_)
2869             if(subcomptr.get() == subcom)
2870                 return subcom;
2871         throw OptionNotFound(subcom->get_name());
2872     }
2873 
2874     /// Check to see if a subcommand is part of this command (text version)
2875     App *get_subcommand(std::string subcom) const {
2876         for(const App_p &subcomptr : subcommands_)
2877             if(subcomptr->check_name(subcom))
2878                 return subcomptr.get();
2879         throw OptionNotFound(subcom);
2880     }
2881 
2882     /// Changes the group membership
2883     App *group(std::string name) {
2884         group_ = name;
2885         return this;
2886     }
2887 
2888     /// The argumentless form of require subcommand requires 1 or more subcommands
2889     App *require_subcommand() {
2890         require_subcommand_min_ = 1;
2891         require_subcommand_max_ = 0;
2892         return this;
2893     }
2894 
2895     /// Require a subcommand to be given (does not affect help call)
2896     /// The number required can be given. Negative values indicate maximum
2897     /// number allowed (0 for any number). Max number inheritable.
2898     App *require_subcommand(int value) {
2899         if(value < 0) {
2900             require_subcommand_min_ = 0;
2901             require_subcommand_max_ = static_cast<size_t>(-value);
2902         } else {
2903             require_subcommand_min_ = static_cast<size_t>(value);
2904             require_subcommand_max_ = static_cast<size_t>(value);
2905         }
2906         return this;
2907     }
2908 
2909     /// Explicitly control the number of subcommands required. Setting 0
2910     /// for the max means unlimited number allowed. Max number inheritable.
2911     App *require_subcommand(size_t min, size_t max) {
2912         require_subcommand_min_ = min;
2913         require_subcommand_max_ = max;
2914         return this;
2915     }
2916 
2917     /// Stop subcommand fallthrough, so that parent commands cannot collect commands after subcommand.
2918     /// Default from parent, usually set on parent.
2919     App *fallthrough(bool value = true) {
2920         fallthrough_ = value;
2921         return this;
2922     }
2923 
2924     /// Check to see if this subcommand was parsed, true only if received on command line.
2925     /// This allows the subcommand to be directly checked.
2926     operator bool() const { return parsed_; }
2927 
2928     ///@}
2929     /// @name Extras for subclassing
2930     ///@{
2931 
2932     /// This allows subclasses to inject code before callbacks but after parse.
2933     ///
2934     /// This does not run if any errors or help is thrown.
2935     virtual void pre_callback() {}
2936 
2937     ///@}
2938     /// @name Parsing
2939     ///@{
2940     //
2941     /// Reset the parsed data
2942     void clear() {
2943 
2944         parsed_ = false;
2945         missing_.clear();
2946         parsed_subcommands_.clear();
2947 
2948         for(const Option_p &opt : options_) {
2949             opt->clear();
2950         }
2951         for(const App_p &app : subcommands_) {
2952             app->clear();
2953         }
2954     }
2955 
2956     /// Parses the command line - throws errors
2957     /// This must be called after the options are in but before the rest of the program.
2958     void parse(int argc, const char *const *argv) {
2959         // If the name is not set, read from command line
2960         if(name_.empty())
2961             name_ = argv[0];
2962 
2963         std::vector<std::string> args;
2964         for(int i = argc - 1; i > 0; i--)
2965             args.emplace_back(argv[i]);
2966         parse(args);
2967     }
2968 
2969     /// The real work is done here. Expects a reversed vector.
2970     /// Changes the vector to the remaining options.
2971     void parse(std::vector<std::string> &args) {
2972         // Clear if parsed
2973         if(parsed_)
2974             clear();
2975 
2976         // Redundant (set by _parse on commands/subcommands)
2977         // but placed here to make sure this is cleared when
2978         // running parse after an error is thrown, even by _validate.
2979         parsed_ = true;
2980 
2981         _validate();
2982         _parse(args);
2983         run_callback();
2984     }
2985 
2986     /// Provide a function to print a help message. The function gets access to the App pointer and error.
2987     void failure_message(std::function<std::string(const App *, const Error &e)> function) {
2988         failure_message_ = function;
2989     }
2990 
2991     /// Print a nice error message and return the exit code
2992     int exit(const Error &e, std::ostream &out = std::cout, std::ostream &err = std::cerr) const {
2993 
2994         /// Avoid printing anything if this is a CLI::RuntimeError
2995         if(dynamic_cast<const CLI::RuntimeError *>(&e) != nullptr)
2996             return e.get_exit_code();
2997 
2998         if(dynamic_cast<const CLI::CallForHelp *>(&e) != nullptr) {
2999             out << help();
3000             return e.get_exit_code();
3001         }
3002 
3003         if(dynamic_cast<const CLI::CallForAllHelp *>(&e) != nullptr) {
3004             out << help("", AppFormatMode::All);
3005             return e.get_exit_code();
3006         }
3007 
3008         if(e.get_exit_code() != static_cast<int>(ExitCodes::Success)) {
3009             if(failure_message_)
3010                 err << failure_message_(this, e) << std::flush;
3011         }
3012 
3013         return e.get_exit_code();
3014     }
3015 
3016     ///@}
3017     /// @name Post parsing
3018     ///@{
3019 
3020     /// Counts the number of times the given option was passed.
3021     size_t count(std::string name) const {
3022         for(const Option_p &opt : options_) {
3023             if(opt->check_name(name)) {
3024                 return opt->count();
3025             }
3026         }
3027         throw OptionNotFound(name);
3028     }
3029 
3030     /// Get a subcommand pointer list to the currently selected subcommands (after parsing by by default, in command
3031     /// line order; use parsed = false to get the original definition list.)
3032     std::vector<App *> get_subcommands() const { return parsed_subcommands_; }
3033 
3034     /// Get a filtered subcommand pointer list from the original definition list. An empty function will provide all
3035     /// subcommands (const)
3036     std::vector<const App *> get_subcommands(const std::function<bool(const App *)> &filter) const {
3037         std::vector<const App *> subcomms(subcommands_.size());
3038         std::transform(std::begin(subcommands_), std::end(subcommands_), std::begin(subcomms), [](const App_p &v) {
3039             return v.get();
3040         });
3041 
3042         if(filter) {
3043             subcomms.erase(std::remove_if(std::begin(subcomms),
3044                                           std::end(subcomms),
3045                                           [&filter](const App *app) { return !filter(app); }),
3046                            std::end(subcomms));
3047         }
3048 
3049         return subcomms;
3050     }
3051 
3052     /// Get a filtered subcommand pointer list from the original definition list. An empty function will provide all
3053     /// subcommands
3054     std::vector<App *> get_subcommands(const std::function<bool(App *)> &filter) {
3055         std::vector<App *> subcomms(subcommands_.size());
3056         std::transform(std::begin(subcommands_), std::end(subcommands_), std::begin(subcomms), [](const App_p &v) {
3057             return v.get();
3058         });
3059 
3060         if(filter) {
3061             subcomms.erase(
3062                 std::remove_if(std::begin(subcomms), std::end(subcomms), [&filter](App *app) { return !filter(app); }),
3063                 std::end(subcomms));
3064         }
3065 
3066         return subcomms;
3067     }
3068 
3069     /// Check to see if given subcommand was selected
3070     bool got_subcommand(App *subcom) const {
3071         // get subcom needed to verify that this was a real subcommand
3072         return get_subcommand(subcom)->parsed_;
3073     }
3074 
3075     /// Check with name instead of pointer to see if subcommand was selected
3076     bool got_subcommand(std::string name) const { return get_subcommand(name)->parsed_; }
3077 
3078     ///@}
3079     /// @name Help
3080     ///@{
3081 
3082     /// Set footer.
3083     App *footer(std::string footer) {
3084         footer_ = footer;
3085         return this;
3086     }
3087 
3088     /// Produce a string that could be read in as a config of the current values of the App. Set default_also to include
3089     /// default arguments. Prefix will add a string to the beginning of each option.
3090     std::string config_to_str(bool default_also = false, bool write_description = false) const {
3091         return config_formatter_->to_config(this, default_also, write_description, "");
3092     }
3093 
3094     /// Makes a help message, using the currently configured formatter
3095     /// Will only do one subcommand at a time
3096     std::string help(std::string prev = "", AppFormatMode mode = AppFormatMode::Normal) const {
3097         if(prev.empty())
3098             prev = get_name();
3099         else
3100             prev += " " + get_name();
3101 
3102         // Delegate to subcommand if needed
3103         auto selected_subcommands = get_subcommands();
3104         if(!selected_subcommands.empty())
3105             return selected_subcommands.at(0)->help(prev);
3106         else
3107             return formatter_->make_help(this, prev, mode);
3108     }
3109 
3110     /// Provided for backwards compatibility \deprecated
3111     CLI11_DEPRECATED("Please use footer instead")
3112     App *set_footer(std::string msg) { return footer(msg); }
3113 
3114     /// Provided for backwards compatibility \deprecated
3115     CLI11_DEPRECATED("Please use name instead")
3116     App *set_name(std::string msg) { return name(msg); }
3117 
3118     /// Provided for backwards compatibility \deprecated
3119     CLI11_DEPRECATED("Please use callback instead")
3120     App *set_callback(std::function<void()> fn) { return callback(fn); }
3121 
3122     ///@}
3123     /// @name Getters
3124     ///@{
3125 
3126     /// Access the formatter
3127     std::shared_ptr<FormatterBase> get_formatter() const { return formatter_; }
3128 
3129     /// Access the config formatter
3130     std::shared_ptr<Config> get_config_formatter() const { return config_formatter_; }
3131 
3132     /// Get the app or subcommand description
3133     std::string get_description() const { return description_; }
3134 
3135     /// Get the list of options (user facing function, so returns raw pointers), has optional filter function
3136     std::vector<const Option *> get_options(const std::function<bool(const Option *)> filter = {}) const {
3137         std::vector<const Option *> options(options_.size());
3138         std::transform(std::begin(options_), std::end(options_), std::begin(options), [](const Option_p &val) {
3139             return val.get();
3140         });
3141 
3142         if(filter) {
3143             options.erase(std::remove_if(std::begin(options),
3144                                          std::end(options),
3145                                          [&filter](const Option *opt) { return !filter(opt); }),
3146                           std::end(options));
3147         }
3148 
3149         return options;
3150     }
3151 
3152     /// Get an option by name
3153     const Option *get_option(std::string name) const {
3154         for(const Option_p &opt : options_) {
3155             if(opt->check_name(name)) {
3156                 return opt.get();
3157             }
3158         }
3159         throw OptionNotFound(name);
3160     }
3161 
3162     /// Get an option by name (non-const version)
3163     Option *get_option(std::string name) {
3164         for(Option_p &opt : options_) {
3165             if(opt->check_name(name)) {
3166                 return opt.get();
3167             }
3168         }
3169         throw OptionNotFound(name);
3170     }
3171 
3172     /// Check the status of ignore_case
3173     bool get_ignore_case() const { return ignore_case_; }
3174 
3175     /// Check the status of fallthrough
3176     bool get_fallthrough() const { return fallthrough_; }
3177 
3178     /// Get the group of this subcommand
3179     const std::string &get_group() const { return group_; }
3180 
3181     /// Get footer.
3182     std::string get_footer() const { return footer_; }
3183 
3184     /// Get the required min subcommand value
3185     size_t get_require_subcommand_min() const { return require_subcommand_min_; }
3186 
3187     /// Get the required max subcommand value
3188     size_t get_require_subcommand_max() const { return require_subcommand_max_; }
3189 
3190     /// Get the prefix command status
3191     bool get_prefix_command() const { return prefix_command_; }
3192 
3193     /// Get the status of allow extras
3194     bool get_allow_extras() const { return allow_extras_; }
3195 
3196     /// Get the status of allow extras
3197     bool get_allow_config_extras() const { return allow_config_extras_; }
3198 
3199     /// Get a pointer to the help flag.
3200     Option *get_help_ptr() { return help_ptr_; }
3201 
3202     /// Get a pointer to the help flag. (const)
3203     const Option *get_help_ptr() const { return help_ptr_; }
3204 
3205     /// Get a pointer to the help all flag. (const)
3206     const Option *get_help_all_ptr() const { return help_all_ptr_; }
3207 
3208     /// Get a pointer to the config option.
3209     Option *get_config_ptr() { return config_ptr_; }
3210 
3211     /// Get a pointer to the config option. (const)
3212     const Option *get_config_ptr() const { return config_ptr_; }
3213 
3214     /// Get the parent of this subcommand (or nullptr if master app)
3215     App *get_parent() { return parent_; }
3216 
3217     /// Get the parent of this subcommand (or nullptr if master app) (const version)
3218     const App *get_parent() const { return parent_; }
3219 
3220     /// Get the name of the current app
3221     std::string get_name() const { return name_; }
3222 
3223     /// Check the name, case insensitive if set
3224     bool check_name(std::string name_to_check) const {
3225         std::string local_name = name_;
3226         if(ignore_case_) {
3227             local_name = detail::to_lower(name_);
3228             name_to_check = detail::to_lower(name_to_check);
3229         }
3230 
3231         return local_name == name_to_check;
3232     }
3233 
3234     /// Get the groups available directly from this option (in order)
3235     std::vector<std::string> get_groups() const {
3236         std::vector<std::string> groups;
3237 
3238         for(const Option_p &opt : options_) {
3239             // Add group if it is not already in there
3240             if(std::find(groups.begin(), groups.end(), opt->get_group()) == groups.end()) {
3241                 groups.push_back(opt->get_group());
3242             }
3243         }
3244 
3245         return groups;
3246     }
3247 
3248     /// This gets a vector of pointers with the original parse order
3249     const std::vector<Option *> &parse_order() const { return parse_order_; }
3250 
3251     /// This returns the missing options from the current subcommand
3252     std::vector<std::string> remaining(bool recurse = false) const {
3253         std::vector<std::string> miss_list;
3254         for(const std::pair<detail::Classifer, std::string> &miss : missing_) {
3255             miss_list.push_back(std::get<1>(miss));
3256         }
3257 
3258         // Recurse into subcommands
3259         if(recurse) {
3260             for(const App *sub : parsed_subcommands_) {
3261                 std::vector<std::string> output = sub->remaining(recurse);
3262                 std::copy(std::begin(output), std::end(output), std::back_inserter(miss_list));
3263             }
3264         }
3265         return miss_list;
3266     }
3267 
3268     /// This returns the number of remaining options, minus the -- seperator
3269     size_t remaining_size(bool recurse = false) const {
3270         auto count = static_cast<size_t>(std::count_if(
3271             std::begin(missing_), std::end(missing_), [](const std::pair<detail::Classifer, std::string> &val) {
3272                 return val.first != detail::Classifer::POSITIONAL_MARK;
3273             }));
3274         if(recurse) {
3275             for(const App_p &sub : subcommands_) {
3276                 count += sub->remaining_size(recurse);
3277             }
3278         }
3279         return count;
3280     }
3281 
3282     ///@}
3283 
3284   protected:
3285     /// Check the options to make sure there are no conflicts.
3286     ///
3287     /// Currently checks to see if multiple positionals exist with -1 args
3288     void _validate() const {
3289         auto count = std::count_if(std::begin(options_), std::end(options_), [](const Option_p &opt) {
3290             return opt->get_items_expected() < 0 && opt->get_positional();
3291         });
3292         if(count > 1)
3293             throw InvalidError(name_);
3294         for(const App_p &app : subcommands_)
3295             app->_validate();
3296     }
3297 
3298     /// Internal function to run (App) callback, top down
3299     void run_callback() {
3300         pre_callback();
3301         if(callback_)
3302             callback_();
3303         for(App *subc : get_subcommands()) {
3304             subc->run_callback();
3305         }
3306     }
3307 
3308     /// Check to see if a subcommand is valid. Give up immediately if subcommand max has been reached.
3309     bool _valid_subcommand(const std::string &current) const {
3310         // Don't match if max has been reached - but still check parents
3311         if(require_subcommand_max_ != 0 && parsed_subcommands_.size() >= require_subcommand_max_) {
3312             return parent_ != nullptr && parent_->_valid_subcommand(current);
3313         }
3314 
3315         for(const App_p &com : subcommands_)
3316             if(com->check_name(current) && !*com)
3317                 return true;
3318 
3319         // Check parent if exists, else return false
3320         return parent_ != nullptr && parent_->_valid_subcommand(current);
3321     }
3322 
3323     /// Selects a Classifier enum based on the type of the current argument
3324     detail::Classifer _recognize(const std::string &current) const {
3325         std::string dummy1, dummy2;
3326 
3327         if(current == "--")
3328             return detail::Classifer::POSITIONAL_MARK;
3329         if(_valid_subcommand(current))
3330             return detail::Classifer::SUBCOMMAND;
3331         if(detail::split_long(current, dummy1, dummy2))
3332             return detail::Classifer::LONG;
3333         if(detail::split_short(current, dummy1, dummy2))
3334             return detail::Classifer::SHORT;
3335         return detail::Classifer::NONE;
3336     }
3337 
3338     /// Internal parse function
3339     void _parse(std::vector<std::string> &args) {
3340         parsed_ = true;
3341         bool positional_only = false;
3342 
3343         while(!args.empty()) {
3344             _parse_single(args, positional_only);
3345         }
3346 
3347         for(const Option_p &opt : options_)
3348             if(opt->get_short_circuit() && opt->count() > 0)
3349                 opt->run_callback();
3350 
3351         // Process an INI file
3352         if(config_ptr_ != nullptr) {
3353             if(*config_ptr_) {
3354                 config_ptr_->run_callback();
3355                 config_required_ = true;
3356             }
3357             if(!config_name_.empty()) {
3358                 try {
3359                     std::vector<ConfigItem> values = config_formatter_->from_file(config_name_);
3360                     _parse_config(values);
3361                 } catch(const FileError &) {
3362                     if(config_required_)
3363                         throw;
3364                 }
3365             }
3366         }
3367 
3368         // Get envname options if not yet passed
3369         for(const Option_p &opt : options_) {
3370             if(opt->count() == 0 && !opt->envname_.empty()) {
3371                 char *buffer = nullptr;
3372                 std::string ename_string;
3373 
3374 #ifdef _MSC_VER
3375                 // Windows version
3376                 size_t sz = 0;
3377                 if(_dupenv_s(&buffer, &sz, opt->envname_.c_str()) == 0 && buffer != nullptr) {
3378                     ename_string = std::string(buffer);
3379                     free(buffer);
3380                 }
3381 #else
3382                 // This also works on Windows, but gives a warning
3383                 buffer = std::getenv(opt->envname_.c_str());
3384                 if(buffer != nullptr)
3385                     ename_string = std::string(buffer);
3386 #endif
3387 
3388                 if(!ename_string.empty()) {
3389                     opt->add_result(ename_string);
3390                 }
3391             }
3392         }
3393 
3394         // Process callbacks
3395         for(const Option_p &opt : options_) {
3396             if(opt->count() > 0 && !opt->get_callback_run()) {
3397                 opt->run_callback();
3398             }
3399         }
3400 
3401         // Verify required options
3402         for(const Option_p &opt : options_) {
3403             // Required or partially filled
3404             if(opt->get_required() || opt->count() != 0) {
3405                 // Make sure enough -N arguments parsed (+N is already handled in parsing function)
3406                 if(opt->get_items_expected() < 0 && opt->count() < static_cast<size_t>(-opt->get_items_expected()))
3407                     throw ArgumentMismatch::AtLeast(opt->get_name(), -opt->get_items_expected());
3408 
3409                 // Required but empty
3410                 if(opt->get_required() && opt->count() == 0)
3411                     throw RequiredError(opt->get_name());
3412             }
3413             // Requires
3414             for(const Option *opt_req : opt->requires_)
3415                 if(opt->count() > 0 && opt_req->count() == 0)
3416                     throw RequiresError(opt->get_name(), opt_req->get_name());
3417             // Excludes
3418             for(const Option *opt_ex : opt->excludes_)
3419                 if(opt->count() > 0 && opt_ex->count() != 0)
3420                     throw ExcludesError(opt->get_name(), opt_ex->get_name());
3421         }
3422 
3423         auto selected_subcommands = get_subcommands();
3424         if(require_subcommand_min_ > selected_subcommands.size())
3425             throw RequiredError::Subcommand(require_subcommand_min_);
3426 
3427         // Convert missing (pairs) to extras (string only)
3428         if(!(allow_extras_ || prefix_command_)) {
3429             size_t num_left_over = remaining_size();
3430             if(num_left_over > 0) {
3431                 args = remaining(false);
3432                 throw ExtrasError(args);
3433             }
3434         }
3435 
3436         if(parent_ == nullptr) {
3437             args = remaining(false);
3438         }
3439     }
3440 
3441     /// Parse one config param, return false if not found in any subcommand, remove if it is
3442     ///
3443     /// If this has more than one dot.separated.name, go into the subcommand matching it
3444     /// Returns true if it managed to find the option, if false you'll need to remove the arg manually.
3445     void _parse_config(std::vector<ConfigItem> &args) {
3446         for(ConfigItem item : args) {
3447             if(!_parse_single_config(item) && !allow_config_extras_)
3448                 throw ConfigError::Extras(item.fullname());
3449         }
3450     }
3451 
3452     /// Fill in a single config option
3453     bool _parse_single_config(const ConfigItem &item, size_t level = 0) {
3454         if(level < item.parents.size()) {
3455             App *subcom;
3456             try {
3457                 std::cout << item.parents.at(level) << std::endl;
3458                 subcom = get_subcommand(item.parents.at(level));
3459             } catch(const OptionNotFound &) {
3460                 return false;
3461             }
3462             return subcom->_parse_single_config(item, level + 1);
3463         }
3464 
3465         Option *op;
3466         try {
3467             op = get_option("--" + item.name);
3468         } catch(const OptionNotFound &) {
3469             // If the option was not present
3470             if(get_allow_config_extras())
3471                 // Should we worry about classifying the extras properly?
3472                 missing_.emplace_back(detail::Classifer::NONE, item.fullname());
3473             return false;
3474         }
3475 
3476         if(!op->get_configurable())
3477             throw ConfigError::NotConfigurable(item.fullname());
3478 
3479         if(op->empty()) {
3480             // Flag parsing
3481             if(op->get_type_size() == 0) {
3482                 op->set_results(config_formatter_->to_flag(item));
3483             } else {
3484                 op->set_results(item.inputs);
3485                 op->run_callback();
3486             }
3487         }
3488 
3489         return true;
3490     }
3491 
3492     /// Parse "one" argument (some may eat more than one), delegate to parent if fails, add to missing if missing from
3493     /// master
3494     void _parse_single(std::vector<std::string> &args, bool &positional_only) {
3495 
3496         detail::Classifer classifer = positional_only ? detail::Classifer::NONE : _recognize(args.back());
3497         switch(classifer) {
3498         case detail::Classifer::POSITIONAL_MARK:
3499             missing_.emplace_back(classifer, args.back());
3500             args.pop_back();
3501             positional_only = true;
3502             break;
3503         case detail::Classifer::SUBCOMMAND:
3504             _parse_subcommand(args);
3505             break;
3506         case detail::Classifer::LONG:
3507             // If already parsed a subcommand, don't accept options_
3508             _parse_arg(args, true);
3509             break;
3510         case detail::Classifer::SHORT:
3511             // If already parsed a subcommand, don't accept options_
3512             _parse_arg(args, false);
3513             break;
3514         case detail::Classifer::NONE:
3515             // Probably a positional or something for a parent (sub)command
3516             _parse_positional(args);
3517         }
3518     }
3519 
3520     /// Count the required remaining positional arguments
3521     size_t _count_remaining_positionals(bool required = false) const {
3522         size_t retval = 0;
3523         for(const Option_p &opt : options_)
3524             if(opt->get_positional() && (!required || opt->get_required()) && opt->get_items_expected() > 0 &&
3525                static_cast<int>(opt->count()) < opt->get_items_expected())
3526                 retval = static_cast<size_t>(opt->get_items_expected()) - opt->count();
3527 
3528         return retval;
3529     }
3530 
3531     /// Parse a positional, go up the tree to check
3532     void _parse_positional(std::vector<std::string> &args) {
3533 
3534         std::string positional = args.back();
3535         for(const Option_p &opt : options_) {
3536             // Eat options, one by one, until done
3537             if(opt->get_positional() &&
3538                (static_cast<int>(opt->count()) < opt->get_items_expected() || opt->get_items_expected() < 0)) {
3539 
3540                 opt->add_result(positional);
3541                 parse_order_.push_back(opt.get());
3542                 args.pop_back();
3543                 return;
3544             }
3545         }
3546 
3547         if(parent_ != nullptr && fallthrough_)
3548             return parent_->_parse_positional(args);
3549         else {
3550             args.pop_back();
3551             missing_.emplace_back(detail::Classifer::NONE, positional);
3552 
3553             if(prefix_command_) {
3554                 while(!args.empty()) {
3555                     missing_.emplace_back(detail::Classifer::NONE, args.back());
3556                     args.pop_back();
3557                 }
3558             }
3559         }
3560     }
3561 
3562     /// Parse a subcommand, modify args and continue
3563     ///
3564     /// Unlike the others, this one will always allow fallthrough
3565     void _parse_subcommand(std::vector<std::string> &args) {
3566         if(_count_remaining_positionals(/* required */ true) > 0)
3567             return _parse_positional(args);
3568         for(const App_p &com : subcommands_) {
3569             if(com->check_name(args.back())) {
3570                 args.pop_back();
3571                 if(std::find(std::begin(parsed_subcommands_), std::end(parsed_subcommands_), com.get()) ==
3572                    std::end(parsed_subcommands_))
3573                     parsed_subcommands_.push_back(com.get());
3574                 com->_parse(args);
3575                 return;
3576             }
3577         }
3578         if(parent_ != nullptr)
3579             return parent_->_parse_subcommand(args);
3580         else
3581             throw HorribleError("Subcommand " + args.back() + " missing");
3582     }
3583 
3584     /// Parse a short (false) or long (true) argument, must be at the top of the list
3585     void _parse_arg(std::vector<std::string> &args, bool second_dash) {
3586 
3587         detail::Classifer current_type = second_dash ? detail::Classifer::LONG : detail::Classifer::SHORT;
3588 
3589         std::string current = args.back();
3590 
3591         std::string name;
3592         std::string value;
3593         std::string rest;
3594 
3595         if(second_dash) {
3596             if(!detail::split_long(current, name, value))
3597                 throw HorribleError("Long parsed but missing (you should not see this):" + args.back());
3598         } else {
3599             if(!detail::split_short(current, name, rest))
3600                 throw HorribleError("Short parsed but missing! You should not see this");
3601         }
3602 
3603         auto op_ptr = std::find_if(std::begin(options_), std::end(options_), [name, second_dash](const Option_p &opt) {
3604             return second_dash ? opt->check_lname(name) : opt->check_sname(name);
3605         });
3606 
3607         // Option not found
3608         if(op_ptr == std::end(options_)) {
3609             // If a subcommand, try the master command
3610             if(parent_ != nullptr && fallthrough_)
3611                 return parent_->_parse_arg(args, second_dash);
3612             // Otherwise, add to missing
3613             else {
3614                 args.pop_back();
3615                 missing_.emplace_back(current_type, current);
3616                 return;
3617             }
3618         }
3619 
3620         args.pop_back();
3621 
3622         // Get a reference to the pointer to make syntax bearable
3623         Option_p &op = *op_ptr;
3624 
3625         int num = op->get_items_expected();
3626 
3627         // Make sure we always eat the minimum for unlimited vectors
3628         int collected = 0;
3629 
3630         // --this=value
3631         if(!value.empty()) {
3632             // If exact number expected
3633             if(num > 0)
3634                 num--;
3635             op->add_result(value);
3636             parse_order_.push_back(op.get());
3637             collected += 1;
3638         } else if(num == 0) {
3639             op->add_result("");
3640             parse_order_.push_back(op.get());
3641             // -Trest
3642         } else if(!rest.empty()) {
3643             if(num > 0)
3644                 num--;
3645             op->add_result(rest);
3646             parse_order_.push_back(op.get());
3647             rest = "";
3648             collected += 1;
3649         }
3650 
3651         // Unlimited vector parser
3652         if(num < 0) {
3653             while(!args.empty() && _recognize(args.back()) == detail::Classifer::NONE) {
3654                 if(collected >= -num) {
3655                     // We could break here for allow extras, but we don't
3656 
3657                     // If any positionals remain, don't keep eating
3658                     if(_count_remaining_positionals() > 0)
3659                         break;
3660                 }
3661                 op->add_result(args.back());
3662                 parse_order_.push_back(op.get());
3663                 args.pop_back();
3664                 collected++;
3665             }
3666 
3667             // Allow -- to end an unlimited list and "eat" it
3668             if(!args.empty() && _recognize(args.back()) == detail::Classifer::POSITIONAL_MARK)
3669                 args.pop_back();
3670 
3671         } else {
3672             while(num > 0 && !args.empty()) {
3673                 num--;
3674                 std::string current_ = args.back();
3675                 args.pop_back();
3676                 op->add_result(current_);
3677                 parse_order_.push_back(op.get());
3678             }
3679 
3680             if(num > 0) {
3681                 throw ArgumentMismatch::TypedAtLeast(op->get_name(), num, op->get_type_name());
3682             }
3683         }
3684 
3685         if(!rest.empty()) {
3686             rest = "-" + rest;
3687             args.push_back(rest);
3688         }
3689     }
3690 };
3691 
3692 namespace FailureMessage {
3693 
3694 inline std::string simple(const App *app, const Error &e) {
3695     std::string header = std::string(e.what()) + "\n";
3696     if(app->get_help_ptr() != nullptr)
3697         header += "Run with " + app->get_help_ptr()->get_name() + " for more information.\n";
3698     return header;
3699 }
3700 
3701 inline std::string help(const App *app, const Error &e) {
3702     std::string header = std::string("ERROR: ") + e.get_name() + ": " + e.what() + "\n";
3703     header += app->help();
3704     return header;
3705 }
3706 
3707 } // namespace FailureMessage
3708 
3709 namespace detail {
3710 /// This class is simply to allow tests access to App's protected functions
3711 struct AppFriend {
3712 
3713     /// Wrap _parse_short, perfectly forward arguments and return
3714     template <typename... Args>
3715     static auto parse_arg(App *app, Args &&... args) ->
3716         typename std::result_of<decltype (&App::_parse_arg)(App, Args...)>::type {
3717         return app->_parse_arg(std::forward<Args>(args)...);
3718     }
3719 
3720     /// Wrap _parse_subcommand, perfectly forward arguments and return
3721     template <typename... Args>
3722     static auto parse_subcommand(App *app, Args &&... args) ->
3723         typename std::result_of<decltype (&App::_parse_subcommand)(App, Args...)>::type {
3724         return app->_parse_subcommand(std::forward<Args>(args)...);
3725     }
3726 };
3727 } // namespace detail
3728 
3729 } // namespace CLI
3730 
3731 // From CLI/Config.hpp:
3732 
3733 namespace CLI {
3734 
3735 inline std::string
3736 ConfigINI::to_config(const App *app, bool default_also, bool write_description, std::string prefix) const {
3737     std::stringstream out;
3738     for(const Option *opt : app->get_options({})) {
3739 
3740         // Only process option with a long-name and configurable
3741         if(!opt->get_lnames().empty() && opt->get_configurable()) {
3742             std::string name = prefix + opt->get_lnames()[0];
3743             std::string value;
3744 
3745             // Non-flags
3746             if(opt->get_type_size() != 0) {
3747 
3748                 // If the option was found on command line
3749                 if(opt->count() > 0)
3750                     value = detail::ini_join(opt->results());
3751 
3752                 // If the option has a default and is requested by optional argument
3753                 else if(default_also && !opt->get_defaultval().empty())
3754                     value = opt->get_defaultval();
3755                 // Flag, one passed
3756             } else if(opt->count() == 1) {
3757                 value = "true";
3758 
3759                 // Flag, multiple passed
3760             } else if(opt->count() > 1) {
3761                 value = std::to_string(opt->count());
3762 
3763                 // Flag, not present
3764             } else if(opt->count() == 0 && default_also) {
3765                 value = "false";
3766             }
3767 
3768             if(!value.empty()) {
3769                 if(write_description && opt->has_description()) {
3770                     if(static_cast<int>(out.tellp()) != 0) {
3771                         out << std::endl;
3772                     }
3773                     out << "; " << detail::fix_newlines("; ", opt->get_description()) << std::endl;
3774                 }
3775                 out << name << "=" << value << std::endl;
3776             }
3777         }
3778     }
3779 
3780     for(const App *subcom : app->get_subcommands({}))
3781         out << to_config(subcom, default_also, write_description, prefix + subcom->get_name() + ".");
3782 
3783     return out.str();
3784 }
3785 
3786 } // namespace CLI
3787 
3788 // From CLI/Formatter.hpp:
3789 
3790 namespace CLI {
3791 
3792 inline std::string
3793 Formatter::make_group(std::string group, bool is_positional, std::vector<const Option *> opts) const {
3794     std::stringstream out;
3795 
3796     out << "\n" << group << ":\n";
3797     for(const Option *opt : opts) {
3798         out << make_option(opt, is_positional);
3799     }
3800 
3801     return out.str();
3802 }
3803 
3804 inline std::string Formatter::make_positionals(const App *app) const {
3805     std::vector<const Option *> opts =
3806         app->get_options([](const Option *opt) { return !opt->get_group().empty() && opt->get_positional(); });
3807 
3808     if(opts.empty())
3809         return std::string();
3810     else
3811         return make_group(get_label("Positionals"), true, opts);
3812 }
3813 
3814 inline std::string Formatter::make_groups(const App *app, AppFormatMode mode) const {
3815     std::stringstream out;
3816     std::vector<std::string> groups = app->get_groups();
3817 
3818     // Options
3819     for(const std::string &group : groups) {
3820         std::vector<const Option *> opts = app->get_options([app, mode, &group](const Option *opt) {
3821             return opt->get_group() == group                    // Must be in the right group
3822                    && opt->nonpositional()                      // Must not be a positional
3823                    && (mode != AppFormatMode::Sub               // If mode is Sub, then
3824                        || (app->get_help_ptr() != opt           // Ignore help pointer
3825                            && app->get_help_all_ptr() != opt)); // Ignore help all pointer
3826         });
3827         if(!group.empty() && !opts.empty()) {
3828             out << make_group(group, false, opts);
3829 
3830             if(group != groups.back())
3831                 out << "\n";
3832         }
3833     }
3834 
3835     return out.str();
3836 }
3837 
3838 inline std::string Formatter::make_description(const App *app) const {
3839     std::string desc = app->get_description();
3840 
3841     if(!desc.empty())
3842         return desc + "\n";
3843     else
3844         return "";
3845 }
3846 
3847 inline std::string Formatter::make_usage(const App *app, std::string name) const {
3848     std::stringstream out;
3849 
3850     out << get_label("Usage") << ":" << (name.empty() ? "" : " ") << name;
3851 
3852     std::vector<std::string> groups = app->get_groups();
3853 
3854     // Print an Options badge if any options exist
3855     std::vector<const Option *> non_pos_options =
3856         app->get_options([](const Option *opt) { return opt->nonpositional(); });
3857     if(!non_pos_options.empty())
3858         out << " [" << get_label("OPTIONS") << "]";
3859 
3860     // Positionals need to be listed here
3861     std::vector<const Option *> positionals = app->get_options([](const Option *opt) { return opt->get_positional(); });
3862 
3863     // Print out positionals if any are left
3864     if(!positionals.empty()) {
3865         // Convert to help names
3866         std::vector<std::string> positional_names(positionals.size());
3867         std::transform(positionals.begin(), positionals.end(), positional_names.begin(), [this](const Option *opt) {
3868             return make_option_usage(opt);
3869         });
3870 
3871         out << " " << detail::join(positional_names, " ");
3872     }
3873 
3874     // Add a marker if subcommands are expected or optional
3875     if(!app->get_subcommands({}).empty()) {
3876         out << " " << (app->get_require_subcommand_min() == 0 ? "[" : "")
3877             << get_label(app->get_require_subcommand_max() < 2 || app->get_require_subcommand_min() > 1 ? "SUBCOMMAND"
3878                                                                                                         : "SUBCOMMANDS")
3879             << (app->get_require_subcommand_min() == 0 ? "]" : "");
3880     }
3881 
3882     out << std::endl;
3883 
3884     return out.str();
3885 }
3886 
3887 inline std::string Formatter::make_footer(const App *app) const {
3888     std::string footer = app->get_footer();
3889     if(!footer.empty())
3890         return footer + "\n";
3891     else
3892         return "";
3893 }
3894 
3895 inline std::string Formatter::make_help(const App *app, std::string name, AppFormatMode mode) const {
3896 
3897     // This immediatly forwards to the make_expanded method. This is done this way so that subcommands can
3898     // have overridden formatters
3899     if(mode == AppFormatMode::Sub)
3900         return make_expanded(app);
3901 
3902     std::stringstream out;
3903 
3904     out << make_description(app);
3905     out << make_usage(app, name);
3906     out << make_positionals(app);
3907     out << make_groups(app, mode);
3908     out << make_subcommands(app, mode);
3909     out << make_footer(app);
3910 
3911     return out.str();
3912 }
3913 
3914 inline std::string Formatter::make_subcommands(const App *app, AppFormatMode mode) const {
3915     std::stringstream out;
3916 
3917     std::vector<const App *> subcommands = app->get_subcommands({});
3918 
3919     // Make a list in definition order of the groups seen
3920     std::vector<std::string> subcmd_groups_seen;
3921     for(const App *com : subcommands) {
3922         std::string group_key = com->get_group();
3923         if(!group_key.empty() &&
3924            std::find_if(subcmd_groups_seen.begin(), subcmd_groups_seen.end(), [&group_key](std::string a) {
3925                return detail::to_lower(a) == detail::to_lower(group_key);
3926            }) == subcmd_groups_seen.end())
3927             subcmd_groups_seen.push_back(group_key);
3928     }
3929 
3930     // For each group, filter out and print subcommands
3931     for(const std::string &group : subcmd_groups_seen) {
3932         out << "\n" << group << ":\n";
3933         std::vector<const App *> subcommands_group = app->get_subcommands(
3934             [&group](const App *app) { return detail::to_lower(app->get_group()) == detail::to_lower(group); });
3935         for(const App *new_com : subcommands_group) {
3936             if(mode != AppFormatMode::All) {
3937                 out << make_subcommand(new_com);
3938             } else {
3939                 out << new_com->help(new_com->get_name(), AppFormatMode::Sub);
3940                 if(new_com != subcommands_group.back())
3941                     out << "\n";
3942             }
3943         }
3944     }
3945 
3946     return out.str();
3947 }
3948 
3949 inline std::string Formatter::make_subcommand(const App *sub) const {
3950     std::stringstream out;
3951     detail::format_help(out, sub->get_name(), sub->get_description(), column_width_);
3952     return out.str();
3953 }
3954 
3955 inline std::string Formatter::make_expanded(const App *sub) const {
3956     std::stringstream out;
3957     if(sub->get_description().empty())
3958         out << sub->get_name();
3959     else
3960         out << sub->get_name() << " -> " << sub->get_description();
3961     out << make_groups(sub, AppFormatMode::Sub);
3962     return out.str();
3963 }
3964 
3965 inline std::string Formatter::make_option_name(const Option *opt, bool is_positional) const {
3966     if(is_positional)
3967         return opt->get_name(true, false);
3968     else
3969         return opt->get_name(false, true);
3970 }
3971 
3972 inline std::string Formatter::make_option_opts(const Option *opt) const {
3973     std::stringstream out;
3974 
3975     if(opt->get_type_size() != 0) {
3976         if(!opt->get_type_name().empty())
3977             out << " " << get_label(opt->get_type_name());
3978         if(!opt->get_defaultval().empty())
3979             out << "=" << opt->get_defaultval();
3980         if(opt->get_expected() > 1)
3981             out << " x " << opt->get_expected();
3982         if(opt->get_expected() == -1)
3983             out << " ...";
3984         if(opt->get_required())
3985             out << " " << get_label("REQUIRED");
3986     }
3987     if(!opt->get_envname().empty())
3988         out << " (" << get_label("Env") << ":" << opt->get_envname() << ")";
3989     if(!opt->get_needs().empty()) {
3990         out << " " << get_label("Needs") << ":";
3991         for(const Option *op : opt->get_needs())
3992             out << " " << op->get_name();
3993     }
3994     if(!opt->get_excludes().empty()) {
3995         out << " " << get_label("Excludes") << ":";
3996         for(const Option *op : opt->get_excludes())
3997             out << " " << op->get_name();
3998     }
3999     return out.str();
4000 }
4001 
4002 inline std::string Formatter::make_option_desc(const Option *opt) const { return opt->get_description(); }
4003 
4004 inline std::string Formatter::make_option_usage(const Option *opt) const {
4005     // Note that these are positionals usages
4006     std::stringstream out;
4007     out << make_option_name(opt, true);
4008 
4009     if(opt->get_expected() > 1)
4010         out << "(" << std::to_string(opt->get_expected()) << "x)";
4011     else if(opt->get_expected() < 0)
4012         out << "...";
4013 
4014     return opt->get_required() ? out.str() : "[" + out.str() + "]";
4015 }
4016 
4017 } // namespace CLI
4018 
4019 
4020 
4021 // Alias to ot
4022 namespace ot {
4023   using ArgParse = CLI::App;
4024 };
4025 
4026 
4027 
4028 
4029 
4030 
4031 
4032 
4033 
4034 
4035