3 #ifndef DUNE_COMMON_HYBRIDUTILITIES_HH
4 #define DUNE_COMMON_HYBRIDUTILITIES_HH
21 template<
class T,
int i>
23 -> decltype(std::integral_constant<std::size_t,i>())
29 template<
class T, T... t,
class Index>
32 using sizeAsType = std::tuple_size<decltype(std::make_tuple(t...))>;
33 return std::integral_constant<std::size_t, sizeAsType::value>();
39 -> decltype(std::integral_constant<std::size_t,std::tuple_size<T>::value>())
47 -> decltype(std::integral_constant<std::size_t,
T::size()>())
85 constexpr
auto size(
const T& t)
94 template<
class Container,
class Index,
95 std::enable_if_t<IsTuple<std::decay_t<Container>>::value,
int> = 0>
98 return std::get<std::decay_t<Index>::value>(c);
101 template<
class T, T... t,
class Index>
104 return std::get<std::decay_t<Index>::value>(std::make_tuple(std::integral_constant<T, t>()...));
107 template<
class Container,
class Index>
137 template<
class Container,
class Index>
138 constexpr decltype(
auto)
elementAt(Container&& c, Index&& i)
147 template<
class Begin,
class End>
152 template<std::
size_t i>
155 return std::integral_constant<typename Begin::value_type, Begin::value+i>();
160 return std::integral_constant<
typename Begin::value_type, End::value - Begin::value>();
175 return end_ - begin_;
186 template<
class Begin,
class End,
190 static_assert(Begin::value <= End::value,
"You cannot create an integralRange where end<begin");
198 template<
class Begin,
class End>
201 assert(begin <= end);
226 template<
class Begin,
class End>
259 template<
class Range,
class F,
class Index, Index... i>
260 constexpr
void forEachIndex(Range&& range, F&& f, std::integer_sequence<Index, i...>)
262 evaluateFoldExpression<int>({(f(
Hybrid::elementAt(range, std::integral_constant<Index,i>())), 0)...});
265 template<
class F,
class Index, Index... i>
268 evaluateFoldExpression<int>({(f(std::integral_constant<Index,i>()), 0)...});
272 template<
class Range,
class F,
273 std::enable_if_t<IsIntegralConstant<decltype(Hybrid::size(std::declval<Range>()))>::value,
int> = 0>
277 auto indices = std::make_index_sequence<size>();
278 forEachIndex(std::forward<Range>(range), std::forward<F>(f), indices);
281 template<
class Range,
class F>
284 for(std::size_t i=0; i<range.size(); ++i)
313 template<
class Range,
class F>
336 template<
class Range,
class T,
class F>
339 forEach(std::forward<Range>(range), [&](
auto&& entry) {
340 value = f(value, entry);
349 template<
class IfFunc,
class ElseFunc>
352 return ifFunc([](
auto&& x) -> decltype(
auto) {
return std::forward<decltype(x)>(x);});
355 template<
class IfFunc,
class ElseFunc>
358 return elseFunc([](
auto&& x) -> decltype(
auto) {
return std::forward<decltype(x)>(x);});
361 template<
class IfFunc,
class ElseFunc>
362 decltype(
auto)
ifElse(const
bool& condition, IfFunc&& ifFunc, ElseFunc&& elseFunc)
365 return ifFunc([](
auto&& x) -> decltype(
auto) {
return std::forward<decltype(x)>(x);});
367 return elseFunc([](
auto&& x) -> decltype(
auto) {
return std::forward<decltype(x)>(x);});
394 template<
class Condition,
class IfFunc,
class ElseFunc>
395 decltype(
auto)
ifElse(const Condition& condition, IfFunc&& ifFunc, ElseFunc&& elseFunc)
397 return Impl::ifElse(condition, std::forward<IfFunc>(ifFunc), std::forward<ElseFunc>(elseFunc));
407 template<
class Condition,
class IfFunc>
408 void ifElse(
const Condition& condition, IfFunc&& ifFunc)
410 ifElse(condition, std::forward<IfFunc>(ifFunc), [](
auto&& i) {});
417 template<
class T1,
class T2>
418 constexpr
auto equals(
const T1& t1,
const T2& t2,
PriorityTag<1>) -> decltype(T1::value, T2::value, std::integral_constant<bool,T1::value == T2::value>())
421 template<
class T1,
class T2>
440 template<
class T1,
class T2>
450 template<
class Result,
class T,
class Value,
class Branches,
class ElseBranch>
451 constexpr Result
switchCases(std::integer_sequence<T>,
const Value& value, Branches&& branches, ElseBranch&& elseBranch)
456 template<
class Result,
class T, T t0, T... tt,
class Value,
class Branches,
class ElseBranch>
457 constexpr Result
switchCases(std::integer_sequence<T, t0, tt...>,
const Value& value, Branches&& branches, ElseBranch&& elseBranch)
461 [&](
auto id) -> decltype(
auto) {
462 return id(branches)(std::integral_constant<T, t0>());
463 }, [&](
auto id) -> decltype(
auto) {
464 return Impl::switchCases<Result>(id(std::integer_sequence<T, tt...>()), value, branches, elseBranch);
499 template<
class Cases,
class Value,
class Branches,
class ElseBranch>
500 constexpr decltype(
auto)
switchCases(const Cases& cases, const Value& value, Branches&& branches, ElseBranch&& elseBranch)
502 return Impl::switchCases<decltype(elseBranch())>(cases, value, std::forward<Branches>(branches), std::forward<ElseBranch>(elseBranch));
525 template<
class Cases,
class Value,
class Branches>
526 constexpr
void switchCases(
const Cases& cases,
const Value& value, Branches&& branches)
528 return Impl::switchCases<void>(cases, value, std::forward<Branches>(branches), []() {});
536 #endif // #ifndef DUNE_COMMON_HYBRIDUTILITIES_HH
vector space out of a tensor product of fields.
Definition: densematrix.hh:39
constexpr Result switchCases(std::integer_sequence< T >, const Value &value, Branches &&branches, ElseBranch &&elseBranch)
Definition: hybridutilities.hh:451
Helper class for tagging priorities.
Definition: typeutilities.hh:59
decltype(auto) constexpr elementAt(Container &&c, Index &&, PriorityTag< 2 >)
Definition: hybridutilities.hh:96
Check if T is an std::integral_constant<I, i>
Definition: typetraits.hh:545
constexpr auto size(const T &t)
Size query.
Definition: hybridutilities.hh:85
constexpr void forEach(std::integer_sequence< Index, i...> range, F &&f, PriorityTag< 2 >)
Definition: hybridutilities.hh:266
Definition: typetraits.hh:207
static constexpr auto size()
Definition: hybridutilities.hh:158
constexpr auto size() const
Definition: hybridutilities.hh:173
constexpr auto equals(T1 &&t1, T2 &&t2)
Equality comparison.
Definition: hybridutilities.hh:441
Utilities for type computations, constraining overloads, ...
decltype(auto) constexpr elementAt(Container &&c, Index &&i)
Get element at given position from container.
Definition: hybridutilities.hh:138
constexpr auto integralRange(const Begin &begin, const End &end, const PriorityTag< 1 > &)
Definition: hybridutilities.hh:188
constexpr DynamicIntegralRange(const T &begin, const T &end)
Definition: hybridutilities.hh:168
constexpr auto operator[](Dune::index_constant< i >) const
Definition: hybridutilities.hh:153
T accumulate(Range &&range, T value, F &&f)
Accumulate values.
Definition: hybridutilities.hh:337
Definition: hybridutilities.hh:148
constexpr void forEachIndex(Range &&range, F &&f, std::integer_sequence< Index, i...>)
Definition: hybridutilities.hh:260
decltype(auto) constexpr ifElse(std::true_type, IfFunc &&ifFunc, ElseFunc &&elseFunc)
Definition: hybridutilities.hh:350
constexpr index_constant< 0 > _0
Compile time index with value 0.
Definition: indices.hh:49
constexpr auto size(const Dune::FieldVector< T, i > *, const PriorityTag< 5 > &) -> decltype(std::integral_constant< std::size_t, i >())
Definition: hybridutilities.hh:22
std::integral_constant< std::size_t, i > index_constant
An index constant with value i.
Definition: indices.hh:26
Helper class for tagging priorities.
Definition: typeutilities.hh:71
Definition: hybridutilities.hh:165
Implements a vector constructed from a given type representing a field and a compile-time given size...
void evaluateFoldExpression(std::initializer_list< T > &&)
Definition: hybridutilities.hh:256
constexpr auto equals(const T1 &t1, const T2 &t2, PriorityTag< 1 >) -> decltype(T1::value, T2::value, std::integral_constant< bool, T1::value==T2::value >())
Definition: hybridutilities.hh:418
constexpr auto integralRange(const Begin &begin, const End &end)
Create an integral range.
Definition: hybridutilities.hh:227
constexpr T operator[](const T &i) const
Definition: hybridutilities.hh:178
Definition: typetraits.hh:200