0

I have an enum class like this:

class ContentTypeEnum {

 public:

  // it might have more types
  enum Code { TEXT, XML, APPLICATION_JSON};

  static const char* to_c_str(unsigned);

};

I was using it like this in my code as of now.

ContentTypeEnum::APPLICATION_JSON

Problem Statement:-

Now I have a string given so I need to use that string and then find the actual ENUM type by iterating it my above enum.

Below is my code:

cout<<"Given String: " << data_args->pp_args->ter_strings[0].c_str() << endl;
const char* test_str = data_args->pp_args->ter_strings[0].c_str();

Now if test_str is xml or XML, then I need to set it like this:

TestClass::SetContentType(ContentTypeEnum::XML)

But if test_str is application_json or APPLICATION_JSON, then I need to set it like this:

TestClass::SetContentType(ContentTypeEnum::APPLICATION_JSON)

And similarly for others as well. Below is my full code:

cout<<"Given String: " << data_args->pp_args->ter_strings[0].c_str() << endl;
char* test_str = data_args->pp_args->ter_strings[0].c_str();

// look up the exact ContentType from the enum using test_str string
// and then set it to below method.
TestClass::SetContentType(set_it_here_basis_on_string_test_str)

If somebody is passing any unknown string which is not there in my enum, then it should use by default as TestClass::SetContentType(ContentTypeEnum::APPLICATION_JSON)

What is the right way to lookup the exact enum type given a string?

Weather Vane
  • 33,872
  • 7
  • 36
  • 56
john
  • 11,311
  • 40
  • 131
  • 251
  • There's no built in facility, but it's straightforward to write your own function that takes a string, compares it to hardcoded literals, and returns an enumeration. – Mooing Duck Apr 21 '15 at 21:59

1 Answers1

4

I suggest writing a function that returns the enum given a string.

Code getCode(std::string const& s)
{
   static std::map<std::string, Code> theMap{{"TEXT", TEXT},
                                             {"XML", XML}
                                             {"APPLICATION_JSON", APPLICATION_JSON}};

   std::map<std::string, Code>::iterator it = theMap.find(s);
   if ( it != theMap.end() )
   {     
      return it->second;
   }
   return APPLICATION_JSON;
}
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • 2
    I'd use `const` and `find`, and be more explicit about the default of `APPLICATION_JSON`. – Mooing Duck Apr 21 '15 at 22:12
  • @MooingDuck - I'd probably toss an exception or otherwise let the caller know a match wasn't found and let the caller deal with what the default should be. I'd probably also convert the incoming string to upper case to make a case-insensitive match. – Andrew Henle Apr 21 '15 at 22:27
  • @AndrewHenle: OP said "If somebody is passing any unknown string which is not there in my enum, then it should use by default as TestClass::SetContentType(ContentTypeEnum::APPLICATION_JSON)", so I followed that. An exception is probably not the right idea for validating input, but maybe a `bool try_get_code(std::string const&, Code&)` wouldn't be amis. – Mooing Duck Apr 21 '15 at 22:29
  • Thanks for suggestion. Do we need to have `theMap` which will have all the ENUM mapping to a String? Can we not iterate the ENUM basis on the string passed and then return the ENUM type if found otherwise return APPLICATION_JSON? In general what is the advantage of using theMap here? – john Apr 21 '15 at 22:33
  • With this way, If I am adding another ENUM Type, then I need to update my theMap as well? Right? – john Apr 21 '15 at 22:35
  • 1
    @david, the advantage of using the map is less code. It might also result in faster lookup but I won't vouch for that without hard data. – R Sahu Apr 21 '15 at 22:35
  • 1
    @david, right. If you add more tokens to the `enum`, you'll have to update the map. – R Sahu Apr 21 '15 at 22:35
  • @RSahu got it. Also, how to deal with lowercase string being passed, like if somebody is passing lowercase `xml` instead of `XML`. Will it still work? – john Apr 21 '15 at 22:36
  • @MooingDuck - True, but I don't like burying logic decisions in a lookup method. "Tell me what you found, not what you think I should do." Just a personal opinion. I should have made that more clear. – Andrew Henle Apr 21 '15 at 22:36
  • 1
    @david: The core of the issue is the exe doesn't have the names of the enumerations, period. So to compare the input with names, you have to _add_ the names to the exe, and store them somewhere. Thus, we make a map. You can use `stricmp` or some other case-insensitive string comparison for those cases. – Mooing Duck Apr 21 '15 at 22:41
  • @MooingDuck understood now. I think we also need to make this case-insensitive match as well right? Bcoz anyone can pass lowercase incoming string? – john Apr 21 '15 at 22:43
  • If you want a case-insensitive comparison, then yes. Do a case-insensitive comparison. – Mooing Duck Apr 21 '15 at 22:50
  • Is there any built in function to make `const& s` to upper case. Sorry asking silly question, I am coming from Java background so not sure on this. – john Apr 21 '15 at 22:54
  • looks like this will work `strupr(s)`. Going to try out. – john Apr 21 '15 at 23:00