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

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.
parent bb9a1881
Branches
No related tags found
No related merge requests found
...@@ -86,6 +86,7 @@ void integralRangeFor(Begin&& begin, End&& end, F&& f, Args&&... args) ...@@ -86,6 +86,7 @@ void integralRangeFor(Begin&& begin, End&& end, F&& f, Args&&... args)
// Implementation of hybridEquals
namespace Imp { namespace Imp {
// Compute t1==t2 either statically or dynamically // Compute t1==t2 either statically or dynamically
...@@ -99,20 +100,80 @@ constexpr auto hybridEquals(const T1& t1, const T2& t2, PriorityTag<0>) ...@@ -99,20 +100,80 @@ constexpr auto hybridEquals(const T1& t1, const T2& t2, PriorityTag<0>)
return t1==t2; 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> 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);}); elseFunc([](auto&& x) { return std::forward<decltype(x)>(x);});
} }
template<class IfFunc, class ElseFunc> 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 } //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 // Everything in the next namespace block is just used to implement StaticSize, HasStaticSize, hybridSize
...@@ -266,90 +327,6 @@ void sparseRangeFor(Range&& range, F&& f) ...@@ -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 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