I am creating a utility to create a view in an object similar to a tuple. The goal is to include code like this:
auto t = std::make_tuple(42, 'c', 3.14);
auto tv = make_tuple_view<2, 1, 0, 1>(t);
++std::get<0>(tv);
Thus, the types of tuple elements are the corresponding types of links to the corresponding elements of the original tuple. I am currently listing reference types:
#include <tuple>
#include <utility>
namespace detail {
template<std::size_t FromIndex, std::size_t... Is, typename Tuple>
constexpr auto make_tuple_range_impl(std::index_sequence<Is...>,
Tuple&& t) noexcept
{
return std::forward_as_tuple(
std::get<FromIndex + Is>(std::forward<Tuple>(t))...);
}
}
template<std::size_t FromIndex, std::size_t ToIndex, typename Tuple>
constexpr auto make_tuple_range(Tuple&& t) noexcept
{
static_assert(FromIndex <= ToIndex,
"FromIndex must be less than or equal to ToIndex");
return detail::make_tuple_range_impl<FromIndex>(
std::make_index_sequence<ToIndex - FromIndex>(),
std::forward<Tuple>(t));
}
template<std::size_t... Is, typename Tuple>
constexpr auto make_tuple_view(Tuple&& t) noexcept
{
return std::forward_as_tuple(std::get<Is>(std::forward<Tuple>(t))...);
}
Tests :
double pi = 3.14;
std::tuple<int, double&, const char, float> t(42, pi, 'c', 0);
static_assert(std::is_same<
decltype(make_tuple_range<0, 3>(t)),
std::tuple<int&, double&, const char&>
>::value, "");
const auto& ct = t;
static_assert(std::is_same<
decltype(make_tuple_view<3, 0, 2, 1>(ct)),
std::tuple<const float&, const int&, const char&, double&>
>::value, "");
static_assert(std::is_same<
decltype(make_tuple_range<1, 4>(std::move(t))),
std::tuple<double&, const char&&, float&&>
>::value, "");
const auto&& crt = std::move(t);
static_assert(std::is_same<
decltype(make_tuple_range<1, 4>(std::move(crt))),
std::tuple<double&, const char&, const float&>
>::value, "");
However, I am not completely sure of my implementation. Is there any extreme case where invalid reference types can be inferred?
: , TIL ! , , make_tuple_view/range . , , . , make_tuple_view/range .