3#ifndef DUNE_COMMON_HYBRIDUTILITIES_HH
4#define DUNE_COMMON_HYBRIDUTILITIES_HH
12#include <dune/common/indices.hh>
13#include <dune/common/assertandreturn.hh>
24 template<
class T,
int i>
26 ->
decltype(std::integral_constant<std::size_t,i>())
33 constexpr auto size(
const T&,
const PriorityTag<3>&)
34 ->
decltype(std::integral_constant<std::size_t,std::tuple_size<T>::value>())
41 constexpr auto size(
const T&,
const PriorityTag<1>&)
42 ->
decltype(std::integral_constant<std::size_t,T::size()>())
49 constexpr auto size(
const T& t,
const PriorityTag<0>&)
80constexpr auto size(
const T& t)
89 template<
class Container,
class Index,
90 std::enable_if_t<IsTuple<std::decay_t<Container>>::value,
int> = 0>
93 return std::get<std::decay_t<Index>::value>(c);
96 template<
class T, T... t,
class Index>
97 constexpr decltype(
auto)
elementAt(std::integer_sequence<T, t...> c, Index, PriorityTag<1>)
102 template<
class Container,
class Index>
103 constexpr decltype(
auto)
elementAt(Container&& c, Index&& i, PriorityTag<0>)
132template<
class Container,
class Index>
133constexpr decltype(
auto)
elementAt(Container&& c, Index&& i)
142 template<
class Begin,
class End,
146 static_assert(Begin::value <= End::value,
"You cannot create an integralRange where end<begin");
154 template<
class Begin,
class End>
155 constexpr auto integralRange(
const Begin& begin,
const End& end,
const PriorityTag<0>&)
181template<
class Begin,
class End>
211 constexpr void evaluateFoldExpression(std::initializer_list<T>&&)
214 template<
class Range,
class F,
class Index, Index... i>
215 constexpr void forEachIndex(Range&& range, F&& f, std::integer_sequence<Index, i...>)
217 evaluateFoldExpression<int>({(f(
Hybrid::elementAt(range, std::integral_constant<Index,i>())), 0)...});
220 template<
class F,
class Index, Index... i>
221 constexpr void forEach(std::integer_sequence<Index, i...> , F&& f, PriorityTag<2>)
223 evaluateFoldExpression<int>({(f(std::integral_constant<Index,i>()), 0)...});
227 template<
class Range,
class F,
228 std::enable_if_t<IsIntegralConstant<decltype(Hybrid::size(std::declval<Range>()))>::value,
int> = 0>
229 constexpr void forEach(Range&& range, F&& f, PriorityTag<1>)
232 auto indices = std::make_index_sequence<size>();
233 (forEachIndex)(std::forward<Range>(range), std::forward<F>(f), indices);
236 template<
class Range,
class F>
237 constexpr void forEach(Range&& range, F&& f, PriorityTag<0>)
239 for(
auto&& e : range)
265template<
class Range,
class F>
288template<
class Range,
class T,
class F>
291 forEach(std::forward<Range>(range), [&](
auto&& entry) {
292 value = f(value, entry);
303 constexpr T operator()(T&& x)
const {
304 return std::forward<T>(x);
308 template<
class IfFunc,
class ElseFunc>
309 constexpr decltype(
auto)
ifElse(std::true_type, IfFunc&& ifFunc, ElseFunc&& )
314 template<
class IfFunc,
class ElseFunc>
315 constexpr decltype(
auto)
ifElse(std::false_type, IfFunc&& , ElseFunc&& elseFunc)
317 return elseFunc(Id{});
320 template<
class IfFunc,
class ElseFunc>
321 decltype(
auto)
ifElse(
const bool& condition, IfFunc&& ifFunc, ElseFunc&& elseFunc)
326 return elseFunc(Id{});
353template<
class Condition,
class IfFunc,
class ElseFunc>
354decltype(
auto)
ifElse(
const Condition& condition, IfFunc&& ifFunc, ElseFunc&& elseFunc)
356 return Impl::ifElse(condition, std::forward<IfFunc>(ifFunc), std::forward<ElseFunc>(elseFunc));
366template<
class Condition,
class IfFunc>
367void ifElse(
const Condition& condition, IfFunc&& ifFunc)
369 ifElse(condition, std::forward<IfFunc>(ifFunc), [](
auto&&) {});
376 template<
class T1,
class T2>
377 constexpr auto equals(
const T1& ,
const T2& ,
PriorityTag<1>) ->
decltype(T1::value, T2::value, std::integral_constant<bool,T1::value == T2::value>())
380 template<
class T1,
class T2>
381 constexpr auto equals(
const T1& t1,
const T2& t2, PriorityTag<0>)
399template<
class T1,
class T2>
409 template<
class Result,
class T,
class Value,
class Branches,
class ElseBranch>
410 constexpr Result
switchCases(std::integer_sequence<T>,
const Value& , Branches&& , ElseBranch&& elseBranch)
415 template<
class Result,
class T, T t0, T... tt,
class Value,
class Branches,
class ElseBranch>
416 constexpr Result
switchCases(std::integer_sequence<T, t0, tt...>,
const Value& value, Branches&& branches, ElseBranch&& elseBranch)
420 [&](
auto id) ->
decltype(
auto) {
421 return id(branches)(std::integral_constant<T, t0>());
422 }, [&](
auto id) ->
decltype(
auto) {
423 return Impl::switchCases<Result>(
id(std::integer_sequence<T, tt...>()), value, branches, elseBranch);
458template<
class Cases,
class Value,
class Branches,
class ElseBranch>
459constexpr decltype(
auto)
switchCases(
const Cases& cases,
const Value& value, Branches&& branches, ElseBranch&& elseBranch)
461 return Impl::switchCases<decltype(elseBranch())>(cases, value, std::forward<Branches>(branches), std::forward<ElseBranch>(elseBranch));
484template<
class Cases,
class Value,
class Branches>
485constexpr void switchCases(
const Cases& cases,
const Value& value, Branches&& branches)
487 Impl::switchCases<void>(cases, value, std::forward<Branches>(branches), []() {});
vector space out of a tensor product of fields.
Definition: fvector.hh:95
dynamic integer range for use in range-based for loops
Definition: rangeutilities.hh:173
static integer range for use in range-based for loops
Definition: rangeutilities.hh:223
Traits for type conversions and type information.
Implements a vector constructed from a given type representing a field and a compile-time given size.
constexpr index_constant< 0 > _0
Compile time index with value 0.
Definition: indices.hh:51
constexpr auto integerSequenceEntry(std::integer_sequence< T, t... >, std::integral_constant< std::size_t, index > i)
Get entry of std::integer_sequence.
Definition: typetraits.hh:462
#define DUNE_ASSERT_AND_RETURN(C, X)
Asserts a condition and return on success in constexpr context.
Definition: assertandreturn.hh:20
void ifElse(const Condition &condition, IfFunc &&ifFunc)
A conditional expression.
Definition: hybridutilities.hh:367
constexpr auto size(const T &t)
Size query.
Definition: hybridutilities.hh:80
constexpr auto integralRange(const End &end)
Create an integral range starting from 0.
Definition: hybridutilities.hh:201
constexpr auto equals(T1 &&t1, T2 &&t2)
Equality comparison.
Definition: hybridutilities.hh:400
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:266
constexpr void switchCases(const Cases &cases, const Value &value, Branches &&branches)
Switch statement.
Definition: hybridutilities.hh:485
constexpr decltype(auto) elementAt(Container &&c, Index &&i)
Get element at given position from container.
Definition: hybridutilities.hh:133
constexpr T accumulate(Range &&range, T value, F &&f)
Accumulate values.
Definition: hybridutilities.hh:289
Dune namespace.
Definition: alignedallocator.hh:11
Utilities for reduction like operations on ranges.
Check if T is an std::integral_constant<I, i>
Definition: typetraits.hh:384
Utilities for type computations, constraining overloads, ...