Parcourir la source

cmArgumentParser: Simplify assignment of marker types

Explicitly allow argument markers to be assigned. Make use of this in
parsing. This simplifies working with these types, by allowing them to
be assigned from the underlying types using simple `a = b` syntax,
rather than requiring gymnastics to access the underlying assignment
operations. It also makes assignment more consistent with
initialization.
Matthew Woehlke il y a 6 mois
Parent
commit
5eec48ee40

+ 2 - 2
Source/cmArgumentParser.cxx

@@ -84,7 +84,7 @@ void Instance::Bind(NonEmpty<std::string>& val)
         this->ParseResults->AddKeywordError(this->Keyword,
                                             "  empty string not allowed\n");
       }
-      val.assign(std::string(arg));
+      val = std::string(arg);
       return Continue::No;
     },
     ExpectAtLeast{ 1 });
@@ -94,7 +94,7 @@ void Instance::Bind(Maybe<std::string>& val)
 {
   this->Bind(
     [&val](cm::string_view arg) -> Continue {
-      static_cast<std::string&>(val) = std::string(arg);
+      val = std::string(arg);
       return Continue::No;
     },
     ExpectAtLeast{ 0 });

+ 8 - 0
Source/cmArgumentParserTypes.h

@@ -17,6 +17,7 @@ template <>
 struct Maybe<std::string> : public std::string
 {
   using std::string::basic_string;
+  using std::string::operator=;
 };
 
 template <typename T>
@@ -26,12 +27,14 @@ template <>
 struct MaybeEmpty<std::vector<std::string>> : public std::vector<std::string>
 {
   using std::vector<std::string>::vector;
+  using std::vector<std::string>::operator=;
 };
 #  endif
 template <typename T>
 struct MaybeEmpty<std::vector<T>> : public std::vector<T>
 {
   using std::vector<T>::vector;
+  using std::vector<T>::operator=;
 };
 
 template <typename T>
@@ -40,11 +43,13 @@ template <typename T>
 struct NonEmpty<std::vector<T>> : public std::vector<T>
 {
   using std::vector<T>::vector;
+  using std::vector<T>::operator=;
 };
 template <>
 struct NonEmpty<std::string> : public std::string
 {
   using std::string::basic_string;
+  using std::string::operator=;
 };
 
 } // namespace ArgumentParser
@@ -57,18 +62,21 @@ template <typename T>
 struct Maybe : public T
 {
   using T::T;
+  using T::operator=;
 };
 
 template <typename T>
 struct MaybeEmpty : public T
 {
   using T::T;
+  using T::operator=;
 };
 
 template <typename T>
 struct NonEmpty : public T
 {
   using T::T;
+  using T::operator=;
 };
 
 } // namespace ArgumentParser

+ 24 - 0
Tests/CMakeLib/testArgumentParser.cxx

@@ -458,6 +458,25 @@ bool testArgumentParserStaticBool()
   return verifyResult(result, unparsedArguments);
 }
 
+bool testArgumentParserTypes()
+{
+  ArgumentParser::Maybe<std::string> maybeString;
+  maybeString = std::string();
+  maybeString = "";
+
+  ArgumentParser::MaybeEmpty<std::vector<std::string>> maybeEmptyVecStr;
+  maybeEmptyVecStr = std::vector<std::string>{};
+
+  ArgumentParser::NonEmpty<std::string> nonEmptyString;
+  nonEmptyString = std::string("x");
+  nonEmptyString = "x";
+
+  ArgumentParser::NonEmpty<std::vector<std::string>> nonEmptyVecStr;
+  nonEmptyVecStr = std::vector<std::string>{ "" };
+
+  return true;
+}
+
 } // namespace
 
 int testArgumentParser(int /*unused*/, char* /*unused*/[])
@@ -482,5 +501,10 @@ int testArgumentParser(int /*unused*/, char* /*unused*/[])
     return -1;
   }
 
+  if (!testArgumentParserTypes()) {
+    std::cout << "While executing testArgumentParserTypes().\n";
+    return -1;
+  }
+
   return 0;
 }