From 64b59f8159146bb87bae6b20bb88a2fa67935cd6 Mon Sep 17 00:00:00 2001 From: "Matwey V. Kornilov" Date: Thu, 21 Nov 2019 19:56:43 +0300 Subject: [PATCH] Introduce variable_value::as_optional<>() In some cases, optional<> types are used to specify missed input parameters in functions. It may be the case when missed parameter has meaning 'unknown' rather than 'default' and requires different behaviour. Introduce convenient interface for program_options to write code as the following: const auto opt = va['opt'].as_optional(); as_optional() returns the value when stored type is T, empty optional when variable_value is empty, or raise bad_cast exception when stored type is other than T (as in case of as()). The latter case is considered as a kind of logic/runtime error since the user is supposed to know which type he expects that the variable has. --- include/boost/program_options/variables_map.hpp | 11 +++++++++++ test/variable_map_test.cpp | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/include/boost/program_options/variables_map.hpp b/include/boost/program_options/variables_map.hpp index 362dedf283..5abadfefe8 100644 --- a/include/boost/program_options/variables_map.hpp +++ b/include/boost/program_options/variables_map.hpp @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -74,6 +75,16 @@ namespace boost { namespace program_options { return boost::any_cast(v); } + /** If stored value is of type T, returns optional having that value. + If variable is empty, returns optional having the none. + Otherwise, throws boost::bad_any_cast exception. */ + template + optional as_optional() const { + if (empty()) return none; + + return as(); + } + /// Returns true if no value is stored. bool empty() const; /** Returns true if the value was not explicitly diff --git a/test/variable_map_test.cpp b/test/variable_map_test.cpp index 04b43473d6..ced9cc4b58 100644 --- a/test/variable_map_test.cpp +++ b/test/variable_map_test.cpp @@ -51,6 +51,8 @@ void test_variable_map() BOOST_CHECK(vm.count("biz") == 1); BOOST_CHECK(vm["biz"].as() == "3"); BOOST_CHECK(vm["output"].as() == "foo"); + BOOST_CHECK(vm["bar"].as_optional() == optional("11")); + BOOST_CHECK(vm["buz"].as_optional() == none); int i; desc.add_options() @@ -71,6 +73,8 @@ void test_variable_map() BOOST_CHECK(vm2["zak"].as() == 13); BOOST_CHECK(vm2["opt"].as() == false); BOOST_CHECK(i == 13); + BOOST_CHECK(vm2["zak"].as_optional() == optional(13)); + BOOST_CHECK(vm2["zoo"].as_optional() == none); options_description desc2; desc2.add_options()