1 #pragma once
2
3 #include <petsc/private/cpp/type_traits.hpp>
4 #include <petsc/private/cpp/utility.hpp>
5
6 #include <tuple>
7
8 namespace Petsc
9 {
10
11 namespace util
12 {
13
14 #if PETSC_CPP_VERSION >= 14
15 using std::tuple_element_t;
16 #else
17 template <std::size_t I, class T>
18 using tuple_element_t = typename std::tuple_element<I, T>::type;
19 #endif
20
21 // tuple_for_each
22 namespace detail
23 {
24
25 template <std::size_t... Idx, typename T, typename F>
tuple_for_each(index_sequence<Idx...>,T && tuple,F && f)26 constexpr inline F &&tuple_for_each(index_sequence<Idx...>, T &&tuple, F &&f)
27 {
28 using expander = int[sizeof...(Idx)];
29 return (void)expander{((void)f(std::get<Idx>(std::forward<T>(tuple))), 0)...}, std::forward<F>(f);
30 }
31
32 template <typename T, typename F>
tuple_for_each(index_sequence<>,T &&,F && f)33 constexpr inline F &&tuple_for_each(index_sequence<>, T &&, F &&f) noexcept
34 {
35 return std::forward<F>(f);
36 }
37
38 } // namespace detail
39
40 template <typename T, typename F>
tuple_for_each(T && tuple,F && f)41 constexpr inline F &&tuple_for_each(T &&tuple, F &&f)
42 {
43 using seq = make_index_sequence<std::tuple_size<remove_reference_t<T>>::value>;
44 return detail::tuple_for_each(seq{}, std::forward<T>(tuple), std::forward<F>(f));
45 }
46
47 } // namespace util
48
49 } // namespace Petsc
50