Preprocessor ? This actually sounds like a challenge. Wonder if Boost.Preprocessor is compatible with C but I don't see any reason why it should not. Warning, I won't bother with the includes or the 'wrap-line' marks ;)
// The formatting of sprintf
#define PRINT_FORMAT_ELEM(z,n,data) // data is the nbColumns (or -1)
BOOST_PP_EXPR_IF(
BOOST_PP_EQUAL(
BOOST_PP_ADD(n, 1),
data
),
"%%.%%df\n",
"%%.%%df "
)
#define PRINT_FORMAT_LINE(z,n,data) // data is (nbRows, nbColumns)
BOOST_PP_REPEAT(
data,
PRINT_FORMAT_ELEM,
BOOST_PP_EXPR_IF(
BOOST_PP_EQUAL(
BOOST_PP_ADD(n, 1),
BOOST_PP_TUPLE_ELEM(2,0,data)
),
-1, // no \n on the last line
BOOST_PP_TUPLE_ELEM(2,1,data)
)
)
#define PRINT_FORMAT(nbRows, nbColumns)
BOOST_PP_REPEAT(
nbRows,
PRINT_FORMAT_LINE,
(nbRows, nbColumns)
)
// The decimals
#define PRINT_MATRIX_ELEM(z,n,data) // data is (decimals, notLastRow, nbColumns)
BOOST_PP_ELEM(3, 0, data)
BOOST_PP_COMMA_IF(
BOOST_PP_AND(
BOOST_PP_TUPLE_ELEM(3, 1, data),
BOOST_PP_NOT_EQUAL(
BOOST_PP_ADD(n,1),
BOOST_PP_TUPLE_ELEM(3, 2, data)
)
)
)
#define PRINT_DECIMAL_LINE(z, n, data) // data is (decimals, nbRows, nbColumns)
BOOST_PP_REPEAT(
BOOST_PP_TUPLE_ELEM(3, 2, data),
PRINT_MATRIX_ELEM,
(
BOOST_PP_TUPLE_ELEM(3, 0, data),
BOOST_PP_NOT_EQUAL(
BOOST_PP_ADD(n,1),
BOOST_PP_TUPLE_ELEM(3, 1, data)
),
BOOST_PP_TUPLE_ELEM(3, 2, data)
)
)
#define PRINT_DECIMALS(decimals, nbRows, nbColumns)
BOOST_PP_REPEAT(
nbRows,
PRINT_DECIMAL_LINE,
(decimals, nbRows, nbColumns)
)
// The matrix itself
#define PRINT_MATRIX_LINE(z, n, data) // data is (name, nbRows, nbColumns)
BOOST_PP_REPEAT(
BOOST_PP_TUPLE_ELEM(3, 2, data),
PRINT_MATRIX_ELEM,
(
BOOST_PP_TUPLE_ELEM(3, 0, data)[n],
BOOST_PP_NOT_EQUAL(
BOOST_PP_ADD(n,1),
BOOST_PP_TUPLE_ELEM(3, 1, data)
),
BOOST_PP_TUPLE_ELEM(3, 2, data)
)
)
#define PRINT_MATRIX_IMPL(name, nbRows, nbColumns)
BOOST_PP_REPEAT(
nbRows,
PRINT_MATRIX_LINE,
(name, nbRows, nbColumns)
)
// And the whole thing
#define PRINT_MATRIX(string, decimals, name, nbRows, nbColumns)
sprintf(string,
PRINT_FORMAT(nbRows, nbColumns),
PRINT_DECIMALS(decimals, nbRows, nbColumns)
);
printf(string,
PRINT_MATRIX_IMPL(name, nbRows, nbColumns)
)
// And now your code:
void print(int decimals)
{
char fmtString[300];
PRINT_MATRIX(fmtString, decimals, m, 4, 4);
}
Anyone helps with the code review ;) ?