Iterating over non-incremental Enum

前端 未结 15 1698
长发绾君心
长发绾君心 2021-01-31 15:42

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

15条回答
  •  生来不讨喜
    2021-01-31 16:15

    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

提交回复
热议问题