diff --git a/dune/solvers/common/algorithm.hh b/dune/solvers/common/algorithm.hh index c78a441dcce366f131af50170f501a903f96d6af..9053b2cff834baefd59a8933683d7f33587cdf21 100644 --- a/dune/solvers/common/algorithm.hh +++ b/dune/solvers/common/algorithm.hh @@ -299,6 +299,74 @@ constexpr void forEach(Range&& range, F&& f) +namespace Imp { + + template<class IfFunc, class ElseFunc> + constexpr void if_(std::true_type, IfFunc&& ifFunc, ElseFunc&& elseFunc) + { + ifFunc([](auto&& x) { return std::forward<decltype(x)>(x);}); + } + + template<class IfFunc, class ElseFunc> + constexpr void if_(std::false_type, IfFunc&& ifFunc, ElseFunc&& elseFunc) + { + elseFunc([](auto&& x) { return std::forward<decltype(x)>(x);}); + } + + template<class IfFunc, class ElseFunc> + constexpr void if_(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 A conditional expression + * + * 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,*>. + * + * In order to do this, the passed functors must have a single + * argument of type auto. + * + * Due to the lazy evaluation mechanism and support for + * std::integral_constant<bool,*> this allows to emulate + * a static if statement. + */ +template<class Condition, class IfFunc, class ElseFunc> +constexpr void if_(const Condition& condition, IfFunc&& ifFunc, ElseFunc&& elseFunc) +{ + Imp::if_(condition, std::forward<IfFunc>(ifFunc), std::forward<ElseFunc>(elseFunc)); +} + +/** + * \brief A conditional expression + * + * This provides an if_ conditional with empty else clause. + */ +template<class Condition, class IfFunc> +constexpr void if_(const Condition& condition, IfFunc&& ifFunc) +{ + if_(condition, std::forward<IfFunc>(ifFunc), [](auto&& i) {}); +} + + + + + + + } // namespace HybridAlgorithm