Original question:
Goal: Write a function enumToSTLContainer()
that is to return any STL container whose elements are from a specified enum
list.
The current solution below uses the assumption that the enum
underlying values start at zero and are consecutive, and hence needs improvement. The solution is in C++11 rather than C++14 so that everyone here should be able to compile it.
#include <iostream>
#include <vector>
#include <set>
enum MyEnum {A, B, C, D, E, NumElements};
template <std::size_t...> struct index_sequence {};
template <std::size_t N, std::size_t... Is>
struct make_index_sequence_helper : make_index_sequence_helper<N-1, N-1, Is...> {};
template <std::size_t... Is>
struct make_index_sequence_helper<0, Is...> {
using type = index_sequence<Is...>;
};
template <std::size_t N>
using make_index_sequence = typename make_index_sequence_helper<N>::type;
template <typename RETURN_TYPE, std::size_t... TYPES>
inline RETURN_TYPE helper (index_sequence<TYPES...>) {
return {static_cast<typename RETURN_TYPE::value_type>(TYPES)...};
}
template <typename CONTAINER, std::size_t N>
CONTAINER enumToSTLContainer() {
return helper<CONTAINER> (make_index_sequence<N>());
}
int main() {
const std::vector<MyEnum> enumVector = enumToSTLContainer<std::vector<MyEnum>, NumElements>();
for (MyEnum x : enumVector)
std::cout << x << ' '; // 0 1 2 3 4
const std::set<MyEnum> enumSet = enumToSTLContainer<std::set<MyEnum>, NumElements>();
std::cout << "\n\n";
for (MyEnum x : enumSet)
std::cout << x << ' '; // 0 1 2 3 4
}
I would appreciate if someone could show me how to improve this solution where the enum
underlying values are not consecutive. Ideally NumElements
should not be needed either. I presume only make_index_sequence_helper
needs to be modified according the MyEnum
underlying values?
The only generalization that I could come up with is the lousy:
template <typename CONTAINER, std::size_t... Is>
CONTAINER enumNonContiguousToSTLContainer() {
return helper<CONTAINER> (index_sequence<Is...>());
}