Home > Enterprise >  Mapping enums to types
Mapping enums to types

Time:09-08

I have two unrelated types: Object and Unrelated implementing the same basic interface Interface (for storing in the same container).

I have an enum class that basically maps these types to enums

enum class TypeEnum {
    TYPE_OBJECT,
    TYPE_UNRELATED,
};

I have a reading method, that basically down-casts from the Interface to an implementation class

template<typename DATA>
const DATA& Read(const Container<Interface>& container, TypeEnum type);

Is it possible to automate the code, such that (this is a pseudo code)

switch(type_enum) {
    case TYPE_OBJECT:
        return Read<Object>(container, type_enum);
    case TYPE_UNRELATED:
        return Read<Unrelated>(container, type_enum);
}

can be made into a one liner?

NB. I have a bunch of enum values around 50 and a number of places i want to use this idiom.

In my want-to-have way, I would prefer something aka

template<TypeName>
struct TypePicker;

template<>
struct TypePicker<TYPE_OBJECT> {
    typedef Object underlying_type;
};

template<>
struct TypePicker<TYPE_UNRELATED> {
    typedef Unrelated underlying_type;
};

and then

return Read<TypePicker<type_enum>::underlying_type>(container, type_enum);

However, type_enum is only known at run-time.

CodePudding user response:

I turn the reference into a copy to fit std::variant,

// using std::type_identity for C  20 or later
template <typename T>
struct type_identity {
    using type = T;
};

using VType = std::variant<type_identity<Object>,
                           type_identity<Unrelated>>;

using RType = std::variant<Object, Unrelated>;

static const std::map<TypeEnum, VType> dispatcher = {
    {TypeEnum::TYPE_OBJECT, type_identity<Object>{}},
    {TypeEnum::TYPE_UNRELATED, type_identity<Unrelated>{}}
};

auto foo(TypeEnum type_enum)
{
    Container<Interface> container;
    return std::visit([&](auto v) -> RType {
        return Read<typename decltype(v)::type>(container, type_enum);
    }, dispatcher.at(type_enum));
}

Demo

  • Related