a cast template

write a function:
cast a container(such as a vector) to a tuple
or
Args&&... to a vector.

or a tuple to a vector

tuple size should be same with the vector.

1
2
3
4
5
6
7
8
9
template<Args&&... args, class T>
std::tuple<Args&&...> ContainerCast1(const std::vector<T>&);

template<Args&&... args, class T>
const std::vector<T>  ContainerCast2(const std::tuple<Args&&...> &);


template<Args&&... args, class T>
const std::vector<T>  ContainerCast2(Args&&...);


it is possible to implement them with integer sequence.
Here's a very rough start:

From tuple to std::vector:
1
2
3
4
5
6
template <typename Tuple, typename ValueT = std::tuple_element_t<0, Tuple>>
auto vector_from(Tuple&& t) {
  return std::apply([](auto&&... args) {
      return std::vector<ValueT>{std::forward<decltype(args)>(args)...};
    }, std::forward<Tuple>(t));
}


Without C++17:
1
2
3
4
5
6
7
8
9
10
template <typename Tuple, typename ValueT, std::size_t... Is>
auto vector_from_impl(Tuple&& t, std::index_sequence<Is...>) {
  return std::vector<ValueT>{ std::get<Is>(t)... };
}

template <typename Tuple, typename ValueT = std::tuple_element_t<0, Tuple>,
          typename Indices = std::make_index_sequence<std::tuple_size_v<Tuple>>>
auto vector_from(Tuple&& t) {
  return vector_from_impl<Tuple, ValueT>(std::forward<Tuple>(t), Indices{});
}


How do you expect to go from a vector (whose size is not a constant expression) to a tuple?
Last edited on
Perhaps use std::common_type to determine the value_type of the vector.

std::make_from_tuple doesn't work for initialiser lists; it does not use a braced-init-list to construct the object.
http://en.cppreference.com/w/cpp/utility/make_from_tuple

For vector to tuple, I don't think there is any way other than by specifying the tuple size as a template argument.
(There was a proposal floating around for a constexpr vector, I don't know what has happened to it.)
Note: std::array to tuple is straightforward.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
namespace impl_detail
{
    template< typename T, typename TUP, std::size_t... I >
    auto to_vec( const TUP& tup, std::index_sequence<I...> )
    {
        // cast to T to avoid implicit narrowing conversions within braces
        return std::vector<T>{ T( std::get<I>(tup) )... };
    }

    template < typename RA_CNTR, std::size_t... I >
    auto to_tup( const RA_CNTR& cntr, std::index_sequence<I...> )
    { return std::make_tuple( cntr[I]... ) ; }
}

template < typename... T >
auto to_vector( const std::tuple<T...>& tup )
{
    using value_type = typename std::common_type<T...>::type ;
    using ISEQ = std::make_index_sequence< sizeof...(T) > ;
    return impl_detail::to_vec<value_type>( tup, ISEQ{} );
}

template <std::size_t N, typename T> auto to_tuple( const std::array<T,N>& arr )
{ return impl_detail::to_tup( arr, std::make_index_sequence<N>{} ) ; }

template< std::size_t N, typename T > auto to_tuple( const std::vector<T>& vec )
{
    if( vec.size() < N ) throw std::out_of_range( "vector size is too small" ) ;
    return impl_detail::to_tup( vec, std::make_index_sequence<N>{} ) ;
}

http://coliru.stacked-crooked.com/a/15ec4e53a0cce915
Topic archived. No new replies allowed.