dispatchTemplatedFunction: dispatch by bool
authorAndrey Alekseenko <al42and@gmail.com>
Tue, 9 Feb 2021 06:15:36 +0000 (06:15 +0000)
committerMark Abraham <mark.j.abraham@gmail.com>
Tue, 9 Feb 2021 06:15:36 +0000 (06:15 +0000)
Add support of boolean template parameters of the subject function in
dispatchTemplatedFunction.

src/gromacs/utility/template_mp.h
src/gromacs/utility/tests/template_mp.cpp

index 14b4f5371d4896ae07259029523cf672a203f016..8eda416476c0036c64ef82424dae389045591600 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2020, by the GROMACS development team, led by
+ * Copyright (c) 2020,2021, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -62,7 +62,7 @@ auto dispatchTemplatedFunction(Function&& f)
 
 /** \internal \brief Helper function to select appropriate template based on runtime values.
  *
- * Can only use enums for template parameters.
+ * Can use enums or booleans for template parameters.
  * These enums must have a member \c Count indicating the total number of valid values.
  *
  * Example usage:
@@ -73,15 +73,15 @@ auto dispatchTemplatedFunction(Function&& f)
         Count = 2
     };
 
-    template<Options p1, Options p2>
+    template<bool p0, Options p1, Options p2>
     bool foo(int i);
 
-    bool bar(Options p1, Options p2, int i) {
+    bool bar(bool p0, Options p1, Options p2, int i) {
         return dispatchTemplatedFunction(
-            [=](auto p1, auto p2) {
-                return foo<p1, p2>(i);
+            [=](auto p0, auto p1, auto p2) {
+                return foo<p0, p1, p2>(i);
             },
-            p1, p2);
+            p0, p1, p2);
     }
  * \endcode
  */
@@ -98,6 +98,18 @@ auto dispatchTemplatedFunction(Function&& f, Enum e, Enums... es)
             es...);
 }
 
+template<class Function, class... Enums>
+auto dispatchTemplatedFunction(Function&& f, bool e, Enums... es)
+{
+    return dispatchTemplatedFunction(
+            [&](auto... es_) {
+                return compat::mp_with_index<2>(size_t(e), [&](auto e_) {
+                    return std::forward<Function>(f)(std::bool_constant<static_cast<bool>(e_)>(), es_...);
+                });
+            },
+            es...);
+}
+
 } // namespace gmx
 
 #endif // GMX_UTILITY_TEMPLATE_MP_H
index 3fe00e7a4c27ee9709c5c5242a3245a5895bff7b..17db397e8427690d9076af255ddd9489d00cb879 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2020, by the GROMACS development team, led by
+ * Copyright (c) 2020,2021, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -57,7 +57,20 @@ static int testEnumTwoIPlusJPlusK(int k)
     return 2 * int(i) + int(j) + k;
 }
 
-TEST(TemplateMPTest, DispatchTemplatedFunction)
+template<bool doDoubling, Options i, Options j>
+static int testBoolEnumTwoIPlusJPlusK(int k)
+{
+    return (doDoubling ? 2 : 1) * int(i) + int(j) + k;
+}
+
+template<bool doDoubling>
+static int testBoolDoubleOrNot(int k)
+{
+    return (doDoubling ? 2 : 1) * k;
+}
+
+
+TEST(TemplateMPTest, DispatchTemplatedFunctionEnum)
 {
     int five           = 5;
     int two1plus2plus5 = dispatchTemplatedFunction(
@@ -65,5 +78,25 @@ TEST(TemplateMPTest, DispatchTemplatedFunction)
     EXPECT_EQ(two1plus2plus5, 9);
 }
 
+TEST(TemplateMPTest, DispatchTemplatedFunctionBool)
+{
+    int five = 5;
+    int double5 = dispatchTemplatedFunction([=](auto p1) { return testBoolDoubleOrNot<p1>(five); }, true);
+    EXPECT_EQ(double5, 10);
+    int just5 = dispatchTemplatedFunction([=](auto p1) { return testBoolDoubleOrNot<p1>(five); }, false);
+    EXPECT_EQ(just5, 5);
+}
+
+TEST(TemplateMPTest, DispatchTemplatedFunctionEnumBool)
+{
+    int five           = 5;
+    int two1plus2plus5 = dispatchTemplatedFunction(
+            [=](auto p1, auto p2, auto p3) { return testBoolEnumTwoIPlusJPlusK<p1, p2, p3>(five); },
+            true,
+            Options::Op1,
+            Options::Op2);
+    EXPECT_EQ(two1plus2plus5, 9);
+}
+
 } // anonymous namespace
 } // namespace gmx