WPILibC++ 2023.4.3-108-ge5452e3
formatter.h
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#pragma once
6
7#include <fmt/format.h>
8
9#include "units/base.h"
10
11/**
12 * Formatter for unit types.
13 *
14 * @tparam Units Unit tag for which type of units the `unit_t` represents (e.g.
15 * meters).
16 * @tparam T Underlying type of the storage. Defaults to double.
17 * @tparam NonLinearScale Optional scale class for the units. Defaults to linear
18 * (i.e. does not scale the unit value). Examples of
19 * non-linear scales could be logarithmic, decibel, or
20 * richter scales. Non-linear scales must adhere to the
21 * non-linear-scale concept.
22 */
23template <class Units, typename T, template <typename> class NonLinearScale>
24struct fmt::formatter<units::unit_t<Units, T, NonLinearScale>>
25 : fmt::formatter<double> {
26 /**
27 * Writes out a formatted unit.
28 *
29 * @param obj Unit instance.
30 * @param ctx Format string context.
31 */
33 fmt::format_context& ctx) const {
34 using BaseUnits =
36 typename units::traits::unit_traits<Units>::base_unit_type>;
37
38 auto out = ctx.out();
39
41 units::convert<Units, BaseUnits>(obj()), ctx);
42
43 if constexpr (units::traits::unit_traits<
44 Units>::base_unit_type::meter_ratio::num != 0) {
45 out = fmt::format_to(out, " m");
46 }
47 if constexpr (units::traits::unit_traits<
48 Units>::base_unit_type::meter_ratio::num != 0 &&
49 units::traits::unit_traits<
50 Units>::base_unit_type::meter_ratio::num != 1) {
51 out = fmt::format_to(
52 out, "^{}",
53 units::traits::unit_traits<Units>::base_unit_type::meter_ratio::num);
54 }
55 if constexpr (units::traits::unit_traits<
56 Units>::base_unit_type::meter_ratio::den != 1) {
57 out = fmt::format_to(
58 out, "/{}",
59 units::traits::unit_traits<Units>::base_unit_type::meter_ratio::den);
60 }
61
62 if constexpr (units::traits::unit_traits<
63 Units>::base_unit_type::kilogram_ratio::num != 0) {
64 out = fmt::format_to(out, " kg");
65 }
66 if constexpr (units::traits::unit_traits<
67 Units>::base_unit_type::kilogram_ratio::num != 0 &&
68 units::traits::unit_traits<
69 Units>::base_unit_type::kilogram_ratio::num != 1) {
70 out = fmt::format_to(out, "^{}",
71 units::traits::unit_traits<
72 Units>::base_unit_type::kilogram_ratio::num);
73 }
74 if constexpr (units::traits::unit_traits<
75 Units>::base_unit_type::kilogram_ratio::den != 1) {
76 out = fmt::format_to(out, "/{}",
77 units::traits::unit_traits<
78 Units>::base_unit_type::kilogram_ratio::den);
79 }
80
81 if constexpr (units::traits::unit_traits<
82 Units>::base_unit_type::second_ratio::num != 0) {
83 out = fmt::format_to(out, " s");
84 }
85 if constexpr (units::traits::unit_traits<
86 Units>::base_unit_type::second_ratio::num != 0 &&
87 units::traits::unit_traits<
88 Units>::base_unit_type::second_ratio::num != 1) {
89 out = fmt::format_to(
90 out, "^{}",
91 units::traits::unit_traits<Units>::base_unit_type::second_ratio::num);
92 }
93 if constexpr (units::traits::unit_traits<
94 Units>::base_unit_type::second_ratio::den != 1) {
95 out = fmt::format_to(
96 out, "/{}",
97 units::traits::unit_traits<Units>::base_unit_type::second_ratio::den);
98 }
99
100 if constexpr (units::traits::unit_traits<
101 Units>::base_unit_type::ampere_ratio::num != 0) {
102 out = fmt::format_to(out, " A");
103 }
104 if constexpr (units::traits::unit_traits<
105 Units>::base_unit_type::ampere_ratio::num != 0 &&
106 units::traits::unit_traits<
107 Units>::base_unit_type::ampere_ratio::num != 1) {
108 out = fmt::format_to(
109 out, "^{}",
110 units::traits::unit_traits<Units>::base_unit_type::ampere_ratio::num);
111 }
112 if constexpr (units::traits::unit_traits<
113 Units>::base_unit_type::ampere_ratio::den != 1) {
114 out = fmt::format_to(
115 out, "/{}",
116 units::traits::unit_traits<Units>::base_unit_type::ampere_ratio::den);
117 }
118
119 if constexpr (units::traits::unit_traits<
120 Units>::base_unit_type::kelvin_ratio::num != 0) {
121 out = fmt::format_to(out, " K");
122 }
123 if constexpr (units::traits::unit_traits<
124 Units>::base_unit_type::kelvin_ratio::num != 0 &&
125 units::traits::unit_traits<
126 Units>::base_unit_type::kelvin_ratio::num != 1) {
127 out = fmt::format_to(
128 out, "^{}",
129 units::traits::unit_traits<Units>::base_unit_type::kelvin_ratio::num);
130 }
131 if constexpr (units::traits::unit_traits<
132 Units>::base_unit_type::kelvin_ratio::den != 1) {
133 out = fmt::format_to(
134 out, "/{}",
135 units::traits::unit_traits<Units>::base_unit_type::kelvin_ratio::den);
136 }
137
138 if constexpr (units::traits::unit_traits<
139 Units>::base_unit_type::mole_ratio::num != 0) {
140 out = fmt::format_to(out, " mol");
141 }
142 if constexpr (units::traits::unit_traits<
143 Units>::base_unit_type::mole_ratio::num != 0 &&
144 units::traits::unit_traits<
145 Units>::base_unit_type::mole_ratio::num != 1) {
146 out = fmt::format_to(
147 out, "^{}",
148 units::traits::unit_traits<Units>::base_unit_type::mole_ratio::num);
149 }
150 if constexpr (units::traits::unit_traits<
151 Units>::base_unit_type::mole_ratio::den != 1) {
152 out = fmt::format_to(
153 out, "/{}",
154 units::traits::unit_traits<Units>::base_unit_type::mole_ratio::den);
155 }
156
157 if constexpr (units::traits::unit_traits<
158 Units>::base_unit_type::candela_ratio::num != 0) {
159 out = fmt::format_to(out, " cd");
160 }
161 if constexpr (units::traits::unit_traits<
162 Units>::base_unit_type::candela_ratio::num != 0 &&
163 units::traits::unit_traits<
164 Units>::base_unit_type::candela_ratio::num != 1) {
165 out = fmt::format_to(out, "^{}",
166 units::traits::unit_traits<
167 Units>::base_unit_type::candela_ratio::num);
168 }
169 if constexpr (units::traits::unit_traits<
170 Units>::base_unit_type::candela_ratio::den != 1) {
171 out = fmt::format_to(out, "/{}",
172 units::traits::unit_traits<
173 Units>::base_unit_type::candela_ratio::den);
174 }
175
176 if constexpr (units::traits::unit_traits<
177 Units>::base_unit_type::radian_ratio::num != 0) {
178 out = fmt::format_to(out, " rad");
179 }
180 if constexpr (units::traits::unit_traits<
181 Units>::base_unit_type::radian_ratio::num != 0 &&
182 units::traits::unit_traits<
183 Units>::base_unit_type::radian_ratio::num != 1) {
184 out = fmt::format_to(
185 out, "^{}",
186 units::traits::unit_traits<Units>::base_unit_type::radian_ratio::num);
187 }
188 if constexpr (units::traits::unit_traits<
189 Units>::base_unit_type::radian_ratio::den != 1) {
190 out = fmt::format_to(
191 out, "/{}",
192 units::traits::unit_traits<Units>::base_unit_type::radian_ratio::den);
193 }
194
195 if constexpr (units::traits::unit_traits<
196 Units>::base_unit_type::byte_ratio::num != 0) {
197 out = fmt::format_to(out, " b");
198 }
199 if constexpr (units::traits::unit_traits<
200 Units>::base_unit_type::byte_ratio::num != 0 &&
201 units::traits::unit_traits<
202 Units>::base_unit_type::byte_ratio::num != 1) {
203 out = fmt::format_to(
204 out, "^{}",
205 units::traits::unit_traits<Units>::base_unit_type::byte_ratio::num);
206 }
207 if constexpr (units::traits::unit_traits<
208 Units>::base_unit_type::byte_ratio::den != 1) {
209 out = fmt::format_to(
210 out, "/{}",
211 units::traits::unit_traits<Units>::base_unit_type::byte_ratio::den);
212 }
213
214 return out;
215 }
216};
Container for values which represent quantities of a given unit.
Definition: base.h:1937
buffer_context< char > format_context
Definition: core.h:1851
Unit Conversion Library namespace.
Definition: magnetic_flux.h:31
auto format(const units::unit_t< Units, T, NonLinearScale > &obj, fmt::format_context &ctx) const
Writes out a formatted unit.
Definition: formatter.h:32
Type representing an arbitrary unit.
Definition: base.h:895
auto format(wformat_string< T... > fmt, T &&... args) -> std::wstring
Definition: xchar.h:87
auto format_to(OutputIt out, const S &fmt, Args &&... args) -> OutputIt
Definition: xchar.h:136