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

Cleanup interface of integralRangeFor

To avoid that two overloads appear in the interface, they are
moved to Imp:: and only a single function remains in the interface.
parent fbc8be30
Branches
No related tags found
No related merge requests found
Pipeline #
...@@ -14,7 +14,7 @@ namespace Dune { ...@@ -14,7 +14,7 @@ namespace Dune {
namespace Solvers { namespace Solvers {
// Everything in the next namespace block is just used to implement integralRangeFor // Implementation of integralRangeFor
namespace Imp { namespace Imp {
template<class ST, ST begin, ST end> template<class ST, ST begin, ST end>
...@@ -36,35 +36,27 @@ struct StaticForLoop<ST, end, end> ...@@ -36,35 +36,27 @@ struct StaticForLoop<ST, end, end>
{} {}
}; };
// Overload for static ranges
template<class Index, class Begin, class End, class F, class... Args,
// Compute t1==t2 either statically or dynamically std::enable_if_t<IsIntegralConstant<Begin>::value and IsIntegralConstant<End>::value, int> = 0>
template<class T1, class T2> void integralRangeFor(Begin&& begin, End&& end, F&& f, Args&&... args)
constexpr auto hybridEquals(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 hybridEquals(const T1& t1, const T2& t2, PriorityTag<0>)
{ {
return t1==t2; static const Index begin_t = begin;
static const Index end_t = end;
StaticForLoop<Index, begin_t, end_t>::apply(std::forward<F>(f), std::forward<Args>(args)...);
} }
template<class IfFunc, class ElseFunc> // Overload for dynamic ranges
void staticIf(IfFunc&& ifFunc, ElseFunc&& elseFunc, std::false_type) template<class Index, class Begin, class End, class F, class... Args,
std::enable_if_t<not(IsIntegralConstant<Begin>::value and IsIntegralConstant<End>::value), int> = 0>
void integralRangeFor(Begin&& begin, End&& end, F&& f, Args&&... args)
{ {
elseFunc([](auto&& x) { return std::forward<decltype(x)>(x);}); for(Index i=begin; i != end; ++i)
f(i, std::forward<Args>(args)...);
} }
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
/** /**
* \brief Hybrid for loop over integral range * \brief Hybrid for loop over integral range
* *
...@@ -81,52 +73,46 @@ void staticIf(IfFunc&& ifFunc, ElseFunc&& elseFunc, std::true_type) ...@@ -81,52 +73,46 @@ void staticIf(IfFunc&& ifFunc, ElseFunc&& elseFunc, std::true_type)
* *
* This is a hybrid for loop that can work on statically and dynamically * This is a hybrid for loop that can work on statically and dynamically
* sized containers. The functor is called with index as first argument * sized containers. The functor is called with index as first argument
* and all additional arguments. * and all additional arguments. If begin and end are both of type
* * std::integral_constant<*,*> than the loop is static with indices
* This is the static-size overload which is selected if begin and * of the form std::integral_constant<Index, *>, otherwise the loop
* end are both static indices, i.e., integral constants. The loop * is dynamic with indices type Index.
* body is called with std::integral_constant<Index,i> where i
* is the static index.
*/ */
template<class Index, class Begin, class End, class F, class... Args, template<class Index, class Begin, class End, class F, class... Args>
std::enable_if_t<IsIntegralConstant<Begin>::value and IsIntegralConstant<End>::value, int> = 0>
void integralRangeFor(Begin&& begin, End&& end, F&& f, Args&&... args) void integralRangeFor(Begin&& begin, End&& end, F&& f, Args&&... args)
{ {
static const Index begin_t = begin; Imp::integralRangeFor<Index>(std::forward<Begin>(begin), std::forward<End>(end), std::forward<F>(f), std::forward<Args>(args)...);
static const Index end_t = end;
Imp::StaticForLoop<Index, begin_t, end_t>::apply(std::forward<F>(f), std::forward<Args>(args)...);
} }
/**
* \brief Hybrid for loop over integral range
* namespace Imp {
* \tparam Index Raw type of used indices
* \tparam Begin Type of begin index // Compute t1==t2 either statically or dynamically
* \tparam End Type of end index template<class T1, class T2>
* \tparam F Type of functor containing the loop body constexpr auto hybridEquals(const T1& t1, const T2& t2, PriorityTag<1>) -> decltype(T1::value, T2::value, std::integral_constant<bool,T1::value == T2::value>())
* \tparam Args Types of further arguments to the loop body { return {}; }
*
* \param begin Initial index template<class T1, class T2>
* \param end One past last index constexpr auto hybridEquals(const T1& t1, const T2& t2, PriorityTag<0>)
* \param f Functor to call in each loop instance
* \param args Additional arguments to be passed to the functor
*
* This is a hybrid for loop that can work on statically and dynamically
* sized containers. The functor is called with index as first argument
* and all additional arguments.
*
* This is the dynamic-size overload which is selected if either begin or
* end is a dynamic index, i.e., not an integral constant. The loop
* body is called with indices of type Index.
*/
template<class Index, class Begin, class End, class F, class... Args,
std::enable_if_t<not(IsIntegralConstant<Begin>::value and IsIntegralConstant<End>::value), int> = 0>
void integralRangeFor(Begin&& begin, End&& end, F&& f, Args&&... args)
{ {
for(Index i=begin; i != end; ++i) return t1==t2;
f(i, std::forward<Args>(args)...);
} }
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
// 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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment