|
1 | 1 | #pragma once
|
2 | 2 |
|
| 3 | +#include <array> |
3 | 4 | #include <cmath>
|
4 | 5 | #include <ratio>
|
5 | 6 | #include <iostream>
|
| 7 | +#include <utility> |
6 | 8 |
|
7 | 9 | // define M_PI if not already defined
|
8 | 10 | #ifndef M_PI
|
@@ -164,43 +166,34 @@ template <isQuantity Q, typename quotient> using Rooted = Named<
|
164 | 166 | std::ratio_divide<typename Q::angle, quotient>, std::ratio_divide<typename Q::temperature, quotient>,
|
165 | 167 | std::ratio_divide<typename Q::luminosity, quotient>, std::ratio_divide<typename Q::moles, quotient>>>;
|
166 | 168 |
|
| 169 | +inline void unit_printer_helper(std::ostream& os, double quantity, |
| 170 | + const std::array<std::pair<intmax_t, intmax_t>, 8>& dims) { |
| 171 | + static constinit std::array<const char*, 8> prefixes {"_kg", "_m", "_s", "_A", "_rad", "_K", "_cd", "_mol"}; |
| 172 | + os << quantity; |
| 173 | + for (size_t i = 0; i != 8; i++) { |
| 174 | + if (dims[i].first != 0) { |
| 175 | + os << prefixes[i]; |
| 176 | + if (dims[i].first != 1 || dims[i].second != 1) os << '^' << dims[i].first; |
| 177 | + if (dims[i].second != 1) os << '/' << dims[i].second; |
| 178 | + } |
| 179 | + } |
| 180 | +} |
| 181 | + |
167 | 182 | template <isQuantity Q> inline std::ostream& operator<<(std::ostream& os, const Q& quantity) {
|
168 | 183 | if constexpr (!std::is_same_v<Named<Q>, Q>) {
|
169 | 184 | os << Named<Q>(quantity);
|
170 | 185 | } else {
|
171 |
| - os << quantity.internal(); |
172 |
| - if constexpr (Q::mass::num != 0) { |
173 |
| - os << " kg^" << Q::mass::num; |
174 |
| - if constexpr (Q::mass::den != 1) os << "/" << Q::mass::den; |
175 |
| - } |
176 |
| - if constexpr (Q::length::num != 0) { |
177 |
| - os << "*m^" << Q::length::num; |
178 |
| - if constexpr (Q::length::den != 1) os << "/" << Q::length::den; |
179 |
| - } |
180 |
| - if constexpr (Q::time::num != 0) { |
181 |
| - os << "*s^" << Q::time::num; |
182 |
| - if constexpr (Q::time::den != 1) os << "/" << Q::time::den; |
183 |
| - } |
184 |
| - if constexpr (Q::current::num != 0) { |
185 |
| - os << "*A^" << Q::current::num; |
186 |
| - if constexpr (Q::current::den != 1) os << "/" << Q::current::den; |
187 |
| - } |
188 |
| - if constexpr (Q::angle::num != 0) { |
189 |
| - os << "*rad^" << Q::angle::num; |
190 |
| - if constexpr (Q::angle::den != 1) os << "/" << Q::angle::den; |
191 |
| - } |
192 |
| - if constexpr (Q::temperature::num != 0) { |
193 |
| - os << "*K^" << Q::temperature::num; |
194 |
| - if constexpr (Q::temperature::den != 1) os << "/" << Q::temperature::den; |
195 |
| - } |
196 |
| - if constexpr (Q::luminosity::num != 0) { |
197 |
| - os << "*cd^" << Q::luminosity::num; |
198 |
| - if constexpr (Q::luminosity::den != 1) os << "/" << Q::luminosity::den; |
199 |
| - } |
200 |
| - if constexpr (Q::moles::num != 0) { |
201 |
| - os << "*mol^" << Q::moles::num; |
202 |
| - if constexpr (Q::moles::den != 1) os << "/" << Q::moles::den; |
203 |
| - } |
| 186 | + constinit static std::array<std::pair<intmax_t, intmax_t>, 8> dims {{ |
| 187 | + {Q::mass::num, Q::mass::den}, |
| 188 | + {Q::length::num, Q::length::den}, |
| 189 | + {Q::time::num, Q::time::den}, |
| 190 | + {Q::current::num, Q::current::den}, |
| 191 | + {Q::angle::num, Q::angle::den}, |
| 192 | + {Q::temperature::num, Q::temperature::den}, |
| 193 | + {Q::luminosity::num, Q::luminosity::den}, |
| 194 | + {Q::moles::num, Q::moles::den}, |
| 195 | + }}; |
| 196 | + unit_printer_helper(os, quantity.internal(), dims); |
204 | 197 | }
|
205 | 198 | return os;
|
206 | 199 | }
|
|
0 commit comments