Skip to content

Instantly share code, notes, and snippets.

@DrPizza
Created August 3, 2015 03:50
Show Gist options
  • Save DrPizza/bf8cbdf63e7a9702e90a to your computer and use it in GitHub Desktop.
Save DrPizza/bf8cbdf63e7a9702e90a to your computer and use it in GitHub Desktop.
#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