瀏覽代碼

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 6 月之前
父節點
當前提交
5eec48ee40
共有 3 個文件被更改,包括 34 次插入2 次删除
  1. 2 2
      Source/cmArgumentParser.cxx
  2. 8 0
      Source/cmArgumentParserTypes.h
  3. 24 0
      Tests/CMakeLib/testArgumentParser.cxx

+ 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;
 }