Is there a way to write
template <int> struct Map;
template <> struct Map<0> { using type = index_sequence<0>; };
template <> struct Map<1> { using type = index_sequence<1>; };
template <> struct Map<2> { using type = index_sequence<2>; };
template <> struct Map<3> { using type = index_sequence<0,1>; };
template <> struct Map<4> { using type = index_sequence<0,2>; };
template <> struct Map<5> { using type = index_sequence<1,2>; };
template <> struct Map<6> { using type = index_sequence<0,1,2>; };
as one single unspecialized template?
template <int N> struct Map {
using type = index_sequence<???>;
};
Here the int template arguments shall always be listed in increasing order and can only have values 0, 1,..., MAX. The case for MAX == 2 is the example above. How to write the above for any value of MAX?
In case you are wondering, this example usage is a motivation for the solution:
#include <iostream>
#include <array>
#include <list>
class Base {
public: virtual ~Base() = default;
};
template <int...> // The ints shall always be listed in increasing order and have values 0, 1, or 2.
class Derived : public Base {};
std::array<std::list<Base*>, 7> groups;
template <int...> struct index_sequence {};
template <int> struct Map;
template <> struct Map<0> { using type = index_sequence<0>; };
template <> struct Map<1> { using type = index_sequence<1>; };
template <> struct Map<2> { using type = index_sequence<2>; };
template <> struct Map<3> { using type = index_sequence<0,1>; };
template <> struct Map<4> { using type = index_sequence<0,2>; };
template <> struct Map<5> { using type = index_sequence<1,2>; };
template <> struct Map<6> { using type = index_sequence<0,1,2>; };
template <int... Is>
bool isDerivedType (const index_sequence<Is...>&, Base* base) {
return dynamic_cast<Derived<Is...>*>(base) != nullptr;
}
template <int N>
void checkTypes (Base* base, std::array<std::list<Base*>, 7>& array) {
if (isDerivedType(typename Map<N>::type{}, base))
groups[N].push_back(base);
else
checkTypes<N+1>(base, array);
}
template <>
void checkTypes<7> (Base*, std::array<std::list<Base*>, 7>&) {} // End of recursion
int main() {
const std::list<Base*> list = {new Derived<0>, new Derived<1,2>, new Derived<0,2>, new Derived<1>, new Derived<1,2>, new Derived<0>, new Derived<0,1,2>, new Derived<0,1>, new Derived<1,2>, new Derived<2>, new Derived<2>, new Derived<0>, new Derived<0,2>};
for (Base* x : list)
checkTypes<0>(x, groups);
for (int i = 0; i < 7; i++) {
std::cout << "Group " << i << ": ";
for (const Base* x : groups[i])
std::cout << x << " ";
std::cout << '\n';
}
}
/*
Output:
Group 0: 0x6e13f0 0x6e1940 0x6e5d80
Group 1: 0x6e1900
Group 2: 0x6e5dd0 0x6e5d60
Group 3: 0x6e5e40
Group 4: 0x6e18e0 0x6e5d70
Group 5: 0x6e1440 0x6e1920 0x6e5db0
Group 6: 0x6e1960
*/
Aucun commentaire:
Enregistrer un commentaire