template <typename...> struct enum_list;
template <typename Enum, typename... Enums>
struct enum_list<Enum, Enums...> : enum_list<Enums...>
{
using base_t = enum_list<Enums...>;
static constexpr int base() { return 100 * sizeof...(Enums); }
static constexpr int unified(Enum value) { return int(value) + base(); }
static constexpr Enum separated(int value, Enum dummy) { return static_cast<Enum>(value - base()); } // plus assertions?
using base_t::unified;
using base_t::separated;
};
template <typename Enum>
struct enum_list<Enum>
{
static constexpr int base() { return 0; }
static constexpr int unified(Enum value) { return int(value); }
static constexpr Enum separated(int value, Enum dummy) { return static_cast<Enum>(value); }
};
///// example
enum Foo { A, B, C };
enum Bar { D, E, F };
typedef enum_list<Foo, Bar> unifier;
template <typename Unifier = unifier, typename E>
int unify(E value) {
return Unifier::unified(value);
}
template <typename E, typename Unifier = unifier>
E separate(int value) {
return Unifier::separated(value, E());
}
#include <iostream>
int
main()
{
std::cout << unify(B) << std::endl;
std::cout << unify(F) << std::endl;
std::cout << separate<Foo>(101) << std::endl;
std::cout << separate<Bar>(1) << std::endl;
}
dGVtcGxhdGUgPHR5cGVuYW1lLi4uPiBzdHJ1Y3QgZW51bV9saXN0Owp0ZW1wbGF0ZSA8dHlwZW5hbWUgRW51bSwgdHlwZW5hbWUuLi4gRW51bXM+CnN0cnVjdCBlbnVtX2xpc3Q8RW51bSwgRW51bXMuLi4+IDogZW51bV9saXN0PEVudW1zLi4uPgp7CiAgICB1c2luZyBiYXNlX3QgPSBlbnVtX2xpc3Q8RW51bXMuLi4+OyAKICAgIHN0YXRpYyBjb25zdGV4cHIgaW50ICBiYXNlKCkgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiAxMDAgKiBzaXplb2YuLi4oRW51bXMpOyB9CiAgICBzdGF0aWMgY29uc3RleHByIGludCAgdW5pZmllZChFbnVtIHZhbHVlKSAgICAgICAgICAgICAgeyByZXR1cm4gaW50KHZhbHVlKSArIGJhc2UoKTsgfQogICAgc3RhdGljIGNvbnN0ZXhwciBFbnVtIHNlcGFyYXRlZChpbnQgdmFsdWUsIEVudW0gZHVtbXkpIHsgcmV0dXJuIHN0YXRpY19jYXN0PEVudW0+KHZhbHVlIC0gYmFzZSgpKTsgfSAgLy8gcGx1cyBhc3NlcnRpb25zPwogICAgdXNpbmcgYmFzZV90Ojp1bmlmaWVkOwogICAgdXNpbmcgYmFzZV90OjpzZXBhcmF0ZWQ7Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgRW51bT4Kc3RydWN0IGVudW1fbGlzdDxFbnVtPgp7CiAgICBzdGF0aWMgY29uc3RleHByIGludCAgYmFzZSgpICAgICAgICAgICAgICAgICB7IHJldHVybiAwOyB9CiAgICBzdGF0aWMgY29uc3RleHByIGludCAgdW5pZmllZChFbnVtIHZhbHVlKSAgICAgICAgICAgICAgeyByZXR1cm4gaW50KHZhbHVlKTsgfQogICAgc3RhdGljIGNvbnN0ZXhwciBFbnVtIHNlcGFyYXRlZChpbnQgdmFsdWUsIEVudW0gZHVtbXkpIHsgcmV0dXJuIHN0YXRpY19jYXN0PEVudW0+KHZhbHVlKTsgfQp9OwoKLy8vLy8gZXhhbXBsZQplbnVtIEZvbyB7IEEsIEIsIEMgfTsKZW51bSBCYXIgeyBELCBFLCBGIH07Cgp0eXBlZGVmIGVudW1fbGlzdDxGb28sIEJhcj4gdW5pZmllcjsKCnRlbXBsYXRlIDx0eXBlbmFtZSBVbmlmaWVyID0gdW5pZmllciwgdHlwZW5hbWUgRT4KaW50IHVuaWZ5KEUgdmFsdWUpIHsKICAgIHJldHVybiBVbmlmaWVyOjp1bmlmaWVkKHZhbHVlKTsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIEUsIHR5cGVuYW1lIFVuaWZpZXIgPSB1bmlmaWVyPgpFIHNlcGFyYXRlKGludCB2YWx1ZSkgewogICAgcmV0dXJuIFVuaWZpZXI6OnNlcGFyYXRlZCh2YWx1ZSwgRSgpKTsKfQoKI2luY2x1ZGUgPGlvc3RyZWFtPgppbnQKbWFpbigpCnsKICAgIHN0ZDo6Y291dCA8PCB1bmlmeShCKSAgICAgICAgICAgICAgICAgICAgICA8PCBzdGQ6OmVuZGw7CiAgICBzdGQ6OmNvdXQgPDwgdW5pZnkoRikgICAgICAgICAgICAgICAgICAgICAgPDwgc3RkOjplbmRsOwogICAgc3RkOjpjb3V0IDw8IHNlcGFyYXRlPEZvbz4oMTAxKSAgICAgICAgICAgIDw8IHN0ZDo6ZW5kbDsKICAgIHN0ZDo6Y291dCA8PCBzZXBhcmF0ZTxCYXI+KDEpICAgICAgICAgICAgICA8PCBzdGQ6OmVuZGw7Cn0=