From ab9b70d4b541c41dca257bbd8bb1603dc4447242 Mon Sep 17 00:00:00 2001 From: Ben Deane Date: Tue, 22 Apr 2025 21:24:38 -0600 Subject: [PATCH] :sparkles: Allow user-defined formatting with `ct_format` Problem: - `ct_format` does not allow for compile-time formatting of user-defined types. Solution: - Add `ct_format_as` customization point that allows user-defined types to be given customized compile-time formatting. --- include/stdx/ct_format.hpp | 8 +++++++- test/ct_format.cpp | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/include/stdx/ct_format.hpp b/include/stdx/ct_format.hpp index c3133b4..d9beace 100644 --- a/include/stdx/ct_format.hpp +++ b/include/stdx/ct_format.hpp @@ -205,6 +205,11 @@ template struct fmt_data { constexpr static auto splits = split_specifiers(fmt); constexpr static auto last_cts = to_ct_string(splits[N]); }; + +template +constexpr auto ct_format_as(T const &t) -> decltype(auto) { + return (t); +} } // namespace detail template (std::index_sequence) { - return (format1.template operator()(FWD(args)) + ... + + using detail::ct_format_as; + return (format1.template operator()(ct_format_as(FWD(args))) + ... + format_result{cts_t{}}); }(std::make_index_sequence{}); return format_result{detail::convert_output(), diff --git a/test/ct_format.cpp b/test/ct_format.cpp index 662052d..cd46234 100644 --- a/test/ct_format.cpp +++ b/test/ct_format.cpp @@ -223,3 +223,18 @@ TEST_CASE("num fmt specifiers", "[ct_format]") { static_assert(stdx::num_fmt_specifiers<"{}"> == 1u); static_assert(stdx::num_fmt_specifiers<"{} {}"> == 2u); } + +namespace user { +struct S { + int x; +}; + +constexpr auto ct_format_as(S const &s) { + return stdx::ct_format<"S: {}">(s.x); +} +} // namespace user + +TEST_CASE("user-defined formatting", "[ct_format]") { + auto r = stdx::ct_format<"Hello {}">(user::S{42}); + CHECK(r == stdx::format_result{"Hello S: {}"_ctst, stdx::make_tuple(42)}); +}