From 06ebdc9268578e50099c48c7e31a30aa0d8216bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Wed, 15 Jun 2016 10:55:42 +0200 Subject: [PATCH 1/2] Avoid ambiguous calls to abs with unsigned integers. --- opm/core/linalg/ParallelIstlInformation.hpp | 34 +++++++++++++++------ tests/test_parallelistlinformation.cpp | 5 ++- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/opm/core/linalg/ParallelIstlInformation.hpp b/opm/core/linalg/ParallelIstlInformation.hpp index 49504dff4..9dae2c4f7 100644 --- a/opm/core/linalg/ParallelIstlInformation.hpp +++ b/opm/core/linalg/ParallelIstlInformation.hpp @@ -578,18 +578,32 @@ private: namespace detail { - /// \brief Computes the maximum of theabsolute values of two values. - template - struct MaxAbsFunctor - { - typedef T result_type; - - result_type operator()(const T& t1, const T& t2) + /// \brief Computes the maximum of the absolute values of two values. + template + struct MaxAbsFunctor { - return std::max(std::abs(t1),std::abs(t2)); - } - }; + typedef T result_type; + + result_type operator()(const T& t1, const T& t2) + { + return std::max(std::abs(t1),std::abs(t2)); + } + }; + + + /// \brief Specialization to avoid ambiguous abs() for unsigned integers. + template <> + struct MaxAbsFunctor + { + typedef std::size_t result_type; + + result_type operator()(const std::size_t& t1, const std::size_t& t2) + { + return std::max(t1, t2); + } + }; } + /// \brief Create a functor for computing a global L infinity norm /// /// To be used with ParallelISTLInformation::computeReduction. diff --git a/tests/test_parallelistlinformation.cpp b/tests/test_parallelistlinformation.cpp index 8258ad329..f0a07283e 100644 --- a/tests/test_parallelistlinformation.cpp +++ b/tests/test_parallelistlinformation.cpp @@ -33,6 +33,7 @@ #include #ifdef HAVE_DUNE_ISTL + template void runSumMaxMinTest(const T offset) { @@ -60,7 +61,9 @@ void runSumMaxMinTest(const T offset) BOOST_CHECK(std::get<1>(values)==std::max(N+offset-1, std::get<1>(oldvalues))); BOOST_CHECK(std::get<2>(values)==std::min(offset, std::get<2>(oldvalues))); BOOST_CHECK(std::get<3>(values)==((end-1)*end*(2*end-1)-(start-1)*start*(2*start-1))/6+std::get<3>(oldvalues)); - BOOST_CHECK(std::get<4>(values)==std::max(std::abs(offset),std::abs(N+offset-1))); + // Must avoid std::abs() directly to prevent ambiguity with unsigned integers. + Opm::Reduction::detail::MaxAbsFunctor maxabsfunc; + BOOST_CHECK(std::get<4>(values)==maxabsfunc(offset, N+offset-1)); } BOOST_AUTO_TEST_CASE(tupleReductionTestInt) From f5d1cbfb757e973c7795e905589a0ccd1e15f4d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Thu, 16 Jun 2016 08:47:21 +0200 Subject: [PATCH 2/2] Make specialization for all unsigned integer types. --- opm/core/linalg/ParallelIstlInformation.hpp | 25 +++++++++++---------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/opm/core/linalg/ParallelIstlInformation.hpp b/opm/core/linalg/ParallelIstlInformation.hpp index 9dae2c4f7..bd497a793 100644 --- a/opm/core/linalg/ParallelIstlInformation.hpp +++ b/opm/core/linalg/ParallelIstlInformation.hpp @@ -579,25 +579,26 @@ private: namespace detail { /// \brief Computes the maximum of the absolute values of two values. - template + template struct MaxAbsFunctor { - typedef T result_type; - - result_type operator()(const T& t1, const T& t2) + using result_type = T; + result_type operator()(const T& t1, + const T& t2) { - return std::max(std::abs(t1),std::abs(t2)); + return std::max(std::abs(t1), std::abs(t2)); } }; - - /// \brief Specialization to avoid ambiguous abs() for unsigned integers. - template <> - struct MaxAbsFunctor + // Specialization for unsigned integers. They need their own + // version since abs(x) is ambiguous (as well as somewhat + // meaningless). + template + struct MaxAbsFunctor::value>::type> { - typedef std::size_t result_type; - - result_type operator()(const std::size_t& t1, const std::size_t& t2) + using result_type = T; + result_type operator()(const T& t1, + const T& t2) { return std::max(t1, t2); }