/*
* 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.
/** \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:
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
*/
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
/*
* 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.
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(
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