From 3143e43db4bdda831cfed905691cc94b47b96fd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carsten=20Gr=C3=A4ser?= <graeser@dune-project.org> Date: Wed, 16 Mar 2016 17:12:55 +0100 Subject: [PATCH] Simplify hybridIf and remove staticIf staticIf is completely replaced by hybridIf. You just have to pass the condition as integral_constant<bool,*> instead of a template parameter. --- dune/solvers/common/algorithm.hh | 151 +++++++++++++------------------ 1 file changed, 64 insertions(+), 87 deletions(-) diff --git a/dune/solvers/common/algorithm.hh b/dune/solvers/common/algorithm.hh index 546929ef..52c6e57f 100644 --- a/dune/solvers/common/algorithm.hh +++ b/dune/solvers/common/algorithm.hh @@ -86,6 +86,7 @@ void integralRangeFor(Begin&& begin, End&& end, F&& f, Args&&... args) +// Implementation of hybridEquals namespace Imp { // Compute t1==t2 either statically or dynamically @@ -99,20 +100,80 @@ constexpr auto hybridEquals(const T1& t1, const T2& t2, PriorityTag<0>) return t1==t2; } +} //end namespace Imp + +/** + * \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 hybridEquals(const T1& t1, const T2& t2) +{ + return Imp::hybridEquals(t1, t2, PriorityTag<1>()); +} + + + +// Implementation of hybridIf +namespace Imp { + +template<class IfFunc, class ElseFunc> +constexpr void hybridIf(std::true_type, IfFunc&& ifFunc, ElseFunc&& elseFunc) +{ + ifFunc([](auto&& x) { return std::forward<decltype(x)>(x);}); +} + template<class IfFunc, class ElseFunc> -void staticIf(IfFunc&& ifFunc, ElseFunc&& elseFunc, std::false_type) +constexpr void hybridIf(std::false_type, IfFunc&& ifFunc, ElseFunc&& elseFunc) { elseFunc([](auto&& x) { return std::forward<decltype(x)>(x);}); } template<class IfFunc, class ElseFunc> -void staticIf(IfFunc&& ifFunc, ElseFunc&& elseFunc, std::true_type) +constexpr void hybridIf(const bool& condition, IfFunc&& ifFunc, ElseFunc&& elseFunc) { - ifFunc([](auto&& x) { return std::forward<decltype(x)>(x);}); + if (condition) + ifFunc([](auto&& x) { return std::forward<decltype(x)>(x);}); + else + elseFunc([](auto&& x) { return std::forward<decltype(x)>(x);}); } } //end 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,*>. + * + * In order to do this, the passed functors must have a single + * argument of type auto. + */ +template<class Condition, class IfFunc, class ElseFunc> +constexpr 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> +constexpr void hybridIf(const Condition& condition, IfFunc&& ifFunc) +{ + hybridIf(condition, std::forward<IfFunc>(ifFunc), [](auto&& i) {}); +} + // Everything in the next namespace block is just used to implement StaticSize, HasStaticSize, hybridSize @@ -266,90 +327,6 @@ 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 hybridEquals(const T1& t1, const T2& t2) -{ - return Imp::hybridEquals(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 -- GitLab