xref: /petsc/include/petsc/private/cpp/tuple.hpp (revision 9dd11ecf0918283bb567d8b33a92f53ac4ea7840)
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