From 2593917370fa424ab1db76db1b870066bfee617c Mon Sep 17 00:00:00 2001 From: Rene Milk <rene.milk@wwu.de> Date: Tue, 31 May 2016 11:47:09 +0200 Subject: [PATCH] [math] clamp now also works for known vector types --- dune/xt/common/math.hh | 15 ++++++++++++++- dune/xt/common/test/math.cc | 24 ++++++++++++++++++------ 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/dune/xt/common/math.hh b/dune/xt/common/math.hh index 326c7de24..8d6c87f12 100644 --- a/dune/xt/common/math.hh +++ b/dune/xt/common/math.hh @@ -35,6 +35,7 @@ #include <dune/xt/common/reenable_warnings.hh> #include <dune/xt/common/type_traits.hh> +#include <dune/xt/common/vector.hh> #include <dune/common/deprecated.hh> namespace Dune { @@ -177,11 +178,23 @@ protected: //! \return var bounded in [min, max] template <typename T> -T clamp(const T var, const T min, const T max) +typename std::enable_if<!is_vector<T>::value, T>::type clamp(const T var, const T min, const T max) { return (var < min) ? min : (var > max) ? max : var; } +template <typename T> +typename std::enable_if<is_vector<T>::value, T>::type clamp(const T var, const T min, const T max) +{ + auto result = var; + std::size_t idx = 0; + for (auto&& element : var) { + result[idx] = clamp(element, min[idx], max[idx]); + ++idx; + } + return result; +} + /** * \returns: -1 iff val < 0 * 0 iff val == 0 diff --git a/dune/xt/common/test/math.cc b/dune/xt/common/test/math.cc index 15faa261c..38ea35329 100644 --- a/dune/xt/common/test/math.cc +++ b/dune/xt/common/test/math.cc @@ -19,27 +19,39 @@ #include <dune/xt/common/ranges.hh> using namespace Dune::XT::Common; +typedef testing::Types<double, int, Dune::FieldVector<double, 3>, std::vector<double>> ClampTestTypes; typedef testing::Types<double, int> TestTypes; typedef testing::Types<std::complex<double>, double, int> ComplexTestTypes; +template <typename T> +static typename std::enable_if<is_vector<T>::value, T>::type init_bound(int val) +{ + const auto size = VectorAbstraction<T>::has_static_size ? VectorAbstraction<T>::static_size : 3u; + return VectorAbstraction<T>::create(size, val); +} +template <typename T> +static typename std::enable_if<!is_vector<T>::value, T>::type init_bound(int val) +{ + return T(val); +} template <class T> struct ClampTest : public testing::Test { const T lower; const T upper; ClampTest() - : lower(T(-1)) - , upper(T(1)) + : lower(init_bound<T>(-1)) + , upper(init_bound<T>(1)) { } }; -TYPED_TEST_CASE(ClampTest, TestTypes); +TYPED_TEST_CASE(ClampTest, ClampTestTypes); TYPED_TEST(ClampTest, All) { - EXPECT_EQ(clamp(TypeParam(-2), this->lower, this->upper), this->lower); - EXPECT_EQ(clamp(TypeParam(2), this->lower, this->upper), this->upper); - EXPECT_EQ(clamp(TypeParam(0), this->lower, this->upper), TypeParam(0)); + EXPECT_EQ(clamp(init_bound<TypeParam>(-2), this->lower, this->upper), this->lower); + EXPECT_EQ(clamp(init_bound<TypeParam>(2), this->lower, this->upper), this->upper); + EXPECT_EQ(clamp(init_bound<TypeParam>(0), this->lower, this->upper), init_bound<TypeParam>(0)); } template <class T> -- GitLab