Skip to content

Instantly share code, notes, and snippets.

@elbeno
Created May 16, 2015 23:22
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save elbeno/969b0f1765ae23554bbe to your computer and use it in GitHub Desktop.
Save elbeno/969b0f1765ae23554bbe to your computer and use it in GitHub Desktop.
Runtime visitation of a tuple in C++
#include <algorithm>
#include <cassert>
#include <tuple>
#include <utility>
namespace detail
{
template <size_t N>
struct visit_impl
{
template <typename T, typename F>
static void visit(T&& t, size_t n, F&& f)
{
if (N-1 == n)
std::forward<F>(f)(std::get<N-1>(std::forward<T>(t)));
else
visit_impl<N-1>::visit(std::forward<T>(t),
n,
std::forward<F>(f));
}
};
template <>
struct visit_impl<0>
{
template <typename T, typename F>
static void visit(T, size_t, F)
{
assert("Tuple index out of range" && false);
}
};
}
template <typename F, typename... Ts>
void visit_at(const std::tuple<Ts...>& t, size_t idx, F&& f)
{
using T = std::tuple<Ts...>;
detail::visit_impl<sizeof...(Ts)>::visit(t,
idx,
std::forward<F>(f));
}
template <typename F, typename... Ts>
void visit_at(std::tuple<Ts...>& t, size_t idx, F&& f)
{
using T = std::tuple<Ts...>;
detail::visit_impl<sizeof...(Ts)>::visit(t,
idx,
std::forward<F>(f));
}
template <typename F, typename... Ts>
void visit_at(std::tuple<Ts...>&& t, size_t idx, F&& f)
{
using T = std::tuple<Ts...>;
detail::visit_impl<sizeof...(Ts)>::visit(std::move(t),
idx,
std::forward<F>(f));
}
/*
#include <iostream>
int main()
{
auto t = std::make_tuple(42, "Wibble", 3.14f);
auto f = [] (const auto& x) { std::cout << x << std::endl; };
visit_at(t, 0, f); // 42
visit_at(t, 1, f); // Wibble
visit_at(t, 2, f); // 3.14
visit_at(t, 3, f); // assert
return 0;
}
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment