12
\$\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?

Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Mar 20, 2013 at 11:17
\$\endgroup\$

2 Answers 2

15
\$\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;
}
answered Mar 21, 2013 at 12:05
\$\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

answered Mar 20, 2013 at 14:24
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.