Before you ask, I\'ve looked and looked for this on SO, and cannot find a solid answer.
I need to be able to dynamically iterate over an enum that has non-incre
I'm using this type of constructions to define my own enums:
#include
namespace enumeration
{
struct enumerator_base : boost::noncopyable
{
typedef
boost::unordered_map
kv_storage_t;
typedef
kv_storage_t::value_type
kv_type;
typedef
std::set
entries_t;
typedef
entries_t::const_iterator
iterator;
typedef
entries_t::const_iterator
const_iterator;
kv_storage_t const & kv() const
{
return storage_;
}
const char * name(int i) const
{
kv_storage_t::const_iterator it = storage_.find(i);
if(it != storage_.end())
return it->second.c_str();
return "empty";
}
iterator begin() const
{
return entries_.begin();
}
iterator end() const
{
return entries_.end();
}
iterator begin()
{
return entries_.begin();
}
iterator end()
{
return entries_.end();
}
void register_e(int val, std::string const & desc)
{
storage_.insert(std::make_pair(val, desc));
entries_.insert(val);
}
protected:
kv_storage_t storage_;
entries_t entries_;
};
template
struct enumerator;
template
struct enum_singleton : enumerator_base
{
static enumerator_base const & instance()
{
static D inst;
return inst;
}
};
}
#define QENUM_ENTRY(K, V, N) K, N register_e((int)K, V);
#define QENUM_ENTRY_I(K, I, V, N) K = I, N register_e((int)K, V);
#define QBEGIN_ENUM(NAME, C) \
enum NAME \
{ \
C \
} \
}; \
} \
#define QEND_ENUM(NAME) \
}; \
namespace enumeration \
{ \
template<> \
struct enumerator\
: enum_singleton< enumerator >\
{ \
enumerator() \
{
QBEGIN_ENUM(test_t,
QENUM_ENTRY(test_entry_1, "number uno",
QENUM_ENTRY_I(test_entry_2, 10, "number dos",
QENUM_ENTRY(test_entry_3, "number tres",
QEND_ENUM(test_t)))))
int _tmain(int argc, _TCHAR* argv[])
{
BOOST_FOREACH(int x, enumeration::enumerator::instance())
std::cout << enumeration::enumerator::instance().name(x) << "=" << x << std::endl;
return 0;
}
Also you can replace storage_
type to boost::bimap
to have bidirectional correspondance int <==> string