Skip to content

Instantly share code, notes, and snippets.

@amullins83
Last active April 14, 2016 14:24
Show Gist options
  • Save amullins83/c84f3466c47d629e4f22bfed682e1a28 to your computer and use it in GitHub Desktop.
Save amullins83/c84f3466c47d629e4f22bfed682e1a28 to your computer and use it in GitHub Desktop.
Attempt to create a reusable enumerated type wrapper
#include <iostream>
#include <string>
enum Type1 {
What,
Hey
};
enum Type2 {
Yo,
Mama
};
template <typename T, int MAX, int MIN=0>
class Enum {
public:
Enum(T t) : thing(t) {}
Enum(std::string name) {
FromString(name);
}
void FromString(std::string name) {
for (int count = MIN; count <= MAX; ++count) {
if (Enum((T)count).GetString() == name) {
thing = (T)count;
break;
}
}
}
Enum& operator= (T val) {
thing = val;
return *this;
}
Enum& operator= (std::string name) {
FromString(name);
return *this;
}
std::string GetString() const;
T GetValue() const {
return thing;
}
operator T() const {
return thing;
}
operator std::string() const {
return GetString();
}
private:
T thing;
};
typedef Enum<Type1, Hey> Enum1;
typedef Enum<Type2, Mama> Enum2;
template<>
std::string Enum1::GetString() const {
return thing == What ? "What" : "Hey";
}
template<>
std::string Enum2::GetString() const {
return thing == Yo ? "Yo" : "Mama";
}
template <typename T, int MAX, int MIN>
std::ostream& operator<<(std::ostream& os, const Enum<T, MAX, MIN> &thing) {
return os << thing.GetString();
}
int main()
{
Enum1 thing(What);
Enum2 other(Mama);
std::cout << "Value of thing: " << thing << std::endl;
std::cout << "Value of other: " << other << std::endl;
std::string testString = "Hey";
Enum1 fromString(testString);
std::cout << "Test string: " << testString << std::endl;
std::cout << "Value of fromString(testString): "
<< Enum1(fromString.GetValue())
<< std::endl;
thing = Hey; // Assignment operator
Type1 wasThing = thing; // Coercion operator
std::cout << "New value of thing: " << thing << std::endl;
std::cout << "New value coerced to Type1 and back: "
<< Enum1(wasThing) << std::endl;
other = "Yo";
Type2 wasOther = other;
std::cout << "New value of other: " << other << std::endl;
std::string yo = other;
std::cout << "Other coerced to string: " << yo << std::endl;
return 0;
}
@amullins83
Copy link
Author

The purpose of this is to avoid defining an identical operator<< overload for each enumerated type that has a GetString function declared like std::string GetString(Type1 enumVal). I am currently working with a codebase that has a lot of these enumerated types and overloads of GetString for each one. These should have been wrapped in a generic class like the one shown here a long time ago.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment