Home > Enterprise >  strongly typed enum from int . C 11
strongly typed enum from int . C 11

Time:01-05

We are recently converting all enum to class enum .

enum class Launches : std::uint32_t {
  D_FROM_FILE=0,
  D_FROM_FDISK,
  D_FROM_RDDISK,
  D_FROM_USB,
  D_FROM_UI,
  D_FROM_NET,
  D_FROM_DEFAULT
};

Launches  launches ;

I need to assign launches values based on int that i received from command line

This is what I am doing after conversion to strongly typed enum

if (receivedInt  == 1)
   launches = D_FROM_FDISK;

I want to avoid and do like

launches = receivedInt;

We fail to compile as this is what strongly typed int are supposed to do.

I want to avoid if and switch cases on receivedInt.

launches = (Launches)receivedInt ; // this compiles ..

but I am hesitant on this or on using static_cast ... whats the proper way ?

using static_cast etc ? What benefit will remain on using strongly types enums then

CodePudding user response:

If you don't want to do typecasts you can use an unordered_map. Here is an example that converts an int you could get from commandline into an enum value in a typesafe manner

#include <cassert>
#include <string>
#include <unordered_map>

enum class Launches 
{
    D_FROM_FILE = 0,
    D_FROM_FDISK,
    D_FROM_RDDISK,
    D_FROM_USB,
    D_FROM_UI,
    D_FROM_NET,
    D_FROM_DEFAULT
};

Launches get_option(const int option)
{
    static const std::unordered_map<int, Launches> launch_options
    {
        {1, Launches::D_FROM_FILE},
        {2, Launches::D_FROM_FDISK},
        //.. etc..
        {6, Launches::D_FROM_NET}
    };

    auto it = launch_options.find(option);
    if (it != launch_options.end())
    {
        return it->second;
    }

    return Launches::D_FROM_DEFAULT;
}


int main()
{
    auto option = get_option(1);
    assert(option == Launches::D_FROM_FILE);

    return 0;
}

CodePudding user response:

What you can do, - create a simple conversion function, check rages and then do the trivial type casting.

#include <system_error>
...
Launches from_code(std::error_code& ec,int code) noexcept 
{
  Launches ret = Launches::D_FROM_DEFAULT;
  if( code < 0 || code > 7) {
    ec = std::make_error_code(std::errc::invalid_argument);
  } else {
    ret = static_cast<Launches>( static_cast<uint32_t>(code) );
  }
  return ret;
}

std::error_code ec;
Lanches launches = from_code(ec,code);
if(ec) {
  // handle error, this code simply thows you can insert your safe logic
  throw std::system_error(ec); 
}
// do what ever you need to
switch(launches) {
  case Launches::D_FROM_FILE:
  ...
  break;
  ...
}
  •  Tags:  
  • Related