Skip to content
Snippets Groups Projects
Commit deb1ced2 authored by Carsten Gräser's avatar Carsten Gräser
Browse files

Implement staticIf, hybridIf, and hybridEqual

parent 188d91ed
No related branches found
No related tags found
No related merge requests found
Pipeline #
...@@ -52,6 +52,31 @@ template<class T> ...@@ -52,6 +52,31 @@ template<class T>
struct IsIntegralConstant : public IsIntegralConstantHelper<std::decay_t<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 } //end namespace Imp
...@@ -271,6 +296,90 @@ void sparseRangeFor(Range&& range, F&& f) ...@@ -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 Solvers
} // namespace Dune } // namespace Dune
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment