5#ifndef DUNE_COMMON_HYBRIDUTILITIES_HH
6#define DUNE_COMMON_HYBRIDUTILITIES_HH
14#include <dune/common/indices.hh>
15#include <dune/common/integersequence.hh>
27 constexpr auto size(
const T&,
const PriorityTag<2>&)
28 ->
decltype(std::integral_constant<std::size_t,std::tuple_size<T>::value>())
35 constexpr auto size(
const T&,
const PriorityTag<1>&)
36 ->
decltype(std::integral_constant<std::size_t,T::size()>())
43 constexpr auto size(
const T& t,
const PriorityTag<0>&)
74constexpr auto size(
const T& t)
83 template<
class Container,
class Index,
84 std::enable_if_t<IsTuple<std::decay_t<Container>>::value,
int> = 0>
87 return std::get<std::decay_t<Index>::value>(c);
90 template<
class T, T... t,
class Index>
91 constexpr decltype(
auto)
elementAt(std::integer_sequence<T, t...> c, Index, PriorityTag<1>)
93 return Dune::get<Index::value>(c);
96 template<
class Container,
class Index>
97 constexpr decltype(
auto)
elementAt(Container&& c, Index&& i, PriorityTag<0>)
126template<
class Container,
class Index>
127constexpr decltype(
auto)
elementAt(Container&& c, Index&& i)
136 template<
class Begin,
class End,
140 static_assert(Begin::value <= End::value,
"You cannot create an integralRange where end<begin");
144 template<
class Begin,
class End>
145 constexpr auto integralRange(
const Begin& begin,
const End& end,
const PriorityTag<0>&)
147 assert(begin<=end &&
"You cannot create an integralRange where end<begin");
172template<
class Begin,
class End>
202 constexpr void evaluateFoldExpression(std::initializer_list<T>&&)
205 template<
class Range,
class F,
class Index, Index... i>
206 constexpr void forEachIndex(Range&&
range, F&& f, std::integer_sequence<Index, i...>)
211 template<
class F,
class Index, Index... i>
212 constexpr void forEach(std::integer_sequence<Index, i...> , F&& f, PriorityTag<2>)
214 evaluateFoldExpression<int>({(f(std::integral_constant<Index,i>()), 0)...});
218 template<
class Range,
class F,
219 std::enable_if_t<IsIntegralConstant<decltype(Hybrid::size(std::declval<Range>()))>::value,
int> = 0>
220 constexpr void forEach(Range&&
range, F&& f, PriorityTag<1>)
223 auto indices = std::make_index_sequence<size>();
224 (forEachIndex)(std::forward<Range>(
range), std::forward<F>(f), indices);
227 template<
class Range,
class F>
228 constexpr void forEach(Range&&
range, F&& f, PriorityTag<0>)
230 for(
auto&& e :
range)
256template<
class Range,
class F>
279template<
class Range,
class T,
class F>
283 value = f(value, entry);
294 constexpr T operator()(T&& x)
const {
295 return std::forward<T>(x);
299 template<
class IfFunc,
class ElseFunc>
300 constexpr decltype(
auto)
ifElse(std::true_type, IfFunc&& ifFunc, ElseFunc&& )
305 template<
class IfFunc,
class ElseFunc>
306 constexpr decltype(
auto)
ifElse(std::false_type, IfFunc&& , ElseFunc&& elseFunc)
308 return elseFunc(Id{});
311 template<
class IfFunc,
class ElseFunc>
312 decltype(
auto)
ifElse(
const bool& condition, IfFunc&& ifFunc, ElseFunc&& elseFunc)
317 return elseFunc(Id{});
344template<
class Condition,
class IfFunc,
class ElseFunc>
345decltype(
auto)
ifElse(
const Condition& condition, IfFunc&& ifFunc, ElseFunc&& elseFunc)
347 return Impl::ifElse(condition, std::forward<IfFunc>(ifFunc), std::forward<ElseFunc>(elseFunc));
357template<
class Condition,
class IfFunc>
358void ifElse(
const Condition& condition, IfFunc&& ifFunc)
360 ifElse(condition, std::forward<IfFunc>(ifFunc), [](
auto&&) {});
368 template<
class... Args>
369 constexpr decltype(
auto)
operator()(Args&&... args)
const
371 using T = std::common_type_t<Args...>;
377 template<
class... Args>
378 constexpr decltype(
auto)
operator()(Args&&... args)
const
380 using T = std::common_type_t<Args...>;
418template<
class Functor>
421 static_assert(std::is_default_constructible_v<Functor>,
422 "Operator in integral expressions shall be constexpr default constructible");
424 inline static constexpr Functor _functor = Functor{};
437 template<
class... Args>
438 constexpr decltype(
auto)
operator()(
const Args&... args)
const
440 if constexpr (std::conjunction_v<IsCompileTimeConstant<Args>...>)
442 constexpr auto result = _functor(Args::value...);
445 return std::integral_constant<std::remove_cv_t<
decltype(result)>,result>{};
450 return _functor(args...);
459template<
class Functor>
460constexpr HybridFunctor<Functor> hybridFunctor(
const Functor&)
485inline constexpr auto max = hybridFunctor(Impl::Max{});
507inline constexpr auto min = hybridFunctor(Impl::Min{});
529inline constexpr auto plus = hybridFunctor(std::plus<>{});
551inline constexpr auto minus = hybridFunctor(std::minus<>{});
573inline constexpr auto equal_to = hybridFunctor(std::equal_to<>{});
587template<
class T1,
class T2>
588[[deprecated(
"Use Hybrid::equal_to instead!")]]
constexpr auto equals(T1&& t1, T2&& t2){
589 return equal_to(std::forward<T1>(t1), std::forward<T2>(t2));
596 template<
class Result,
class T, T t0, T... tt,
class ValueType, ValueType value,
class Branches,
class ElseBranch>
597 constexpr Result
switchCases(std::integer_sequence<T, t0, tt...>,
const std::integral_constant<ValueType, value>& , Branches&& branches, ElseBranch&& elseBranch)
605 if constexpr (((t0 == value) || ... || (tt == value)))
606 return branches(std::integral_constant<T, value>{});
612 template<
class Result,
class T,
class Value,
class Branches,
class ElseBranch>
613 constexpr Result
switchCases(std::integer_sequence<T>,
const Value& , Branches&& , ElseBranch&& elseBranch)
618 template<
class Result,
class T, T t0, T... tt,
class Value,
class Branches,
class ElseBranch>
619 constexpr Result
switchCases(std::integer_sequence<T, t0, tt...>,
const Value& value, Branches&& branches, ElseBranch&& elseBranch)
622 return branches(std::integral_constant<T, t0>());
624 return Impl::switchCases<Result>(std::integer_sequence<T, tt...>(), value, branches, elseBranch);
628 template <
class Result,
class T,
class Value,
class Branches,
class ElseBranch>
629 constexpr Result
switchCases(IntegralRange<T>
range,
const Value& value, Branches&& branches, ElseBranch&& elseBranch)
631 return range.contains(value) ? branches(T(value)) : elseBranch();
635 template <
class Result,
class T, T to, T from,
class Value,
class Branches,
class ElseBranch>
636 constexpr Result
switchCases(StaticIntegralRange<T, to, from>
range,
const Value& value, Branches&& branches, ElseBranch&& elseBranch)
638 using seq =
typename decltype(
range)::integer_sequence;
639 return Impl::switchCases<Result>(seq{}, value, branches, elseBranch);
673template<
class Cases,
class Value,
class Branches,
class ElseBranch>
674constexpr decltype(
auto)
switchCases(
const Cases& cases,
const Value& value, Branches&& branches, ElseBranch&& elseBranch)
676 return Impl::switchCases<decltype(elseBranch())>(cases, value, std::forward<Branches>(branches), std::forward<ElseBranch>(elseBranch));
698template<
class Cases,
class Value,
class Branches>
699constexpr void switchCases(
const Cases& cases,
const Value& value, Branches&& branches)
701 Impl::switchCases<void>(cases, value, std::forward<Branches>(branches),
702 []{ assert(
false &&
"value not found in range"); });
723template <
class T,
class Value,
class Branches>
726 assert(
range.contains(value) &&
"value not found in range");
Adapter of a hybrid functor that maintains results hybrid.
Definition: hybridutilities.hh:419
dynamic integer range for use in range-based for loops
Definition: rangeutilities.hh:177
static integer range for use in range-based for loops
Definition: rangeutilities.hh:230
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:52
void ifElse(const Condition &condition, IfFunc &&ifFunc)
A conditional expression.
Definition: hybridutilities.hh:358
constexpr auto size(const T &t)
Size query.
Definition: hybridutilities.hh:74
constexpr auto integralRange(const End &end)
Create an integral range starting from 0.
Definition: hybridutilities.hh:192
constexpr auto minus
Function object for performing subtraction.
Definition: hybridutilities.hh:551
constexpr auto equals(T1 &&t1, T2 &&t2)
Equality comparison.
Definition: hybridutilities.hh:588
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:257
constexpr auto equal_to
Function object for performing equality comparison.
Definition: hybridutilities.hh:573
constexpr auto max
Function object that returns the greater of the given values.
Definition: hybridutilities.hh:485
constexpr auto plus
Function object for performing addition.
Definition: hybridutilities.hh:529
constexpr auto min
Function object that returns the smaller of the given values.
Definition: hybridutilities.hh:507
constexpr decltype(auto) elementAt(Container &&c, Index &&i)
Get element at given position from container.
Definition: hybridutilities.hh:127
constexpr T accumulate(Range &&range, T value, F &&f)
Accumulate values.
Definition: hybridutilities.hh:280
constexpr void switchCases(IntegralRange< T > range, const Value &value, Branches &&branches)
Switch statement.
Definition: hybridutilities.hh:724
static constexpr IntegralRange< std::decay_t< T > > range(T &&from, U &&to) noexcept
free standing function for setting up a range based for loop over an integer range for (auto i: range...
Definition: rangeutilities.hh:294
Dune namespace.
Definition: alignedallocator.hh:13
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
Utilities for reduction like operations on ranges.
Check if T is an std::integral_constant<I, i>
Definition: typetraits.hh:384
Helper class for tagging priorities.
Definition: typeutilities.hh:73
Utilities for type computations, constraining overloads, ...