Confirm arguments are parsed before allowing ArgumentParser::get

If the developer forgot to call ArgumentParser::parse_args<>, attempts to
use ::get, ::present, etc., would raise "No value provided...".  With this
change, the error better describes what went wrong.

Signed-off-by: Sean Robinson <sean.robinson@scottsdalecc.edu>
This commit is contained in:
Sean Robinson 2021-07-22 06:45:44 -07:00
parent 6344b5dcc7
commit f0d68de134
2 changed files with 14 additions and 0 deletions

View File

@ -911,12 +911,16 @@ public:
}
/* Getter for options with default values.
* @throws std::logic_error if parse_args() has not been previously called
* @throws std::logic_error if there is no such option
* @throws std::logic_error if the option has no value
* @throws std::bad_any_cast if the option is not of type T
*/
template <typename T = std::string>
T get(std::string_view aArgumentName) const {
if (!mIsParsed) {
throw std::logic_error("Nothing parsed, no arguments are available.");
}
return (*this)[aArgumentName].get<T>();
}
@ -1076,6 +1080,7 @@ private:
throw std::runtime_error("Unknown argument");
}
}
mIsParsed = true;
}
/*
@ -1115,6 +1120,7 @@ private:
std::string mVersion;
std::string mDescription;
std::string mEpilog;
bool mIsParsed = false;
std::list<Argument> mPositionalArguments;
std::list<Argument> mOptionalArguments;
std::map<std::string_view, list_iterator, std::less<>> mArgumentMap;

View File

@ -10,6 +10,14 @@ TEST_CASE("Getting a simple argument" * test_suite("ArgumentParser::get")) {
REQUIRE(program.get("--stuff") == "./src");
}
TEST_CASE("Skipped call to parse_args" * test_suite("ArgumentParser::get")) {
argparse::ArgumentParser program("test");
program.add_argument("stuff");
REQUIRE_THROWS_WITH_AS(program.get("stuff"),
"Nothing parsed, no arguments are available.",
std::logic_error);
}
TEST_CASE("Missing argument" * test_suite("ArgumentParser::get")) {
argparse::ArgumentParser program("test");
program.add_argument("-s", "--stuff");