| #include <iostream> | |
| #include <list> | |
| #include <tuple> | |
| #include <memory> | |
| #include <type_traits> | |
| template<typename Function, typename Tuple, std::size_t... Indices, typename = std::enable_if_t<std::is_void<std::result_of_t<Function(std::tuple_element_t<0, std::decay_t<Tuple>>)>>::value>> | |
| constexpr void tuple_for_each_aux(Function&& f, Tuple&& t, std::index_sequence<Indices...>) | |
| { | |
| using swallow = int[]; | |
| // 10) In list-initialization, every value computation and side effect of a given initializer clause is sequenced before every value computation and side effect associated with any initializer clause that follows it in the brace-enclosed comma-separated list of initalizers. | |
| static_cast<void>(swallow{ 0, (std::forward<Function>(f)(std::get<Indices>(std::forward<Tuple>(t))), void(), 0)... }); | |
| } | |
| template<typename Function, typename Tuple, std::size_t... Indices, typename = std::enable_if_t<!std::is_void<std::result_of_t<Function(std::tuple_element_t<0, std::decay_t<Tuple>>)>>::value>> | |
| constexpr decltype(auto) tuple_for_each_aux(Function&& f, Tuple&& t, std::index_sequence<Indices...>) | |
| { | |
| // 10) In list-initialization, every value computation and side effect of a given initializer clause is sequenced before every value computation and side effect associated with any initializer clause that follows it in the brace-enclosed comma-separated list of initalizers. | |
| return decltype(std::make_tuple(std::forward<Function>(f)(std::get<Indices>(std::forward<Tuple>(t)))...)){std::forward<Function>(f)(std::get<Indices>(std::forward<Tuple>(t))) ...}; | |
| } | |
| template<typename Tuple, typename Function> | |
| constexpr decltype(auto) tuple_for_each(Function&& f, Tuple&& t) | |
| { | |
| return tuple_for_each_aux(std::forward<Function>(f), std::forward<Tuple>(t), std::make_index_sequence<std::tuple_size<std::decay_t<Tuple>>::value>{}); | |
| } | |
| int main() | |
| { | |
| auto t1 = std::make_tuple(1, 2.0, 'a'); | |
| tuple_for_each([](const auto& u) { std::cout << u << " "; }, t1); // prints 1 2 a | |
| std::cout << std::endl; | |
| auto x = tuple_for_each([](const auto& u) { std::cout << u << " "; return 0; }, t1); // prints a 2 1, should be 1 2 a | |
| std::cout << std::endl; | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment