Fix math library std::formatters & make them use format rules derived from base scalar type

This commit is contained in:
Nikita Lisitsa 2025-10-18 15:27:39 +03:00
parent b1ea7bc763
commit 78e9731d8d
5 changed files with 47 additions and 52 deletions

View file

@ -355,27 +355,19 @@ namespace std
template <typename T, std::size_t N, typename Char> template <typename T, std::size_t N, typename Char>
struct formatter<::psemek::math::box<T, N>, Char> struct formatter<::psemek::math::box<T, N>, Char>
: formatter<::psemek::math::interval<T>>
{ {
constexpr auto parse(std::format_parse_context & ctx) using formatter<::psemek::math::interval<T>>::parse;
{
return ctx.begin();
}
auto format(::psemek::math::point<T, N> const & p, std::format_context & ctx) const template <typename FormatContext>
auto format(::psemek::math::box<T, N> const & b, FormatContext & ctx) const
{ {
if constexpr (N == 0) for (std::size_t i = 0; i < b.dimension(); ++i)
{ {
return std::format_to(ctx.out(), "()"); if (i > 0) ctx.advance_to(std::format_to(ctx.out(), "x"));
} formatter<::psemek::math::interval<T>>::format(b[i], ctx);
else
{
auto out = ctx.out();
out = std::format_to(out, "({}", p[0]);
for (std::size_t i = 1; i < p.dimension(); ++i)
out = std::format_to(out, ", {}", p[i]);
out = std::format_to(out, ")");
return out;
} }
return ctx.out();
} }
}; };

View file

@ -341,15 +341,18 @@ namespace std
template <typename T, typename Char> template <typename T, typename Char>
struct formatter<::psemek::math::interval<T>, Char> struct formatter<::psemek::math::interval<T>, Char>
: formatter<T>
{ {
constexpr auto parse(std::format_parse_context & ctx) using formatter<T>::parse;
{
return ctx.begin();
}
auto format(::psemek::math::interval<T> const & i, std::format_context & ctx) const template <typename FormatContext>
auto format(::psemek::math::interval<T> const & i, FormatContext & ctx) const
{ {
return std::format_to(ctx.out(), "[{} .. {}]", i.min, i.max); ctx.advance_to(std::format_to(ctx.out(), "["));
ctx.advance_to(formatter<T>::format(i.min, ctx));
ctx.advance_to(std::format_to(ctx.out(), " .. "));
ctx.advance_to(formatter<T>::format(i.max, ctx));
return std::format_to(ctx.out(), "]");
} }
}; };

View file

@ -223,25 +223,24 @@ namespace std
template <typename T, std::size_t N> template <typename T, std::size_t N>
struct hash<::psemek::math::point<T, N>> struct hash<::psemek::math::point<T, N>>
{ {
std::uint64_t operator()(::psemek::math::point<T, N> const & v) const noexcept std::uint64_t operator()(::psemek::math::point<T, N> const & p) const noexcept
{ {
hash<T> h; hash<T> h;
std::uint64_t r = 0; std::uint64_t r = 0;
for (std::size_t i = 0; i < N; ++i) for (std::size_t i = 0; i < N; ++i)
::psemek::util::hash_combine(r, h(v[i])); ::psemek::util::hash_combine(r, h(p[i]));
return r; return r;
} }
}; };
template <typename T, std::size_t N, typename Char> template <typename T, std::size_t N, typename Char>
struct formatter<::psemek::math::point<T, N>, Char> struct formatter<::psemek::math::point<T, N>, Char>
: formatter<T>
{ {
constexpr auto parse(std::format_parse_context & ctx) using formatter<T>::parse;
{
return ctx.begin();
}
auto format(::psemek::math::point<T, N> const & p, std::format_context & ctx) const template <typename FormatContext>
auto format(::psemek::math::point<T, N> const & p, FormatContext & ctx) const
{ {
if constexpr (N == 0) if constexpr (N == 0)
{ {
@ -249,12 +248,13 @@ namespace std
} }
else else
{ {
auto out = ctx.out(); ctx.advance_to(std::format_to(ctx.out(), "("));
out = std::format_to(out, "({}", p[0]); for (std::size_t i = 0; i < p.dimension(); ++i)
for (std::size_t i = 1; i < p.dimension(); ++i) {
out = std::format_to(out, ", {}", p[i]); if (i > 0) ctx.advance_to(std::format_to(ctx.out(), ", "));
out = std::format_to(out, ")"); formatter<T>::format(p[i], ctx);
return out; }
return std::format_to(ctx.out(), ")");
} }
} }
}; };

View file

@ -346,15 +346,15 @@ namespace std
template <typename T, typename Char> template <typename T, typename Char>
struct formatter<::psemek::math::quaternion<T>, Char> struct formatter<::psemek::math::quaternion<T>, Char>
: formatter<::psemek::math::vector<T, 4>>
{ {
constexpr auto parse(std::format_parse_context & ctx) using formatter<::psemek::math::vector<T, 4>>::parse;
{
return ctx.begin();
}
auto format(::psemek::math::quaternion<T> const & q, std::format_context & ctx) const template <typename FormatContext>
auto format(::psemek::math::quaternion<T> const & q, FormatContext & ctx) const
{ {
return std::format_to(ctx.out(), "{}", q.coords); formatter<::psemek::math::vector<T, 4>>::format(q.coords, ctx);
return ctx.out();
} }
}; };

View file

@ -524,13 +524,12 @@ namespace std
template <typename T, std::size_t N, typename Char> template <typename T, std::size_t N, typename Char>
struct formatter<::psemek::math::vector<T, N>, Char> struct formatter<::psemek::math::vector<T, N>, Char>
: formatter<T>
{ {
constexpr auto parse(std::format_parse_context & ctx) using formatter<T>::parse;
{
return ctx.begin();
}
auto format(::psemek::math::vector<T, N> const & v, std::format_context & ctx) const template <typename FormatContext>
auto format(::psemek::math::vector<T, N> const & v, FormatContext & ctx) const
{ {
if constexpr (N == 0) if constexpr (N == 0)
{ {
@ -538,12 +537,13 @@ namespace std
} }
else else
{ {
auto out = ctx.out(); ctx.advance_to(std::format_to(ctx.out(), "("));
out = std::format_to(out, "({}", v[0]); for (std::size_t i = 0; i < v.dimension(); ++i)
for (std::size_t i = 1; i < v.dimension(); ++i) {
out = std::format_to(out, ", {}", v[i]); if (i > 0) ctx.advance_to(std::format_to(ctx.out(), ", "));
out = std::format_to(out, ")"); formatter<T>::format(v[i], ctx);
return out; }
return std::format_to(ctx.out(), ")");
} }
} }
}; };