diff --git a/dumux/common/partial.hh b/dumux/common/partial.hh index 1dc4dbeabd0f57e9c01006425bc3ed3594c011ee..26b34d832c94183c236b5710235411c6dff8c5bf 100644 --- a/dumux/common/partial.hh +++ b/dumux/common/partial.hh @@ -28,9 +28,11 @@ #include <type_traits> #include <dune/istl/multitypeblockvector.hh> +#include <dune/common/version.hh> namespace Dumux { +#if DUNE_VERSION_GT_REV(DUNE_ISTL,2,6,0) /*! * \brief a function to get a MultiTypeBlockVector with references to some entries of another MultiTypeBlockVector * \param v a MultiTypeBlockVector @@ -42,6 +44,58 @@ auto partial(Dune::MultiTypeBlockVector<Args...>& v, Dune::index_constant<i>... return Dune::MultiTypeBlockVector<std::add_lvalue_reference_t<std::decay_t<std::tuple_element_t<indices, std::tuple<Args...>>>>...>(v[indices]...); } +#else + +// for backwards-compatibility of partial with v2.6.0 +template<typename ... Args> +class MultiTypeBlockVectorProxy : public std::tuple<Args...> +{ + typedef std::tuple<Args...> ParentType; +public: + using ParentType::ParentType; + + typedef MultiTypeBlockVectorProxy<Args...> type; + typedef double field_type; + + /** \brief Random-access operator + */ + template< std::size_t index > + typename std::tuple_element<index, ParentType>::type& + operator[] ( const std::integral_constant< std::size_t, index > indexVariable ) + { + DUNE_UNUSED_PARAMETER(indexVariable); + return std::get<index>(*this); + } + + /** \brief Const random-access operator + */ + template< std::size_t index > + const typename std::tuple_element<index, ParentType>::type& + operator[] ( const std::integral_constant< std::size_t, index > indexVariable ) const + { + DUNE_UNUSED_PARAMETER(indexVariable); + return std::get<index>(*this); + } +}; + +template<class T> struct isMultiTypeBlockVector; + +template<class... T> +struct isMultiTypeBlockVector<MultiTypeBlockVectorProxy<T...> > : public std::true_type {}; + +/*! + * \brief a function to get a MultiTypeBlockVector with references to some entries of another MultiTypeBlockVector + * \param v a MultiTypeBlockVector + * \param indices the indices of the entries that should be referenced + */ +template<class ...Args, std::size_t ...i> +auto partial(Dune::MultiTypeBlockVector<Args...>& v, Dune::index_constant<i>... indices) +{ + return MultiTypeBlockVectorProxy<std::add_lvalue_reference_t<std::decay_t<std::tuple_element_t<indices, std::tuple<Args...>>>>...>(v[indices]...); +} + +#endif + /*! * \brief a function to get a tuple with references to some entries of another tuple * \param v a tuple diff --git a/test/common/test_partial.cc b/test/common/test_partial.cc index f420efc90a4c3bc1c4ded62753cab3bee07d2b8b..11ade4186bd7a3bdce7f7c26b93506b4b11eab8c 100644 --- a/test/common/test_partial.cc +++ b/test/common/test_partial.cc @@ -12,6 +12,7 @@ #include <dune/istl/multitypeblockvector.hh> #include <dumux/common/partial.hh> +#include <dune/common/version.hh> namespace Dumux { @@ -41,8 +42,14 @@ void runTest() auto p = partial(m, _0, _2); p = partial(m, std::make_tuple(_0, _2)); +#if DUNE_VERSION_GT_REV(DUNE_ISTL,2,6,0) if (!std::is_same<T<Block1&, Block2&>, std::decay_t<decltype(p)>>::value) DUNE_THROW(Dune::Exception, "Dumux::partial() returned wrong type: " << Dune::className(p)); +#else + // for dune less or equal than v2.6.0, partial returns a std::tuple + if (!(std::is_same<T<Block1&, Block2&>, std::decay_t<decltype(p)>>::value || std::is_same<MultiTypeBlockVectorProxy<Block1&, Block2&>, std::decay_t<decltype(p)>>::value)) + DUNE_THROW(Dune::Exception, "Dumux::partial() returned wrong type: " << Dune::className(p)); +#endif std::get<1>(p)[0][0] = 5.0;