Boost.Fusion - , , , ++ 11 std::tuple :
template <unsigned ... indices>
struct sequence
{
typedef sequence type;
};
template <unsigned size, unsigned ... indices>
struct static_range : static_range<size-1,size-1,indices...> {};
template <unsigned ... indices>
struct static_range<0, indices...> : sequence<indices...> {};
template <class Function, class Tuple, unsigned ... indices>
auto transform_impl(const Tuple & t, Function f, sequence<indices...>) ->
std::tuple<decltype(f(std::get<indices>(t)))...>
{
return std::make_tuple(f(std::get<indices>(t))...);
}
template <class Function, class Tuple>
auto transform_tuple(const Tuple & t, Function f) ->
decltype(transform_impl(t, f, static_range<std::tuple_size<Tuple>::value>()))
{
return transform_impl(t, f, static_range<std::tuple_size<Tuple>::value>());
}
sequence/static_range ( std::tuple s) , std::get .
In addition, I believe that the code is quite simple, but it should be noted that with this method the order in which ftuple is called in each element is undefined.
Usage will look like this:
std::tuple<char, short, int, long long> t;
struct addone
{ template <class T> auto operator()(T t) -> decltype(t+1) {return t + 1;}};
auto t2 = transform_tuple(t, addone());
The resulting tuple will not have the same types as the input tuple due to the holistic progression, each of which will have a type typename std::common_type<T,int>::type.