VCCC  2024.05
VisualCamp Common C++ library
tuple_for_each.hpp
Go to the documentation of this file.
1 //
2 // Created by YongGyu Lee on 4/9/24.
3 //
4 
5 #ifndef VCCC_TUPLE_TUPLE_FOR_EACH_HPP_
6 #define VCCC_TUPLE_TUPLE_FOR_EACH_HPP_
7 
8 #include <cstddef>
9 #include <tuple>
10 #include <utility>
11 #include <type_traits>
12 
19 
20 namespace vccc {
21 namespace detail {
22 
23 template<typename Tuple>
24 using tuple_index_sequence = std::make_index_sequence<std::tuple_size<remove_cvref_t<Tuple>>::value>;
25 
26 template<typename Tuple, typename F, typename Seq>
27 struct tuple_for_each_invocable_impl;
28 
29 template<typename Tuple, typename F, std::size_t... I>
30 struct tuple_for_each_invocable_impl<Tuple, F, std::index_sequence<I...>>
31  : conjunction<
32  is_invocable<F, decltype(std::get<I>(std::declval<Tuple>()))>...
33  > {};
34 
35 template<typename Tuple, typename F>
36 struct tuple_for_each_invocable
37  : tuple_for_each_invocable_impl<Tuple, F, tuple_index_sequence<Tuple>> {};
38 
39 template<typename Tuple, typename F, std::size_t... I>
40 constexpr void tuple_for_each_impl(std::index_sequence<I...>, Tuple&& t, F&& f) {
41  int dummy[] = {
42  (vccc::invoke(f, std::get<I>(std::forward<Tuple>(t))), 0)...
43  };
44  (void)dummy;
45 }
46 
47 template<typename Tuple, typename F, typename Seq>
48 struct tuple_for_each_in_place_index_invocable_impl;
49 
50 template<typename Tuple, typename F, std::size_t... I>
51 struct tuple_for_each_in_place_index_invocable_impl<Tuple, F, std::index_sequence<I...>>
52  : conjunction<
53  is_invocable<F, decltype(std::get<I>(std::declval<Tuple>())), std::integral_constant<std::size_t, I>>...
54  > {};
55 
56 template<typename Tuple, typename F>
57 struct tuple_for_each_in_place_index_invocable
58  : tuple_for_each_in_place_index_invocable_impl<Tuple, F, tuple_index_sequence<Tuple>> {};
59 
60 template<typename Tuple, typename F, std::size_t... I>
61 constexpr void tuple_for_each_index_impl(std::index_sequence<I...>, Tuple&& t, F&& f) {
62  int dummy[] = {
63  (vccc::invoke(f, std::get<I>(std::forward<Tuple>(t)), std::integral_constant<std::size_t, I>{}), 0)...
64  };
65  (void)dummy;
66 }
67 
68 } // namespace detail
69 
72 
73 // Invokes f(std::get<i>(t)) for each i in [0, std::tuple_size<Tuple>)
74 template<typename Tuple, typename F>
76 tuple_for_each(Tuple&& t, F&& f) {
77  return vccc::detail::tuple_for_each_impl(
78  detail::tuple_index_sequence<Tuple>{},
79  std::forward<Tuple>(t),
80  std::forward<F>(f)
81  );
82 }
83 
84 // Invokes f(std::get<i>(t), std::integral_constant<std::size_t, i>{}) for each i in [0, std::tuple_size<Tuple>)
85 template<typename Tuple, typename F>
87 tuple_for_each_index(Tuple&& t, F&& f) {
88  return vccc::detail::tuple_for_each_index_impl(
89  detail::tuple_index_sequence<Tuple>{},
90  std::forward<Tuple>(t),
91  std::forward<F>(f)
92  );
93 }
94 
96 
97 } // namespace vccc
98 
99 #endif // VCCC_TUPLE_TUPLE_FOR_EACH_HPP_
constexpr invoke_result_t< F, Args... > invoke(F &&f, Args &&... args) noexcept(is_nothrow_invocable< F, Args... >::value)
Definition: invoke.hpp:38
constexpr std::enable_if_t< detail::tuple_for_each_in_place_index_invocable< Tuple, F >::value > tuple_for_each_index(Tuple &&t, F &&f)
Definition: tuple_for_each.hpp:87
constexpr std::enable_if_t< detail::tuple_for_each_invocable< Tuple, F >::value > tuple_for_each(Tuple &&t, F &&f)
Definition: tuple_for_each.hpp:76
Definition: matrix.hpp:495
Definition: directory.h:12
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 1 > value
Definition: key_value.hpp:35