Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Somewhat clearer (???) with a bit of boost preprocessing. </p> <p>You define your enums by a sequence </p> <pre><code>#define CAPI_SUBTYPE_E_Sequence \ (CAPI_SUBTYPE_NULL)(0) \ (CAPI_SUBTYPE_DIAG_DFD)(1) ... </code></pre> <p>then you can automate (through macros) the declaration of the enum, </p> <pre><code>DECL_ENUM(CAPI_SUBTYPE_E) ; </code></pre> <p>the table that indexes it</p> <pre><code>DECL_ENUM_TABLE(CAPI_SUBTYPE_E); </code></pre> <p>the number of enums / size of the table</p> <pre><code>ENUM_SIZE(CAPI_SUBTYPE_E) </code></pre> <p>and access to it:</p> <pre><code>ITER_ENUM_i(i,CAPI_SUBTYPE_E) </code></pre> <p>Here is the full text.</p> <pre><code>#include &lt;boost/preprocessor.hpp&gt; // define your enum as (name)(value) sequence #define CAPI_SUBTYPE_E_Sequence \ (CAPI_SUBTYPE_NULL)(0) /* Null subtype. */ \ (CAPI_SUBTYPE_DIAG_DFD)(1) /* Data Flow diag. */ \ (CAPI_SUBTYPE_DIAG_ERD)(2) /* Entity-Relationship diag. */ \ (CAPI_SUBTYPE_DIAG_DSD)(5) /* Data Structure diag. */ \ (CAPI_SUBTYPE_DD_ALL)(13) /* DD Entries (All). */ // # enums #define ENUM_SIZE(name) \ BOOST_PP_DIV(BOOST_PP_SEQ_SIZE(BOOST_PP_CAT(name,_Sequence)),2) #define ENUM_NAME_N(N,seq) BOOST_PP_SEQ_ELEM(BOOST_PP_MUL(N,2),seq) #define ENUM_VALUE_N(N,seq) BOOST_PP_SEQ_ELEM(BOOST_PP_INC(BOOST_PP_MUL(N,2)),seq) // declare Nth enum #define DECL_ENUM_N(Z,N,seq) \ BOOST_PP_COMMA_IF(N) ENUM_NAME_N(N,seq) = ENUM_VALUE_N(N,seq) // declare whole enum #define DECL_ENUM(name) \ typedef enum { \ BOOST_PP_REPEAT( ENUM_SIZE(name) , DECL_ENUM_N , BOOST_PP_CAT(name,_Sequence) ) \ } name DECL_ENUM(CAPI_SUBTYPE_E) ; // declare Nth enum value #define DECL_ENUM_TABLE_N(Z,N,seq) \ BOOST_PP_COMMA_IF(N) ENUM_NAME_N(N,seq) // declare table #define DECL_ENUM_TABLE(name) \ static const name BOOST_PP_CAT(name,_Table) [ENUM_SIZE(name)] = { \ BOOST_PP_REPEAT( ENUM_SIZE(name) , DECL_ENUM_TABLE_N , BOOST_PP_CAT(name,_Sequence) ) \ } DECL_ENUM_TABLE(CAPI_SUBTYPE_E); #define ITER_ENUM_i(i,name) BOOST_PP_CAT(name,_Table) [i] // demo // outputs : [0:0] [1:1] [2:2] [3:5] [4:13] #include &lt;iostream&gt; int main() { for (int i=0; i&lt;ENUM_SIZE(CAPI_SUBTYPE_E) ; i++) std::cout &lt;&lt; "[" &lt;&lt; i &lt;&lt; ":" &lt;&lt; ITER_ENUM_i(i,CAPI_SUBTYPE_E) &lt;&lt; "] "; return 0; } // bonus : check enums are unique and in-order #include &lt;boost/preprocessor/stringize.hpp&gt; #include &lt;boost/static_assert.hpp&gt; #define CHECK_ENUM_N(Z,N,seq) \ BOOST_PP_IF( N , \ BOOST_STATIC_ASSERT_MSG( \ ENUM_VALUE_N(BOOST_PP_DEC(N),seq) &lt; ENUM_VALUE_N(N,seq) , \ BOOST_PP_STRINGIZE( ENUM_NAME_N(BOOST_PP_DEC(N),seq) ) " not &lt; " BOOST_PP_STRINGIZE( ENUM_NAME_N(N,seq) ) ) \ , ) ; #define CHECK_ENUM(name) \ namespace { void BOOST_PP_CAT(check_enum_,name) () { \ BOOST_PP_REPEAT( ENUM_SIZE(name) , CHECK_ENUM_N , BOOST_PP_CAT(name,_Sequence) ) } } // enum OK CHECK_ENUM(CAPI_SUBTYPE_E) #define Bad_Enum_Sequence \ (one)(1)\ (five)(5)\ (seven)(7)\ (three)(3) // enum not OK : enum_iter.cpp(81): error C2338: seven not &lt; three CHECK_ENUM(Bad_Enum) </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload