Skip to content

Commit 38a709d

Browse files
committed
implement full std::format support
1 parent 1b859ae commit 38a709d

File tree

4 files changed

+73
-19
lines changed

4 files changed

+73
-19
lines changed

include/units/Pose.hpp

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,32 @@ using VelocityPose = AbstractPose<std::ratio<1>>;
7373
// AccelerationPose (Length / Time^2, Angle / Time^2)
7474
using AccelerationPose = AbstractPose<std::ratio<2>>;
7575

76-
} // namespace units
76+
} // namespace units
77+
78+
template <> struct std::formatter<units::Pose, char> : std::formatter<double, char> {
79+
// Parse specifiers (using the base class's parse function)
80+
template <typename ParseContext> constexpr auto parse(ParseContext& ctx) {
81+
// Call parse on the current object (base class subobject)
82+
return std::formatter<double, char>::parse(ctx);
83+
}
84+
85+
// Format the units::Pose object
86+
template <typename FormatContext> auto format(const units::Pose& vector, FormatContext& ctx) const {
87+
auto it = ctx.out();
88+
it = format_to(it, "(");
89+
90+
// Create temporary formatter objects for Length and Angle
91+
std::formatter<Length, char> fmtLength {};
92+
std::formatter<Angle, char> fmtAngle {};
93+
94+
// Use the temporary objects to format each component.
95+
it = fmtLength.format(vector.x, ctx);
96+
it = format_to(it, ", ");
97+
it = fmtLength.format(vector.y, ctx);
98+
it = format_to(it, ", ");
99+
it = fmtAngle.format(vector.orientation, ctx);
100+
it = format_to(it, ")");
101+
102+
return it;
103+
}
104+
};

include/units/Vector2D.hpp

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
#include "units/Angle.hpp"
44

5+
namespace units {
6+
57
/**
68
* @class Vector2D
79
*
@@ -276,12 +278,19 @@ constexpr Vector2D<Q3> operator*(Q1 lhs, const Vector2D<Q2>& rhs) {
276278
*/
277279
template <isQuantity Q> constexpr Vector2D<Q> operator*(double lhs, const Vector2D<Q>& rhs) { return rhs * lhs; }
278280

279-
namespace std {
280-
template <typename T> struct formatter<Vector2D<T>> : formatter<T> {
281+
// define some common vector types
282+
typedef Vector2D<Length> V2Position;
283+
typedef Vector2D<LinearVelocity> V2Velocity;
284+
typedef Vector2D<LinearAcceleration> V2Acceleration;
285+
typedef Vector2D<Force> V2Force;
286+
287+
} // namespace units
288+
289+
template <typename T> struct std::formatter<units::Vector2D<T>> : std::formatter<T> {
281290
// Optionally parse format specifiers for T
282291
constexpr auto parse(auto& ctx) { return formatter<T>::parse(ctx); }
283292

284-
auto format(const Vector2D<T>& vector, format_context& ctx) const {
293+
auto format(const units::Vector2D<T>& vector, format_context& ctx) const {
285294
auto it = ctx.out();
286295
it = format_to(it, "(");
287296

@@ -295,11 +304,4 @@ template <typename T> struct formatter<Vector2D<T>> : formatter<T> {
295304

296305
return it;
297306
}
298-
};
299-
} // namespace std
300-
301-
// define some common vector types
302-
typedef Vector2D<Length> V2Position;
303-
typedef Vector2D<LinearVelocity> V2Velocity;
304-
typedef Vector2D<LinearAcceleration> V2Acceleration;
305-
typedef Vector2D<Force> V2Force;
307+
};

include/units/Vector3D.hpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,4 +351,28 @@ typedef Vector3D<Length> V3Position;
351351
typedef Vector3D<LinearVelocity> V3Velocity;
352352
typedef Vector3D<LinearAcceleration> V3Acceleration;
353353
typedef Vector3D<Force> V3Force;
354-
} // namespace units
354+
} // namespace units
355+
356+
template <typename T> struct std::formatter<units::Vector3D<T>> : std::formatter<T> {
357+
// Optionally parse format specifiers for T
358+
constexpr auto parse(auto& ctx) { return formatter<T>::parse(ctx); }
359+
360+
auto format(const units::Vector3D<T>& vector, format_context& ctx) const {
361+
auto it = ctx.out();
362+
it = format_to(it, "(");
363+
364+
// Format vector.x using the base formatter<T>
365+
it = static_cast<const formatter<T>*>(this)->format(vector.x, ctx);
366+
it = format_to(it, ", ");
367+
368+
// Format vector.y using the base formatter<T>
369+
it = static_cast<const formatter<T>*>(this)->format(vector.y, ctx);
370+
it = format_to(it, ", ");
371+
372+
// Format vector.z using the base formatter<T>
373+
it = static_cast<const formatter<T>*>(this)->format(vector.z, ctx);
374+
it = format_to(it, ")");
375+
376+
return it;
377+
}
378+
};

src/main.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ void initialize() {
1515
std::cout << std::format("{:.2f}", units::pow<5>(505_cm) * 15_celsius) << std::endl;
1616
Number a(2.123);
1717
std::cout << std::format("{:.2f}", a) << std::endl;
18-
Vector2D<Length> v2a = V2Position(2_in, 2_in) / 2;
18+
units::Vector2D<Length> v2a = units::V2Position(2_in, 2_in) / 2;
1919
std::cout << std::format("{}", v2a) << std::endl;
2020
}
2121

@@ -50,11 +50,11 @@ constexpr void v3dTests() {
5050

5151
constexpr void v2dTests() {
5252
// check Vector2D overloads
53-
Vector2D<Length> v2a = V2Position(2_in, 2_in) / 2;
54-
Vector2D<Length> v2b = 2 * V2Position(2_in, 2_in) * 2;
55-
Vector2D<Area> v2c = 2_in * V2Position(2_in, 2_in);
56-
Vector2D<Area> v2d = V2Position(2_in, 2_in) * 2_in;
57-
Vector2D<Number> v2e = V2Position(2_in, 2_in) / 2_in;
53+
units::Vector2D<Length> v2a = units::V2Position(2_in, 2_in) / 2;
54+
units::Vector2D<Length> v2b = 2 * units::V2Position(2_in, 2_in) * 2;
55+
units::Vector2D<Area> v2c = 2_in * units::V2Position(2_in, 2_in);
56+
units::Vector2D<Area> v2d = units::V2Position(2_in, 2_in) * 2_in;
57+
units::Vector2D<Number> v2e = units::V2Position(2_in, 2_in) / 2_in;
5858
}
5959

6060
constexpr void angleTests() {

0 commit comments

Comments
 (0)