I need to map certain OpenGL enums to indices in range 0..N-1 where N is the number of enums. This should happen in compile time and in such a way that unsupported enums generate an compilation error. This would be used in OpenGL state cache/stack 'library'.
Partial solution for mapping function might be:
inline EnableState GetState(GLenum glenum) {
switch(glenum) {
case GL_ALPHA_TEST: return ALPHA_TEST; // 0
..
case GL_VERTEX_ARRAY: return VERTEX_ARRAY; // N-1
default: <GENERATE_COMPILE_TIME_ERROR>
}
}
this is called by other inline functions that enable/disable/push/pop opengl states. For example Enable function:
inline void Enable(GLenum glenum) {
const EnableState state = GetState(glenum);
if(!*EnableStackPtrs[state]) {
glEnable(EnableEnums[state]);
*EnableStackPtrs[state] = true;
}
}
This works and all inlines collapse into tight code so that's good so far. Problem is I haven't been able to work out satisfactory solution to that second requirement: error generation at compile-time when 'wrong' GLenum is used. Either A) error happens runtime or B) error happens ALWAYS at compile-time. I just can't get it to work _only_ when that invalid enum is used.
Part of the problem is that constant value given as argument to function is not an constant expression anymore inside the function. If it was I could fex. use template specialization instead to do the mapping and errors would be automatically caught:
template<GLenum> struct MapEnum {};
template<> struct MapEnum<GL_ALPHA_TEST> { enum { value = DEPTH_TEST }; };
..
template<> struct MapEnum<GL_VERTEX_ARRAY> { enum { value = VERTEX_ARRAY }; };
inline void Enable(GLenum glenum) {
const EnableState state = MapEnum<glenum>::value;
..
}
I could give up and just throw error at runtime, but that feels somehow wrong. I hope there might be an easy solution and it's just my ignorance of this cursed
run/compile time boundary thing that's confusing me. I would appreciate any comments or ideas here.