mp11 icon indicating copy to clipboard operation
mp11 copied to clipboard

request: tuple_slice

Open HDembinski opened this issue 6 years ago • 6 comments

I am manipulating function arguments in boost.histogram, which I pass around as std::tuple. I found that I need a tuple_slice function, something which strips off some elements from a tuple of values from the front and/or back. I use this implementation:

template <class... Ns>
struct tuple_slice_impl {
  template <typename T>
  static decltype(auto) apply(const T& t) {
    return std::forward_as_tuple(std::get<Ns::value>(t)...);
  }
};

template <std::size_t Offset, std::size_t N, typename T>
decltype(auto) tuple_slide(const T& t) {
  using LN = mp11::mp_iota_c<N>;
  using OffsetAdder = mp11::mp_bind_front<mp11::mp_plus, mp11::mp_size_t<Offset>>;
  using LN2 = mp11::mp_transform_q<OffsetAdder, LN>;
  return mp11::mp_rename<LN2, tuple_slice_impl>::apply(t);
}

Basically, I generate an integer sequence of indices of the elements that should remain in the slice and then use a parameter pack expansion of std::gets.

Usage:

auto tup1 = std::make_tuple(1, "foo", 3.0);
auto tup2 = tuple_slice<0, 2>(tup1); // == std::make_tuple(1, "foo");
auto tup3 = tuple_slice<1, 2>(tup1); // == std::make_tuple("foo", 3.0);
// and so on

I think this is a useful addition to Mp11. The implementation is not trivial and it seems like a common tuple manipulation.

HDembinski avatar Jan 07 '19 19:01 HDembinski

A simpler implementation:

template <std::size_t Offset, class T, std::size_t... I>
decltype(auto) tuple_slice_impl(T&& t, index_sequence<I...>) {
    return std::forward_as_tuple(std::get<(I + Offset)>(std::forward<T>(t))...);
}

template <std::size_t I, std::size_t N, class T>
decltype(auto) tuple_slice(T&& t) {
    return tuple_slice_impl<I>(std::forward<T>(t), make_index_sequence<N>{});
}

decltype(auto) needs to be replaced with an explicitly computed type in C++11.

HDembinski avatar Jan 07 '19 20:01 HDembinski

Related SO questions with similar implementations https://stackoverflow.com/questions/8569567/get-part-of-stdtuple https://stackoverflow.com/questions/17854219/creating-a-sub-tuple-starting-from-a-stdtuplesome-types

HDembinski avatar Jan 07 '19 20:01 HDembinski

Is this supposed to return a "view" into the original tuple, instead of a copy?

pdimov avatar Jan 08 '19 04:01 pdimov

Yes, I think a view is appropriate.

HDembinski avatar Jan 08 '19 15:01 HDembinski

If we return to this one, while we're at it, a view makes sense, but in this case I'd prefer if the function has view in the name. How about tuple_subview after static_string::subview (as opposed to substr)?

pdimov avatar May 24 '20 14:05 pdimov

Agreed, I was thinking along the same lines recently.

HDembinski avatar May 25 '20 15:05 HDembinski