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.
* add test for byte formatting with `FMT_COMPILE`
* fix byte formatting with `FMT_COMPILE`, use `__cpp_lib_byte` macro
* use is not custom mapped type check
* workaround MSVC bug
* eliminate one case where basic_print_context would copy a string into a fmt::basic_memory_buffer character by character instead of using fmt::basic_memory_buffer::append
* use detail::write instead of re-implementing it
* use to_unsigned to avoid signedness conversion warnings
Problem:
- On Apple clang version 11.0.3 (clang-1103.0.32.62) in C++17 and C++20
mode, clang 11.0.0 in C++17 and C++20 mode, and clang 9.0.1 in C++17
mode, the following error is generated:
In file included from test/compile-test.cc:16:
include/fmt/compile.h:518:25: error: implicit conversion changes signedness: 'long' to 'unsigned long' [-Werror,-Wsign-conversion]
return {f, pos + (end - str.data()) + 1, ctx.next_arg_id()};
~ ~~~~^~~~~~~~~~~~
include/fmt/compile.h:538:31: note: in instantiation of function template specialization
'fmt::v7::detail::parse_specs<int, char>' requested here
constexpr auto result = parse_specs<id_type>(str, POS + 2, ID);
^
include/fmt/compile.h:569:17: note: in instantiation of function template specialization
'fmt::v7::detail::compile_format_string<fmt::v7::detail::type_list<int>, 0, 0, FMT_COMPILE_STRING>' requested here
detail::compile_format_string<detail::type_list<Args...>, 0, 0>(
^
include/fmt/compile.h:648:37: note: in instantiation of function template specialization
'fmt::v7::detail::compile<int, FMT_COMPILE_STRING, 0>' requested here
constexpr auto compiled = detail::compile<Args...>(S());
^
test/compile-test.cc:140:24: note: in instantiation of function template specialization
'fmt::v7::format<FMT_COMPILE_STRING, int, 0>' requested here
EXPECT_EQ("42", fmt::format(FMT_COMPILE("{:x}"), 0x42));
^
In file included from test/compile-test.cc:16:
include/fmt/compile.h:518:25: error: implicit conversion changes signedness: 'long' to 'unsigned long' [-Werror,-Wsign-conversion]
return {f, pos + (end - str.data()) + 1, ctx.next_arg_id()};
~ ~~~~^~~~~~~~~~~~
include/fmt/compile.h:538:31: note: in instantiation of function template specialization
'fmt::v7::detail::parse_specs<char [4], char>' requested here
constexpr auto result = parse_specs<id_type>(str, POS + 2, ID);
^
include/fmt/compile.h:494:27: note: in instantiation of function template specialization
'fmt::v7::detail::compile_format_string<fmt::v7::detail::type_list<int, int, char const (&)[4], int>, 5, 2, FMT_COMPILE_STRING>'
requested here
constexpr auto tail = compile_format_string<Args, POS, ID>(format_str);
^
include/fmt/compile.h:539:14: note: in instantiation of function template specialization
'fmt::v7::detail::parse_tail<fmt::v7::detail::type_list<int, int, char const (&)[4], int>, 5, 2, fmt::v7::detail::spec_field<char, int, 0>, FMT_COMPILE_STRING>' requested here
return parse_tail<Args, result.end, result.next_arg_id>(
^
include/fmt/compile.h:569:17: note: in instantiation of function template specialization
'fmt::v7::detail::compile_format_string<fmt::v7::detail::type_list<int, int, char const (&)[4], int>, 0, 0, FMT_COMPILE_STRING>'
requested here
detail::compile_format_string<detail::type_list<Args...>, 0, 0>(
^
include/fmt/compile.h:648:37: note: in instantiation of function template specialization
'fmt::v7::detail::compile<int, int, char const (&)[4], int, FMT_COMPILE_STRING, 0>' requested here
constexpr auto compiled = detail::compile<Args...>(S());
^
test/compile-test.cc:145:18: note: in instantiation of function template specialization
'fmt::v7::format<FMT_COMPILE_STRING, int, int, char const (&)[4], int, 0>' requested here
fmt::format(FMT_COMPILE("{:{}}{:{}}"), 42, 4, "foo", 5));
^
2 errors generated.
Solution:
- Explicitly cast the result of the subtraction to the (unsigned) outer
type.
Co-authored-by: Jonathan Gopel <jgopel@quantlab.com>
Using sizeof causes some compilers to complain:
'operand of sizeof is not a type, variable, or dereferenced pointer'
static_cast itself should be enough to silence unused variable warning
Co-authored-by: Łukasz Mitka <lukasz.mitka@aptiv.com>