Requirements:
- Must be able to use C strings as well as C++ strings
- Fast
- No maps
- No templates
- No direct lookup, i.e. index might be out of bounds.
- Index is not consecutive
- Enums and strings contained in one header file
- Only instantiate what you use.
This is what I have come up with so far:
- test.hh - // Generic mapper // // The idea here is to create a map between an integer and a string. // By including it inside a class we prevent every module which // includes this include file from creating their own instance. // struct Mapper_s { int Idx; const char *pStr; }; // Status enum State_t { Running = 1, Jumping = 6, Singing = 12 }; struct State_s { static const Mapper_s *GetpMap(void) { static Mapper_s Map[] = { { Running, 'Running' }, { Jumping, 'Jumping' }, { Singing, 'Singing' }, { 0, 0} }; return Map; }; }; - test.cc - // This is a generic function const char *MapEnum2Str(int Idx, const Mapper_s *pMap) { int i; static const char UnknownStr[] = 'Unknown'; for (i = 0; pMap[i].pStr != 0; i++) { if (Idx == pMap[i].Idx) { return pMap[i].pStr; } } return UnknownStr; } int main() { cout << 'State: ' << MapEnum2Str(State, State_s::GetpMap()) << endl; return 0; }
Any suggestions on how to improve this ?
I feel that the header file looks slightly cluttered…
Here is what I settled on. Using this technique all you need to do is to include a header file. You will only instantiate what you use. You could also store a perfect hash table instead of just Idx & pStr. This approach does not work in C.
file: e2str.hh
file: mapper.hh
file: test.cc