mirror of
https://github.com/fmtlib/fmt.git
synced 2024-11-25 19:50:05 +00:00
fmt::ptr: Support function pointers (#2131)
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))); with GCC and Clang. Let's add an overload to support that usage. Unfortunately, MSVC would consider the overload to be ambiguous for unknown reasons: D:\a\fmt\fmt\test\format-test.cc(1485,1): error C2668: 'fmt::v7::ptr': ambiguous call to overloaded function [D:\a\fmt\build\test\format-test.vcxproj] D:\a\fmt\fmt\include\fmt/format.h(3742,60): message : could be 'const void *fmt::v7::ptr<void,int,double,std::string>(T (__cdecl *)(int,double,std::string))' [D:\a\fmt\build\test\format-test.vcxproj] with [ T=void ] D:\a\fmt\fmt\include\fmt/format.h(3735,42): message : or 'const void *fmt::v7::ptr<void(int,double,std::string)>(T (__cdecl *))' [D:\a\fmt\build\test\format-test.vcxproj] with [ T=void (int,double,std::string) ] D:\a\fmt\fmt\test\format-test.cc(1486,1): message : while trying to match the argument list '(overloaded-function)' [D:\a\fmt\build\test\format-test.vcxproj] but luckily this means that the overload is unnecessary in that case anyway, so we can just make it conditional.
This commit is contained in:
parent
58aa04573f
commit
e6ef927e6b
@ -314,6 +314,7 @@ Utilities
|
||||
.. doxygenfunction:: fmt::ptr(const T *p)
|
||||
.. doxygenfunction:: fmt::ptr(const std::unique_ptr<T> &p)
|
||||
.. doxygenfunction:: fmt::ptr(const std::shared_ptr<T> &p)
|
||||
.. doxygenfunction:: fmt::ptr(T (*fn)(Args...))
|
||||
|
||||
.. doxygenfunction:: fmt::to_string(const T &value)
|
||||
|
||||
|
@ -3739,6 +3739,13 @@ template <typename T> inline const void* ptr(const std::unique_ptr<T>& p) {
|
||||
template <typename T> inline const void* ptr(const std::shared_ptr<T>& p) {
|
||||
return p.get();
|
||||
}
|
||||
#if !FMT_MSC_VER
|
||||
// MSVC lets function pointers decay to void pointers, so this
|
||||
// overload is unnecessary.
|
||||
template <typename T, typename... Args> inline const void* ptr(T (*fn)(Args...)) {
|
||||
return detail::bit_cast<const void *>(fn);
|
||||
}
|
||||
#endif
|
||||
|
||||
class bytes {
|
||||
private:
|
||||
|
@ -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<void*>(0x1234), "p", "pointer");
|
||||
EXPECT_EQ("0x0", format("{0}", static_cast<void*>(nullptr)));
|
||||
@ -1479,6 +1482,8 @@ TEST(FormatterTest, FormatPointer) {
|
||||
EXPECT_EQ(format("{}", fmt::ptr(up.get())), format("{}", fmt::ptr(up)));
|
||||
std::shared_ptr<int> sp(new int(1));
|
||||
EXPECT_EQ(format("{}", fmt::ptr(sp.get())), format("{}", fmt::ptr(sp)));
|
||||
EXPECT_EQ(format("{}", fmt::detail::bit_cast<const void *>(&function_pointer_test)),
|
||||
format("{}", fmt::ptr(function_pointer_test)));
|
||||
EXPECT_EQ("0x0", format("{}", nullptr));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user