From 83efd727f256d8debf671c6f5dcceec60fe747f3 Mon Sep 17 00:00:00 2001 From: Baruch Burstein Date: Mon, 3 Jul 2017 13:46:42 +0300 Subject: [PATCH] Add support for multi-flags --- include/clara.hpp | 24 +++++++++++++++++++++--- src/ClaraTests.cpp | 9 ++++++++- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/include/clara.hpp b/include/clara.hpp index bf4664a..ffdb787 100644 --- a/include/clara.hpp +++ b/include/clara.hpp @@ -331,7 +331,7 @@ namespace detail { virtual auto isFlag() const -> bool = 0; - virtual auto isContainer() const -> bool { return false; } + virtual auto allowMulti() const -> bool { return false; } virtual auto setValue(std::string const &arg) -> ParserResult = 0; @@ -375,7 +375,7 @@ namespace detail { explicit BoundRef(std::vector &ref) : m_ref(ref) {} - auto isContainer() const -> bool override { return true; } + auto allowMulti() const -> bool override { return true; } auto setValue(std::string const &arg) -> ParserResult override { T temp; @@ -397,6 +397,21 @@ namespace detail { } }; + template + struct BoundMultiFlagRef : BoundFlagRefBase { + T &m_ref; + + explicit BoundMultiFlagRef(T &ref) : m_ref(ref) {} + + auto allowMulti() const -> bool override { return true; } + + auto setFlag(bool flag) -> ParserResult override { + if (flag) + ++m_ref; + return ParserResult::ok(ParseResultType::Matched); + } + }; + template struct LambdaInvoker { static_assert(std::is_same::value, "Lambda must return void or clara::ParserResult"); @@ -516,7 +531,7 @@ namespace detail { } auto cardinality() const -> size_t override { - if (m_ref->isContainer()) + if (m_ref->allowMulti()) return 0; else return 1; @@ -606,6 +621,9 @@ namespace detail { explicit Opt( bool &ref ) : ParserRefImpl(std::make_shared(ref)) {} + template + explicit Opt( T &ref ) : ParserRefImpl(std::make_shared>(ref)) {} + template Opt( LambdaT const &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {} diff --git a/src/ClaraTests.cpp b/src/ClaraTests.cpp index c9f0dc8..5ed13db 100644 --- a/src/ClaraTests.cpp +++ b/src/ClaraTests.cpp @@ -61,6 +61,7 @@ struct Config { std::vector m_tests; bool m_flag = false; double m_value = 0; + int m_flagCount = 0; }; TEST_CASE( "Combined parser" ) { @@ -82,6 +83,9 @@ TEST_CASE( "Combined parser" ) { + Opt( [&]( double value ){ config.m_value = value; }, "number" ) ["-d"]["--double"] ( "just some number" ) + + Opt( config.m_flagCount ) + ["-v"] + ( "a flag to set multiple times" ) + Arg( config.m_tests, "test name|tags|pattern" ) ( "which test or tests to use" ); @@ -99,16 +103,19 @@ TEST_CASE( "Combined parser" ) { " -n, --name the name to use\n" " -f, --flag a flag to set\n" " -d, --double just some number\n" + " -v a flag to set multiple times\n" ); } SECTION( "some args" ) { - auto result = parser.parse( Args{ "TestApp", "-n", "Bill", "-d:123.45", "-f", "test1", "test2" } ); + auto result = parser.parse( Args{ "TestApp", "-n", "Bill", "-d:123.45", "-f", "-vvv", "test1", "test2" } ); CHECK( result ); CHECK( result.value().type() == ParseResultType::Matched ); REQUIRE( config.m_name == "Bill" ); REQUIRE( config.m_value == 123.45 ); REQUIRE( config.m_tests == std::vector { "test1", "test2" } ); + REQUIRE( config.m_flag ); + REQUIRE( config.m_flagCount == 3 ); CHECK( showHelp == false ); } SECTION( "help" ) {