Commits

Martin Felis committed dee4553

added compile time assertions to SimpleMath

Comments (0)

Files changed (2)

src/SimpleMathFixed.h

 #include <cstdlib>
 #include <assert.h>
 
+#include "compileassert.h"
+
 /** \brief Namespace for a highly inefficient math library
  *
  */
  * desired information.
  *
  */
-template <typename val_type, unsigned int BlockRows, unsigned int BlockCols>
+template <typename val_type, unsigned int block_rows, unsigned int block_cols>
 class Block {
 	public:
 	Block () :
-		nrows(BlockRows),
-		ncols(BlockCols),
 		parent_nrows(0),
 		parent_ncols(0),
 		parent_row_index(0),
 		parent(NULL)
 	{ }
 	Block (const Block& other) :
-		nrows(BlockRows),
-		ncols(BlockCols),
 		parent_nrows(other.parent_nrows),
 		parent_ncols(other.parent_ncols),
 		parent_row_index(other.parent_row_index),
 			unsigned int parent_row_start,
 			unsigned int parent_col_start,
 			unsigned int parent_num_rows,
-			unsigned int parent_num_cols) :
-		nrows(BlockRows),
-		ncols(BlockCols)
+			unsigned int parent_num_cols)
 	{
 		parent = parent_data;
 		parent_row_index = parent_row_start;
 	Block& operator=(const Block& other) {
 		if (this != &other) {
 			// copy the data, but we have to ensure, that the sizes match!
-			assert (nrows == other.nrows);
-			assert (ncols == other.ncols);
 
 			unsigned int i, j;
-			for (i = 0; i < nrows; i++) {
-				for (j = 0; j < ncols; j++) {
+			for (i = 0; i < block_rows; i++) {
+				for (j = 0; j < block_cols; j++) {
 					this->operator()(i,j) = other(i,j);
 				}
 			}
 	Block& operator=(const Matrix<val_type, other_rows, other_cols>& data_in) {
 		assert (parent != NULL);
 		// copy the data, but we have to ensure, that the sizes match!
-		assert (nrows == other_rows);
-		assert (ncols == other_cols);
+		COMPILE_ASSERT (block_rows == other_rows);
+		COMPILE_ASSERT (block_cols == other_cols);
 
 		if (!transposed) {
-			for (unsigned int i = 0; i < nrows; i++) {
-				for (unsigned int j = 0; j < ncols; j++) {
+			for (unsigned int i = 0; i < block_rows; i++) {
+				for (unsigned int j = 0; j < block_cols; j++) {
 					parent[parent_nrows * (i + parent_row_index) + j + parent_col_index] = data_in(i,j);
 				}
 			}
 		} else {
-			for (unsigned int i = 0; i < nrows; i++) {
-				for (unsigned int j = 0; j < ncols; j++) {
+			for (unsigned int i = 0; i < block_rows; i++) {
+				for (unsigned int j = 0; j < block_cols; j++) {
 					parent[parent_nrows * (j + parent_row_index) + i + parent_col_index] = data_in(i,j);
 				}
 			}
 
 	const val_type& operator() (const unsigned int i, const unsigned int j) const {
 		assert (parent != NULL);
-		assert (i < nrows);
-		assert (j < ncols);
+		assert (i < block_rows);
+		assert (j < block_cols);
 
 		if (!transposed)
 			return parent[parent_nrows * (i + parent_row_index) + j + parent_col_index];
 
 	val_type& operator() (const unsigned int i, const unsigned int j) {
 		assert (parent != NULL);
-		assert (i < nrows);
-		assert (j < ncols);
+		assert (i < block_rows);
+		assert (j < block_cols);
 
 		if (!transposed)
 			return parent[parent_nrows * (i + parent_row_index) + j + parent_col_index];
 	operator Matrix<val_type, other_rows, other_cols>() {
 
 		if (!transposed) {
-			assert (nrows == other_rows);
-			assert (ncols == other_cols);
+			assert (block_rows == other_rows);
+			assert (block_cols == other_cols);
 
 			Matrix<val_type, other_rows, other_cols> result;
-			for (unsigned int i = 0; i < nrows; i++) 
-				for (unsigned int j = 0; j < ncols; j++)
+			for (unsigned int i = 0; i < block_rows; i++) 
+				for (unsigned int j = 0; j < block_cols; j++)
 					result(i,j) = parent[parent_nrows * (i + parent_row_index) + j + parent_col_index];
 
 			return result;
 		} 
 
-		assert (nrows == other_cols);
-		assert (ncols == other_rows);
+		assert (block_rows == other_cols);
+		assert (block_cols == other_rows);
 
 		Matrix<val_type, other_rows, other_cols> result;
-		for (unsigned int i = 0; i < nrows; i++) 
-			for (unsigned int j = 0; j < ncols; j++)
+		for (unsigned int i = 0; i < block_rows; i++) 
+			for (unsigned int j = 0; j < block_cols; j++)
 				result(j,i) = parent[parent_nrows * (i + parent_row_index) + j + parent_col_index];
 
 		return result;
 	}
 
-	unsigned int nrows;
-	unsigned int ncols;
 	unsigned int parent_nrows;
 	unsigned int parent_ncols;
 	unsigned int parent_row_index;
 		void set(
 				const val_type &v00, const val_type &v01, const val_type &v02
 				) {
-			assert (rows * cols == 3);
+			COMPILE_ASSERT (nrows * ncols == 3);
 
 			mData[0] = v00;
 			mData[1] = v01;
 				const val_type &v10, const val_type &v11, const val_type &v12,
 				const val_type &v20, const val_type &v21, const val_type &v22
 				) {
-			assert (nrows == 3);
-			assert (ncols == 3);
+			COMPILE_ASSERT (nrows == 3);
+			COMPILE_ASSERT (ncols == 3);
 
 			mData[0] = v00;
 			mData[1] = v01;
 				const val_type v10, const val_type v11, const val_type v12,
 				const val_type v20, const val_type v21, const val_type v22
 				) {
-			assert (rows == 3);
-			assert (cols == 3);
+			COMPILE_ASSERT (nrows == 3);
+			COMPILE_ASSERT (ncols == 3);
 
 			mData[0] = v00;
 			mData[1] = v01;
 				const val_type &v00, const val_type &v01, const val_type &v02,
 				const val_type &v03, const val_type &v04, const val_type &v05
 				) {
-			assert (nrows == 6);
-			assert (ncols == 1);
+			COMPILE_ASSERT (nrows == 6);
+			COMPILE_ASSERT (ncols == 1);
 
 			mData[0] = v00;
 			mData[1] = v01;
 				const val_type &v00, const val_type &v01, const val_type &v02,
 				const val_type &v03, const val_type &v04, const val_type &v05
 				) {
-			assert (nrows * ncols == 6);
+			COMPILE_ASSERT (nrows * ncols == 6);
 
 			mData[0] = v00;
 			mData[1] = v01;
 				const val_type &v50, const val_type &v51, const val_type &v52,
 				const val_type &v53, const val_type &v54, const val_type &v55
 				) {
-			assert (nrows == 6);
-			assert (ncols == 6);
+			COMPILE_ASSERT (nrows == 6);
+			COMPILE_ASSERT (ncols == 6);
 
 			mData[0] = v00;
 			mData[1] = v01;
 				const val_type v50, const val_type v51, const val_type v52,
 				const val_type v53, const val_type v54, const val_type v55
 				) {
-			assert (nrows == 6);
-			assert (ncols == 6);
+			COMPILE_ASSERT (nrows == 6);
+			COMPILE_ASSERT (ncols == 6);
 
 			mData[0] = v00;
 			mData[1] = v01;
 			return false;
 		}
 
-
 		// access operators
 		const double& operator[](const unsigned int &index) const {
 			assert (index	>= 0 && index < nrows * ncols);
 		}
 
 		Matrix<val_type, 3, 1> cross(const Matrix<val_type, 3, 1> &other_vector) {
-			assert (nrows * ncols == 3);
+			COMPILE_ASSERT (nrows * ncols == 3);
 
 			Matrix<val_type, 3, 1> result;
 			result[0] = mData[1] * other_vector[2] - mData[2] * other_vector[1];
 		}
 
 		void identity() {
-			assert (ncols == nrows);
+			COMPILE_ASSERT (nrows == ncols);
 
 			zero();
 			for (unsigned int i = 0; i < ncols; i++)
 		}
 
 		val_type squaredNorm() const {
-			assert (ncols == 1 || nrows == 1);
+			COMPILE_ASSERT (ncols == 1 || nrows == 1);
 			val_type result = 0;
 
 			for (unsigned int i = 0; i < nrows * ncols; i++)
 		}
 
 		val_type dot(const matrix_type &matrix) const {
-			assert (ncols == 1 || nrows == 1);
+			COMPILE_ASSERT (ncols == 1 || nrows == 1);
 			val_type result = 0;
 
 			for (unsigned int i = 0; i < nrows * ncols; i++)
 		// Block accessing functions
 		template <unsigned int blockrows, unsigned int blockcols>
 		Block<val_type, blockrows, blockcols> block (unsigned int i, unsigned int j) const {
+			COMPILE_ASSERT (nrows > blockrows);
+			COMPILE_ASSERT (ncols > blockcols);
 			return Block<val_type, blockrows, blockcols> (const_cast<double*> (this->mData), i, j, nrows, ncols);
 		}
 
 
 		template <unsigned int other_rows, unsigned int other_cols>
 		Matrix<val_type, nrows, other_cols> operator*(const Matrix<val_type, other_rows, other_cols> &matrix) {
-			assert (ncols == matrix.rows());
+			COMPILE_ASSERT (ncols == other_rows);
 
 			Matrix<val_type, nrows, other_cols> result;
 			
 		}
 
 		operator val_type() {
-			assert (nrows == 1u);
-			assert (ncols == 1u);
+			COMPILE_ASSERT (nrows == 1);
+			COMPILE_ASSERT (nrows == 1);
 
 			return mData[0];
 		}

src/compileassert.h

+#ifndef _COMPILE_ASSERT_H
+#define _COMPILE_ASSERT_H
+
+/* 
+ * This is a simple compile time assertion tool taken from:
+ *   http://blogs.msdn.com/b/abhinaba/archive/2008/10/27/c-c-compile-time-asserts.aspx
+ * written by Abhinaba Basu!
+ *
+ * Thanks!
+ */
+
+#ifdef __cplusplus
+
+#define JOIN( X, Y ) JOIN2(X,Y)
+#define JOIN2( X, Y ) X##Y
+
+namespace static_assert
+{
+    template <bool> struct STATIC_ASSERT_FAILURE;
+    template <> struct STATIC_ASSERT_FAILURE<true> { enum { value = 1 }; };
+
+    template<int x> struct static_assert_test{};
+}
+
+#define COMPILE_ASSERT(x) \
+    typedef ::static_assert::static_assert_test<\
+        sizeof(::static_assert::STATIC_ASSERT_FAILURE< (bool)( x ) >)>\
+            JOIN(_static_assert_typedef, __LINE__)
+
+#else // __cplusplus
+
+#define COMPILE_ASSERT(x) extern int __dummy[(int)x]
+
+#endif // __cplusplus
+
+#define VERIFY_EXPLICIT_CAST(from, to) COMPILE_ASSERT(sizeof(from) == sizeof(to)) 
+
+// _COMPILE_ASSERT_H_
+#endif