From b5bd5c73884a1fb6f6be5e175ebecb23f826530e Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Tue, 18 Feb 2025 21:38:06 +0200 Subject: [PATCH] Various implementations in FmtFormatter + tests --- openVulkanoCpp/Extensions/FmtFormatter.hpp | 350 +++++++++++++++------ openVulkanoCpp/Math/ByteSize.hpp | 3 +- tests/Extensions/FmtFormatterTest.cpp | 177 +++++++++++ 3 files changed, 433 insertions(+), 97 deletions(-) create mode 100644 tests/Extensions/FmtFormatterTest.cpp diff --git a/openVulkanoCpp/Extensions/FmtFormatter.hpp b/openVulkanoCpp/Extensions/FmtFormatter.hpp index 2c3b9d2..737ec30 100644 --- a/openVulkanoCpp/Extensions/FmtFormatter.hpp +++ b/openVulkanoCpp/Extensions/FmtFormatter.hpp @@ -13,9 +13,17 @@ #else #error "Failed to find fmt include" #endif -#include "Math/ByteSize.hpp" #include "Math/Math.hpp" +#include "Math/ByteSize.hpp" +#include "Math/DenseVector3i.hpp" +#include "Math/Float16.hpp" +#include "Math/Int24.hpp" #include "Math/Range.hpp" +#include "Math/RGB10A2.hpp" +#include "Math/RGB565.hpp" +#include "Math/RGBA5551.hpp" +#include "Math/Timestamp.hpp" +#include "Math/UInt24.hpp" #include "Base/UUID.hpp" #include @@ -48,132 +56,170 @@ template<> struct fmt::formatter : fmt::formatter -struct fmt::formatter> +struct fmt::formatter> : fmt::formatter { - template constexpr auto parse(ParseContext& ctx) - { - return ctx.begin(); - } - - template - auto format(const glm::vec<2, T, Q>& v, FormatContext& ctx) const - { - return fmt::format_to(ctx.out(), "({}, {})", v.x, v.y); - } + template + auto format(const glm::vec<2, T, Q>& v, FormatContext& ctx) const + { + fmt::format_to(ctx.out(), "("); + formatter::format(v.x, ctx); + fmt::format_to(ctx.out(), ", "); + formatter::format(v.y, ctx); + return fmt::format_to(ctx.out(), ")"); + } }; template -struct fmt::formatter> +struct fmt::formatter> : fmt::formatter { - template constexpr auto parse(ParseContext& ctx) - { - return ctx.begin(); - } - - template - auto format(const glm::vec<3, T, Q>& v, FormatContext& ctx) const - { - return fmt::format_to(ctx.out(), "({}, {}, {})", v.x, v.y, v.z); - } + template + auto format(const glm::vec<3, T, Q>& v, FormatContext& ctx) const + { + fmt::format_to(ctx.out(), "("); + formatter::format(v.x, ctx); + fmt::format_to(ctx.out(), ", "); + formatter::format(v.y, ctx); + fmt::format_to(ctx.out(), ", "); + formatter::format(v.z, ctx); + return fmt::format_to(ctx.out(), ")"); + } }; template -struct fmt::formatter> +struct fmt::formatter> : fmt::formatter { - template constexpr auto parse(ParseContext& ctx) - { - return ctx.begin(); - } - - template - auto format(const glm::vec<4, T, Q>& v, FormatContext& ctx) const - { - return fmt::format_to(ctx.out(), "({}, {}, {}, {})", v.x, v.y, v.z, v.w); - } + template + auto format(const glm::vec<4, T, Q>& v, FormatContext& ctx) const + { + fmt::format_to(ctx.out(), "("); + formatter::format(v.x, ctx); + fmt::format_to(ctx.out(), ", "); + formatter::format(v.y, ctx); + fmt::format_to(ctx.out(), ", "); + formatter::format(v.z, ctx); + fmt::format_to(ctx.out(), ", "); + formatter::format(v.w, ctx); + return fmt::format_to(ctx.out(), ")"); + } }; template -struct fmt::formatter> +struct fmt::formatter> : fmt::formatter { - template constexpr auto parse(ParseContext& ctx) - { - return ctx.begin(); - } - - template - auto format(const glm::mat<2, 2, T, Q>& m, FormatContext& ctx) const - { - return fmt::format_to(ctx.out(), "[[{}, {}], [{}, {}]]", - m[0][0], m[1][0], - m[0][1], m[1][1]); - } + template + auto format(const glm::mat<2, 2, T, Q>& m, FormatContext& ctx) const + { + fmt::format_to(ctx.out(), "[["); + formatter::format(m[0][0], ctx); + fmt::format_to(ctx.out(), ", "); + formatter::format(m[1][0], ctx); + fmt::format_to(ctx.out(), "], ["); + formatter::format(m[0][1], ctx); + fmt::format_to(ctx.out(), ", "); + formatter::format(m[1][1], ctx); + return fmt::format_to(ctx.out(), "]]"); + } }; template -struct fmt::formatter> +struct fmt::formatter> : fmt::formatter { - template constexpr auto parse(ParseContext& ctx) - { - return ctx.begin(); - } - - template - auto format(const glm::mat<3, 3, T, Q>& m, FormatContext& ctx) const - { - return fmt::format_to(ctx.out(), "[[{}, {}, {}], [{}, {}, {}], [{}, {}, {}]]", - m[0][0], m[1][0], m[2][0], - m[0][1], m[1][1], m[2][1], - m[0][2], m[1][2], m[2][2]); - } + template + auto format(const glm::mat<3, 3, T, Q>& m, FormatContext& ctx) const + { + fmt::format_to(ctx.out(), "[["); + formatter::format(m[0][0], ctx); + fmt::format_to(ctx.out(), ", "); + formatter::format(m[1][0], ctx); + fmt::format_to(ctx.out(), ", "); + formatter::format(m[2][0], ctx); + fmt::format_to(ctx.out(), "], ["); + formatter::format(m[0][1], ctx); + fmt::format_to(ctx.out(), ", "); + formatter::format(m[1][1], ctx); + fmt::format_to(ctx.out(), ", "); + formatter::format(m[2][1], ctx); + fmt::format_to(ctx.out(), "], ["); + formatter::format(m[0][2], ctx); + fmt::format_to(ctx.out(), ", "); + formatter::format(m[1][2], ctx); + fmt::format_to(ctx.out(), ", "); + formatter::format(m[2][2], ctx); + return fmt::format_to(ctx.out(), "]]"); + } }; template -struct fmt::formatter> +struct fmt::formatter> : fmt::formatter { - template constexpr auto parse(ParseContext& ctx) - { - return ctx.begin(); - } - - template - auto format(const glm::mat<4, 4, T, Q>& m, FormatContext& ctx) const - { - return fmt::format_to(ctx.out(), "[[{}, {}, {}, {}], [{}, {}, {}, {}], [{}, {}, {}, {}], [{}, {}, {}, {}]]", - m[0][0], m[1][0], m[2][0], m[3][0], - m[0][1], m[1][1], m[2][1], m[3][1], - m[0][2], m[1][2], m[2][2], m[3][2], - m[0][3], m[1][3], m[2][3], m[3][3]); - } + template + auto format(const glm::mat<4, 4, T, Q>& m, FormatContext& ctx) const + { + fmt::format_to(ctx.out(), "[["); + formatter::format(m[0][0], ctx); + fmt::format_to(ctx.out(), ", "); + formatter::format(m[1][0], ctx); + fmt::format_to(ctx.out(), ", "); + formatter::format(m[2][0], ctx); + fmt::format_to(ctx.out(), ", "); + formatter::format(m[3][0], ctx); + fmt::format_to(ctx.out(), "], ["); + formatter::format(m[0][1], ctx); + fmt::format_to(ctx.out(), ", "); + formatter::format(m[1][1], ctx); + fmt::format_to(ctx.out(), ", "); + formatter::format(m[2][1], ctx); + fmt::format_to(ctx.out(), ", "); + formatter::format(m[3][1], ctx); + fmt::format_to(ctx.out(), "], ["); + formatter::format(m[0][2], ctx); + fmt::format_to(ctx.out(), ", "); + formatter::format(m[1][2], ctx); + fmt::format_to(ctx.out(), ", "); + formatter::format(m[2][2], ctx); + fmt::format_to(ctx.out(), ", "); + formatter::format(m[3][2], ctx); + fmt::format_to(ctx.out(), "], ["); + formatter::format(m[0][3], ctx); + fmt::format_to(ctx.out(), ", "); + formatter::format(m[1][3], ctx); + fmt::format_to(ctx.out(), ", "); + formatter::format(m[2][3], ctx); + fmt::format_to(ctx.out(), ", "); + formatter::format(m[3][3], ctx); + return fmt::format_to(ctx.out(), "]]"); + } }; template -struct fmt::formatter> +struct fmt::formatter> : fmt::formatter { - template constexpr auto parse(ParseContext& ctx) - { - return ctx.begin(); - } - - template - auto format(const glm::qua& q, FormatContext& ctx) const - { - return fmt::format_to(ctx.out(), "({}, {}, {}, {})", q.w, q.x, q.y, q.z); - } + template + auto format(const glm::qua& q, FormatContext& ctx) const + { + fmt::format_to(ctx.out(), "("); + formatter::format(q.w, ctx); + fmt::format_to(ctx.out(), ", "); + formatter::format(q.x, ctx); + fmt::format_to(ctx.out(), ", "); + formatter::format(q.y, ctx); + fmt::format_to(ctx.out(), ", "); + formatter::format(q.z, ctx); + return fmt::format_to(ctx.out(), ")"); + } }; template -struct fmt::formatter> : fmt::formatter +struct fmt::formatter> : fmt::formatter { - template - constexpr auto parse(ParseContext& ctx) - { - return ctx.begin(); - } - template auto format(const OpenVulkano::Math::Range& range, FormatContext& ctx) const { - return fmt::format_to(ctx.out(), "[{}, {}]", range.min, range.max); + fmt::format_to(ctx.out(), "["); + formatter::format(range.min, ctx); + fmt::format_to(ctx.out(), ", "); + formatter::format(range.max, ctx); + return fmt::format_to(ctx.out(), "]"); } }; @@ -191,4 +237,118 @@ struct fmt::formatter : fmt::formatter { return fmt::format_to(ctx.out(), "{}", uuid.string()); } +}; + +template<> +struct fmt::formatter +{ + template + constexpr auto parse(ParseContext& ctx) + { + return ctx.begin(); + } + + template + auto format(const OpenVulkano::Math::RGB565& color, FormatContext& ctx) const + { + return fmt::format_to(ctx.out(), "RGB565(r:{}, g:{}, b:{})", + color.r, color.g, color.b); + } +}; + +template<> +struct fmt::formatter +{ + template + constexpr auto parse(ParseContext& ctx) + { + return ctx.begin(); + } + + template + auto format(const OpenVulkano::Math::RGBA5551& color, FormatContext& ctx) const + { + return fmt::format_to(ctx.out(), "RGBA5551(r:{}, g:{}, b:{}, a:{})", + color.r, color.g, color.b, color.a); + } +}; + +template +struct fmt::formatter> +{ + template + constexpr auto parse(ParseContext& ctx) + { + return ctx.begin(); + } + + template + auto format(const OpenVulkano::Math::RGB10A2& color, FormatContext& ctx) const + { + return fmt::format_to(ctx.out(), "RGB10A2(r:{}, g:{}, b:{}, a:{})", + color.r, color.g, color.b, color.a); + } +}; + +template +struct fmt::formatter> +{ + template + constexpr auto parse(ParseContext& ctx) + { + return ctx.begin(); + } + + template + auto format(const OpenVulkano::Math::DenseVector3i& vec, + FormatContext& ctx) const + { + return fmt::format_to(ctx.out(), "DenseVector3i({}, {}, {})", vec.X(), vec.Y(), vec.Z()); + } +}; + +template<> +struct fmt::formatter +{ + template + constexpr auto parse(ParseContext& ctx) + { + return ctx.begin(); + } + + template + auto format(const OpenVulkano::Math::Timestamp& ts, FormatContext& ctx) const + { + return fmt::format_to(ctx.out(), "{}ns", ts.GetNanos()); + } +}; + +template<> +struct fmt::formatter : fmt::formatter +{ + template + auto format(const float16& f, FormatContext& ctx) const + { + return fmt::formatter::format(static_cast(f), ctx); + } +}; + +template<> +struct fmt::formatter : fmt::formatter +{ + template + auto format(const OpenVulkano::int24& i, FormatContext& ctx) const + { + return fmt::formatter::format(static_cast(i), ctx); + } +}; + +template<> +struct fmt::formatter : fmt::formatter +{ + template + auto format(const OpenVulkano::uint24& i, FormatContext& ctx) const + { + return fmt::formatter::format(static_cast(i), ctx); + } }; \ No newline at end of file diff --git a/openVulkanoCpp/Math/ByteSize.hpp b/openVulkanoCpp/Math/ByteSize.hpp index 830861d..4e53a98 100644 --- a/openVulkanoCpp/Math/ByteSize.hpp +++ b/openVulkanoCpp/Math/ByteSize.hpp @@ -72,7 +72,7 @@ namespace OpenVulkano { for (int i = (si ? EB : EiB); i >= (si ? kB : kiB); i--) { - if (size > FACTORS[i]) return { static_cast(i) }; + if (size >= FACTORS[i]) return { static_cast(i) }; } return { B }; } @@ -162,4 +162,3 @@ namespace OpenVulkano constexpr ByteSize operator"" _PB(unsigned long long int num) { return { num, ByteSizeUnit::PB }; } constexpr ByteSize operator"" _EB(unsigned long long int num) { return { num, ByteSizeUnit::EB }; } } - diff --git a/tests/Extensions/FmtFormatterTest.cpp b/tests/Extensions/FmtFormatterTest.cpp new file mode 100644 index 0000000..aa4d787 --- /dev/null +++ b/tests/Extensions/FmtFormatterTest.cpp @@ -0,0 +1,177 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#include +#include + +#include "Extensions/FmtFormatter.hpp" + +using namespace OpenVulkano; +using namespace OpenVulkano::Math; + +TEST_CASE("GLM Vector Formatters", "[fmt]") +{ + SECTION("Vector2f") + { + Vector2f v(1.2345f, 2.3456f); + CHECK(fmt::format("{}", v) == "(1.2345, 2.3456)"); + CHECK(fmt::format("{:.2f}", v) == "(1.23, 2.35)"); + } + + SECTION("Vector3f") + { + Vector3f v(1.2345f, 2.3456f, 3.4567f); + CHECK(fmt::format("{}", v) == "(1.2345, 2.3456, 3.4567)"); + CHECK(fmt::format("{:.2f}", v) == "(1.23, 2.35, 3.46)"); + } + + SECTION("Vector4f") + { + Vector4f v(1.2345f, 2.3456f, 3.4567f, 4.5678f); + CHECK(fmt::format("{}", v) == "(1.2345, 2.3456, 3.4567, 4.5678)"); + CHECK(fmt::format("{:.2f}", v) == "(1.23, 2.35, 3.46, 4.57)"); + } +} + +TEST_CASE("GLM Matrix Formatters", "[fmt]") +{ + SECTION("Matrix2f") + { + Matrix2f m = Matrix2f(1.0f); + CHECK(fmt::format("{}", m) == "[[1, 0], [0, 1]]"); + CHECK(fmt::format("{:.1f}", m) == "[[1.0, 0.0], [0.0, 1.0]]"); + } + + SECTION("Matrix3f") + { + Matrix3f m = Matrix3f(1.0f); + CHECK(fmt::format("{}", m) == "[[1, 0, 0], [0, 1, 0], [0, 0, 1]]"); + CHECK(fmt::format("{:.1f}", m) == "[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]"); + } + + SECTION("Matrix4f") + { + Matrix4f m = Matrix4f(1.0f); + CHECK(fmt::format("{}", m) == "[[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]"); + CHECK(fmt::format("{:.1f}", m) == "[[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0]]"); + } +} + +TEST_CASE("GLM Quaternion Formatter", "[fmt]") +{ + QuaternionF q(1.0f, 0.0f, 0.0f, 0.0f); + CHECK(fmt::format("{}", q) == "(1, 0, 0, 0)"); + CHECK(fmt::format("{:.2f}", q) == "(1.00, 0.00, 0.00, 0.00)"); +} + +TEST_CASE("Range Formatter", "[fmt]") +{ + Math::Range range(1.2345f, 2.3456f); + CHECK(fmt::format("{}", range) == "[1.2345, 2.3456]"); + CHECK(fmt::format("{:.2f}", range) == "[1.23, 2.35]"); +} + +TEST_CASE("Color Format Formatters", "[fmt]") +{ + SECTION("RGB565") + { + RGB565 color; + color.r = 31; + color.g = 63; + color.b = 31; + CHECK(fmt::format("{}", color) == "RGB565(r:31, g:63, b:31)"); + } + + SECTION("RGBA5551") + { + RGBA5551 color; + color.r = 31; + color.g = 31; + color.b = 31; + color.a = 1; + CHECK(fmt::format("{}", color) == "RGBA5551(r:31, g:31, b:31, a:1)"); + } + + SECTION("RGB10A2") + { + RGB10A2U color; + color.r = 1023; + color.g = 1023; + color.b = 1023; + color.a = 3; + CHECK(fmt::format("{}", color) == "RGB10A2(r:1023, g:1023, b:1023, a:3)"); + } +} + +TEST_CASE("DenseVector3i Formatter", "[fmt]") +{ + DenseVector3i vec(1, 2, 3); + CHECK(fmt::format("{}", vec) == "DenseVector3i(1, 2, 3)"); +} + +TEST_CASE("Timestamp Formatter", "[fmt]") +{ + Timestamp ts((uint64_t)1000000); + CHECK(fmt::format("{}", ts) == "1000000ns"); +} + +TEST_CASE("Numeric Type Formatters", "[fmt]") +{ + SECTION("float16") + { + float16 f(1.5f); + std::string formatted = fmt::format("{}", f); + CHECK((formatted == "1.5" || formatted == "1.500000")); + CHECK(fmt::format("{:.1f}", f) == "1.5"); + } + + SECTION("int24") + { + OpenVulkano::int24 i(1000); + CHECK(fmt::format("{}", i) == "1000"); + } + + SECTION("uint24") + { + OpenVulkano::uint24 u(1000); + CHECK(fmt::format("{}", u) == "1000"); + } +} + +TEST_CASE("ByteSize Formatter", "[fmt]") +{ + SECTION("1000 bytes") + { + ByteSize size(1000); + CHECK(fmt::format("{}", size) == "1e+03 B"); + } + + SECTION("1024 bytes (1 kiB)") + { + ByteSize size(1024); + CHECK(fmt::format("{}", size) == "1 kiB"); + } + + SECTION("1 mebibyte") + { + ByteSize size(1024 * 1024); + CHECK(fmt::format("{}", size) == "1 MiB"); + } + + SECTION("Using unit constructors") + { + CHECK(fmt::format("{}", ByteSize(1, ByteSizeUnit(ByteSizeUnit::kiB))) == "1 kiB"); + CHECK(fmt::format("{}", ByteSize(1, ByteSizeUnit(ByteSizeUnit::MiB))) == "1 MiB"); + } +} + +TEST_CASE("UUID Formatter", "[fmt]") +{ + UUID uuid = GenerateTimePrefixedCustomUUID(); + std::string formatted = fmt::format("{}", uuid); + CHECK(formatted.length() == 36); + CHECK(formatted.find('-') != std::string::npos); +}