10
\$\begingroup\$

I need to map from one enum type to another. Here is the enum I am given:

enum CfgFruitType { CFGNoFruit, CFGApple, CFGApricot, CFGBanana,
   CFGMango, CFGKiwi, CFGFig, CFGGrape, CFGMelon, CFGLemon,
   CFGNectarine, CFGPineapple, CFGWatermelon, CFGCherry, CFGPear,
   CFGStrawberry };

and I need to map this to a second enum:

enum FAddressType { AddressTypeUnknown, AddressTypeCherry,
  AddressTypeApple, AddressTypePear, AddressTypePlum,
  AddressTypeStrawberry };

Here is my implementation:

FAddressType maptype(CfgFruitType cfgtype) {
   int mapper[16][2] =
   {
      { CFGNoFruit,          AddressTypeUnknown },
      { CFGApple,            AddressTypeApple },
      { CFGApricot,          AddressTypeUnknown },
      { CFGBanana,           AddressTypeUnknown },
      { CFGMango,            AddressTypeUnknown },
      { CFGKiwi,             AddressTypeUnknown },
      { CFGFig,              AddressTypeUnknown },
      { CFGGrape,            AddressTypeUnknown },
      { CFGMelon,            AddressTypeUnknown },
      { CFGLemon,            AddressTypeUnknown },
      { CFGNectarine,        AddressTypeUnknown },
      { CFGPineapple,        AddressTypeUnknown },
      { CFGWatermelon,       AddressTypeUnknown },
      { CFGCherry,           AddressTypeCherry },
      { CFGPear,             AddressTypePear },
      { CFGStrawberry,       AddressTypeStrawberry }
     };

   return cfgtype < 16 ? (FAddressType)mapper[cfgtype][1] : AddressTypeUnknown;
}

Is this the best approach? How can it be improved?

\$\endgroup\$
14
\$\begingroup\$

You made a look-up table. Here's 2 things to note:

  1. Your look up table is between 2 types, but your table is only 1 type. You break type safety. They are enums and it's 'safe' if the enums have the same underlying type, but dirty either way.

  2. A switch frequently generates a look up table for you, and in this case definitely will on any decent compiler. It will not generate an if-if else-else chain. See the following:

:

FAddressType maptype(CfgFruitType cfgtype)
{
    switch(cfgtype)
    {
    case CFGNoFruit:    return AddressTypeUnknown;
    case CFGApple:      return AddressTypeApple;
    case CFGApricot:    return AddressTypeUnknown;
    case CFGBanana:     return AddressTypeUnknown;
    case CFGMango:      return AddressTypeUnknown;
    case CFGKiwi:       return AddressTypeUnknown;
    case CFGFig:        return AddressTypeUnknown;
    case CFGGrape:      return AddressTypeUnknown;
    case CFGMelon:      return AddressTypeUnknown;
    case CFGLemon:      return AddressTypeUnknown;
    case CFGNectarine:  return AddressTypeUnknown;
    case CFGPineapple:  return AddressTypeUnknown;
    case CFGWatermelon: return AddressTypeUnknown;
    case CFGCherry:     return AddressTypeCherry;
    case CFGPear:       return AddressTypePear;
    case CFGStrawberry: return AddressTypeStrawberry;
    default:            assert(!"Not a valid CfgFruitType!"); return AddressTypeUnknown;
    }
}

Shorter code, very clear, easy to add new cases, very likely to outperform (by a negligible margin) your code.

Or, you could be less explicit and make it really short:

switch(cfgtype)
{
case CFGApple:      return AddressTypeApple;
case CFGCherry:     return AddressTypeCherry;
case CFGPear:       return AddressTypePear;
case CFGStrawberry: return AddressTypeStrawberry;
default:            return AddressTypeUnknown;
}
\$\endgroup\$
0
\$\begingroup\$

If I were you I'd write a function to convert from one to the other which would perform a switch on your input.

My motivation to do so would be to :

  • have warnings/errors whenever a case is not handled. If you do so and you update the enum, you can't forget to update your code performing handling the conversion (-Wswitch : Warn whenever a switch statement has an index of enumerated type and lacks a case for one or more of the named codes of that enumeration)
  • you can easily update your code if you need to.

And the overhead in terms of code and

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.