3 #ifndef DUNE_COMMON_HYBRIDUTILITIES_HH
4 #define DUNE_COMMON_HYBRIDUTILITIES_HH
25 template<
class T,
int i>
27 -> decltype(std::integral_constant<std::size_t,i>())
35 -> decltype(std::integral_constant<std::size_t,std::tuple_size<T>::value>())
43 -> decltype(std::integral_constant<std::size_t,
T::size()>())
81 constexpr
auto size(
const T& t)
90 template<
class Container,
class Index,
91 std::enable_if_t<IsTuple<std::decay_t<Container>>::value,
int> = 0>
94 return std::get<std::decay_t<Index>::value>(c);
97 template<
class T, T... t,
class Index>
98 constexpr decltype(
auto)
elementAt(std::integer_sequence<T, t...> c, Index, PriorityTag<1>)
103 template<
class Container,
class Index>
104 constexpr decltype(
auto)
elementAt(Container&& c, Index&& i, PriorityTag<0>)
133 template<
class Container,
class Index>
134 constexpr decltype(
auto)
elementAt(Container&& c, Index&& i)
143 template<
class Begin,
class End,
147 static_assert(Begin::value <= End::value,
"You cannot create an integralRange where end<begin");
155 template<
class Begin,
class End>
156 constexpr
auto integralRange(
const Begin& begin,
const End& end,
const PriorityTag<0>&)
182 template<
class Begin,
class End>
212 void evaluateFoldExpression(std::initializer_list<T>&&)
215 template<
class Range,
class F,
class Index, Index... i>
216 constexpr
void forEachIndex(Range&&
range, F&& f, std::integer_sequence<Index, i...>)
221 template<
class F,
class Index, Index... i>
222 constexpr
void forEach(std::integer_sequence<Index, i...> , F&& f, PriorityTag<2>)
224 evaluateFoldExpression<int>({(f(std::integral_constant<Index,i>()), 0)...});
228 template<
class Range,
class F,
229 std::enable_if_t<IsIntegralConstant<decltype(Hybrid::size(std::declval<Range>()))>::value,
int> = 0>
230 constexpr
void forEach(Range&&
range, F&& f, PriorityTag<1>)
233 auto indices = std::make_index_sequence<size>();
234 (forEachIndex)(std::forward<Range>(
range), std::forward<F>(f), indices);
237 template<
class Range,
class F>
238 constexpr
void forEach(Range&&
range, F&& f, PriorityTag<0>)
240 for(
auto&& e :
range)
266 template<
class Range,
class F>
289 template<
class Range,
class T,
class F>
293 value = f(value, entry);
304 constexpr T operator()(T&& x)
const {
305 return std::forward<T>(x);
309 template<
class IfFunc,
class ElseFunc>
310 constexpr decltype(
auto)
ifElse(std::true_type, IfFunc&& ifFunc, ElseFunc&& )
315 template<
class IfFunc,
class ElseFunc>
316 constexpr decltype(
auto)
ifElse(std::false_type, IfFunc&& , ElseFunc&& elseFunc)
318 return elseFunc(Id{});
321 template<
class IfFunc,
class ElseFunc>
322 decltype(
auto)
ifElse(const
bool& condition, IfFunc&& ifFunc, ElseFunc&& elseFunc)
327 return elseFunc(Id{});
354 template<
class Condition,
class IfFunc,
class ElseFunc>
355 decltype(
auto)
ifElse(const Condition& condition, IfFunc&& ifFunc, ElseFunc&& elseFunc)
357 return Impl::ifElse(condition, std::forward<IfFunc>(ifFunc), std::forward<ElseFunc>(elseFunc));
367 template<
class Condition,
class IfFunc>
368 void ifElse(
const Condition& condition, IfFunc&& ifFunc)
377 template<
class T1,
class T2>
378 constexpr
auto equals(
const T1& ,
const T2& ,
PriorityTag<1>) -> decltype(T1::value, T2::value, std::integral_constant<bool,T1::value == T2::value>())
381 template<
class T1,
class T2>
382 constexpr
auto equals(
const T1& t1,
const T2& t2, PriorityTag<0>)
400 template<
class T1,
class T2>
410 template<
class Result,
class T,
class Value,
class Branches,
class ElseBranch>
411 constexpr Result
switchCases(std::integer_sequence<T>,
const Value& , Branches&& , ElseBranch&& elseBranch)
416 template<
class Result,
class T, T t0, T... tt,
class Value,
class Branches,
class ElseBranch>
417 constexpr Result
switchCases(std::integer_sequence<T, t0, tt...>,
const Value& value, Branches&& branches, ElseBranch&& elseBranch)
421 [&](
auto id) -> decltype(
auto) {
422 return id(branches)(std::integral_constant<T, t0>());
423 }, [&](
auto id) -> decltype(
auto) {
424 return Impl::switchCases<Result>(
id(std::integer_sequence<T, tt...>()), value, branches, elseBranch);
459 template<
class Cases,
class Value,
class Branches,
class ElseBranch>
460 constexpr decltype(
auto)
switchCases(const Cases& cases, const Value& value, Branches&& branches, ElseBranch&& elseBranch)
462 return Impl::switchCases<decltype(elseBranch())>(cases, value, std::forward<Branches>(branches), std::forward<ElseBranch>(elseBranch));
485 template<
class Cases,
class Value,
class Branches>
486 constexpr
void switchCases(
const Cases& cases,
const Value& value, Branches&& branches)
488 return Impl::switchCases<void>(cases, value, std::forward<Branches>(branches), []() {});
496 #endif // #ifndef DUNE_COMMON_HYBRIDUTILITIES_HH