mirror of
https://github.com/CLIUtils/CLI11.git
synced 2025-05-03 14:03:52 +00:00
get_subcommand_no_throw (#1016)
get_subcommand when used for parsing config files, was throwing and catching as part of control flow and expected operation, this resulting in a performance hit in select cases. A get_subcommand_no_throw was added to resolve this issue. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
c04c9b2252
commit
6cd171ad3f
@ -733,6 +733,10 @@ class App {
|
|||||||
/// Check to see if a subcommand is part of this command (text version)
|
/// Check to see if a subcommand is part of this command (text version)
|
||||||
CLI11_NODISCARD App *get_subcommand(std::string subcom) const;
|
CLI11_NODISCARD App *get_subcommand(std::string subcom) const;
|
||||||
|
|
||||||
|
/// Get a subcommand by name (noexcept non-const version)
|
||||||
|
/// returns null if subcommand doesn't exist
|
||||||
|
CLI11_NODISCARD App *get_subcommand_no_throw(std::string subcom) const noexcept;
|
||||||
|
|
||||||
/// Get a pointer to subcommand by index
|
/// Get a pointer to subcommand by index
|
||||||
CLI11_NODISCARD App *get_subcommand(int index = 0) const;
|
CLI11_NODISCARD App *get_subcommand(int index = 0) const;
|
||||||
|
|
||||||
@ -907,8 +911,9 @@ class App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Check with name instead of pointer to see if subcommand was selected
|
/// Check with name instead of pointer to see if subcommand was selected
|
||||||
CLI11_NODISCARD bool got_subcommand(std::string subcommand_name) const {
|
CLI11_NODISCARD bool got_subcommand(std::string subcommand_name) const noexcept {
|
||||||
return get_subcommand(subcommand_name)->parsed_ > 0;
|
App *sub = get_subcommand_no_throw(subcommand_name);
|
||||||
|
return (sub != nullptr) ? (sub->parsed_ > 0) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets excluded options for the subcommand
|
/// Sets excluded options for the subcommand
|
||||||
@ -1038,7 +1043,7 @@ class App {
|
|||||||
std::vector<Option *> get_options(const std::function<bool(Option *)> filter = {});
|
std::vector<Option *> get_options(const std::function<bool(Option *)> filter = {});
|
||||||
|
|
||||||
/// Get an option by name (noexcept non-const version)
|
/// Get an option by name (noexcept non-const version)
|
||||||
Option *get_option_no_throw(std::string option_name) noexcept;
|
CLI11_NODISCARD Option *get_option_no_throw(std::string option_name) noexcept;
|
||||||
|
|
||||||
/// Get an option by name (noexcept const version)
|
/// Get an option by name (noexcept const version)
|
||||||
CLI11_NODISCARD const Option *get_option_no_throw(std::string option_name) const noexcept;
|
CLI11_NODISCARD const Option *get_option_no_throw(std::string option_name) const noexcept;
|
||||||
|
@ -457,6 +457,10 @@ CLI11_NODISCARD CLI11_INLINE App *App::get_subcommand(std::string subcom) const
|
|||||||
return subc;
|
return subc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CLI11_NODISCARD CLI11_INLINE App *App::get_subcommand_no_throw(std::string subcom) const noexcept {
|
||||||
|
return _find_subcommand(subcom, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
CLI11_NODISCARD CLI11_INLINE App *App::get_subcommand(int index) const {
|
CLI11_NODISCARD CLI11_INLINE App *App::get_subcommand(int index) const {
|
||||||
if(index >= 0) {
|
if(index >= 0) {
|
||||||
auto uindex = static_cast<unsigned>(index);
|
auto uindex = static_cast<unsigned>(index);
|
||||||
@ -796,7 +800,7 @@ CLI11_INLINE std::vector<Option *> App::get_options(const std::function<bool(Opt
|
|||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLI11_INLINE Option *App::get_option_no_throw(std::string option_name) noexcept {
|
CLI11_NODISCARD CLI11_INLINE Option *App::get_option_no_throw(std::string option_name) noexcept {
|
||||||
for(Option_p &opt : options_) {
|
for(Option_p &opt : options_) {
|
||||||
if(opt->check_name(option_name)) {
|
if(opt->check_name(option_name)) {
|
||||||
return opt.get();
|
return opt.get();
|
||||||
@ -1441,12 +1445,8 @@ CLI11_INLINE void App::_parse_config(const std::vector<ConfigItem> &args) {
|
|||||||
CLI11_INLINE bool App::_parse_single_config(const ConfigItem &item, std::size_t level) {
|
CLI11_INLINE bool App::_parse_single_config(const ConfigItem &item, std::size_t level) {
|
||||||
|
|
||||||
if(level < item.parents.size()) {
|
if(level < item.parents.size()) {
|
||||||
try {
|
auto *subcom = get_subcommand_no_throw(item.parents.at(level));
|
||||||
auto *subcom = get_subcommand(item.parents.at(level));
|
return (subcom != nullptr) ? subcom->_parse_single_config(item, level + 1) : false;
|
||||||
return subcom->_parse_single_config(item, level + 1);
|
|
||||||
} catch(const OptionNotFound &) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// check for section open
|
// check for section open
|
||||||
if(item.name == "++") {
|
if(item.name == "++") {
|
||||||
|
@ -16,8 +16,10 @@ TEST_CASE_METHOD(TApp, "BasicSubcommands", "[subcom]") {
|
|||||||
|
|
||||||
CHECK(app.get_subcommand(sub1) == sub1);
|
CHECK(app.get_subcommand(sub1) == sub1);
|
||||||
CHECK(app.get_subcommand("sub1") == sub1);
|
CHECK(app.get_subcommand("sub1") == sub1);
|
||||||
|
CHECK(app.get_subcommand_no_throw("sub1") == sub1);
|
||||||
CHECK_THROWS_AS(app.get_subcommand("sub3"), CLI::OptionNotFound);
|
CHECK_THROWS_AS(app.get_subcommand("sub3"), CLI::OptionNotFound);
|
||||||
|
CHECK_NOTHROW(app.get_subcommand_no_throw("sub3"));
|
||||||
|
CHECK(app.get_subcommand_no_throw("sub3") == nullptr);
|
||||||
run();
|
run();
|
||||||
CHECK(app.get_subcommands().empty());
|
CHECK(app.get_subcommands().empty());
|
||||||
|
|
||||||
@ -90,7 +92,7 @@ TEST_CASE_METHOD(TApp, "MultiSubFallthrough", "[subcom]") {
|
|||||||
CHECK(!sub2->parsed());
|
CHECK(!sub2->parsed());
|
||||||
CHECK(0u == sub2->count());
|
CHECK(0u == sub2->count());
|
||||||
|
|
||||||
CHECK_THROWS_AS(app.got_subcommand("sub3"), CLI::OptionNotFound);
|
CHECK(!app.got_subcommand("sub3"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(TApp, "CrazyNameSubcommand", "[subcom]") {
|
TEST_CASE_METHOD(TApp, "CrazyNameSubcommand", "[subcom]") {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user