Should I join a union?

10 08 2010

arg, not managing to keep up with every 3 days. I’ll try again. It isn’t that I don’t want to, but I’ve been knee-deep in matrix maths [trying to make sure that the inverse of a generic matrix4 is correct took me 3 A4 pages] it just doesn’t seem like an interesting topic to post about. But then again why not? I won’t post my treatment of the Matrix4 pages since that would surely make anyone reading this [including myself] cross-eyed and probably a bit green in the face, so I’ll post about something else. Unions.

Unions are interesting little beasts. They give us the ability to layout different data in a single memory block [calculated to the largest data member]. Let’s illustrate this with a simple example;
union Data{
  float a;
  int b;

Now we got a memory block the size of a float which can be accessed as either a float or an int [not both at once]. Its a pretty powerful tool which can also be used for some pretty bad things; I won’t detail it here but google up a union cast and you’ll see what I mean.

For a more relevant example imagine the following idea:
union Data{
  float m[4];
  float mm[2][2];

Hey, that sort of looks familiar doesn’t it? That’s because it’s a good candidate for laying out the memory block of a matrix [which is what I’ve done].

The other nice feature about unions is that unlike their C bretherns which are only PODs [Plain Old Data], a C++ union is actually a limited type of class. This means unions also support functions, constructors, etc. What’s the limited aspect of the union? For one, a union can’t be used as a base class, nor is it allowed to have a base class or virtual functions [ie. unions cannot participate in runtime polymorphism, although they do support static, template-based, polymorphism]. And finally, unions can’t have static variables.

I’ve embedded a union [data] member in each of my matrix classes on the public scope, this allows me to control the data layout and access easily from the union class [as well as change it if I want] and gives me the freedom to change the underlying data without worrying too much about clients [ie. Me] needing to interface that data directly.

The code looks similiar to this:
template<size_t R, size_t C, typename T>
union Data{
    T& operator()(size_t i) { return m[i]; }
    T& operator()(size_t r, size_t c) { return mm[r][c]; }
    T m[R*C];
    T mm[R][C];

And the code for the matrix class:
struct M2{
  Data<2,2,float> component;

It’s fairly easy now to simply create more and more matrices [and vectors] of different values and sizes and costumize them to fit my needs. It doesn’t mean it’s the best solution, but it’s one of them and the more we know, the better we can adapt for future requirements.

I’m off, the dishes are done, my coffee is waiting and I’ve got to hook up OpenGL tonight so I can finally show some progress to my [very patient] artist.

“Outside on a winter’s night as a rain begins to fall”




Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: