diff --git a/dune/solvers/common/algorithm.hh b/dune/solvers/common/algorithm.hh index 26137563ea3bad05581b43586e08a73b7433341b..65181d8b67f52f72795d750dcc8b2448ec2b7811 100644 --- a/dune/solvers/common/algorithm.hh +++ b/dune/solvers/common/algorithm.hh @@ -4,6 +4,7 @@ #define DUNE_SOLVERS_COMMON_ALGORITHM_HH +#include <dune/common/typeutilities.hh> namespace Dune { namespace Solvers { @@ -33,17 +34,22 @@ struct StaticForLoop<ST, end, end> // Check if T is an integral constant template<class T> -struct IsIntegralConstant +struct IsIntegralConstantHelper { static const bool value = false; }; template<class T, T t> -struct IsIntegralConstant<std::integral_constant<T, t>> +struct IsIntegralConstantHelper<std::integral_constant<T, t>> { static const bool value = true; }; +// Check if T is an integral constant +template<class T> +struct IsIntegralConstant : public IsIntegralConstantHelper<std::decay_t<T>> +{}; + } //end namespace Imp @@ -139,6 +145,14 @@ constexpr auto staticSize(const T*, const PriorityTag<2>&) return {}; } +// Try if tuple_size is implemented for class +template<class T, int i> +constexpr auto staticSize(const Dune::FieldVector<T, i>*, const PriorityTag<3>&) + -> decltype(std::integral_constant<std::size_t,i>()) +{ + return {}; +} + template<class T> constexpr std::false_type hasStaticSize(const T* t, const PriorityTag<0>& p) { @@ -200,7 +214,7 @@ struct StaticSize : */ template<class T, std::enable_if_t<HasStaticSize<T>::value, int> = 0> -auto hybridSize(const T& t) +constexpr auto hybridSize(const T& t) { return Imp::staticSize((T*)(nullptr), PriorityTag<42>()); } @@ -221,7 +235,7 @@ auto hybridSize(const T& t) */ template<class T, std::enable_if_t<not HasStaticSize<T>::value, int> = 0> -auto hybridSize(const T& t) +constexpr auto hybridSize(const T& t) { return t.size(); }