mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-28 02:11:43 +00:00
[wpimath] Generalize Eigen formatter (#5360)
This commit is contained in:
@@ -4,120 +4,45 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "Eigen/Core"
|
||||
#include "Eigen/SparseCore"
|
||||
|
||||
/**
|
||||
* Formatter for Eigen::Matrix<double, Rows, Cols>.
|
||||
*
|
||||
* @tparam Rows Number of rows.
|
||||
* @tparam Cols Number of columns.
|
||||
* @tparam Args Defaulted template arguments to Eigen::Matrix<>.
|
||||
* Formatter for classes derived from Eigen::MatrixBase<Derived> or
|
||||
* Eigen::SparseCompressedBase<Derived>.
|
||||
*/
|
||||
template <int Rows, int Cols, int... Args>
|
||||
struct fmt::formatter<Eigen::Matrix<double, Rows, Cols, Args...>> {
|
||||
/**
|
||||
* Storage for format specifier.
|
||||
*/
|
||||
char presentation = 'f';
|
||||
|
||||
/**
|
||||
* Format string parser.
|
||||
*
|
||||
* @param ctx Format string context.
|
||||
*/
|
||||
template <typename Derived, typename CharT>
|
||||
struct fmt::formatter<
|
||||
Derived, CharT,
|
||||
std::enable_if_t<
|
||||
std::is_base_of_v<Eigen::MatrixBase<Derived>, Derived> ||
|
||||
std::is_base_of_v<Eigen::SparseCompressedBase<Derived>, Derived>,
|
||||
void>> {
|
||||
constexpr auto parse(fmt::format_parse_context& ctx) {
|
||||
auto it = ctx.begin(), end = ctx.end();
|
||||
if (it != end && (*it == 'f' || *it == 'e')) {
|
||||
presentation = *it++;
|
||||
}
|
||||
|
||||
if (it != end && *it != '}') {
|
||||
throw fmt::format_error("invalid format");
|
||||
}
|
||||
|
||||
return it;
|
||||
return m_underlying.parse(ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes out a formatted matrix.
|
||||
*
|
||||
* @tparam FormatContext Format string context type.
|
||||
* @param mat Matrix to format.
|
||||
* @param ctx Format string context.
|
||||
*/
|
||||
template <typename FormatContext>
|
||||
auto format(const Eigen::Matrix<double, Rows, Cols, Args...>& mat,
|
||||
FormatContext& ctx) {
|
||||
auto format(const Derived& mat, fmt::format_context& ctx) const {
|
||||
auto out = ctx.out();
|
||||
for (int i = 0; i < mat.rows(); ++i) {
|
||||
for (int j = 0; j < mat.cols(); ++j) {
|
||||
out = fmt::format_to(out, " {:f}", mat(i, j));
|
||||
|
||||
for (int row = 0; row < mat.rows(); ++row) {
|
||||
for (int col = 0; col < mat.cols(); ++col) {
|
||||
out = fmt::format_to(out, " ");
|
||||
out = m_underlying.format(mat.coeff(row, col), ctx);
|
||||
}
|
||||
|
||||
if (i < mat.rows() - 1) {
|
||||
out = fmt::format_to(out, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Formatter for Eigen::SparseMatrix<double>.
|
||||
*
|
||||
* @tparam Options Union of bit flags controlling the storage scheme.
|
||||
* @tparam StorageIndex The type of the indices.
|
||||
*/
|
||||
template <int Options, typename StorageIndex>
|
||||
struct fmt::formatter<Eigen::SparseMatrix<double, Options, StorageIndex>> {
|
||||
/**
|
||||
* Storage for format specifier.
|
||||
*/
|
||||
char presentation = 'f';
|
||||
|
||||
/**
|
||||
* Format string parser.
|
||||
*
|
||||
* @param ctx Format string context.
|
||||
*/
|
||||
constexpr auto parse(fmt::format_parse_context& ctx) {
|
||||
auto it = ctx.begin(), end = ctx.end();
|
||||
if (it != end && (*it == 'f' || *it == 'e')) {
|
||||
presentation = *it++;
|
||||
}
|
||||
|
||||
if (it != end && *it != '}') {
|
||||
throw fmt::format_error("invalid format");
|
||||
}
|
||||
|
||||
return it;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes out a formatted matrix.
|
||||
*
|
||||
* @tparam FormatContext Format string context type.
|
||||
* @param mat Matrix to format.
|
||||
* @param ctx Format string context.
|
||||
*/
|
||||
template <typename FormatContext>
|
||||
auto format(const Eigen::SparseMatrix<double, Options, StorageIndex>& mat,
|
||||
FormatContext& ctx) {
|
||||
auto out = ctx.out();
|
||||
for (int i = 0; i < mat.rows(); ++i) {
|
||||
for (int j = 0; j < mat.cols(); ++j) {
|
||||
out = fmt::format_to(out, " {:f}", mat.coeff(i, j));
|
||||
}
|
||||
|
||||
if (i < mat.rows() - 1) {
|
||||
if (row < mat.rows() - 1) {
|
||||
out = fmt::format_to(out, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
private:
|
||||
fmt::formatter<typename Derived::Scalar, CharT> m_underlying;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user