From 93993c7ad4f634451fb1c8f67f00d4d959d199ac Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Wed, 19 Jul 2023 16:44:59 -0400 Subject: cmArgumentParser: support storing a context value with parsing This allows for parsing of contextual keywords. For example: ``` some_command( ARG_WITH_CONTEXT foo CONTEXT bar ARG_WITH_CONTEXT quux) ``` will be able to store that `foo` happened without context (or, rather, its default value) and `quux` was provided in a `bar` context. --- Source/cmArgumentParser.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/Source/cmArgumentParser.h b/Source/cmArgumentParser.h index fdf54fb..b35d7f3 100644 --- a/Source/cmArgumentParser.h +++ b/Source/cmArgumentParser.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -176,6 +177,17 @@ public: void Bind(MaybeEmpty>& val); void Bind(NonEmpty>& val); void Bind(std::vector>& val); + template + void Bind(NonEmpty>>& val, + U const& context) + { + this->Bind( + [&val, &context](cm::string_view arg) -> Continue { + val.emplace_back(std::string(arg), context); + return Continue::Yes; + }, + ExpectAtLeast{ 1 }); + } // cm::optional<> records the presence the keyword to which it binds. template @@ -187,6 +199,15 @@ public: this->Bind(*optVal); } + template + void Bind(cm::optional& optVal, U const& context) + { + if (!optVal) { + optVal.emplace(); + } + this->Bind(*optVal, context); + } + template void Parse(Range const& args, std::size_t pos = 0) { @@ -232,6 +253,17 @@ public: return *this; } + template + cmArgumentParser& BindWithContext(cm::static_string_view name, + T Result::*member, U Result::*context) + { + this->Base::Bind(name, [member, context](Instance& instance) { + auto* result = static_cast(instance.Result); + instance.Bind(result->*member, result->*context); + }); + return *this; + } + cmArgumentParser& Bind(cm::static_string_view name, Continue (Result::*member)(cm::string_view), ExpectAtLeast expect = { 1 }) -- cgit v0.12