Tags technique

Suppose you’ll need to write some class mat4, that represent transformation 4×4 matrix. This matrix is widely used in graphics. The first question that you need to address as developer is “what default constructor of mat4 should look like?” Well, of course, you can set all elements of matrix to zero. But this kind of matrix is not usable in graphics application. The more common matrix is identity matrix. On the other hand, you want to aware of unnecessary initialization of matrix. Here is the technique that help us to solve all these designing questions.
Let’s introduce some tags
in *.h file:

struct mat4_identity{ static mat4_identity tag; };
struct mat4_zero{ static mat4_zero tag; };
struct mat4_unitialized{ static mat4_unitialized tag; };
_Winnie C++ Colorizer

in *.cpp file:

mat4_identity mat4_identity::tag;
mat4_zero mat4_zero::tag;
mat4_unitialized mat4_unitialized::tag;
_Winnie C++ Colorizer

And delete our default constructor:

mat4() = delete;
_Winnie C++ Colorizer

Now implement three constructors:

mat4::mat4(mat4_identity)
{
for(size_t i = 0; i < mat4::arity; ++i)
for(size_t j = 0; j < mat4::arity; ++j)
{
data[i][j] = i == j ? scalar(1) : scalar(0);
}
}

mat4::mat4(mat4_zero)
{
for(size_t i = 0; i < mat4::arity; ++i)
for(size_t j = 0; j < mat4::arity; ++j)
data[i][j] = scalar(0);
}

mat4::mat4(mat4_unitialized)
{
//yep, it is your decision
}

_Winnie C++ Colorizer

Now we can perform calculations are very quickly. Without additional overhead to matrix initialization.

mat4 mat4::operator+(const mat4& rhs)
{
mat4 result(mat4_unitialized::tag);

for(size_t i = 0; i < arity; ++i)
for(size_t j = 0; j < arity; ++j)
result.data[i][j] = data[i][j] + rhs.data[i][j];

return result;
}

_Winnie C++ Colorizer
Advertisements