Skip to content

Instantly share code, notes, and snippets.

@klmr
Created May 9, 2011 20:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save klmr/963346 to your computer and use it in GitHub Desktop.
Save klmr/963346 to your computer and use it in GitHub Desktop.
Smart, strongly-typed enums in C++
#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)
#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