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

Add header for basic algorithms

Currently it contains a hybrid for loop over ranges of
integral values begin,begin+1,...,end-1. Using generic
lambdas this allows to write for loops that work with
dynamically sized or statically sized multitype containers.
parent 069dbc0b
Branches
No related tags found
No related merge requests found
Pipeline #
install(FILES install(FILES
algorithm.hh
arithmetic.hh arithmetic.hh
boxconstraint.hh boxconstraint.hh
canignore.hh canignore.hh
......
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_SOLVERS_COMMON_ALGORITHM_HH
#define DUNE_SOLVERS_COMMON_ALGORITHM_HH
namespace Dune {
namespace Solvers {
namespace Imp {
template<class ST, ST begin, ST end>
struct StaticForLoop
{
template<class F, class...Args>
static void apply(F&& f, Args&&... args)
{
f(std::integral_constant<ST, begin>(), std::forward<Args>(args)...);
StaticForLoop<ST, begin+1, end>::apply(std::forward<F>(f), std::forward<Args>(args)...);
}
};
template<class ST, ST end>
struct StaticForLoop<ST, end, end>
{
template<class F, class...Args>
static void apply(F&& f, Args&&...)
{}
};
// Check if T is an integral constant
template<class T>
struct IsIntegralConstant
{
static const bool value = false;
};
template<class T, T t>
struct IsIntegralConstant<std::integral_constant<T, t>>
{
static const bool value = true;
};
} //end namespace Imp
/**
* \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 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.
*/
template<class Index, class Begin, class End, class F, class... Args,
std::enable_if_t<Imp::IsIntegralConstant<Begin>::value and Imp::IsIntegralConstant<End>::value, int> = 0>
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)...);
}
/**
* \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(Imp::IsIntegralConstant<Begin>::value and Imp::IsIntegralConstant<End>::value), int> = 0>
void integralRangeFor(Begin&& begin, End&& end, F&& f, Args&&... args)
{
for(Index i=begin; i != end; ++i)
f(i, std::forward<Args>(args)...);
}
} // namespace Solvers
} // namespace Dune
#endif// DUNE_SOLVERS_COMMON_FORLOOP_HH
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment