Skip to content

Instantly share code, notes, and snippets.

@Garciat
Last active October 3, 2016 09:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Garciat/cf1d50f2564e5efe7931c343e0e6aa49 to your computer and use it in GitHub Desktop.
Save Garciat/cf1d50f2564e5efe7931c343e0e6aa49 to your computer and use it in GitHub Desktop.
#include <utility>
#include <type_traits>
template<typename T>
struct identity { using type = T; };
template<std::size_t I, typename... Ts>
struct nth_type;
template<typename T, typename... Ts>
struct nth_type<0, T, Ts...> : identity<T> {};
template<std::size_t I, typename T, typename... Ts>
struct nth_type<I, T, Ts...> : nth_type<I - 1, Ts...> {};
template<std::size_t I, typename... Ts>
using nth_type_t = typename nth_type<I, Ts...>::type;
template<std::size_t I, typename T>
struct tuple_field {
T value;
};
template<typename I, typename... Ts>
struct tuple_storage;
template<std::size_t... Is, typename... Ts>
struct tuple_storage<std::index_sequence<Is...>, Ts...>
: tuple_field<Is, Ts>... {
template<std::size_t... Js, typename... Us>
tuple_storage(std::index_sequence<Js...>, Us&&... vals)
: tuple_field<Js, nth_type_t<Js, Ts...>>{std::forward<Us>(vals)}...
{}
};
template<typename... Ts>
struct tuple : tuple_storage<std::make_index_sequence<sizeof...(Ts)>, Ts...> {
using super_t = tuple_storage<std::make_index_sequence<sizeof...(Ts)>, Ts...>;
template<typename... Us>
tuple(Us&&... vals)
: super_t(std::make_index_sequence<sizeof...(Us)>(), std::forward<Us>(vals)...)
{}
};
template<std::size_t I, typename T>
decltype(auto) get_helper_ix(tuple_field<I, T> &fld) {
return fld.value;
}
template<typename T, std::size_t I>
decltype(auto) get_helper_ty(tuple_field<I, T> &fld) {
return fld.value;
}
template<std::size_t I, typename... Ts>
decltype(auto) get(tuple<Ts...> &tup) {
return get_helper_ix<I>(tup);
}
template<std::size_t I, typename... Ts>
decltype(auto) get(tuple<Ts...> &&tup) {
return get_helper_ix<I>(tup);
}
template<typename T, typename... Ts>
decltype(auto) get(tuple<Ts...> &tup) {
return get_helper_ty<T>(tup);
}
template<typename T, typename... Ts>
decltype(auto) get(tuple<Ts...> &&tup) {
return get_helper_ty<T>(tup);
}
template<typename... Ts>
auto make_tuple(Ts&&... vals) {
return tuple<Ts...>{std::forward<Ts>(vals)...};
}
auto what() {
return make_tuple(1LL, 2LL);
}
auto hello() {
return get<1>(what());
}
auto poop() {
return get<int>(make_tuple(1, 2LL));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment