‹— back

Platform layer with designated array initializers

When writing for a specific API or library, like creating an OpenGL renderer, you're going to write something like this:

When you port your renderer to something like DirectX you end up writing an equivalent function call to match the behaviour of OpenGL. You'll wrap it up in a function call like upload_texture(...). But what about those data types, the pixel format of GL_RGBA8 and data type of GL_UNSIGNED_BYTES? Things the client application wants to set and look at. So you write a nice wrapper:

Then you need to convert between your own layer and the way the API wants it. Something like this?

Functional but gross, you could so easily miss a value! You could use a switch statement with a warning for unhandled cases, but you still need to have a block of code that manually does the conversions.

You get clever (uh-oh), and do something like this.

Great! You call Platform_PixelFormat[pixel_format] and wonderful, everything maps! Except later on someone (probably spiteful future you) reorders the enum. Maybe you've added a second array to reflectively print out a pretty string with the enum value. It all goes wrong. You can assign eRGB = 1 if you think you can trust the ordering of the platform-specific arrays which might work here, but less so when you start dealing with constants you can't easily visually verify like 0x739AF84.

Designated Array Initialisers

Still not a part of the spec but widely supported by extensions (you know, the typical 'why can't we have the nice things from C90 and beyond?` thing ^-^) are designated array initializers, which let us use enum values to map across multiple arrays. We can change our code to this:

Now we can have completely mismatched ordering between any of these types and it won't bite us layer. Two caveats:

  • The enum has to be unscoped (so we dropped the enum class)
  • Same as before, the size of the array will grow to fit the possible enum range. So don't set eRGB = 0x1907 unless you want roomy thousands-long arrays.

Of course then DirectX will hit you with tying its pixel formats and data types end with you writing a conversion wrapper anyway >.< But designated array initialisers will still be there to help you out, and for all of those reflective string cases!