The C/C++ enumeration syntax exists to support the use of human readable character names to support a specific list of available values for the specified variable. This is enabled in C and C++ as a set of named integer constants. This can be expressed as #define preprocessor directives or as a C or C++ enumerated type "enum". Both C and C++ use the same enumeration syntax. We also give an example of a C++ enumeration class which extends the capability of the C enumeration.
Basic C/C++ enumeration declaration and use:
File: enumExample.cpp
#include <iostream> using namespace std; main() { enum { monday, tuesday, wednesday, thursday, friday, saturday, sunday } day; day = wednesday; if(day == saturday || day == sunday) cout << "Day is a weekend day" << endl; else if(day == wednesday) cout << "Day is hump day - middle of the work week" << endl; }
Enumerations are represented as incrementing integers beginning with the value 0. One can specify the integer representation of the enumeration by specifying the integer from which the index begins incrementing. More than one enumeration can be represented by the same integer.
File: enumExample2.cpp
#include <iostream> using namespace std; main() { enum { saturday = 0, sunday = 0, monday, tuesday, wednesday, thursday, friday } DAY; DAY day = sunday; if(day == 0) cout << "Day is a weekend day" << endl; else if(day == wednesday) cout << "Day is hump day - middle of the work week" << endl; }
File: enumExample3.cpp
#include <iostream> using namespace std; main() { typedef enum { thirteen = 10, fourteen, fifteen, sixteen, seventeen, eighteen, nineteen } TEENS; TEENS teen = seventeen; if(teen == seventeen) cout << seventeen << endl; }
Obviously if we started the enumeration at 13 instead of 10 we would have had alignment with the integer in our results.
One can create and enumeration class in C++ to extend the capabilities of enumerations.
File: CDay.hpp
#ifndef DAY_HPP__ #define DAY_HPP__ #include <ostream> #include <string> #include <algorithm> class Day { public: enum Enum { sunday = 0, monday, tuesday, wednesday, thursday, friday, saturday, InvalidDay }; // Constructors Day(void); Day(Enum ee); explicit Day(const std::string& ss); // Overloaded assignment operators Day& operator = (const Day& cc); Day& operator = (const std::string& ss); Day& operator = (Enum ee); // Overloaded comparison operators bool operator< (const Day& cc) const; bool operator< (Enum ee) const; bool operator<= (const Day& cc) const; bool operator<= (Enum ee) const; bool operator> (const Day& cc) const; bool operator> (Enum ee) const; bool operator>= (const Day& cc) const; bool operator>= (Enum ee) const; bool operator== (const Day& cc) const; bool operator== (const std::string& ss) const; bool operator== (const Enum ee) const; bool operator!= (const Day& cc) const; bool operator!= (const std::string& ss) const; bool operator!= (const Enum ee) const; // Accessor functions inline std::string getString (void) const; inline Enum getEnum (void) const; inline int getValue (void) const; private: // Static functions static Enum fromString(std::string ss); static std::string toString(Enum ee); static int toValue(Enum ee); // Data members Enum m_enum; std::string m_string; int m_value; }; inline std::ostream& operator<< (std::ostream& _os, const Day& _e) { _os << _e.getString(); return _os; } inline std::string Day::getString(void) const { return m_string; } Day::Enum Day::getEnum(void) const { return m_enum; } int Day::getValue(void) const { return m_value; } #endif
File: CDay.cpp
#include <stdexcept< // Constructors Day::Day(void) : m_enum(sunday), m_string("Sunday"), m_value(0) {} Day::Day(Enum _e) : m_enum(_e), m_string(toString(_e)), m_value(0) {} Day::Day(const std::string& _s) : m_enum(fromString(_s)), m_string(_s), m_value(toValue(m_enum)) {} // Assignment operators Day& Day::operator= (const Day& _c) { m_string = _c.m_string; m_enum = _c.m_enum; m_value = _c.m_value; return *this; } Day& Day::operator= (const std::string& _s) { m_string = _s; m_enum = fromString(_s); m_value = toValue(m_enum); return *this; } Day& Day::operator= (Enum _e) { m_enum = _e; m_string = toString(_e); m_value = toValue(_e); return *this; } bool Day::operator< (const Day& _c) const { return (m_value < _c.m_value); } bool Day::operator< (Enum _e) const { return (m_value < toValue(_e)); } bool Day::operator<= (const Day& _c) const { return (m_value <= _c.m_value); } bool Day::operator<= (Enum _e) const { return (m_value <= toValue(_e)); } bool Day::operator> (const Day& _c) const { return (m_value > _c.m_value); } bool Day::operator> (Enum _e) const { return (m_value > toValue(_e)); } bool Day::operator>= (const Day& _c) const { return (m_value >= _c.m_value); } bool Day::operator>= (Enum _e) const { return (m_value >= toValue(_e)); } bool Day::operator== (const Day& _c) const { return (m_enum == _c.m_enum); } bool Day::operator== (const std::string& _s) const { return (m_string == _s); } bool Day::operator== (const Enum _e) const { return (m_enum == _e); } bool Day::operator!= (const Day& _c) const { return (m_enum != _c.m_enum); } bool Day::operator!= (const std::string& _s) const { return (m_string != _s); } bool Day::operator!= (const Enum _e) const { return (m_enum != _e); } Day::Enum Day::fromString(std::string _s) { // Case insensitive - make all upper case transform(_s.begin(), _s.end(), _s.begin(), toupper); if(_s == "SUNDAY") return sunday; else if(_s == "MONDAY") return monday; else if(_s == "TUESDAY") return tuesday; else if(_s == "WEDNESDAY") return wednesday; else if(_s == "THURSDAY") return thursday; else if(_s == "FRIDAY") return friday; else if(_s == "SATURDAY") return saturday; throw std::range_error("Not a valid Day value: " + _s); return InvalidDay; }; std::string Day::toString(Day::Enum _e) { switch (_e) { case sunday: { return "SUNDAY"; } case monday: { return "MONDAY"; } case tuesday: { return "TUESDAY"; } case wednesday: { return "WEDNESDAY"; } case thursday: { return "THURSDAY"; } case friday: { return "FRIDAY"; } case saturday: { return "SATURDAY"; } } return "InvalidDay"; } int Day::toValue(Day::Enum _e) { switch (_e) { case sunday: { return 0; } case monday: { return 2; } case tuesday: { return 3; } case wednesday: { return 4; } case thursday: { return 5; } case friday: { return 6; } case saturday: { return 7; } } return 8; // Invalid }
File: dayProg.cpp
#include <iostream> #include "CDay.hpp" using namespace std; main() { Day day; day = "Saturday"; if(day == Day::saturday || day == Day::sunday) cout << "Day is a weekend day" << endl; }
Results: Day is a weekend day
Associated string array:
File: enumExample5.cpp
#include <iostream> typedef enum { monday, tuesday, wednesday, thursday, friday, saturday, sunday } Day; const char *day_str[]={ "Monday","Tuesday","Wednesday","Thursday","Friday","Saturday", "Sunday" }; using namespace std; main() { Day day = saturday; if(day == saturday || day == sunday) cout << day_str[day] << endl; }
Run: ./a.out
Result: Saturday
C define macros:
File: enumExample6.cpp
#include <iostream> #define SUNDAY 0 #define MONDAY 1 #define TUESDAY 2 #define WEDNESDAY 3 #define THURSDAY 4 #define FRIDAY 5 #define SATURDAY 6 using namespace std; main() { int day; day = SATURDAY; if(day == SATURDAY || day == SUNDAY) cout << "Day is a weekend day" << endl; }
Run: ./a.out
Result: Day is a weekend day
Other methodologies could include STL Map or Boost smart_enum constructs.