Make format_custom() constexpr to improve constexpr formatting

Added test shows a simple example when this matters.
This commit is contained in:
Ivan Lazaric 2026-09-20 23:21:52 +02:00
parent e4751cc709
commit 8b72fcd0d2
2 changed files with 27 additions and 2 deletions

View File

@ -2275,8 +2275,9 @@ template <typename Context> class value {
// Formats an argument of a custom type, such as a user-defined class.
template <typename T>
static void format_custom(void* arg, parse_context<char_type>& parse_ctx,
Context& ctx) {
static FMT_CONSTEXPR void format_custom(void* arg,
parse_context<char_type>& parse_ctx,
Context& ctx) {
auto f = formatter<T, char_type>();
parse_ctx.advance_to(f.parse(parse_ctx));
using qualified_type =

View File

@ -494,3 +494,27 @@ TEST(compile_test, format_as) {
// compiled field path rather than the to_string fast path.
EXPECT_EQ("[42]", fmt::format(FMT_COMPILE("[{}]"), type_with_format_as{42}));
}
#if FMT_CPLUSPLUS >= 202000L
struct consteval_printable {};
template<>
struct fmt::formatter<consteval_printable> {
bool debug = false;
consteval auto parse(auto& ctx) {
if (ctx.begin() != ctx.end() && *ctx.begin() == '?') {
debug = true;
ctx.advance_to(ctx.begin() + 1);
}
return ctx.begin();
}
consteval auto format(consteval_printable, auto& ctx) const {
return fmt::formatter<std::string_view>{}.format(debug ? "debug" : "regular", ctx);
}
};
static_assert(fmt::format(FMT_COMPILE("{}"), consteval_printable{}) == "regular");
static_assert(fmt::format(FMT_COMPILE("[{}]"), consteval_printable{}) == "[regular]");
static_assert(fmt::format(FMT_COMPILE("{:?}"), consteval_printable{}) == "debug");
static_assert(fmt::format(FMT_COMPILE("[{:?}]"), consteval_printable{}) == "[debug]");
#endif // FMT_CPLUSPLUS >= 202000L