Skip to content

Commit

Permalink
Merge pull request #100 from skrobinson/wip-is_used-method
Browse files Browse the repository at this point in the history
Add ArgumentParser.is_used to discern user-supplied values from defaults
  • Loading branch information
p-ranav authored Apr 7, 2021
2 parents 65f2ad4 + 3efd045 commit 1344889
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 0 deletions.
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,28 @@ if (auto fn = program.present("-o")) {

Similar to `get`, the `present` method also accepts a template argument. But rather than returning `T`, `parser.present<T>(key)` returns `std::optional<T>`, so that when the user does not provide a value to this parameter, the return value compares equal to `std::nullopt`.

#### Deciding if the value was given by the user

If you want to know whether the user supplied a value for an argument that has a ```.default_value```, check whether the argument ```.is_used()```.

```cpp
program.add_argument("--color")
.default_value("orange")
.help("specify the cat's fur color");

try {
program.parse_args(argc, argv); // Example: ./main --color orange
}
catch (const std::runtime_error& err) {
std::cout << err.what() << std::endl;
std::cout << program;
exit(0);
}

auto color = program.get<std::string>("--color"); // "orange"
auto explicit_color = program.is_used("--color"); // true, user provided orange
```

#### Joining values of repeated optional arguments

You may want to allow an optional argument to be repeated and gather all values in one place.
Expand Down
7 changes: 7 additions & 0 deletions include/argparse/argparse.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -925,6 +925,13 @@ class ArgumentParser {
return (*this)[aArgumentName].present<T>();
}

/* Getter that returns true for user-supplied options. Returns false if not
* user-supplied, even with a default value.
*/
auto is_used(std::string_view aArgumentName) const {
return (*this)[aArgumentName].mIsUsed;
}

/* Indexing operator. Return a reference to an Argument object
* Used in conjuction with Argument.operator== e.g., parser["foo"] == true
* @throws std::logic_error in case of an invalid argument name
Expand Down
1 change: 1 addition & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ file(GLOB ARGPARSE_TEST_SOURCES
test_container_arguments.cpp
test_help.cpp
test_invalid_arguments.cpp
test_is_used.cpp
test_issue_37.cpp
test_negative_numbers.cpp
test_optional_arguments.cpp
Expand Down
22 changes: 22 additions & 0 deletions test/test_is_used.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include <doctest.hpp>
#include <argparse/argparse.hpp>

using doctest::test_suite;

TEST_CASE("User-supplied argument" * test_suite("is_used")) {
argparse::ArgumentParser program("test");
program.add_argument("--dir")
.default_value(std::string("/"));
program.parse_args({ "test", "--dir", "/home/user" });
REQUIRE(program.get("--dir") == "/home/user");
REQUIRE(program.is_used("--dir") == true);
}

TEST_CASE("Not user-supplied argument" * test_suite("is_used")) {
argparse::ArgumentParser program("test");
program.add_argument("--dir")
.default_value(std::string("/"));
program.parse_args({ "test" });
REQUIRE(program.get("--dir") == "/");
REQUIRE(program.is_used("--dir") == false);
}

0 comments on commit 1344889

Please sign in to comment.