Matrix is a templatised utility class with many uses. One of it best features is it takes away the complexity of creating COM arrays (SAFEARRAYS). Matrix was initially designed as a 2D array helper class. It later became far more useful when changed to a template class to store different types. A Matrix object can be treated as if it were a VARIANT data type. Anything that can be stored in a VARIANT, including arrays, can be stored in a Matrix. Anything you previously marshalled between apartment/process/machine boundaries can use Matrix.
I will begin describing Matrix in its simplest form and then progressing to more advanced and useful features.
What Can Be Stored in a Matrix?
In its simplest form, the Matrix can be used like so:
CMatrix<long>
matrixLong ;
matrixLong.cell(1,1)=111 ;
matrixLong.cell(2,2)=222 ;
printf("Contents of cell 1,1 is %d and cell 2,2 is %d",
matrixLong.cell(1,1),
matrixLong.cell(2,2));
This outputs:
Contents of cell 1,1 is 111 and cell 2,2 is 222
Another example uses a user-defined object:
class CMyObject
{
long m_lNumber ;
public:
CMyObject( long l ) { m_lNumber = l; }
long getNumber( )const { return m_lNumber; }
};
CMatrix<CMyObject*> m ;
for ( int i = 0 ; i < 100 ; i++ )
m.cell(i,0)=new CMyObject( i*2 ) ;
long l = m.cell(5,0)->getNumber( );
printf("Contents of cell 5,5 is %d\n", l ) ;
The example above creates a Matrix and fills it with CMyObjects. It then retrieves a cell at position 5,0. This cell contains a .CMyObject* (or whatever else in specified in the template declaration).
What Else Does Matrix Do?
One of the most interesting features of Matrix is it's ability to hide the details of creating and using SAFEARRAYs. The following example creates a two-dimensional array and passes it to a function in a VARIANT form. The function then creates a Matrix from the VARIANT.
void giveMeAVariant(VARIANT v )
{
CMatrix<_variant_t> t(v);
printf("matrix is %d wide & %d high\n", t.width( ),
t.height( ) ) ;
printf("Contents of cell 5,5 is %d", (long)t.cell(5,5) ) ;
}
CMatrix<_variant_t> m;
for ( long i = 0 ; i < 100 ; i++ )
m.cell(i,i)=i;
giveMeAVariant( m ) ;
This outputs:
matrix is 100 wide & 100 high
Contents of cell 5,5 is 5
In this example, we have created a SAFEARRAY packaged in a VARIANT in 3 lines of code. Remember, the function .giveMeAVariant. can be in a different apartment, module, application, or even machine. Hopefully, you can see that this utility class is very useful in hiding the complexities of SAFEARRAYs as well as handling two-dimensional arrays easily.
How Do I Integrate It with My Existing Code?
The complete implementation of Matrix is surprisingly small. It is self-contained within 1 header file (matrix.h). To include the file in your project, ensure the path where you store the file is in your path look-up settings for your project. Then, simply include the header file wherever you want to use a Matrix class. Because it is simply a header file, it will inherit whatever project settings you have specified, such as warning level and UNICODE setting.
With What Compilers/Tools Can I Use It?
Because Matrix is a simple header file, it can (in theory, I haven't tried it) be used with any compiler that supports templates. I have used Matrix on Visual Studio 6 and Visual Studio .Net.
Roundup
There are many features in Matrix that make it a valuable aid in your day-to-day programming. In the near future, I will provide more examples of how to use this powerful class.
Downloads