/** @file G3D/enumclass.h @maintainer Morgan McGuire, http://graphics.cs.williams.edu @created 2007-01-27 @edited 2007-07-20 */ #ifndef G3D_enumclass_h #define G3D_enumclass_h #include "G3D/HashTrait.h" #include "G3D/BinaryInput.h" #include "G3D/BinaryOutput.h" /** \def G3D_DECLARE_ENUM_CLASS_METHODS \brief Creates a series of methods that turn a class into a scoped enumeration. Uses the "Intelligent Enum" design pattern http://www.codeguru.com/cpp/cpp/cpp_mfc/article.php/c4001/ Enum classes are initialized to their zero value by default. You must implement the following method before calling G3D_DECLARE_ENUM_CLASS_METHODS, as either:
static const char* toString(int i, Value& v) { static const char* str[] = {"FUEL", "FOOD", "WATER", NULL}; // Whatever your enum values are static const Value val[] = {FUEL, FOOD, WATER}; // Whatever your enum values are const char* s = str[i]; if (s) { v = val[i]; } return s; }See GLG3D/GKey.h for an example. \sa G3D_DECLARE_ENUM_CLASS_HASHCODE */ #define G3D_DECLARE_ENUM_CLASS_METHODS(Classname)\ private: \ void fromString(const std::string& x) {\ Value v;\ const char* s;\ int i = 0;\ \ do {\ s = toString(i, v);\ if (x == s) {\ value = v;\ return;\ }\ ++i;\ } while (s);\ }\ \ public:\ \ const char* toString() const {\ const char* s;\ int i = 0;\ Value v = (Value)0;\ while (true) {\ s = toString(i, v);\ if ((s == NULL) || (v == value)) {\ return s;\ }\ ++i;\ }\ return NULL;\ }\ \ explicit Classname(const std::string& x) : value((Value)0) {\ fromString(x);\ }\ \ Classname(const Any& a) : value((Value)0) {\ fromString(a.string());\ }\ \ operator Any() const {\ return Any(toString());\ }\ \ Classname(char v) : value((Value)v) {}\ \ Classname() : value((Value)0) {}\ \ Classname(const Value v) : value(v) {}\ \ explicit Classname(int v) : value((Value)v) {}\ \ /** Support cast back to the Value type, which is needed to allow implicit assignment inside unions. */\ /*inline operator Value() const { return value; }*/\ \ operator int() const {\ return (int)value;\ }\ \ bool operator== (const Classname other) const {\ return value == other.value;\ }\ \ bool operator== (const Classname::Value other) const {\ return value == other;\ }\ \ bool operator!= (const Classname other) const {\ return value != other.value;\ }\ \ bool operator!= (const Classname::Value other) const {\ return value != other;\ }\ \ bool operator< (const Classname other) const {\ return value < other.value;\ }\ \ bool operator> (const Classname other) const {\ return value > other.value;\ }\ \ bool operator>= (const Classname other) const {\ return value >= other.value;\ }\ \ bool operator<= (const Classname other) const {\ return value <= other.value;\ }\ \ bool operator< (const Value other) const {\ return value < other;\ }\ \ bool operator> (const Value other) const {\ return value > other;\ }\ \ bool operator<= (const Value other) const {\ return value <= other;\ }\ \ bool operator>= (const Value other) const {\ return value >= other;\ }\ \ Classname& operator-- () {\ value = (Value)((int)value - 1);\ return *this;\ }\ \ Classname& operator++ () {\ value = (Value)((int)value + 1);\ return *this;\ }\ \ Classname& operator+= (const int x) {\ value = (Value)((int)value + x);\ return *this;\ }\ \ Classname& operator-= (const int x) {\ value = (Value)((int)value - x);\ return *this;\ }\ \ Classname operator+ (const int x) const {\ return Classname((int)value + x);\ }\ \ Classname operator- (const int x) const {\ return Classname((int)value - x);\ }\ \ unsigned int hashCode() const {\ return (unsigned int)value;\ }\ \ void serialize(BinaryOutput& b) const {\ b.writeInt32(value);\ }\ \ void deserialize(BinaryInput& b) {\ value = (Value)b.readInt32();\ } /** \def G3D_DECLARE_ENUM_CLASS_HASHCODE */ #define G3D_DECLARE_ENUM_CLASS_HASHCODE(Classname)\ template <> struct HashTrait