Skip to content

Instantly share code, notes, and snippets.

@cleoold
Created October 17, 2020 19:32
Show Gist options
  • Save cleoold/a3da3aa06c5bb3843cfb7e7301fc23c5 to your computer and use it in GitHub Desktop.
Save cleoold/a3da3aa06c5bb3843cfb7e7301fc23c5 to your computer and use it in GitHub Desktop.
std::tuple map and foldl
// c++17
#pragma once
#include <tuple>
#include <utility>
namespace detail {
template<class T, class F, size_t ...N>
auto constexpr tuple_map_impl(const T &t, F &&f, std::index_sequence<N...>) {
return std::make_tuple(std::forward<F>(f)(std::get<N>(t))...);
}
template<size_t cnt, class T, class T1, class F>
auto constexpr tuple_reduce_impl(const T &t, F &&f, T1 &&acc) {
if constexpr (cnt == std::tuple_size_v<T>)
return acc;
else
return tuple_reduce_impl<cnt+1>(t, std::forward<F>(f),
std::forward<F>(f)(std::forward<T1>(acc), std::get<cnt>(t)));
}
}
template<class T, class F>
auto constexpr tuple_map(const T &t, F &&f) {
auto constexpr sz = std::tuple_size_v<T>;
return detail::tuple_map_impl(t, std::forward<F>(f), std::make_index_sequence<sz>{});
}
template<class T, class F>
auto constexpr tuple_reduce(const T &t, F &&f) {
return detail::tuple_reduce_impl<1>(t, std::forward<F>(f), std::get<0>(t));
}
template<class T, class F, class InitT>
auto constexpr tuple_reduce(const T &t, F &&f, InitT &&init) {
return detail::tuple_reduce_impl<0>(t, std::forward<F>(f), std::forward<InitT>(init));
}
//auto v = std::make_tuple(1,2,3,4.4,4.4);
//auto vm = tuple_map(v, [](auto x) {return x+1;});
//std::cout << std::get<0>(vm) << std::endl; // 2
//std::cout << tuple_reduce(v, [](auto x, auto y){return x+y;}) << std::endl; // 14.8
// std::cout << tuple_reduce(v, [](auto x, auto y){return x+y;}, 0) << std::endl; // 14.8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment