Skip to content

Commit

Permalink
Use fmt::formatter specialization for std::reference_wrapper to avoid…
Browse files Browse the repository at this point in the history
… undefined behavior

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
  • Loading branch information
phprus committed Sep 18, 2024
1 parent ed8f8be commit 0d8da58
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 10 deletions.
22 changes: 12 additions & 10 deletions include/fmt/std.h
Original file line number Diff line number Diff line change
Expand Up @@ -692,15 +692,17 @@ template <typename T, typename Char> struct formatter<std::complex<T>, Char> {
}
};

FMT_END_NAMESPACE

namespace std {

template <typename T>
constexpr auto format_as(std::reference_wrapper<T> ref) -> T& {
return ref.get();
}

} // namespace std
FMT_EXPORT
template <typename T, typename Char>
struct formatter<std::reference_wrapper<T>, Char,
enable_if_t<is_formattable<remove_cvref_t<T>, Char>::value>>
: formatter<remove_cvref_t<T>, Char> {
template <typename FormatContext>
auto format(const std::reference_wrapper<T>& ref, FormatContext& ctx) const
-> decltype(ctx.out()) {
return formatter<remove_cvref_t<T>, Char>::format(ref.get(), ctx);
}
};

FMT_END_NAMESPACE
#endif // FMT_STD_H_
3 changes: 3 additions & 0 deletions test/std-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -399,4 +399,7 @@ TEST(std_test, format_shared_ptr) {
TEST(std_test, format_reference_wrapper) {
int num = 35;
EXPECT_EQ("35", fmt::to_string(std::cref(num)));

std::atomic<bool> b(true);
EXPECT_EQ(fmt::format("{}", std::cref(b)), "true");
}

0 comments on commit 0d8da58

Please sign in to comment.