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 {
namespace Solvers {
// Everything in the next namespace block is just used to implement integralRangeFor
// Implementation of integralRangeFor
namespace Imp {
template<class ST, ST begin, ST end>
......@@ -36,35 +36,27 @@ struct StaticForLoop<ST, end, end>
{}
};
// Compute t1==t2 either statically or dynamically
template<class T1, class T2>
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>)
// Overload for static ranges
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)
{
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>
void staticIf(IfFunc&& ifFunc, ElseFunc&& elseFunc, std::false_type)
// Overload for dynamic ranges
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
*
......@@ -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
* sized containers. The functor is called with index as first argument
* and all additional arguments.
*
* This is the static-size overload which is selected if begin and
* end are both static indices, i.e., integral constants. The loop
* body is called with std::integral_constant<Index,i> where i
* is the static index.
* and all additional arguments. If begin and end are both of type
* std::integral_constant<*,*> than the loop is static with indices
* of the form std::integral_constant<Index, *>, otherwise the loop
* is dynamic with indices type Index.
*/
template<class Index, class Begin, class End, class F, class... Args,
std::enable_if_t<IsIntegralConstant<Begin>::value and IsIntegralConstant<End>::value, int> = 0>
template<class Index, class Begin, class End, class F, class... Args>
void integralRangeFor(Begin&& begin, End&& end, F&& f, Args&&... args)
{
static const Index begin_t = begin;
static const Index end_t = end;
Imp::StaticForLoop<Index, begin_t, end_t>::apply(std::forward<F>(f), std::forward<Args>(args)...);
Imp::integralRangeFor<Index>(std::forward<Begin>(begin), std::forward<End>(end), std::forward<F>(f), std::forward<Args>(args)...);
}
/**
* \brief Hybrid for loop over integral range
*
* \tparam Index Raw type of used indices
* \tparam Begin Type of begin index
* \tparam End Type of end index
* \tparam F Type of functor containing the loop body
* \tparam Args Types of further arguments to the loop body
*
* \param begin Initial index
* \param end One past last index
* \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)
namespace Imp {
// Compute t1==t2 either statically or dynamically
template<class T1, class T2>
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>)
{
for(Index i=begin; i != end; ++i)
f(i, std::forward<Args>(args)...);
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
// 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