I have a tuple of structs that are defined using variadic arguments:
#include <tuple>
#include <vector>
template<class Type>
struct Pool {
std::vector<Type> components;
};
template<class... Types>
class Storage {
public:
std::tuple<Pool<Types>...> pools;
template<class SelectedType0, class... SelectedTypes>
std::tuple<std::vector<SelectedTypes>&...> getVectorsFromTuple();
template<class... SelectedTypes>
void iterate();
};
I want a way to select subset of types from the tuple and create a new tuple that is based on contents of it. Essentially, this is what I am trying to achieve:
template<class... Types>
template<class... SelectedTypes>
void Storage<Types...>::iterate() {
std::tuple<std::vector<SelectedTypes>&...> vectors = getVectorsFromTuple<SelectedTypes...>(pools);
// getVectorsFromTuple should get the values in the tuple based on types
// and save reference to each tuple item's structure's `components`
// property in another tuple
}
One idea that I got for it was to "define" first template parameter in another function and then use that function to recursively define other parameters:
template <class... Types>
template<class SelectedType0, class... SelectedTypes>
inline std::tuple<std::vector<SelectedType0>&, std::vector<SelectedTypes>&...> EntityStorageSparseSet<ComponentTypes...>::getVectorsFromPools() {
return std::make_tuple(std::get<PickComponent0>(pools).components, getVectorsFromPools<PickComponents...>());
}
But I don't know how to unroll/flatten the recursed tuples so this function returns something like:
std::tuple<SelectedType0, SelectedType1, ...>
instead of
std::tuple<SelectedType0, std::tuple<SelectedType1, std::tuple<SelectedType2, ...>>>
How can I unroll the tuples or is there a better way to implement what I am trying to achieve?
Following seems to do the job (assuming uniqueness of type in Types
):
template <typename... Types>
template <typename... SelectedTypes>
std::tuple<std::vector<SelectedTypes>&...>
EntityStorageSparseSet<Types...>::getVectorsFromPools()
{
return { std::get<SelectedTypes>(pools).components... };
}