Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-01 08:34:30

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