Finished cleaning up the code and added a proper set of unit tests for it (using the CxxTest unit-testing framework). Download glutty_vector-0.91.zip here, or view the latest source online here!
Now to resume my regular programming and put this new class into use!
Update:
I think I have figured out how to safely remove the virtual destructor. The size of the class is purely just the array of elements now. i.e., A 2D vector of 4-byte floats will be exactly 8 bytes in size (assuming no padding). New download is
glutty_vector-0.92.zip.
Thursday, April 2, 2009
Wednesday, April 1, 2009
Glutty Vector - initial version
I finally finished re-doing my multi-dimensional vector class. By dimension, I mean how many elements there are in the vector (i.e. 2 for 2D vectors, 3 for 3D vectors, 4 for quaternions, etc.). It still needs more testing and clean-up, but it's more or less functional. My previous multi-dimensional vector
This new version supports static type-checking for all dimensions, thanks to some template meta-programming trickery (the Curiously Recurring Template Pattern is one of the techniques I use). However, I do pity whoever needs to figure it out. Which will probably be me, long after I have forgotten how it actually works. :(
The main benefit of this class is that it will instantiate the class to have functions only relevant for their dimension. For example a 2D vector will only have
This is done WITHOUT implementing the 2D and 3D (or any dimension really) vectors as two, nearly-identical but separate classes, which is how it is commonly done from what I have seen. My vectors both instantiate from the same set of template classes, so there is less code duplication in that respect. Although it's arguable whether the final result is smaller because of all the template code I had to put in to make it work.
The memory footprint of a vector is just a fixed-size array that is just large enough to hold the values of the vector. So a two-dimensional,
Take a look at
All the source is in my Google Code repository:
http://code.google.com/p/glutinous/source/browse/trunk/glutty_vector/
NVect.h, which I did many years ago, was a bit bloated. I did not care much for performance then so it suited my needs. It relied on run-time checks to catch errors to do with applying higher-dimension operations to vectors with an insufficiently-high dimension - for example, trying to access the Z value from a 2D vector, or performing a cross product with a 2D vector. Its support for variable arguments was implemented in a very weird and wasteful way too. :)
This new version supports static type-checking for all dimensions, thanks to some template meta-programming trickery (the Curiously Recurring Template Pattern is one of the techniques I use). However, I do pity whoever needs to figure it out. Which will probably be me, long after I have forgotten how it actually works. :(
The main benefit of this class is that it will instantiate the class to have functions only relevant for their dimension. For example a 2D vector will only have
getX() and getY() accessor functions. If you try call getZ() on a 2D vector, you will get an error at compile-time. Also, only a 3D vector will have a crossProduct() function. Construction of the vectors are also checked at compile-time: a 2D vector constructor will only accept 2 arguments and a 3D vector will only accept 3 arguments.
This is done WITHOUT implementing the 2D and 3D (or any dimension really) vectors as two, nearly-identical but separate classes, which is how it is commonly done from what I have seen. My vectors both instantiate from the same set of template classes, so there is less code duplication in that respect. Although it's arguable whether the final result is smaller because of all the template code I had to put in to make it work.
The memory footprint of a vector is just a fixed-size array that is just large enough to hold the values of the vector. So a two-dimensional,
float vector would just be an array of two, float elements. There should be no additional memory overheard for storing anything else as far as I can see, except for the presence of a virtual table (I made the destructor virtual) and alignment padding. It might even be possible to do away with the v-table, but the additional code to support that does not seem worth it for me.
Take a look at
main.cpp for an example of how it is used - it is pretty intuitive! Take a look at the header files for implementation details (and the template/meta-programming madness).
All the source is in my Google Code repository:
http://code.google.com/p/glutinous/source/browse/trunk/glutty_vector/
Subscribe to:
Comments (Atom)
