diff --git a/dune/solvers/common/algorithm.hh b/dune/solvers/common/algorithm.hh
index e99cc75f52b87d7f20c15f27de0f2238bc1d89c8..fc47a3b5f24780c20da07f7c9b047733a57f52a7 100644
--- a/dune/solvers/common/algorithm.hh
+++ b/dune/solvers/common/algorithm.hh
@@ -52,6 +52,31 @@ template<class T>
 struct IsIntegralConstant : public IsIntegralConstantHelper<std::decay_t<T>>
 {};
 
+
+
+// Compute t1==t2 either statically or dynamically
+template<class T1, class T2>
+constexpr auto hybridEqual(const T1& t1, const T2& t2, PriorityTag<1>) -> decltype(T1::value, T2::value, std::integral_constant<bool,T1::value == T2::value>())
+{ return {}; }
+
+template<class T1, class T2>
+constexpr auto hybridEqual(const T1& t1, const T2& t2, PriorityTag<0>)
+{
+  return t1==t2;
+}
+
+template<class IfFunc, class ElseFunc>
+void staticIf(IfFunc&& ifFunc, ElseFunc&& elseFunc, std::false_type)
+{
+  elseFunc([](auto&& x) { return std::forward<decltype(x)>(x);});
+}
+
+template<class IfFunc, class ElseFunc>
+void staticIf(IfFunc&& ifFunc, ElseFunc&& elseFunc, std::true_type)
+{
+  ifFunc([](auto&& x) { return std::forward<decltype(x)>(x);});
+}
+
 } //end namespace Imp
 
 
@@ -271,6 +296,90 @@ void sparseRangeFor(Range&& range, F&& f)
 
 
 
+/**
+ * \brief Hybrid equality comparison
+ *
+ * If both types have a static member value, the result of comparing
+ * these is returned as std::integral_constant<bool, *>. Otherwise
+ * the result of a runtime comparison of t1 and t2 is directly returned.
+ */
+template<class T1, class T2>
+constexpr auto hybridEqual(const T1& t1, const T2& t2)
+{
+  return Imp::hybridEqual(t1, t2, PriorityTag<1>());
+}
+
+
+/**
+ * \brief Static if emulation
+ *
+ * This will call either ifFunc or elseFunc depending
+ * on the condition. In any case a single argument
+ * will be passed to the called function. This will always
+ * be the indentity function. Passing an expression through
+ * this function will lead to lazy evaluation. This way both
+ * 'branches' can contain expressions that are only valid
+ * within this branch.
+ */
+template<bool condition, class IfFunc, class ElseFunc>
+void staticIf(IfFunc&& ifFunc, ElseFunc&& elseFunc)
+{
+  Imp::staticIf(std::forward<IfFunc>(ifFunc), std::forward<ElseFunc>(elseFunc), std::integral_constant<bool, condition>());
+}
+
+
+
+namespace Imp {
+
+template<bool condition, class IfFunc, class ElseFunc>
+void hybridIf(const std::integral_constant<bool, condition>&, IfFunc&& ifFunc, ElseFunc&& elseFunc)
+{
+  staticIf<condition>(std::forward<IfFunc>(ifFunc), std::forward<ElseFunc>(elseFunc));
+}
+
+template<class IfFunc, class ElseFunc>
+void hybridIf(const bool& condition, IfFunc&& ifFunc, ElseFunc&& elseFunc)
+{
+  if (condition)
+    ifFunc([](auto&& x) { return std::forward<decltype(x)>(x);});
+  else
+    elseFunc([](auto&& x) { return std::forward<decltype(x)>(x);});
+}
+
+} // namespace Imp
+
+
+
+/**
+ * \brief Hybrid if
+ *
+ * This will call either ifFunc or elseFunc depending
+ * on the condition. In any case a single argument
+ * will be passed to the called function. This will always
+ * be the indentity function. Passing an expression through
+ * this function will lead to lazy evaluation. This way both
+ * 'branches' can contain expressions that are only valid
+ * within this branch if the condition is a std::integral_constant<bool,*>.
+ */
+template<class Condition, class IfFunc, class ElseFunc>
+void hybridIf(const Condition& condition, IfFunc&& ifFunc, ElseFunc&& elseFunc)
+{
+  Imp::hybridIf(condition, std::forward<IfFunc>(ifFunc), std::forward<ElseFunc>(elseFunc));
+}
+
+
+
+/**
+ * \brief Hybrid if
+ *
+ * This provides a hybridIf with empty else clause.
+ */
+template<class Condition, class IfFunc>
+void hybridIf(const Condition& condition, IfFunc&& ifFunc)
+{
+  hybridIf(condition, std::forward<IfFunc>(ifFunc), [](auto&& i) {});
+}
+
 } // namespace Solvers
 } // namespace Dune