解决此类问题的 C 方法可能是使用宏和脚本来简化所有可能性的生成。但是,我们使用 C++ 进行编码,所以让我们用模板替换宏。毕竟,这些都是基本类型的宏。
所以我的想法是将你的类型分解为更基本的类型,并使用模板来构造它们。
enum {
RECTANGULAR,
SYMMETRIC,
} DimKind;
enum {
DENSE,
PARSE
} Density;
enum {
STD_ARRAY,
STD_VECTOR
} ContainerType;
enum {
FLOAT,
DOUBLE
} CoordType;
template <CoordType CT>
struct coord_def {
};
struct coord_def<FLOAT>{
typedef float type;
};
struct coord_def<DOUBLE> {
typedef double type;
};
template <ContainerType Cont, CoordType Coord, int Dimension>
struct container_def {
};
template <CoordType Coord, int Dim>
struct container_def<STD_ARRAY, Coord, Dim> {
typedef std::array<Coord,Dim> type;
static const int dim = Dim;
// add any other helper function needed to build the test case for that particular
// container
};
template <CoordType Coord, int Dim>
struct container_def<STD_VECTOR, Coord, Dim> {
typedef std::vector<Coord> type;
static const int dim = Dim;
};
template <Density D, DimKind DK, ContainerType Cont,
CoordType Coord, int XDim, int YDim>
struct TestMatrix {
};
// here specialize the above according to the parameters
// you may need to include helper function to build an instance using the template
// parameters (dimension comesto mind)
然后,您必须定义要测试的操作类型。它们当然可以归类为带分量的矩阵、带向量的矩阵、带矩阵的矩阵。
enum {
// matrix ops list
} MatrixOp;
template <MatrixOp Op, typename M1, typename M2, typename Ret>
Ret binary_op(M1 m1, M2 m2);
// overload for specific functions
template <MatrixOp Op,
ContainerType Cont1, ContainerType Cont2
CoordType Coord1, CoordType Coord2,
int XDim1, int YDim1, int XDim2, int YDim2,
Denstity D1, Density D2,
DimKind K1, DimKind K2>
struct test_op {
typedef TestMatrix<...>::type M1;
typedef TestMatrix<...>::type M2;
void test(M1 m1, M2 m2){
binary_op<MatrixOp,M1,M2>(m1, m2);
}
};
接下来,您的矩阵之间肯定存在代数关系,您可以将其编码为模板,并用于您的测试。
例如,DenseSymmetricMatrix
模板的参数似乎指定了一个静态大小的容器类型,对于这样一个 *n 矩阵,数组的维度必须是 n * (n+1) / 2。DenseRectangularMatrix
另一方面,它的维度似乎定义为运行。但是由于您具有上述维度的关系,您可以轻松地将两个测试用例编写为模板:一个构建两个维度匹配的矩阵,另一个构建维度不匹配的矩阵。
最后一步是所有可能性的产生。一个简单的脚本遍历所有枚举值应该有助于生成所有可能的测试。
我相信您也可以使用现有的单元测试框架(如 boost 框架)和这些模板来构建您的测试。