#pragma once #include "compat/assert.hpp" #include #include #include #include namespace fmt { template<> struct formatter { template static constexpr auto parse(ParseContext& ctx) { return ctx.begin(); } template auto format(Corrade::Containers::StringView const& s, FormatContext& ctx); }; template<> struct formatter { template static constexpr auto parse(ParseContext& ctx) { return ctx.begin(); } template auto format(Corrade::Containers::String const& s, FormatContext& ctx); }; } // namespace fmt #if !FMT_USE_NONTYPE_TEMPLATE_ARGS namespace floormat::detail::fmt { template struct fmt_string final { static constexpr size_t size = N; char data[N]; template consteval fmt_string(const char (&arr)[N]) noexcept { for (auto i = 0uz; i < N; i++) data[i] = arr[i]; } }; } // namespace floormat::detail::fmt #endif #if !FMT_USE_NONTYPE_TEMPLATE_ARGS template<::floormat::detail::fmt::fmt_string s> consteval auto operator""_cf() noexcept { return FMT_COMPILE(s.data); } #else using namespace fmt::literals; #endif namespace floormat { template size_t snformat(char(&buf)[N], Fmt&& fmt, Xs&&... args) { constexpr size_t n = N > 0 ? N - 1 : 0; auto result = fmt::format_to_n(buf, n, forward(fmt), forward(args)...); const auto len = n < result.size ? n : result.size; fm_assert(len > 0); #if 0 if constexpr(N > 0) buf[len] = '\0'; #else buf[len] = '\0'; #endif return result.size; } } // namespace floormat template auto fmt::formatter::format(Corrade::Containers::StringView const& s, FormatContext& ctx) { return fmt::format_to(ctx.out(), "{}"_cf, basic_string_view{s.data(), s.size()}); } template auto fmt::formatter::format(Corrade::Containers::String const& s, FormatContext& ctx) { return fmt::format_to(ctx.out(), "{}"_cf, basic_string_view{s.data(), s.size()}); }