This code works correctly on clang and g++ (using C++11):
http://coliru.stacked-crooked.com/a/c8071ab447e10a31
Produces a std::tuple
with Max_N
elements of the same type, and fills it up with the first values of the given list. If less elements in list than Max_N
, fills the last elements with sentinel values.
In practice, using std::array<C, N>
may be more useful for something like this, if there is a need to pass from a list with a dynamic number of elements to one from a constant number of elements.
#include <tuple>
#include <type_traits>
#include <list>
#include <iostream>
#include <typeinfo>
template<std::size_t Max_N, typename List>
class list_to_tuple {
public:
using value_type = typename List::value_type;
using iterator_type = typename List::const_iterator;
using tuple_type = decltype(std::tuple_cat(
std::tuple<typename List::value_type>(),
typename list_to_tuple<Max_N-1, List>::tuple_type()
));
tuple_type operator()(const List& lst, const value_type& sentinel) {
return convert(lst.begin(), lst.end(), sentinel);
}
tuple_type convert(iterator_type begin, iterator_type end, const value_type& sentinel) const {
list_to_tuple<Max_N-1, List> remaining;
if(begin != end) {
auto current = std::make_tuple(*begin);
++begin;
return std::tuple_cat(current, remaining.convert(begin, end, sentinel));
} else {
return std::tuple_cat(std::make_tuple(sentinel), remaining.convert(begin, end, sentinel));
}
}
};
template<typename List>
class list_to_tuple<0, List> {
public:
using value_type = typename List::value_type;
using iterator_type = typename List::const_iterator;
using tuple_type = std::tuple<>;
tuple_type convert(iterator_type begin, iterator_type end, const value_type& sentinel) const {
return std::tuple<>();
}
};
int main() {
std::list<int> lst = {1, 2, 3};
list_to_tuple<5, std::list<int>> to_tup;
auto tup = to_tup(lst, 0);
std::cout << std::get<0>(tup) << std::endl;
std::cout << std::get<1>(tup) << std::endl;
std::cout << std::get<2>(tup) << std::endl;
std::cout << std::get<3>(tup) << std::endl;
std::cout << std::get<4>(tup) << std::endl;
std::cout << typeid(tup).name() << std::endl;
}
11
solved Turning a BOUNDED std::list