From d7d64d35b2c0182d24720eb90679d6dfbbf2ec2f Mon Sep 17 00:00:00 2001 From: Mike Crowe Date: Tue, 9 Feb 2021 14:11:38 +0000 Subject: [PATCH] fmt::ptr: Support function pointers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Passing a function pointer to fmt::ptr results in: In file included from /home/mac/git/fmt/test/gmock/gmock.h:238, from /home/mac/git/fmt/test/format-test.cc:31: .../fmt/test/format-test.cc: In member function ‘virtual void FormatterTest_FormatPointer_Test::TestBody()’: .../fmt/test/format-test.cc:1486:56: error: no matching function for call to ‘ptr(void (&)(int, double, std::__cxx11::string))’ format("{}", fmt::ptr(function_pointer_test))); Let's add an overload to support that usage. --- doc/api.rst | 1 + include/fmt/format.h | 7 +++++++ test/format-test.cc | 5 +++++ 3 files changed, 13 insertions(+) diff --git a/doc/api.rst b/doc/api.rst index f89d13a806e6f..6616818d68428 100644 --- a/doc/api.rst +++ b/doc/api.rst @@ -314,6 +314,7 @@ Utilities .. doxygenfunction:: fmt::ptr(const T *p) .. doxygenfunction:: fmt::ptr(const std::unique_ptr &p) .. doxygenfunction:: fmt::ptr(const std::shared_ptr &p) +.. doxygenfunction:: fmt::ptr(T (*fn)(Args...)) .. doxygenfunction:: fmt::to_string(const T &value) diff --git a/include/fmt/format.h b/include/fmt/format.h index 06c2f63f4fd72..de0a379ee0ada 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -3739,6 +3739,13 @@ template inline const void* ptr(const std::unique_ptr& p) { template inline const void* ptr(const std::shared_ptr& p) { return p.get(); } +#if !FMT_MSC_VER +// MSVC lets function pointers decay to void pointers, so this +// overload is unnecessary. +template inline const void* ptr(T (*fn)(Args...)) { + return detail::bit_cast(fn); +} +#endif class bytes { private: diff --git a/test/format-test.cc b/test/format-test.cc index 37c22e1afc847..684dd1b8c0e1e 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -1467,6 +1467,9 @@ TEST(FormatterTest, FormatUCharString) { EXPECT_EQ("test", format("{0:s}", ptr)); } +void function_pointer_test(int, double, std::string) { +} + TEST(FormatterTest, FormatPointer) { check_unknown_types(reinterpret_cast(0x1234), "p", "pointer"); EXPECT_EQ("0x0", format("{0}", static_cast(nullptr))); @@ -1479,6 +1482,8 @@ TEST(FormatterTest, FormatPointer) { EXPECT_EQ(format("{}", fmt::ptr(up.get())), format("{}", fmt::ptr(up))); std::shared_ptr sp(new int(1)); EXPECT_EQ(format("{}", fmt::ptr(sp.get())), format("{}", fmt::ptr(sp))); + EXPECT_EQ(format("{}", fmt::detail::bit_cast(&function_pointer_test)), + format("{}", fmt::ptr(function_pointer_test))); EXPECT_EQ("0x0", format("{}", nullptr)); }