hierarchical non-rectangular list of names and enums in c++98

77 Views Asked by At

I'm trying to assemble a hierarchical list of enums (indices) and their corresponding names so that I can access specific ones by name or loop through all of them, depending on the section of my code I'm in. The list will be constant once compiled, but it needs to be easily changed in code. I am using X macros to streamline this but I'm a bit stuck on how to get the flexibility I'm aiming for. Perhaps I'm going about it all wrong.

This part works:

namespace another
{
    // Define individual groups
    //-------------------------
        // <<Self>> group
        #define XLIST \
        X(Lat               ) \
        X(Lon               ) \
        X(Altitude          ) \
        X(Weight            )
        #define X(a) a,
            enum class enum_Self { XLIST NUMEL };
        #undef X
        #define X(a) #a,
            const char * const name_Self[] = { XLIST };
        #undef X
        #undef XLIST

        // <<Target>> group
        #define XLIST \
        X(Lat               ) \
        X(Lon               ) \
        X(Altitude          )
        #define X(a) a,
            enum class enum_Target { XLIST NUMEL };
        #undef X
        #define X(a) #a,
            const char * const name_Target[] = { XLIST };
        #undef X
        #undef XLIST

    // List of the "another" groups
    //-----------------------------
    #define XLIST \
    X(Self      ) \
    X(Target    )
    // Group name enumeration
    #define X(a) a,
        enum class groupEnum { XLIST NUMEL };
    #undef X
    // Group name strings
    #define X(a) #a,
        const char * const groupName[] = { XLIST };
    #undef X
    // An array which contains the number of flags in each group
    #define X(a) (const int) another::enum_ ##a::NUMEL,
        const int groupSize[] = { XLIST };
    #undef X
    #undef XLIST
} // end another namespace

Then in main, I can loop through the groups using something like this:

for (int ii=0; ii<(int)another::groupEnum::NUMEL; ii++)
    printf("Group %d is %s\n",ii,(int)another::groupName[ii]);

And if I pick a specific group by name, I can do something like this:

printf("another::enum_Self contains:\n");
for (int ii=0; ii<(int)another::enum_Self::NUMEL; ii++)
    printf("\t%s\n",another::name_Self[ii]);

And I can access a specific item like this: another::enum_Self::Altitude

The problem is that I can't loop through each of the groups and then each of the items within that group. I was trying to create an array of structs, each of which contained an enum and const char * const array of names, but I couldn't figure out how to define a generic struct up front and then initialize it with the particular values. And I couldn't do a 2-D array from the top level because not every group will have the same number of items in it. I thought about vectors too, but those are intended to be dynamic and the whole point here is that this stuff shouldn't change at all once compiled. I suspect I'm simply thinking about the problem the wrong way...

0

There are 0 best solutions below