diff --git a/include/cxxopts.hpp b/include/cxxopts.hpp index 0b272ace..7224807d 100644 --- a/include/cxxopts.hpp +++ b/include/cxxopts.hpp @@ -1538,6 +1538,15 @@ CXXOPTS_DIAGNOSTIC_POP return CXXOPTS_RTTI_CAST&>(*m_value).get(); } +#ifdef CXXOPTS_HAS_OPTIONAL + template + std::optional + as_optional() const + { + return as(); + } +#endif + private: void ensure_value(const std::shared_ptr& details) @@ -1750,6 +1759,24 @@ CXXOPTS_DIAGNOSTIC_POP return viter->second; } +#ifdef CXXOPTS_HAS_OPTIONAL + template + std::optional + as_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.as_optional(); + } + } + return std::nullopt; + } +#endif + const std::vector& arguments() const { diff --git a/test/options.cpp b/test/options.cpp index 24fc7068..bb90f825 100644 --- a/test/options.cpp +++ b/test/options.cpp @@ -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()) + ("float", "Float", cxxopts::value()) + ("string", "String", cxxopts::value()) + ; + + 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.as_optional("int")); + CHECK(result.as_optional("float")); + CHECK(result.as_optional("string")); + + CHECK(*result.as_optional("int") == 42); + CHECK(*result.as_optional("float") == 3.141); + CHECK(*result.as_optional("string") == "Hello"); + } + + SECTION("Unavailable") { + Argv av({ + }); + + auto** argv = av.argv(); + auto argc = av.argc(); + + auto result = options.parse(argc, argv); + + CHECK(!result.as_optional("int")); + CHECK(!result.as_optional("float")); + CHECK(!result.as_optional("string")); + } + +} +#endif + TEST_CASE("Initializer list with group", "[options]") { cxxopts::Options options("Initializer list group", " - test initializer list with group");