cmArgumentParser: Factor out common static/dynamic implementation

This commit is contained in:
Brad King
2022-06-20 14:37:21 -04:00
parent 84b335c286
commit 119e1f7fbc
+32 -29
View File
@@ -32,6 +32,26 @@ public:
const_iterator Find(cm::string_view name) const; const_iterator Find(cm::string_view name) const;
}; };
class Base
{
public:
using Instance = ArgumentParser::Instance;
ArgumentParser::ActionMap Bindings;
bool MaybeBind(cm::string_view name, Action action)
{
return this->Bindings.Emplace(name, std::move(action)).second;
}
void Bind(cm::string_view name, Action action)
{
bool const inserted = this->MaybeBind(name, std::move(action));
assert(inserted);
static_cast<void>(inserted);
}
};
class Instance class Instance
{ {
public: public:
@@ -96,7 +116,7 @@ private:
} // namespace ArgumentParser } // namespace ArgumentParser
template <typename Result> template <typename Result>
class cmArgumentParser class cmArgumentParser : private ArgumentParser::Base
{ {
public: public:
// I *think* this function could be made `constexpr` when the code is // I *think* this function could be made `constexpr` when the code is
@@ -104,15 +124,9 @@ public:
template <typename T> template <typename T>
cmArgumentParser& Bind(cm::static_string_view name, T Result::*member) cmArgumentParser& Bind(cm::static_string_view name, T Result::*member)
{ {
bool const inserted = this->Base::Bind(name, [member](Instance& instance) {
this->Bindings instance.Bind(static_cast<Result*>(instance.Result)->*member);
.Emplace(name, });
[member](ArgumentParser::Instance& instance) {
instance.Bind(
static_cast<Result*>(instance.Result)->*member);
})
.second;
assert(inserted), (void)inserted;
return *this; return *this;
} }
@@ -122,9 +136,8 @@ public:
std::vector<cm::string_view>* keywordsMissingValue = nullptr, std::vector<cm::string_view>* keywordsMissingValue = nullptr,
std::vector<cm::string_view>* parsedKeywords = nullptr) const std::vector<cm::string_view>* parsedKeywords = nullptr) const
{ {
ArgumentParser::Instance instance(this->Bindings, unparsedArguments, Instance instance(this->Bindings, unparsedArguments, keywordsMissingValue,
keywordsMissingValue, parsedKeywords, parsedKeywords, &result);
&result);
instance.Parse(args); instance.Parse(args);
} }
@@ -138,20 +151,16 @@ public:
parsedKeywords); parsedKeywords);
return result; return result;
} }
private:
ArgumentParser::ActionMap Bindings;
}; };
template <> template <>
class cmArgumentParser<void> class cmArgumentParser<void> : private ArgumentParser::Base
{ {
public: public:
template <typename T> template <typename T>
cmArgumentParser& Bind(cm::static_string_view name, T& ref) cmArgumentParser& Bind(cm::static_string_view name, T& ref)
{ {
bool const inserted = this->Bind(cm::string_view(name), ref); this->Base::Bind(name, [&ref](Instance& instance) { instance.Bind(ref); });
assert(inserted), (void)inserted;
return *this; return *this;
} }
@@ -160,8 +169,8 @@ public:
std::vector<cm::string_view>* keywordsMissingValue = nullptr, std::vector<cm::string_view>* keywordsMissingValue = nullptr,
std::vector<cm::string_view>* parsedKeywords = nullptr) const std::vector<cm::string_view>* parsedKeywords = nullptr) const
{ {
ArgumentParser::Instance instance(this->Bindings, unparsedArguments, Instance instance(this->Bindings, unparsedArguments, keywordsMissingValue,
keywordsMissingValue, parsedKeywords); parsedKeywords);
instance.Parse(args); instance.Parse(args);
} }
@@ -169,13 +178,7 @@ protected:
template <typename T> template <typename T>
bool Bind(cm::string_view name, T& ref) bool Bind(cm::string_view name, T& ref)
{ {
return this->Bindings return this->MaybeBind(name,
.Emplace( [&ref](Instance& instance) { instance.Bind(ref); });
name,
[&ref](ArgumentParser::Instance& instance) { instance.Bind(ref); })
.second;
} }
private:
ArgumentParser::ActionMap Bindings;
}; };