Created
May 9, 2011 20:39
-
-
Save klmr/963346 to your computer and use it in GitHub Desktop.
Smart, strongly-typed enums in C++
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iosfwd> | |
#include <string> | |
#include <vector> | |
#include <boost/preprocessor.hpp> | |
template <typename T> | |
T atomic_inc(volatile T& value) { | |
#pragma omp atomic | |
value += 1; | |
return value; | |
} | |
template <typename T, typename IdType = unsigned> | |
struct Enum { | |
friend bool operator ==(Enum const& a, Enum const& b) { | |
return a.id == b.id; | |
} | |
friend bool operator !=(Enum const& a, Enum const& b) { | |
return not (a == b); | |
} | |
friend std::ostream& operator <<(std::ostream& out, Enum const& e) { | |
return out << Enum::names()[e.id - 1]; | |
} | |
// Default generated copy constructor and assignment. | |
// TODO Generate more useful methods like parsing ... | |
protected: | |
Enum(char const* name) : id(atomic_inc(next_id)) { | |
names().push_back(name); | |
} | |
private: | |
IdType id; | |
static std::vector<char const*>& names() { | |
static std::vector<char const*> names; | |
return names; | |
} | |
static IdType next_id; | |
}; | |
template <typename T, typename IdType> | |
IdType Enum<T, IdType>::next_id = 0u; | |
#define MYLIB_DECLARE_ENUM_CONST(r, data, value) \ | |
static const data value; | |
#define MYLIB_DEFINE_ENUM_CONST(r, data, value) \ | |
data const data::value = data(BOOST_PP_STRINGIZE(value)); | |
#define MYLIB_ENUM(enumname, values) \ | |
struct enumname : Enum<enumname> { \ | |
BOOST_PP_SEQ_FOR_EACH(MYLIB_DECLARE_ENUM_CONST, enumname, values) \ | |
private: \ | |
enumname(char const* name) : Enum<enumname>(name) { } \ | |
}; \ | |
BOOST_PP_SEQ_FOR_EACH(MYLIB_DEFINE_ENUM_CONST, enumname, values) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include "enum.hpp" | |
MYLIB_ENUM(Color, | |
(Red)(Green)(Blue)(Yellow)) | |
void foo(Color c) { | |
std::cout << c << " " << ((c == Color::Red) ? '=' : '!') << "= Red" << std::endl; | |
} | |
int main() { | |
foo(Color::Red); | |
foo(Color::Blue); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment