From 0be82d488c3ab44a51709187f75f2c912ef52d41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carsten=20Gr=C3=A4ser?= <graeser@dune-project.org> Date: Mon, 12 Dec 2022 12:22:53 +0100 Subject: [PATCH] Improve specializations of Hybrid::size() The interfaces tested subsequently for `Hybrid::size(const T& t)` are now * standard tuple-like interface `std::tuple_size<T>::value` (e.g. needed for `std::tuple`), * static constexpr `T::size()` (e.g. needed for `Dune::TupleVector`), * dynamic member function `t.size()` (e.g. needed for `std::vector`). This patch removes a special case for `FieldVector` which is already covered by the `static constexpr size()` case. To ensure this, a corresponding test case was added. Also the documentation of the different cases was fixed. Notice that this does not work necessarily with matrices, because many of them only provide a (potentially `static constexpr`) method `N()` instead of `size()`. --- dune/common/hybridutilities.hh | 20 ++++++-------------- dune/common/test/hybridutilitiestest.cc | 14 +++++++++++++- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/dune/common/hybridutilities.hh b/dune/common/hybridutilities.hh index 2c120286f..25e74c016 100644 --- a/dune/common/hybridutilities.hh +++ b/dune/common/hybridutilities.hh @@ -22,23 +22,15 @@ namespace Hybrid { namespace Impl { - // Try if tuple_size is implemented for class - template<class T, int i> - constexpr auto size(const Dune::FieldVector<T, i>&, const PriorityTag<5>&) - -> decltype(std::integral_constant<std::size_t,i>()) - { - return {}; - } - - // Try if tuple_size is implemented for class + // Try if std::tuple_size is implemented for class template<class T> - constexpr auto size(const T&, const PriorityTag<3>&) + constexpr auto size(const T&, const PriorityTag<2>&) -> decltype(std::integral_constant<std::size_t,std::tuple_size<T>::value>()) { return {}; } - // Try if there's a static constexpr size() + // Try if there's a static constexpr size() method template<class T> constexpr auto size(const T&, const PriorityTag<1>&) -> decltype(std::integral_constant<std::size_t,T::size()>()) @@ -46,7 +38,7 @@ namespace Impl { return {}; } - // As a last resort try if there's a static constexpr size() + // As a last resort try if there's a non-static size() template<class T> constexpr auto size(const T& t, const PriorityTag<0>&) { @@ -75,8 +67,8 @@ namespace Impl { * Supported types for deriving the size at compile time are: * * instances of std::integer_sequence * * all types std::tuple_size is implemented for - * * all typed that have a static method ::size() - * * instances of Dune::FieldVector + * * all types that have a static constexpr method ::size() + * The latter e.g. includes Dune::FieldVector */ template<class T> constexpr auto size(const T& t) diff --git a/dune/common/test/hybridutilitiestest.cc b/dune/common/test/hybridutilitiestest.cc index 749ba2e66..41a975b00 100644 --- a/dune/common/test/hybridutilitiestest.cc +++ b/dune/common/test/hybridutilitiestest.cc @@ -173,6 +173,7 @@ int main() { std::size_t one = 1; // run-time value auto vector = std::vector<int>{1, 2, 3}; + auto fieldVector = Dune::FieldVector<double,3>({1, 2, 3}); auto numberTuple = Dune::makeTupleVector(0.1, 2, 3); Dune::TestSuite test; @@ -208,6 +209,10 @@ int main() test.check(numberTuple == Dune::makeTupleVector(1.1, 3, 4)) << "Incrementing tuple entries with Hybrid::forEach failed."; + incrementAll(fieldVector); + test.check(fieldVector == Dune::FieldVector<double,3>({2, 3, 4})) + << "Incrementing FieldVector entries with Hybrid::forEach failed."; + addIndex(vector); test.check(vector == std::vector<int>{2, 4, 6}) << "Adding indices to vector entries with Hybrid::forEach failed."; @@ -215,7 +220,14 @@ int main() addIndex(numberTuple); test.check(numberTuple == Dune::makeTupleVector(1.1, 4, 6)) << "Adding indices to vector entries with Hybrid::forEach failed."; - + test.check(Dune::IsIntegralConstant<decltype(Dune::Hybrid::size(numberTuple))>::value) + << "Hybrid::size() of std::tuple is not an std::integral_constant."; + + addIndex(fieldVector); + test.check(fieldVector == Dune::FieldVector<double,3>({2, 4, 6})) + << "Adding indices to FieldVector entries with Hybrid::forEach failed."; + test.check(Dune::IsIntegralConstant<decltype(Dune::Hybrid::size(fieldVector))>::value) + << "Hybrid::size() of FieldVector is not an std::integral_constant."; auto mixedTuple = Dune::makeTupleVector(std::string("1"), 2, 3); incAndAppendToFirst(mixedTuple); -- GitLab