I ported an application that I wrote some time ago from Java to C ++. One thing that I quickly realized was that the rich Java Enum (which were introduced in Java 5) were far superior to the Java resources presented above in C ++. C ++ 0x and later versions of C ++ 11 Strongly Typed Enumerations (the so-called enum classes) still do not provide the richness provided by Java Enums, and I could not find anything to emulate this object here.
I decided to try to imitate some functions like standing by classes, and I would like some of them to help implement this, perhaps using templates if necessary (it just seems like there should be a more general way to implement this), you will see that the ability to search for a specific Enum using a string name is quite fully implemented - (this is an emulation of the Java ENUM valueOf (String str) method - it works, but I'm sure this is far from optimal. The way I implemented Enum instances uses static const instances inside class - I'm on I ate it somewhere in Stack Overflow, but I can not remember exactly where - sorry.
The FYI application is an NMEA String parser, and here are a few of the most interesting Enum classes:
Here is the title
#ifndef _NMEASentence_h_ #define _NMEASentence_h_
Here is the CPP
// SYSTEM INCLUDES // APPLICATION INCLUDES
Here is a subclass of the general class NMEASentence
#ifndef _CDUMessage_h_ #define _CDUMessage_h_
And the corresponding CPP
// SYSTEM INCLUDES //#include <...> // APPLICATION INCLUDES #include "vcdu/CDUMessage.h" // EXTERNAL FUNCTIONS // EXTERNAL VARIABLES // CONSTANTS // STATIC VARIABLE INITIALIZATIONS // this is the heartbeat message (not associated with any line => -1 for last paramter) const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUAlive ("PCDUALIVE", CDUMessage::Alive, JustifyStyle::Left, -1); // the following 3 messages are associated with the title line const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayDataStatusBlock("PCDUDSB", CDUMessage::Display, JustifyStyle::Left, 0); const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayTitle("PCDUTIT", CDUMessage::Display, JustifyStyle::Center, 0); const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayPageNumber("PCDUPGE", CDUMessage::Display, JustifyStyle::Right, 0); // these messages are associated with the active display area const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayScratchPad("PCDUSPD", CDUMessage::Display, JustifyStyle::Left, 13); const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS1Text("PCDUL1T", CDUMessage::Display, JustifyStyle::Left, 2); const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS2Text("PCDUL2T", CDUMessage::Display, JustifyStyle::Left, 4); const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS3Text("PCDUL3T", CDUMessage::Display, JustifyStyle::Left, 6); const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS4Text("PCDUL4T", CDUMessage::Display, JustifyStyle::Left, 8); const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS5Text("PCDUL5T", CDUMessage::Display, JustifyStyle::Left, 10); const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS6Text("PCDUL6T", CDUMessage::Display, JustifyStyle::Left, 12); const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS1SText("PCDUL1S", CDUMessage::Display, JustifyStyle::Left, 1); const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS2SText("PCDUL2S", CDUMessage::Display, JustifyStyle::Left, 3); const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS3SText("PCDUL3S", CDUMessage::Display, JustifyStyle::Left, 5); const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS4SText("PCDUL4S", CDUMessage::Display, JustifyStyle::Left, 7); const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS5SText("PCDUL5S", CDUMessage::Display, JustifyStyle::Left, 9); const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS6SText("PCDUL6S", CDUMessage::Display, JustifyStyle::Left, 11); const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS1Text("PCDUR1T", CDUMessage::Display, JustifyStyle::Right, 2); const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS2Text("PCDUR2T", CDUMessage::Display, JustifyStyle::Right, 4); const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS3Text("PCDUR3T", CDUMessage::Display, JustifyStyle::Right, 6); const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS4Text("PCDUR4T", CDUMessage::Display, JustifyStyle::Right, 8); const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS5Text("PCDUR5T", CDUMessage::Display, JustifyStyle::Right, 10); const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS6Text("PCDUR6T", CDUMessage::Display, JustifyStyle::Right, 12); const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS1SText("PCDUR1S", CDUMessage::Display, JustifyStyle::Right, 1); const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS2SText("PCDUR2S", CDUMessage::Display, JustifyStyle::Right, 3); const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS3SText("PCDUR3S", CDUMessage::Display, JustifyStyle::Right, 5); const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS4SText("PCDUR4S", CDUMessage::Display, JustifyStyle::Right, 7); const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS5SText("PCDUR5S", CDUMessage::Display, JustifyStyle::Right, 9); const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS6SText("PCDUR6S", CDUMessage::Display, JustifyStyle::Right, 11); // these messages are not associated with a paricular line# which is why we specify -1 for the last parameter const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayCLS("PCDUCLS", CDUMessage::Display, JustifyStyle::Left, -1); const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayPutString("PCDUPUTS", CDUMessage::XYDisplay, JustifyStyle::None, -1); const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUStatus("PCDUSID", CDUMessage::Status, JustifyStyle::Left, -1); const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUKeyboard("PCDUKEY", CDUMessage::Keyboard, JustifyStyle::Left, -1); const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUSet("PCDUSETV", CDUMessage::Configuration, JustifyStyle::Left, -1); const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUGet("PCDUGETV", CDUMessage::Configuration, JustifyStyle::Left, -1);
And just to show a general example of using Enums here, we have some more Enum C ++ classes that I need to use throughout the application. They all look pretty similar, and I can't help but feel that there should be an easier and less detailed way to implement this. Any help or ideas would really be welcome.
class JustifyStyle { public: static const JustifyStyle Left, Center, Right, None; inline std::string getName() const { return mName; } private: JustifyStyle(const std::string& rName) : mName(rName) {} std::string mName; }; class FontSize { public: static const FontSize F1, F2, F3, F4, F5, F6; inline std::string getName() const { return mName; } static std::vector<FontSize>& getValues() { static std::vector<FontSize> gValues; if (gValues.empty()) { gValues.push_back(F1); gValues.push_back(F2); gValues.push_back(F3); gValues.push_back(F4); gValues.push_back(F5); gValues.push_back(F6); } return gValues; } private: FontSize(const std::string& rName) : mName(rName) {} std::string mName; }; class FontStyle { public: static const FontStyle S, B, I, U, N; inline std::string getName() const { return mName; } static std::vector<FontStyle>& getValues() { static std::vector<FontStyle> gValues; if (gValues.empty()) { gValues.push_back(S); gValues.push_back(B); gValues.push_back(I); gValues.push_back(U); gValues.push_back(N); } return gValues; } inline bool operator<(const FontStyle& rhs) const { return mName < rhs.mName; } private: FontStyle(const std::string& rName) : mName(rName) {} std::string mName; }; class FontColor { public: static const FontColor BLACK, CYAN, RED, YELLOW, GREEN, MAGENTA, AMBER, WHITE; inline int getValue() const { return mValue; } inline std::string getValueStr() const { return UtlStringUtils::integerToString(mValue); } static std::vector<FontColor>& getValues() { static std::vector<FontColor> gValues; if (gValues.empty()) { gValues.push_back(BLACK); gValues.push_back(CYAN); gValues.push_back(RED); gValues.push_back(YELLOW); gValues.push_back(GREEN); gValues.push_back(MAGENTA); gValues.push_back(AMBER); gValues.push_back(WHITE); } return gValues; } private: