Merge topic 'genex-IN_LIST-operator'

5089f560 Genex: Add IN_LIST logical operator

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !1724
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index 13948d3..04cb1dc 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -57,6 +57,8 @@
   ``1`` if ``a`` is STREQUAL ``b``, else ``0``
 ``$<EQUAL:a,b>``
   ``1`` if ``a`` is EQUAL ``b`` in a numeric comparison, else ``0``
+``$<IN_LIST:a,b>``
+  ``1`` if ``a`` is IN_LIST ``b``, else ``0``
 ``$<CONFIG:cfg>``
   ``1`` if config is ``cfg``, else ``0``. This is a case-insensitive comparison.
   The mapping in :prop_tgt:`MAP_IMPORTED_CONFIG_<CONFIG>` is also considered by
diff --git a/Help/release/dev/genex-IN_LIST-logical-operator.rst b/Help/release/dev/genex-IN_LIST-logical-operator.rst
new file mode 100644
index 0000000..28fa7ce
--- /dev/null
+++ b/Help/release/dev/genex-IN_LIST-logical-operator.rst
@@ -0,0 +1,5 @@
+genex-IN_LIST-logical-operator
+------------------------------
+
+* A new ``$<IN_LIST:...>`` :manual:`generator expression <cmake-generator-expressions(7)>`
+  has been added.
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index c1f1ee4..0d22028 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -275,6 +275,31 @@
   }
 } equalNode;
 
+static const struct InListNode : public cmGeneratorExpressionNode
+{
+  InListNode() {}
+
+  int NumExpectedParameters() const override { return 2; }
+
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* /*context*/,
+    const GeneratorExpressionContent* /*content*/,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
+  {
+    std::vector<std::string> values;
+    cmSystemTools::ExpandListArgument(parameters[1], values);
+    if (values.empty()) {
+      return "0";
+    }
+
+    return std::find(values.cbegin(), values.cend(), parameters.front()) ==
+        values.cend()
+      ? "0"
+      : "1";
+  }
+} inListNode;
+
 static const struct LowerCaseNode : public cmGeneratorExpressionNode
 {
   LowerCaseNode() {}
@@ -1827,6 +1852,7 @@
     nodeMap["TARGET_BUNDLE_CONTENT_DIR"] = &targetBundleContentDirNode;
     nodeMap["STREQUAL"] = &strEqualNode;
     nodeMap["EQUAL"] = &equalNode;
+    nodeMap["IN_LIST"] = &inListNode;
     nodeMap["LOWER_CASE"] = &lowerCaseNode;
     nodeMap["UPPER_CASE"] = &upperCaseNode;
     nodeMap["MAKE_C_IDENTIFIER"] = &makeCIdentifierNode;
diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt
index 19d12e5..3d08704 100644
--- a/Tests/GeneratorExpression/CMakeLists.txt
+++ b/Tests/GeneratorExpression/CMakeLists.txt
@@ -57,6 +57,11 @@
     -Dtest_strequal_angle_r_comma=$<STREQUAL:$<ANGLE-R>,$<COMMA>>
     -Dtest_strequal_both_empty=$<STREQUAL:,>
     -Dtest_strequal_one_empty=$<STREQUAL:something,>
+    -Dtest_inlist_true=$<IN_LIST:a,a$<SEMICOLON>b>
+    -Dtest_inlist_false=$<IN_LIST:c,a$<SEMICOLON>b>
+    -Dtest_inlist_empty_1=$<IN_LIST:a,>
+    -Dtest_inlist_empty_2=$<IN_LIST:,a>
+    -Dtest_inlist_empty_3=$<IN_LIST:,>
     -Dtest_angle_r=$<ANGLE-R>
     -Dtest_comma=$<COMMA>
     -Dtest_semicolon=$<SEMICOLON>
diff --git a/Tests/GeneratorExpression/check-part1.cmake b/Tests/GeneratorExpression/check-part1.cmake
index 60b193f..41bcd6d 100644
--- a/Tests/GeneratorExpression/check-part1.cmake
+++ b/Tests/GeneratorExpression/check-part1.cmake
@@ -49,6 +49,11 @@
 check(test_strequal_angle_r_comma "0")
 check(test_strequal_both_empty "1")
 check(test_strequal_one_empty "0")
+check(test_inlist_true "1")
+check(test_inlist_false "0")
+check(test_inlist_empty_1 "0")
+check(test_inlist_empty_2 "0")
+check(test_inlist_empty_3 "0")
 check(test_angle_r ">")
 check(test_comma ",")
 check(test_semicolon ";")