Dandelion 2.0.0
A light-weight 3D builder for educational usage
载入中...
搜索中...
未找到
formatter.hpp
浏览该文件的文档.
1#ifndef DANDELION_UTILS_FORMATTER_HPP
2#define DANDELION_UTILS_FORMATTER_HPP
3
4#include <format>
5
6#include <Eigen/Core>
7
8/*!
9 * \file utils/formatter.hpp
10 * \ingroup utils
11 * \~chinese
12 * \brief 提供对 Eigen 列向量和方阵类型的格式化支持。
13 */
14
15/*!
16 * \~chinese
17 * \brief 提供对 Eigen 列向量类型的格式化支持。
18 *
19 * 这个格式化器调用 `Scalar` 类型的格式化器来格式化每个分量,
20 * 并在各分量之间添加逗号、空格,在开头和结尾添加括号。由于它直接调用 `Scalar`
21 * 类型的格式化器格式化分量,任何可用于 `Scalar` 类型的格式符也都可用于格式化列向量。
22 * 相应地,`Scalar` 类型必须可以被格式化。
23 *
24 * 格式符:与分量类型的格式符相同,例如 `Vector3f` 可以使用所有 `float`
25 * 类型的格式符,`Vector2i` 可以使用所有 `int` 类型的格式符。
26 *
27 * \tparam Scalar 向量中分量的类型
28 * \tparam n_dim 向量维数
29 */
30template<typename Scalar, int n_dim>
31struct std::formatter<Eigen::Matrix<Scalar, n_dim, 1>> : std::formatter<Scalar>
32{
33 static_assert(n_dim > 0, "Dimension of a vector must be positive");
34
35 std::format_context::iterator
36 format(const Eigen::Matrix<Scalar, n_dim, 1>& v, format_context& ctx) const
37 {
38 std::format_context::iterator iter = std::format_to(ctx.out(), "(");
39 iter = std::formatter<Scalar>::format(v(0), ctx);
40 for (int i = 1; i < n_dim; ++i) {
41 iter = std::format_to(iter, ", ");
42 iter = std::formatter<Scalar>::format(v(i), ctx);
43 }
44 iter = std::format_to(iter, ")");
45 return iter;
46 }
47};
48
49/*!
50 * \~chinese
51 * \brief 提供对 Eigen 方阵类型的格式化支持。
52 *
53 * 这个格式化器调用 `Scalar` 类型的格式化器来格式化每个元素,
54 * 并在同一行的各元素间添加空格,在行间添加换行符。由于它直接调用 `Scalar`
55 * 类型的格式化器来格式化元素,任何可用于 `Scalar` 类型的格式符也都可用于格式化方阵。
56 * 相应地,`Scalar` 类型必须可以被格式化。
57 *
58 * 格式符:与元素类型的格式符相同,例如 `Matrix4f` 可以使用所有 `float`
59 * 类型的格式符,`Matrix3d` 可以使用所有 `double` 类型的格式符。
60 *
61 * 请注意,方阵的最后一行不会添加换行符,如果使用 `std::printf` /
62 * `std::cout` 等工具直接输出时,请自行添加换行。使用 spdlog 的日志输出则不必。
63 *
64 * 当矩阵中的元素位数不一时(例如 10 和 0),默认的格式符 `{}` 并不会对齐它们。
65 * 如果使用者希望将数字右对齐,请直接使用 std::format 的右对齐格式,例如:
66 * ```cpp
67 * Eigen::Matrix4f m = 10.0f * Eigen::Matrix4f::Identity();
68 * std::cout << std::format("matrix: {:>5.1f}", m);
69 * ```
70 * 会输出
71 * ```
72 * matrix:
73 * 10.0 0.0 0.0 0.0
74 * 0.0 10.0 0.0 0.0
75 * 0.0 0.0 10.0 0.0
76 * 0.0 0.0 0.0 10.0
77 * ```
78 *
79 * \tparam Scalar 方阵中的元素类型
80 * \tparam n_dim 方阵的维数
81 */
82template<typename Scalar, int n_dim>
83struct std::formatter<Eigen::Matrix<Scalar, n_dim, n_dim, 0, n_dim, n_dim>> : std::formatter<Scalar>
84{
85 static_assert(n_dim > 0, "Dimension of a square matrix must be positive");
86
87 std::format_context::iterator
88 format(const Eigen::Matrix<Scalar, n_dim, n_dim, 0, n_dim, n_dim>& m, format_context& ctx) const
89 {
90 std::format_context::iterator iter = std::format_to(ctx.out(), "\n");
91 for (int row = 0; row < n_dim - 1; ++row) {
92 for (int column = 0; column < n_dim; ++column) {
93 iter = std::formatter<Scalar>::format(m(row, column), ctx);
94 iter = std::format_to(iter, " ");
95 }
96 iter = std::format_to(iter, "\n");
97 }
98 for (int column = 0; column < n_dim; ++column) {
99 iter = std::formatter<Scalar>::format(m(n_dim - 1, column), ctx);
100 iter = std::format_to(iter, " ");
101 }
102 return iter;
103 }
104};
105
106#endif // DANDELION_UTILS_FORMATTER_HPP