top of page
  • Writer's pictureEngineer Luna

C++ STL Reflected Enums – The Cursed Edition

How did we end up here?


Several years ago, as I was building my own game engine to hone my skills, I felt the need to incorporate string reflection within enums. I was operating with C++ 11 and made the conscious decision to stick solely to the standard library and DirectX 11, avoiding any other external support libraries.


The end result of this journey ended up looking something like this:


So how was this achieved?


In our implementation, we harnessed the power of C++11's constant expressions to achieve our objective. Essentially, we processed the variadic macro __VA_ARGS__, segmenting the string into its constituent parts. By analysing and counting these fragments, we were able to dynamically generate a string list entirely at compile-time. Once this list was assembled, we embedded it into a dedicated support structure.


This structure contained a constexpr string array, ensuring that the data remained constant and was optimized at compile-time.


The foundational macro that underpins the REnum() function is structured as follows:

The most bewitched line of code I've ever penned in my professional journey is static constexpr auto, and it will haunt me forever.


Before we delve deeper, there are some pressing matters to address. Firstly, what exactly is a CEXPArray? How does ProcessEnumStrings operate? And lastly, the nature and functionality of GetTokenCount. Let's initiate our discussion with the last topic.


GetTokenCount

The functionality of this function mirrors that of the STL's GetTokenCount. The distinction, however, lies in its support for constexpr, as it operates on std::basic_string_view<char>. Abiding by the stipulations of constexpr, every function nested within a constexpr function must also carry the constexpr qualifier. As a result, I found myself needing to reimplement several fundamental STL functions to ensure they were constexpr compliant.


ProcessEnumStrings


This auxiliary function is supplied to CEXPArray. Its design permits the acceptance of any function type, enabling diverse data processing methods, as we'll explore further below.

CEXPArray


CreateEnumArray returns a TCEXPArray<> this is a helper function for passing in a void function pointer, and is set to use std::basic_string_View<char>. There are two of these functions but we mostly use the first one.



Now we can have a look at the meat and bones of the Template CEXPArray structure.


We're presented with a foundational structure that possesses two constructors and a pair of operator overloads for accessing its private data. While this structure could be further elaborated upon, it primarily served as a prototype in its current state.


This was all a bit of chaos, but honestly this was a fun learning experience.

30 views0 comments
bottom of page