Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:54:43

0001 // Copyright (c) 2017-2023, University of Cincinnati, developed by Henry Schreiner
0002 // under NSF AWARD 1414736 and by the respective contributors.
0003 // All rights reserved.
0004 //
0005 // SPDX-License-Identifier: BSD-3-Clause
0006 
0007 #pragma once
0008 
0009 // [CLI11:public_includes:set]
0010 #include <algorithm>
0011 #include <cstdint>
0012 #include <functional>
0013 #include <iostream>
0014 #include <iterator>
0015 #include <memory>
0016 #include <numeric>
0017 #include <set>
0018 #include <sstream>
0019 #include <string>
0020 #include <utility>
0021 #include <vector>
0022 // [CLI11:public_includes:end]
0023 
0024 // CLI Library includes
0025 #include "ConfigFwd.hpp"
0026 #include "Error.hpp"
0027 #include "FormatterFwd.hpp"
0028 #include "Macros.hpp"
0029 #include "Option.hpp"
0030 #include "Split.hpp"
0031 #include "StringTools.hpp"
0032 #include "TypeTools.hpp"
0033 
0034 namespace CLI {
0035 // [CLI11:app_hpp:verbatim]
0036 
0037 #ifndef CLI11_PARSE
0038 #define CLI11_PARSE(app, argc, argv)                                                                                   \
0039     try {                                                                                                              \
0040         (app).parse((argc), (argv));                                                                                   \
0041     } catch(const CLI::ParseError &e) {                                                                                \
0042         return (app).exit(e);                                                                                          \
0043     }
0044 #endif
0045 
0046 namespace detail {
0047 enum class Classifier { NONE, POSITIONAL_MARK, SHORT, LONG, WINDOWS_STYLE, SUBCOMMAND, SUBCOMMAND_TERMINATOR };
0048 struct AppFriend;
0049 }  // namespace detail
0050 
0051 namespace FailureMessage {
0052 /// Printout a clean, simple message on error (the default in CLI11 1.5+)
0053 CLI11_INLINE std::string simple(const App *app, const Error &e);
0054 
0055 /// Printout the full help string on error (if this fn is set, the old default for CLI11)
0056 CLI11_INLINE std::string help(const App *app, const Error &e);
0057 }  // namespace FailureMessage
0058 
0059 /// enumeration of modes of how to deal with extras in config files
0060 
0061 enum class config_extras_mode : char { error = 0, ignore, ignore_all, capture };
0062 
0063 class App;
0064 
0065 using App_p = std::shared_ptr<App>;
0066 
0067 namespace detail {
0068 /// helper functions for adding in appropriate flag modifiers for add_flag
0069 
0070 template <typename T, enable_if_t<!std::is_integral<T>::value || (sizeof(T) <= 1U), detail::enabler> = detail::dummy>
0071 Option *default_flag_modifiers(Option *opt) {
0072     return opt->always_capture_default();
0073 }
0074 
0075 /// summing modifiers
0076 template <typename T, enable_if_t<std::is_integral<T>::value && (sizeof(T) > 1U), detail::enabler> = detail::dummy>
0077 Option *default_flag_modifiers(Option *opt) {
0078     return opt->multi_option_policy(MultiOptionPolicy::Sum)->default_str("0")->force_callback();
0079 }
0080 
0081 }  // namespace detail
0082 
0083 class Option_group;
0084 /// Creates a command line program, with very few defaults.
0085 /** To use, create a new `Program()` instance with `argc`, `argv`, and a help description. The templated
0086  *  add_option methods make it easy to prepare options. Remember to call `.start` before starting your
0087  * program, so that the options can be evaluated and the help option doesn't accidentally run your program. */
0088 class App {
0089     friend Option;
0090     friend detail::AppFriend;
0091 
0092   protected:
0093     // This library follows the Google style guide for member names ending in underscores
0094 
0095     /// @name Basics
0096     ///@{
0097 
0098     /// Subcommand name or program name (from parser if name is empty)
0099     std::string name_{};
0100 
0101     /// Description of the current program/subcommand
0102     std::string description_{};
0103 
0104     /// If true, allow extra arguments (ie, don't throw an error). INHERITABLE
0105     bool allow_extras_{false};
0106 
0107     /// If ignore, allow extra arguments in the ini file (ie, don't throw an error). INHERITABLE
0108     /// if error error on an extra argument, and if capture feed it to the app
0109     config_extras_mode allow_config_extras_{config_extras_mode::ignore};
0110 
0111     ///  If true, return immediately on an unrecognized option (implies allow_extras) INHERITABLE
0112     bool prefix_command_{false};
0113 
0114     /// If set to true the name was automatically generated from the command line vs a user set name
0115     bool has_automatic_name_{false};
0116 
0117     /// If set to true the subcommand is required to be processed and used, ignored for main app
0118     bool required_{false};
0119 
0120     /// If set to true the subcommand is disabled and cannot be used, ignored for main app
0121     bool disabled_{false};
0122 
0123     /// Flag indicating that the pre_parse_callback has been triggered
0124     bool pre_parse_called_{false};
0125 
0126     /// Flag indicating that the callback for the subcommand should be executed immediately on parse completion which is
0127     /// before help or ini files are processed. INHERITABLE
0128     bool immediate_callback_{false};
0129 
0130     /// This is a function that runs prior to the start of parsing
0131     std::function<void(std::size_t)> pre_parse_callback_{};
0132 
0133     /// This is a function that runs when parsing has finished.
0134     std::function<void()> parse_complete_callback_{};
0135 
0136     /// This is a function that runs when all processing has completed
0137     std::function<void()> final_callback_{};
0138 
0139     ///@}
0140     /// @name Options
0141     ///@{
0142 
0143     /// The default values for options, customizable and changeable INHERITABLE
0144     OptionDefaults option_defaults_{};
0145 
0146     /// The list of options, stored locally
0147     std::vector<Option_p> options_{};
0148 
0149     ///@}
0150     /// @name Help
0151     ///@{
0152 
0153     /// Footer to put after all options in the help output INHERITABLE
0154     std::string footer_{};
0155 
0156     /// This is a function that generates a footer to put after all other options in help output
0157     std::function<std::string()> footer_callback_{};
0158 
0159     /// A pointer to the help flag if there is one INHERITABLE
0160     Option *help_ptr_{nullptr};
0161 
0162     /// A pointer to the help all flag if there is one INHERITABLE
0163     Option *help_all_ptr_{nullptr};
0164 
0165     /// A pointer to a version flag if there is one
0166     Option *version_ptr_{nullptr};
0167 
0168     /// This is the formatter for help printing. Default provided. INHERITABLE (same pointer)
0169     std::shared_ptr<FormatterBase> formatter_{new Formatter()};
0170 
0171     /// The error message printing function INHERITABLE
0172     std::function<std::string(const App *, const Error &e)> failure_message_{FailureMessage::simple};
0173 
0174     ///@}
0175     /// @name Parsing
0176     ///@{
0177 
0178     using missing_t = std::vector<std::pair<detail::Classifier, std::string>>;
0179 
0180     /// Pair of classifier, string for missing options. (extra detail is removed on returning from parse)
0181     ///
0182     /// This is faster and cleaner than storing just a list of strings and reparsing. This may contain the -- separator.
0183     missing_t missing_{};
0184 
0185     /// This is a list of pointers to options with the original parse order
0186     std::vector<Option *> parse_order_{};
0187 
0188     /// This is a list of the subcommands collected, in order
0189     std::vector<App *> parsed_subcommands_{};
0190 
0191     /// this is a list of subcommands that are exclusionary to this one
0192     std::set<App *> exclude_subcommands_{};
0193 
0194     /// This is a list of options which are exclusionary to this App, if the options were used this subcommand should
0195     /// not be
0196     std::set<Option *> exclude_options_{};
0197 
0198     /// this is a list of subcommands or option groups that are required by this one, the list is not mutual,  the
0199     /// listed subcommands do not require this one
0200     std::set<App *> need_subcommands_{};
0201 
0202     /// This is a list of options which are required by this app, the list is not mutual, listed options do not need the
0203     /// subcommand not be
0204     std::set<Option *> need_options_{};
0205 
0206     ///@}
0207     /// @name Subcommands
0208     ///@{
0209 
0210     /// Storage for subcommand list
0211     std::vector<App_p> subcommands_{};
0212 
0213     /// If true, the program name is not case sensitive INHERITABLE
0214     bool ignore_case_{false};
0215 
0216     /// If true, the program should ignore underscores INHERITABLE
0217     bool ignore_underscore_{false};
0218 
0219     /// Allow subcommand fallthrough, so that parent commands can collect commands after subcommand.  INHERITABLE
0220     bool fallthrough_{false};
0221 
0222     /// Allow '/' for options for Windows like options. Defaults to true on Windows, false otherwise. INHERITABLE
0223     bool allow_windows_style_options_{
0224 #ifdef _WIN32
0225         true
0226 #else
0227         false
0228 #endif
0229     };
0230     /// specify that positional arguments come at the end of the argument sequence not inheritable
0231     bool positionals_at_end_{false};
0232 
0233     enum class startup_mode : char { stable, enabled, disabled };
0234     /// specify the startup mode for the app
0235     /// stable=no change, enabled= startup enabled, disabled=startup disabled
0236     startup_mode default_startup{startup_mode::stable};
0237 
0238     /// if set to true the subcommand can be triggered via configuration files INHERITABLE
0239     bool configurable_{false};
0240 
0241     /// If set to true positional options are validated before assigning INHERITABLE
0242     bool validate_positionals_{false};
0243 
0244     /// If set to true optional vector arguments are validated before assigning INHERITABLE
0245     bool validate_optional_arguments_{false};
0246 
0247     /// indicator that the subcommand is silent and won't show up in subcommands list
0248     /// This is potentially useful as a modifier subcommand
0249     bool silent_{false};
0250 
0251     /// Counts the number of times this command/subcommand was parsed
0252     std::uint32_t parsed_{0U};
0253 
0254     /// Minimum required subcommands (not inheritable!)
0255     std::size_t require_subcommand_min_{0};
0256 
0257     /// Max number of subcommands allowed (parsing stops after this number). 0 is unlimited INHERITABLE
0258     std::size_t require_subcommand_max_{0};
0259 
0260     /// Minimum required options (not inheritable!)
0261     std::size_t require_option_min_{0};
0262 
0263     /// Max number of options allowed. 0 is unlimited (not inheritable)
0264     std::size_t require_option_max_{0};
0265 
0266     /// A pointer to the parent if this is a subcommand
0267     App *parent_{nullptr};
0268 
0269     /// The group membership INHERITABLE
0270     std::string group_{"Subcommands"};
0271 
0272     /// Alias names for the subcommand
0273     std::vector<std::string> aliases_{};
0274 
0275     ///@}
0276     /// @name Config
0277     ///@{
0278 
0279     /// Pointer to the config option
0280     Option *config_ptr_{nullptr};
0281 
0282     /// This is the formatter for help printing. Default provided. INHERITABLE (same pointer)
0283     std::shared_ptr<Config> config_formatter_{new ConfigTOML()};
0284 
0285     ///@}
0286 
0287     /// Special private constructor for subcommand
0288     App(std::string app_description, std::string app_name, App *parent);
0289 
0290   public:
0291     /// @name Basic
0292     ///@{
0293 
0294     /// Create a new program. Pass in the same arguments as main(), along with a help string.
0295     explicit App(std::string app_description = "", std::string app_name = "")
0296         : App(app_description, app_name, nullptr) {
0297         set_help_flag("-h,--help", "Print this help message and exit");
0298     }
0299 
0300     App(const App &) = delete;
0301     App &operator=(const App &) = delete;
0302 
0303     /// virtual destructor
0304     virtual ~App() = default;
0305 
0306     /// Set a callback for execution when all parsing and processing has completed
0307     ///
0308     /// Due to a bug in c++11,
0309     /// it is not possible to overload on std::function (fixed in c++14
0310     /// and backported to c++11 on newer compilers). Use capture by reference
0311     /// to get a pointer to App if needed.
0312     App *callback(std::function<void()> app_callback) {
0313         if(immediate_callback_) {
0314             parse_complete_callback_ = std::move(app_callback);
0315         } else {
0316             final_callback_ = std::move(app_callback);
0317         }
0318         return this;
0319     }
0320 
0321     /// Set a callback for execution when all parsing and processing has completed
0322     /// aliased as callback
0323     App *final_callback(std::function<void()> app_callback) {
0324         final_callback_ = std::move(app_callback);
0325         return this;
0326     }
0327 
0328     /// Set a callback to execute when parsing has completed for the app
0329     ///
0330     App *parse_complete_callback(std::function<void()> pc_callback) {
0331         parse_complete_callback_ = std::move(pc_callback);
0332         return this;
0333     }
0334 
0335     /// Set a callback to execute prior to parsing.
0336     ///
0337     App *preparse_callback(std::function<void(std::size_t)> pp_callback) {
0338         pre_parse_callback_ = std::move(pp_callback);
0339         return this;
0340     }
0341 
0342     /// Set a name for the app (empty will use parser to set the name)
0343     App *name(std::string app_name = "");
0344 
0345     /// Set an alias for the app
0346     App *alias(std::string app_name);
0347 
0348     /// Remove the error when extras are left over on the command line.
0349     App *allow_extras(bool allow = true) {
0350         allow_extras_ = allow;
0351         return this;
0352     }
0353 
0354     /// Remove the error when extras are left over on the command line.
0355     App *required(bool require = true) {
0356         required_ = require;
0357         return this;
0358     }
0359 
0360     /// Disable the subcommand or option group
0361     App *disabled(bool disable = true) {
0362         disabled_ = disable;
0363         return this;
0364     }
0365 
0366     /// silence the subcommand from showing up in the processed list
0367     App *silent(bool silence = true) {
0368         silent_ = silence;
0369         return this;
0370     }
0371 
0372     /// Set the subcommand to be disabled by default, so on clear(), at the start of each parse it is disabled
0373     App *disabled_by_default(bool disable = true) {
0374         if(disable) {
0375             default_startup = startup_mode::disabled;
0376         } else {
0377             default_startup = (default_startup == startup_mode::enabled) ? startup_mode::enabled : startup_mode::stable;
0378         }
0379         return this;
0380     }
0381 
0382     /// Set the subcommand to be enabled by default, so on clear(), at the start of each parse it is enabled (not
0383     /// disabled)
0384     App *enabled_by_default(bool enable = true) {
0385         if(enable) {
0386             default_startup = startup_mode::enabled;
0387         } else {
0388             default_startup =
0389                 (default_startup == startup_mode::disabled) ? startup_mode::disabled : startup_mode::stable;
0390         }
0391         return this;
0392     }
0393 
0394     /// Set the subcommand callback to be executed immediately on subcommand completion
0395     App *immediate_callback(bool immediate = true);
0396 
0397     /// Set the subcommand to validate positional arguments before assigning
0398     App *validate_positionals(bool validate = true) {
0399         validate_positionals_ = validate;
0400         return this;
0401     }
0402 
0403     /// Set the subcommand to validate optional vector arguments before assigning
0404     App *validate_optional_arguments(bool validate = true) {
0405         validate_optional_arguments_ = validate;
0406         return this;
0407     }
0408 
0409     /// ignore extras in config files
0410     App *allow_config_extras(bool allow = true) {
0411         if(allow) {
0412             allow_config_extras_ = config_extras_mode::capture;
0413             allow_extras_ = true;
0414         } else {
0415             allow_config_extras_ = config_extras_mode::error;
0416         }
0417         return this;
0418     }
0419 
0420     /// ignore extras in config files
0421     App *allow_config_extras(config_extras_mode mode) {
0422         allow_config_extras_ = mode;
0423         return this;
0424     }
0425 
0426     /// Do not parse anything after the first unrecognized option and return
0427     App *prefix_command(bool allow = true) {
0428         prefix_command_ = allow;
0429         return this;
0430     }
0431 
0432     /// Ignore case. Subcommands inherit value.
0433     App *ignore_case(bool value = true);
0434 
0435     /// Allow windows style options, such as `/opt`. First matching short or long name used. Subcommands inherit
0436     /// value.
0437     App *allow_windows_style_options(bool value = true) {
0438         allow_windows_style_options_ = value;
0439         return this;
0440     }
0441 
0442     /// Specify that the positional arguments are only at the end of the sequence
0443     App *positionals_at_end(bool value = true) {
0444         positionals_at_end_ = value;
0445         return this;
0446     }
0447 
0448     /// Specify that the subcommand can be triggered by a config file
0449     App *configurable(bool value = true) {
0450         configurable_ = value;
0451         return this;
0452     }
0453 
0454     /// Ignore underscore. Subcommands inherit value.
0455     App *ignore_underscore(bool value = true);
0456 
0457     /// Set the help formatter
0458     App *formatter(std::shared_ptr<FormatterBase> fmt) {
0459         formatter_ = fmt;
0460         return this;
0461     }
0462 
0463     /// Set the help formatter
0464     App *formatter_fn(std::function<std::string(const App *, std::string, AppFormatMode)> fmt) {
0465         formatter_ = std::make_shared<FormatterLambda>(fmt);
0466         return this;
0467     }
0468 
0469     /// Set the config formatter
0470     App *config_formatter(std::shared_ptr<Config> fmt) {
0471         config_formatter_ = fmt;
0472         return this;
0473     }
0474 
0475     /// Check to see if this subcommand was parsed, true only if received on command line.
0476     CLI11_NODISCARD bool parsed() const { return parsed_ > 0; }
0477 
0478     /// Get the OptionDefault object, to set option defaults
0479     OptionDefaults *option_defaults() { return &option_defaults_; }
0480 
0481     ///@}
0482     /// @name Adding options
0483     ///@{
0484 
0485     /// Add an option, will automatically understand the type for common types.
0486     ///
0487     /// To use, create a variable with the expected type, and pass it in after the name.
0488     /// After start is called, you can use count to see if the value was passed, and
0489     /// the value will be initialized properly. Numbers, vectors, and strings are supported.
0490     ///
0491     /// ->required(), ->default, and the validators are options,
0492     /// The positional options take an optional number of arguments.
0493     ///
0494     /// For example,
0495     ///
0496     ///     std::string filename;
0497     ///     program.add_option("filename", filename, "description of filename");
0498     ///
0499     Option *add_option(std::string option_name,
0500                        callback_t option_callback,
0501                        std::string option_description = "",
0502                        bool defaulted = false,
0503                        std::function<std::string()> func = {});
0504 
0505     /// Add option for assigning to a variable
0506     template <typename AssignTo,
0507               typename ConvertTo = AssignTo,
0508               enable_if_t<!std::is_const<ConvertTo>::value, detail::enabler> = detail::dummy>
0509     Option *add_option(std::string option_name,
0510                        AssignTo &variable,  ///< The variable to set
0511                        std::string option_description = "") {
0512 
0513         auto fun = [&variable](const CLI::results_t &res) {  // comment for spacing
0514             return detail::lexical_conversion<AssignTo, ConvertTo>(res, variable);
0515         };
0516 
0517         Option *opt = add_option(option_name, fun, option_description, false, [&variable]() {
0518             return CLI::detail::checked_to_string<AssignTo, ConvertTo>(variable);
0519         });
0520         opt->type_name(detail::type_name<ConvertTo>());
0521         // these must be actual lvalues since (std::max) sometimes is defined in terms of references and references
0522         // to structs used in the evaluation can be temporary so that would cause issues.
0523         auto Tcount = detail::type_count<AssignTo>::value;
0524         auto XCcount = detail::type_count<ConvertTo>::value;
0525         opt->type_size(detail::type_count_min<ConvertTo>::value, (std::max)(Tcount, XCcount));
0526         opt->expected(detail::expected_count<ConvertTo>::value);
0527         opt->run_callback_for_default();
0528         return opt;
0529     }
0530 
0531     /// Add option for assigning to a variable
0532     template <typename AssignTo, enable_if_t<!std::is_const<AssignTo>::value, detail::enabler> = detail::dummy>
0533     Option *add_option_no_stream(std::string option_name,
0534                                  AssignTo &variable,  ///< The variable to set
0535                                  std::string option_description = "") {
0536 
0537         auto fun = [&variable](const CLI::results_t &res) {  // comment for spacing
0538             return detail::lexical_conversion<AssignTo, AssignTo>(res, variable);
0539         };
0540 
0541         Option *opt = add_option(option_name, fun, option_description, false, []() { return std::string{}; });
0542         opt->type_name(detail::type_name<AssignTo>());
0543         opt->type_size(detail::type_count_min<AssignTo>::value, detail::type_count<AssignTo>::value);
0544         opt->expected(detail::expected_count<AssignTo>::value);
0545         opt->run_callback_for_default();
0546         return opt;
0547     }
0548 
0549     /// Add option for a callback of a specific type
0550     template <typename ArgType>
0551     Option *add_option_function(std::string option_name,
0552                                 const std::function<void(const ArgType &)> &func,  ///< the callback to execute
0553                                 std::string option_description = "") {
0554 
0555         auto fun = [func](const CLI::results_t &res) {
0556             ArgType variable;
0557             bool result = detail::lexical_conversion<ArgType, ArgType>(res, variable);
0558             if(result) {
0559                 func(variable);
0560             }
0561             return result;
0562         };
0563 
0564         Option *opt = add_option(option_name, std::move(fun), option_description, false);
0565         opt->type_name(detail::type_name<ArgType>());
0566         opt->type_size(detail::type_count_min<ArgType>::value, detail::type_count<ArgType>::value);
0567         opt->expected(detail::expected_count<ArgType>::value);
0568         return opt;
0569     }
0570 
0571     /// Add option with no description or variable assignment
0572     Option *add_option(std::string option_name) {
0573         return add_option(option_name, CLI::callback_t{}, std::string{}, false);
0574     }
0575 
0576     /// Add option with description but with no variable assignment or callback
0577     template <typename T,
0578               enable_if_t<std::is_const<T>::value && std::is_constructible<std::string, T>::value, detail::enabler> =
0579                   detail::dummy>
0580     Option *add_option(std::string option_name, T &option_description) {
0581         return add_option(option_name, CLI::callback_t(), option_description, false);
0582     }
0583 
0584     /// Set a help flag, replace the existing one if present
0585     Option *set_help_flag(std::string flag_name = "", const std::string &help_description = "");
0586 
0587     /// Set a help all flag, replaced the existing one if present
0588     Option *set_help_all_flag(std::string help_name = "", const std::string &help_description = "");
0589 
0590     /// Set a version flag and version display string, replace the existing one if present
0591     Option *set_version_flag(std::string flag_name = "",
0592                              const std::string &versionString = "",
0593                              const std::string &version_help = "Display program version information and exit");
0594 
0595     /// Generate the version string through a callback function
0596     Option *set_version_flag(std::string flag_name,
0597                              std::function<std::string()> vfunc,
0598                              const std::string &version_help = "Display program version information and exit");
0599 
0600   private:
0601     /// Internal function for adding a flag
0602     Option *_add_flag_internal(std::string flag_name, CLI::callback_t fun, std::string flag_description);
0603 
0604   public:
0605     /// Add a flag with no description or variable assignment
0606     Option *add_flag(std::string flag_name) { return _add_flag_internal(flag_name, CLI::callback_t(), std::string{}); }
0607 
0608     /// Add flag with description but with no variable assignment or callback
0609     /// takes a constant string,  if a variable string is passed that variable will be assigned the results from the
0610     /// flag
0611     template <typename T,
0612               enable_if_t<std::is_const<T>::value && std::is_constructible<std::string, T>::value, detail::enabler> =
0613                   detail::dummy>
0614     Option *add_flag(std::string flag_name, T &flag_description) {
0615         return _add_flag_internal(flag_name, CLI::callback_t(), flag_description);
0616     }
0617 
0618     /// Other type version accepts all other types that are not vectors such as bool, enum, string or other classes
0619     /// that can be converted from a string
0620     template <typename T,
0621               enable_if_t<!detail::is_mutable_container<T>::value && !std::is_const<T>::value &&
0622                               !std::is_constructible<std::function<void(int)>, T>::value,
0623                           detail::enabler> = detail::dummy>
0624     Option *add_flag(std::string flag_name,
0625                      T &flag_result,  ///< A variable holding the flag result
0626                      std::string flag_description = "") {
0627 
0628         CLI::callback_t fun = [&flag_result](const CLI::results_t &res) {
0629             using CLI::detail::lexical_cast;
0630             return lexical_cast(res[0], flag_result);
0631         };
0632         auto *opt = _add_flag_internal(flag_name, std::move(fun), std::move(flag_description));
0633         return detail::default_flag_modifiers<T>(opt);
0634     }
0635 
0636     /// Vector version to capture multiple flags.
0637     template <typename T,
0638               enable_if_t<!std::is_assignable<std::function<void(std::int64_t)> &, T>::value, detail::enabler> =
0639                   detail::dummy>
0640     Option *add_flag(std::string flag_name,
0641                      std::vector<T> &flag_results,  ///< A vector of values with the flag results
0642                      std::string flag_description = "") {
0643         CLI::callback_t fun = [&flag_results](const CLI::results_t &res) {
0644             bool retval = true;
0645             for(const auto &elem : res) {
0646                 using CLI::detail::lexical_cast;
0647                 flag_results.emplace_back();
0648                 retval &= lexical_cast(elem, flag_results.back());
0649             }
0650             return retval;
0651         };
0652         return _add_flag_internal(flag_name, std::move(fun), std::move(flag_description))
0653             ->multi_option_policy(MultiOptionPolicy::TakeAll)
0654             ->run_callback_for_default();
0655     }
0656 
0657     /// Add option for callback that is triggered with a true flag and takes no arguments
0658     Option *add_flag_callback(std::string flag_name,
0659                               std::function<void(void)> function,  ///< A function to call, void(void)
0660                               std::string flag_description = "");
0661 
0662     /// Add option for callback with an integer value
0663     Option *add_flag_function(std::string flag_name,
0664                               std::function<void(std::int64_t)> function,  ///< A function to call, void(int)
0665                               std::string flag_description = "");
0666 
0667 #ifdef CLI11_CPP14
0668     /// Add option for callback (C++14 or better only)
0669     Option *add_flag(std::string flag_name,
0670                      std::function<void(std::int64_t)> function,  ///< A function to call, void(std::int64_t)
0671                      std::string flag_description = "") {
0672         return add_flag_function(std::move(flag_name), std::move(function), std::move(flag_description));
0673     }
0674 #endif
0675 
0676     /// Set a configuration ini file option, or clear it if no name passed
0677     Option *set_config(std::string option_name = "",
0678                        std::string default_filename = "",
0679                        const std::string &help_message = "Read an ini file",
0680                        bool config_required = false);
0681 
0682     /// Removes an option from the App. Takes an option pointer. Returns true if found and removed.
0683     bool remove_option(Option *opt);
0684 
0685     /// creates an option group as part of the given app
0686     template <typename T = Option_group>
0687     T *add_option_group(std::string group_name, std::string group_description = "") {
0688         if(!detail::valid_alias_name_string(group_name)) {
0689             throw IncorrectConstruction("option group names may not contain newlines or null characters");
0690         }
0691         auto option_group = std::make_shared<T>(std::move(group_description), group_name, this);
0692         auto *ptr = option_group.get();
0693         // move to App_p for overload resolution on older gcc versions
0694         App_p app_ptr = std::dynamic_pointer_cast<App>(option_group);
0695         add_subcommand(std::move(app_ptr));
0696         return ptr;
0697     }
0698 
0699     ///@}
0700     /// @name Subcommands
0701     ///@{
0702 
0703     /// Add a subcommand. Inherits INHERITABLE and OptionDefaults, and help flag
0704     App *add_subcommand(std::string subcommand_name = "", std::string subcommand_description = "");
0705 
0706     /// Add a previously created app as a subcommand
0707     App *add_subcommand(CLI::App_p subcom);
0708 
0709     /// Removes a subcommand from the App. Takes a subcommand pointer. Returns true if found and removed.
0710     bool remove_subcommand(App *subcom);
0711 
0712     /// Check to see if a subcommand is part of this command (doesn't have to be in command line)
0713     /// returns the first subcommand if passed a nullptr
0714     App *get_subcommand(const App *subcom) const;
0715 
0716     /// Check to see if a subcommand is part of this command (text version)
0717     CLI11_NODISCARD App *get_subcommand(std::string subcom) const;
0718 
0719     /// Get a pointer to subcommand by index
0720     CLI11_NODISCARD App *get_subcommand(int index = 0) const;
0721 
0722     /// Check to see if a subcommand is part of this command and get a shared_ptr to it
0723     CLI::App_p get_subcommand_ptr(App *subcom) const;
0724 
0725     /// Check to see if a subcommand is part of this command (text version)
0726     CLI11_NODISCARD CLI::App_p get_subcommand_ptr(std::string subcom) const;
0727 
0728     /// Get an owning pointer to subcommand by index
0729     CLI11_NODISCARD CLI::App_p get_subcommand_ptr(int index = 0) const;
0730 
0731     /// Check to see if an option group is part of this App
0732     CLI11_NODISCARD App *get_option_group(std::string group_name) const;
0733 
0734     /// No argument version of count counts the number of times this subcommand was
0735     /// passed in. The main app will return 1. Unnamed subcommands will also return 1 unless
0736     /// otherwise modified in a callback
0737     CLI11_NODISCARD std::size_t count() const { return parsed_; }
0738 
0739     /// Get a count of all the arguments processed in options and subcommands, this excludes arguments which were
0740     /// treated as extras.
0741     CLI11_NODISCARD std::size_t count_all() const;
0742 
0743     /// Changes the group membership
0744     App *group(std::string group_name) {
0745         group_ = group_name;
0746         return this;
0747     }
0748 
0749     /// The argumentless form of require subcommand requires 1 or more subcommands
0750     App *require_subcommand() {
0751         require_subcommand_min_ = 1;
0752         require_subcommand_max_ = 0;
0753         return this;
0754     }
0755 
0756     /// Require a subcommand to be given (does not affect help call)
0757     /// The number required can be given. Negative values indicate maximum
0758     /// number allowed (0 for any number). Max number inheritable.
0759     App *require_subcommand(int value) {
0760         if(value < 0) {
0761             require_subcommand_min_ = 0;
0762             require_subcommand_max_ = static_cast<std::size_t>(-value);
0763         } else {
0764             require_subcommand_min_ = static_cast<std::size_t>(value);
0765             require_subcommand_max_ = static_cast<std::size_t>(value);
0766         }
0767         return this;
0768     }
0769 
0770     /// Explicitly control the number of subcommands required. Setting 0
0771     /// for the max means unlimited number allowed. Max number inheritable.
0772     App *require_subcommand(std::size_t min, std::size_t max) {
0773         require_subcommand_min_ = min;
0774         require_subcommand_max_ = max;
0775         return this;
0776     }
0777 
0778     /// The argumentless form of require option requires 1 or more options be used
0779     App *require_option() {
0780         require_option_min_ = 1;
0781         require_option_max_ = 0;
0782         return this;
0783     }
0784 
0785     /// Require an option to be given (does not affect help call)
0786     /// The number required can be given. Negative values indicate maximum
0787     /// number allowed (0 for any number).
0788     App *require_option(int value) {
0789         if(value < 0) {
0790             require_option_min_ = 0;
0791             require_option_max_ = static_cast<std::size_t>(-value);
0792         } else {
0793             require_option_min_ = static_cast<std::size_t>(value);
0794             require_option_max_ = static_cast<std::size_t>(value);
0795         }
0796         return this;
0797     }
0798 
0799     /// Explicitly control the number of options required. Setting 0
0800     /// for the max means unlimited number allowed. Max number inheritable.
0801     App *require_option(std::size_t min, std::size_t max) {
0802         require_option_min_ = min;
0803         require_option_max_ = max;
0804         return this;
0805     }
0806 
0807     /// Stop subcommand fallthrough, so that parent commands cannot collect commands after subcommand.
0808     /// Default from parent, usually set on parent.
0809     App *fallthrough(bool value = true) {
0810         fallthrough_ = value;
0811         return this;
0812     }
0813 
0814     /// Check to see if this subcommand was parsed, true only if received on command line.
0815     /// This allows the subcommand to be directly checked.
0816     explicit operator bool() const { return parsed_ > 0; }
0817 
0818     ///@}
0819     /// @name Extras for subclassing
0820     ///@{
0821 
0822     /// This allows subclasses to inject code before callbacks but after parse.
0823     ///
0824     /// This does not run if any errors or help is thrown.
0825     virtual void pre_callback() {}
0826 
0827     ///@}
0828     /// @name Parsing
0829     ///@{
0830     //
0831     /// Reset the parsed data
0832     void clear();
0833 
0834     /// Parses the command line - throws errors.
0835     /// This must be called after the options are in but before the rest of the program.
0836     void parse(int argc, const char *const *argv);
0837 
0838     /// Parse a single string as if it contained command line arguments.
0839     /// This function splits the string into arguments then calls parse(std::vector<std::string> &)
0840     /// the function takes an optional boolean argument specifying if the programName is included in the string to
0841     /// process
0842     void parse(std::string commandline, bool program_name_included = false);
0843 
0844     /// The real work is done here. Expects a reversed vector.
0845     /// Changes the vector to the remaining options.
0846     void parse(std::vector<std::string> &args);
0847 
0848     /// The real work is done here. Expects a reversed vector.
0849     void parse(std::vector<std::string> &&args);
0850 
0851     void parse_from_stream(std::istream &input);
0852 
0853     /// Provide a function to print a help message. The function gets access to the App pointer and error.
0854     void failure_message(std::function<std::string(const App *, const Error &e)> function) {
0855         failure_message_ = function;
0856     }
0857 
0858     /// Print a nice error message and return the exit code
0859     int exit(const Error &e, std::ostream &out = std::cout, std::ostream &err = std::cerr) const;
0860 
0861     ///@}
0862     /// @name Post parsing
0863     ///@{
0864 
0865     /// Counts the number of times the given option was passed.
0866     CLI11_NODISCARD std::size_t count(std::string option_name) const { return get_option(option_name)->count(); }
0867 
0868     /// Get a subcommand pointer list to the currently selected subcommands (after parsing by default, in command
0869     /// line order; use parsed = false to get the original definition list.)
0870     CLI11_NODISCARD std::vector<App *> get_subcommands() const { return parsed_subcommands_; }
0871 
0872     /// Get a filtered subcommand pointer list from the original definition list. An empty function will provide all
0873     /// subcommands (const)
0874     std::vector<const App *> get_subcommands(const std::function<bool(const App *)> &filter) const;
0875 
0876     /// Get a filtered subcommand pointer list from the original definition list. An empty function will provide all
0877     /// subcommands
0878     std::vector<App *> get_subcommands(const std::function<bool(App *)> &filter);
0879 
0880     /// Check to see if given subcommand was selected
0881     bool got_subcommand(const App *subcom) const {
0882         // get subcom needed to verify that this was a real subcommand
0883         return get_subcommand(subcom)->parsed_ > 0;
0884     }
0885 
0886     /// Check with name instead of pointer to see if subcommand was selected
0887     CLI11_NODISCARD bool got_subcommand(std::string subcommand_name) const {
0888         return get_subcommand(subcommand_name)->parsed_ > 0;
0889     }
0890 
0891     /// Sets excluded options for the subcommand
0892     App *excludes(Option *opt) {
0893         if(opt == nullptr) {
0894             throw OptionNotFound("nullptr passed");
0895         }
0896         exclude_options_.insert(opt);
0897         return this;
0898     }
0899 
0900     /// Sets excluded subcommands for the subcommand
0901     App *excludes(App *app) {
0902         if(app == nullptr) {
0903             throw OptionNotFound("nullptr passed");
0904         }
0905         if(app == this) {
0906             throw OptionNotFound("cannot self reference in needs");
0907         }
0908         auto res = exclude_subcommands_.insert(app);
0909         // subcommand exclusion should be symmetric
0910         if(res.second) {
0911             app->exclude_subcommands_.insert(this);
0912         }
0913         return this;
0914     }
0915 
0916     App *needs(Option *opt) {
0917         if(opt == nullptr) {
0918             throw OptionNotFound("nullptr passed");
0919         }
0920         need_options_.insert(opt);
0921         return this;
0922     }
0923 
0924     App *needs(App *app) {
0925         if(app == nullptr) {
0926             throw OptionNotFound("nullptr passed");
0927         }
0928         if(app == this) {
0929             throw OptionNotFound("cannot self reference in needs");
0930         }
0931         need_subcommands_.insert(app);
0932         return this;
0933     }
0934 
0935     /// Removes an option from the excludes list of this subcommand
0936     bool remove_excludes(Option *opt);
0937 
0938     /// Removes a subcommand from the excludes list of this subcommand
0939     bool remove_excludes(App *app);
0940 
0941     /// Removes an option from the needs list of this subcommand
0942     bool remove_needs(Option *opt);
0943 
0944     /// Removes a subcommand from the needs list of this subcommand
0945     bool remove_needs(App *app);
0946     ///@}
0947     /// @name Help
0948     ///@{
0949 
0950     /// Set footer.
0951     App *footer(std::string footer_string) {
0952         footer_ = std::move(footer_string);
0953         return this;
0954     }
0955     /// Set footer.
0956     App *footer(std::function<std::string()> footer_function) {
0957         footer_callback_ = std::move(footer_function);
0958         return this;
0959     }
0960     /// Produce a string that could be read in as a config of the current values of the App. Set default_also to
0961     /// include default arguments. write_descriptions will print a description for the App and for each option.
0962     CLI11_NODISCARD std::string config_to_str(bool default_also = false, bool write_description = false) const {
0963         return config_formatter_->to_config(this, default_also, write_description, "");
0964     }
0965 
0966     /// Makes a help message, using the currently configured formatter
0967     /// Will only do one subcommand at a time
0968     CLI11_NODISCARD std::string help(std::string prev = "", AppFormatMode mode = AppFormatMode::Normal) const;
0969 
0970     /// Displays a version string
0971     CLI11_NODISCARD std::string version() const;
0972     ///@}
0973     /// @name Getters
0974     ///@{
0975 
0976     /// Access the formatter
0977     CLI11_NODISCARD std::shared_ptr<FormatterBase> get_formatter() const { return formatter_; }
0978 
0979     /// Access the config formatter
0980     CLI11_NODISCARD std::shared_ptr<Config> get_config_formatter() const { return config_formatter_; }
0981 
0982     /// Access the config formatter as a configBase pointer
0983     CLI11_NODISCARD std::shared_ptr<ConfigBase> get_config_formatter_base() const {
0984         // This is safer as a dynamic_cast if we have RTTI, as Config -> ConfigBase
0985 #if CLI11_USE_STATIC_RTTI == 0
0986         return std::dynamic_pointer_cast<ConfigBase>(config_formatter_);
0987 #else
0988         return std::static_pointer_cast<ConfigBase>(config_formatter_);
0989 #endif
0990     }
0991 
0992     /// Get the app or subcommand description
0993     CLI11_NODISCARD std::string get_description() const { return description_; }
0994 
0995     /// Set the description of the app
0996     App *description(std::string app_description) {
0997         description_ = std::move(app_description);
0998         return this;
0999     }
1000 
1001     /// Get the list of options (user facing function, so returns raw pointers), has optional filter function
1002     std::vector<const Option *> get_options(const std::function<bool(const Option *)> filter = {}) const;
1003 
1004     /// Non-const version of the above
1005     std::vector<Option *> get_options(const std::function<bool(Option *)> filter = {});
1006 
1007     /// Get an option by name (noexcept non-const version)
1008     Option *get_option_no_throw(std::string option_name) noexcept;
1009 
1010     /// Get an option by name (noexcept const version)
1011     CLI11_NODISCARD const Option *get_option_no_throw(std::string option_name) const noexcept;
1012 
1013     /// Get an option by name
1014     CLI11_NODISCARD const Option *get_option(std::string option_name) const {
1015         const auto *opt = get_option_no_throw(option_name);
1016         if(opt == nullptr) {
1017             throw OptionNotFound(option_name);
1018         }
1019         return opt;
1020     }
1021 
1022     /// Get an option by name (non-const version)
1023     Option *get_option(std::string option_name) {
1024         auto *opt = get_option_no_throw(option_name);
1025         if(opt == nullptr) {
1026             throw OptionNotFound(option_name);
1027         }
1028         return opt;
1029     }
1030 
1031     /// Shortcut bracket operator for getting a pointer to an option
1032     const Option *operator[](const std::string &option_name) const { return get_option(option_name); }
1033 
1034     /// Shortcut bracket operator for getting a pointer to an option
1035     const Option *operator[](const char *option_name) const { return get_option(option_name); }
1036 
1037     /// Check the status of ignore_case
1038     CLI11_NODISCARD bool get_ignore_case() const { return ignore_case_; }
1039 
1040     /// Check the status of ignore_underscore
1041     CLI11_NODISCARD bool get_ignore_underscore() const { return ignore_underscore_; }
1042 
1043     /// Check the status of fallthrough
1044     CLI11_NODISCARD bool get_fallthrough() const { return fallthrough_; }
1045 
1046     /// Check the status of the allow windows style options
1047     CLI11_NODISCARD bool get_allow_windows_style_options() const { return allow_windows_style_options_; }
1048 
1049     /// Check the status of the allow windows style options
1050     CLI11_NODISCARD bool get_positionals_at_end() const { return positionals_at_end_; }
1051 
1052     /// Check the status of the allow windows style options
1053     CLI11_NODISCARD bool get_configurable() const { return configurable_; }
1054 
1055     /// Get the group of this subcommand
1056     CLI11_NODISCARD const std::string &get_group() const { return group_; }
1057 
1058     /// Generate and return the footer.
1059     CLI11_NODISCARD std::string get_footer() const {
1060         return (footer_callback_) ? footer_callback_() + '\n' + footer_ : footer_;
1061     }
1062 
1063     /// Get the required min subcommand value
1064     CLI11_NODISCARD std::size_t get_require_subcommand_min() const { return require_subcommand_min_; }
1065 
1066     /// Get the required max subcommand value
1067     CLI11_NODISCARD std::size_t get_require_subcommand_max() const { return require_subcommand_max_; }
1068 
1069     /// Get the required min option value
1070     CLI11_NODISCARD std::size_t get_require_option_min() const { return require_option_min_; }
1071 
1072     /// Get the required max option value
1073     CLI11_NODISCARD std::size_t get_require_option_max() const { return require_option_max_; }
1074 
1075     /// Get the prefix command status
1076     CLI11_NODISCARD bool get_prefix_command() const { return prefix_command_; }
1077 
1078     /// Get the status of allow extras
1079     CLI11_NODISCARD bool get_allow_extras() const { return allow_extras_; }
1080 
1081     /// Get the status of required
1082     CLI11_NODISCARD bool get_required() const { return required_; }
1083 
1084     /// Get the status of disabled
1085     CLI11_NODISCARD bool get_disabled() const { return disabled_; }
1086 
1087     /// Get the status of silence
1088     CLI11_NODISCARD bool get_silent() const { return silent_; }
1089 
1090     /// Get the status of disabled
1091     CLI11_NODISCARD bool get_immediate_callback() const { return immediate_callback_; }
1092 
1093     /// Get the status of disabled by default
1094     CLI11_NODISCARD bool get_disabled_by_default() const { return (default_startup == startup_mode::disabled); }
1095 
1096     /// Get the status of disabled by default
1097     CLI11_NODISCARD bool get_enabled_by_default() const { return (default_startup == startup_mode::enabled); }
1098     /// Get the status of validating positionals
1099     CLI11_NODISCARD bool get_validate_positionals() const { return validate_positionals_; }
1100     /// Get the status of validating optional vector arguments
1101     CLI11_NODISCARD bool get_validate_optional_arguments() const { return validate_optional_arguments_; }
1102 
1103     /// Get the status of allow extras
1104     CLI11_NODISCARD config_extras_mode get_allow_config_extras() const { return allow_config_extras_; }
1105 
1106     /// Get a pointer to the help flag.
1107     Option *get_help_ptr() { return help_ptr_; }
1108 
1109     /// Get a pointer to the help flag. (const)
1110     CLI11_NODISCARD const Option *get_help_ptr() const { return help_ptr_; }
1111 
1112     /// Get a pointer to the help all flag. (const)
1113     CLI11_NODISCARD const Option *get_help_all_ptr() const { return help_all_ptr_; }
1114 
1115     /// Get a pointer to the config option.
1116     Option *get_config_ptr() { return config_ptr_; }
1117 
1118     /// Get a pointer to the config option. (const)
1119     CLI11_NODISCARD const Option *get_config_ptr() const { return config_ptr_; }
1120 
1121     /// Get a pointer to the version option.
1122     Option *get_version_ptr() { return version_ptr_; }
1123 
1124     /// Get a pointer to the version option. (const)
1125     CLI11_NODISCARD const Option *get_version_ptr() const { return version_ptr_; }
1126 
1127     /// Get the parent of this subcommand (or nullptr if main app)
1128     App *get_parent() { return parent_; }
1129 
1130     /// Get the parent of this subcommand (or nullptr if main app) (const version)
1131     CLI11_NODISCARD const App *get_parent() const { return parent_; }
1132 
1133     /// Get the name of the current app
1134     CLI11_NODISCARD const std::string &get_name() const { return name_; }
1135 
1136     /// Get the aliases of the current app
1137     CLI11_NODISCARD const std::vector<std::string> &get_aliases() const { return aliases_; }
1138 
1139     /// clear all the aliases of the current App
1140     App *clear_aliases() {
1141         aliases_.clear();
1142         return this;
1143     }
1144 
1145     /// Get a display name for an app
1146     CLI11_NODISCARD std::string get_display_name(bool with_aliases = false) const;
1147 
1148     /// Check the name, case insensitive and underscore insensitive if set
1149     CLI11_NODISCARD bool check_name(std::string name_to_check) const;
1150 
1151     /// Get the groups available directly from this option (in order)
1152     CLI11_NODISCARD std::vector<std::string> get_groups() const;
1153 
1154     /// This gets a vector of pointers with the original parse order
1155     CLI11_NODISCARD const std::vector<Option *> &parse_order() const { return parse_order_; }
1156 
1157     /// This returns the missing options from the current subcommand
1158     CLI11_NODISCARD std::vector<std::string> remaining(bool recurse = false) const;
1159 
1160     /// This returns the missing options in a form ready for processing by another command line program
1161     CLI11_NODISCARD std::vector<std::string> remaining_for_passthrough(bool recurse = false) const;
1162 
1163     /// This returns the number of remaining options, minus the -- separator
1164     CLI11_NODISCARD std::size_t remaining_size(bool recurse = false) const;
1165 
1166     ///@}
1167 
1168   protected:
1169     /// Check the options to make sure there are no conflicts.
1170     ///
1171     /// Currently checks to see if multiple positionals exist with unlimited args and checks if the min and max options
1172     /// are feasible
1173     void _validate() const;
1174 
1175     /// configure subcommands to enable parsing through the current object
1176     /// set the correct fallthrough and prefix for nameless subcommands and manage the automatic enable or disable
1177     /// makes sure parent is set correctly
1178     void _configure();
1179 
1180     /// Internal function to run (App) callback, bottom up
1181     void run_callback(bool final_mode = false, bool suppress_final_callback = false);
1182 
1183     /// Check to see if a subcommand is valid. Give up immediately if subcommand max has been reached.
1184     CLI11_NODISCARD bool _valid_subcommand(const std::string &current, bool ignore_used = true) const;
1185 
1186     /// Selects a Classifier enum based on the type of the current argument
1187     CLI11_NODISCARD detail::Classifier _recognize(const std::string &current,
1188                                                   bool ignore_used_subcommands = true) const;
1189 
1190     // The parse function is now broken into several parts, and part of process
1191 
1192     /// Read and process a configuration file (main app only)
1193     void _process_config_file();
1194 
1195     /// Get envname options if not yet passed. Runs on *all* subcommands.
1196     void _process_env();
1197 
1198     /// Process callbacks. Runs on *all* subcommands.
1199     void _process_callbacks();
1200 
1201     /// Run help flag processing if any are found.
1202     ///
1203     /// The flags allow recursive calls to remember if there was a help flag on a parent.
1204     void _process_help_flags(bool trigger_help = false, bool trigger_all_help = false) const;
1205 
1206     /// Verify required options and cross requirements. Subcommands too (only if selected).
1207     void _process_requirements();
1208 
1209     /// Process callbacks and such.
1210     void _process();
1211 
1212     /// Throw an error if anything is left over and should not be.
1213     void _process_extras();
1214 
1215     /// Throw an error if anything is left over and should not be.
1216     /// Modifies the args to fill in the missing items before throwing.
1217     void _process_extras(std::vector<std::string> &args);
1218 
1219     /// Internal function to recursively increment the parsed counter on the current app as well unnamed subcommands
1220     void increment_parsed();
1221 
1222     /// Internal parse function
1223     void _parse(std::vector<std::string> &args);
1224 
1225     /// Internal parse function
1226     void _parse(std::vector<std::string> &&args);
1227 
1228     /// Internal function to parse a stream
1229     void _parse_stream(std::istream &input);
1230 
1231     /// Parse one config param, return false if not found in any subcommand, remove if it is
1232     ///
1233     /// If this has more than one dot.separated.name, go into the subcommand matching it
1234     /// Returns true if it managed to find the option, if false you'll need to remove the arg manually.
1235     void _parse_config(const std::vector<ConfigItem> &args);
1236 
1237     /// Fill in a single config option
1238     bool _parse_single_config(const ConfigItem &item, std::size_t level = 0);
1239 
1240     /// Parse "one" argument (some may eat more than one), delegate to parent if fails, add to missing if missing
1241     /// from main return false if the parse has failed and needs to return to parent
1242     bool _parse_single(std::vector<std::string> &args, bool &positional_only);
1243 
1244     /// Count the required remaining positional arguments
1245     CLI11_NODISCARD std::size_t _count_remaining_positionals(bool required_only = false) const;
1246 
1247     /// Count the required remaining positional arguments
1248     CLI11_NODISCARD bool _has_remaining_positionals() const;
1249 
1250     /// Parse a positional, go up the tree to check
1251     /// @param haltOnSubcommand if set to true the operation will not process subcommands merely return false
1252     /// Return true if the positional was used false otherwise
1253     bool _parse_positional(std::vector<std::string> &args, bool haltOnSubcommand);
1254 
1255     /// Locate a subcommand by name with two conditions, should disabled subcommands be ignored, and should used
1256     /// subcommands be ignored
1257     CLI11_NODISCARD App *
1258     _find_subcommand(const std::string &subc_name, bool ignore_disabled, bool ignore_used) const noexcept;
1259 
1260     /// Parse a subcommand, modify args and continue
1261     ///
1262     /// Unlike the others, this one will always allow fallthrough
1263     /// return true if the subcommand was processed false otherwise
1264     bool _parse_subcommand(std::vector<std::string> &args);
1265 
1266     /// Parse a short (false) or long (true) argument, must be at the top of the list
1267     /// return true if the argument was processed or false if nothing was done
1268     bool _parse_arg(std::vector<std::string> &args, detail::Classifier current_type);
1269 
1270     /// Trigger the pre_parse callback if needed
1271     void _trigger_pre_parse(std::size_t remaining_args);
1272 
1273     /// Get the appropriate parent to fallthrough to which is the first one that has a name or the main app
1274     App *_get_fallthrough_parent();
1275 
1276     /// Helper function to run through all possible comparisons of subcommand names to check there is no overlap
1277     CLI11_NODISCARD const std::string &_compare_subcommand_names(const App &subcom, const App &base) const;
1278 
1279     /// Helper function to place extra values in the most appropriate position
1280     void _move_to_missing(detail::Classifier val_type, const std::string &val);
1281 
1282   public:
1283     /// function that could be used by subclasses of App to shift options around into subcommands
1284     void _move_option(Option *opt, App *app);
1285 };  // namespace CLI
1286 
1287 /// Extension of App to better manage groups of options
1288 class Option_group : public App {
1289   public:
1290     Option_group(std::string group_description, std::string group_name, App *parent)
1291         : App(std::move(group_description), "", parent) {
1292         group(group_name);
1293         // option groups should have automatic fallthrough
1294     }
1295     using App::add_option;
1296     /// Add an existing option to the Option_group
1297     Option *add_option(Option *opt) {
1298         if(get_parent() == nullptr) {
1299             throw OptionNotFound("Unable to locate the specified option");
1300         }
1301         get_parent()->_move_option(opt, this);
1302         return opt;
1303     }
1304     /// Add an existing option to the Option_group
1305     void add_options(Option *opt) { add_option(opt); }
1306     /// Add a bunch of options to the group
1307     template <typename... Args> void add_options(Option *opt, Args... args) {
1308         add_option(opt);
1309         add_options(args...);
1310     }
1311     using App::add_subcommand;
1312     /// Add an existing subcommand to be a member of an option_group
1313     App *add_subcommand(App *subcom) {
1314         App_p subc = subcom->get_parent()->get_subcommand_ptr(subcom);
1315         subc->get_parent()->remove_subcommand(subcom);
1316         add_subcommand(std::move(subc));
1317         return subcom;
1318     }
1319 };
1320 
1321 /// Helper function to enable one option group/subcommand when another is used
1322 CLI11_INLINE void TriggerOn(App *trigger_app, App *app_to_enable);
1323 
1324 /// Helper function to enable one option group/subcommand when another is used
1325 CLI11_INLINE void TriggerOn(App *trigger_app, std::vector<App *> apps_to_enable);
1326 
1327 /// Helper function to disable one option group/subcommand when another is used
1328 CLI11_INLINE void TriggerOff(App *trigger_app, App *app_to_enable);
1329 
1330 /// Helper function to disable one option group/subcommand when another is used
1331 CLI11_INLINE void TriggerOff(App *trigger_app, std::vector<App *> apps_to_enable);
1332 
1333 /// Helper function to mark an option as deprecated
1334 CLI11_INLINE void deprecate_option(Option *opt, const std::string &replacement = "");
1335 
1336 /// Helper function to mark an option as deprecated
1337 inline void deprecate_option(App *app, const std::string &option_name, const std::string &replacement = "") {
1338     auto *opt = app->get_option(option_name);
1339     deprecate_option(opt, replacement);
1340 }
1341 
1342 /// Helper function to mark an option as deprecated
1343 inline void deprecate_option(App &app, const std::string &option_name, const std::string &replacement = "") {
1344     auto *opt = app.get_option(option_name);
1345     deprecate_option(opt, replacement);
1346 }
1347 
1348 /// Helper function to mark an option as retired
1349 CLI11_INLINE void retire_option(App *app, Option *opt);
1350 
1351 /// Helper function to mark an option as retired
1352 CLI11_INLINE void retire_option(App &app, Option *opt);
1353 
1354 /// Helper function to mark an option as retired
1355 CLI11_INLINE void retire_option(App *app, const std::string &option_name);
1356 
1357 /// Helper function to mark an option as retired
1358 CLI11_INLINE void retire_option(App &app, const std::string &option_name);
1359 
1360 namespace detail {
1361 /// This class is simply to allow tests access to App's protected functions
1362 struct AppFriend {
1363 #ifdef CLI11_CPP14
1364 
1365     /// Wrap _parse_short, perfectly forward arguments and return
1366     template <typename... Args> static decltype(auto) parse_arg(App *app, Args &&...args) {
1367         return app->_parse_arg(std::forward<Args>(args)...);
1368     }
1369 
1370     /// Wrap _parse_subcommand, perfectly forward arguments and return
1371     template <typename... Args> static decltype(auto) parse_subcommand(App *app, Args &&...args) {
1372         return app->_parse_subcommand(std::forward<Args>(args)...);
1373     }
1374 #else
1375     /// Wrap _parse_short, perfectly forward arguments and return
1376     template <typename... Args>
1377     static auto parse_arg(App *app, Args &&...args) ->
1378         typename std::result_of<decltype (&App::_parse_arg)(App, Args...)>::type {
1379         return app->_parse_arg(std::forward<Args>(args)...);
1380     }
1381 
1382     /// Wrap _parse_subcommand, perfectly forward arguments and return
1383     template <typename... Args>
1384     static auto parse_subcommand(App *app, Args &&...args) ->
1385         typename std::result_of<decltype (&App::_parse_subcommand)(App, Args...)>::type {
1386         return app->_parse_subcommand(std::forward<Args>(args)...);
1387     }
1388 #endif
1389     /// Wrap the fallthrough parent function to make sure that is working correctly
1390     static App *get_fallthrough_parent(App *app) { return app->_get_fallthrough_parent(); }
1391 };
1392 }  // namespace detail
1393 
1394 // [CLI11:app_hpp:end]
1395 }  // namespace CLI
1396 
1397 #ifndef CLI11_COMPILE
1398 #include "impl/App_inl.hpp"
1399 #endif