From 2b05334a3c37f471e4a26dbebd19ab5fee6e1aa4 Mon Sep 17 00:00:00 2001 From: Sean Robinson Date: Tue, 26 Oct 2021 12:58:24 -0700 Subject: [PATCH] Run Argumnet::action functor for zero-parameter arguments Previously, only arguments with one or more parameters would run actions. But, at times it can be useful to run an action when an argument does not expect any parameters. Closes #104 Signed-off-by: Sean Robinson --- README.md | 18 ++++++++++++++++++ include/argparse/argparse.hpp | 1 + test/test_actions.cpp | 24 ++++++++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/README.md b/README.md index fd8860f..db53e64 100644 --- a/README.md +++ b/README.md @@ -200,6 +200,24 @@ auto colors = program.get>("--color"); // {"red", "gre Notice that ```.default_value``` is given an explicit template parameter to match the type you want to ```.get```. +#### Repeating an argument to increase a value + +A common pattern is to repeat an argument to indicate a greater value. + +```cpp +int verbosity = 0; +program.add_argument("-V", "--verbose") + .action([&](const auto &) { ++verbosity; }) + .append() + .default_value(false) + .implicit_value(true) + .nargs(0); + +program.parse_args(argc, argv); // Example: ./main -VVVV + +std::cout << "verbose level: " << verbosity << std::endl; // verbose level: 4 +``` + ### Negative Numbers Optional arguments start with ```-```. Can ```argparse``` handle negative numbers? The answer is yes! diff --git a/include/argparse/argparse.hpp b/include/argparse/argparse.hpp index 8a6dff8..980ebc7 100644 --- a/include/argparse/argparse.hpp +++ b/include/argparse/argparse.hpp @@ -442,6 +442,7 @@ public: mUsedName = usedName; if (mNumArgs == 0) { mValues.emplace_back(mImplicitValue); + std::visit([](auto &aAction) { aAction({}); }, mAction); return start; } else if (mNumArgs <= std::distance(start, end)) { if (auto expected = maybe_nargs()) { diff --git a/test/test_actions.cpp b/test/test_actions.cpp index 6d624af..7c5fd10 100644 --- a/test/test_actions.cpp +++ b/test/test_actions.cpp @@ -133,3 +133,27 @@ TEST_CASE("Users can use actions on remaining arguments" * program.parse_args({"sum", "42", "100", "-3", "-20"}); REQUIRE(result == 119); } + +TEST_CASE("Users can run actions on parameterless optional arguments" * + test_suite("actions")) { + argparse::ArgumentParser program("test"); + + GIVEN("a flag argument with a counting action") { + int count = 0; + program.add_argument("-V", "--verbose") + .action([&](const auto &) { ++count; }) + .append() + .default_value(false) + .implicit_value(true) + .nargs(0); + + WHEN("the flag is repeated") { + program.parse_args({"test", "-VVVV"}); + + THEN("the count increments once per use") { + REQUIRE(program.get("-V")); + REQUIRE(count == 4); + } + } + } +}