Extend cxxopts API to support std::optional non-throwing query of values
This commit is contained in:
parent
4bf61f0869
commit
270a03a888
@ -1538,6 +1538,22 @@ CXXOPTS_DIAGNOSTIC_POP
|
||||
return CXXOPTS_RTTI_CAST<const values::standard_value<T>&>(*m_value).get();
|
||||
}
|
||||
|
||||
#ifdef CXXOPTS_HAS_OPTIONAL
|
||||
template <typename T>
|
||||
std::optional<T>
|
||||
optional() const
|
||||
{
|
||||
try
|
||||
{
|
||||
return as<T>();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
void
|
||||
ensure_value(const std::shared_ptr<const OptionDetails>& details)
|
||||
@ -1750,6 +1766,24 @@ CXXOPTS_DIAGNOSTIC_POP
|
||||
return viter->second;
|
||||
}
|
||||
|
||||
#ifdef CXXOPTS_HAS_OPTIONAL
|
||||
template <typename T>
|
||||
std::optional<T>
|
||||
optional(const std::string& option) const
|
||||
{
|
||||
auto iter = m_keys.find(option);
|
||||
if (iter != m_keys.end())
|
||||
{
|
||||
auto viter = m_values.find(iter->second);
|
||||
if (viter != m_values.end())
|
||||
{
|
||||
return viter->second.optional<T>();
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
#endif
|
||||
|
||||
const std::vector<KeyValue>&
|
||||
arguments() const
|
||||
{
|
||||
|
||||
@ -821,6 +821,57 @@ TEST_CASE("Options empty", "[options]") {
|
||||
CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::exceptions::no_such_option);
|
||||
}
|
||||
|
||||
#ifdef CXXOPTS_HAS_OPTIONAL
|
||||
TEST_CASE("Optional value", "[optional]")
|
||||
{
|
||||
cxxopts::Options options("options", "query as std::optional");
|
||||
options.add_options()
|
||||
("int", "Integer", cxxopts::value<int>())
|
||||
("float", "Float", cxxopts::value<float>())
|
||||
("string", "String", cxxopts::value<std::string>())
|
||||
;
|
||||
|
||||
SECTION("Available") {
|
||||
Argv av({
|
||||
"--int",
|
||||
"42",
|
||||
"--float",
|
||||
"3.141",
|
||||
"--string",
|
||||
"Hello"
|
||||
});
|
||||
|
||||
auto** argv = av.argv();
|
||||
auto argc = av.argc();
|
||||
|
||||
auto result = options.parse(argc, argv);
|
||||
|
||||
CHECK(result.optional<int>("int"));
|
||||
CHECK(result.optional<float>("float"));
|
||||
CHECK(result.optional<string>("string"));
|
||||
|
||||
CHECK(*result.optional<int>("int") == 42);
|
||||
CHECK(*result.optional<float>("float") == 3.141);
|
||||
CHECK(*result.optional<string>("string") == "Hello");
|
||||
}
|
||||
|
||||
SECTION("Unavailable") {
|
||||
Argv av({
|
||||
});
|
||||
|
||||
auto** argv = av.argv();
|
||||
auto argc = av.argc();
|
||||
|
||||
auto result = options.parse(argc, argv);
|
||||
|
||||
CHECK(!result.optional<int>("int"));
|
||||
CHECK(!result.optional<float>("float"));
|
||||
CHECK(!result.optional<string>("string"));
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_CASE("Initializer list with group", "[options]") {
|
||||
cxxopts::Options options("Initializer list group", " - test initializer list with group");
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user