diff options
author | Ben Boeckel <ben.boeckel@kitware.com> | 2023-07-19 20:44:59 (GMT) |
---|---|---|
committer | Ben Boeckel <ben.boeckel@kitware.com> | 2023-07-31 15:37:47 (GMT) |
commit | 93993c7ad4f634451fb1c8f67f00d4d959d199ac (patch) | |
tree | 27cc11a752d8bd8bf643d40aa19759fc198930e6 | |
parent | c9ca5f6326136d02c8d12b0a749076ff375dae4c (diff) | |
download | CMake-93993c7ad4f634451fb1c8f67f00d4d959d199ac.zip CMake-93993c7ad4f634451fb1c8f67f00d4d959d199ac.tar.gz CMake-93993c7ad4f634451fb1c8f67f00d4d959d199ac.tar.bz2 |
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.
-rw-r--r-- | Source/cmArgumentParser.h | 32 |
1 files changed, 32 insertions, 0 deletions
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 <cassert> #include <cstddef> #include <functional> +#include <iterator> #include <map> #include <string> #include <utility> @@ -176,6 +177,17 @@ public: void Bind(MaybeEmpty<std::vector<std::string>>& val); void Bind(NonEmpty<std::vector<std::string>>& val); void Bind(std::vector<std::vector<std::string>>& val); + template <typename U> + void Bind(NonEmpty<std::vector<std::pair<std::string, U>>>& 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 <typename T> @@ -187,6 +199,15 @@ public: this->Bind(*optVal); } + template <typename T, typename U> + void Bind(cm::optional<T>& optVal, U const& context) + { + if (!optVal) { + optVal.emplace(); + } + this->Bind(*optVal, context); + } + template <typename Range> void Parse(Range const& args, std::size_t pos = 0) { @@ -232,6 +253,17 @@ public: return *this; } + template <typename T, typename U> + 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<Result*>(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 }) |