* Don't include <cassert>. (#2148)
This commit replaces use of the assert() macro in format-inl.h with
FMT_ASSERT(). This allows us to drop the cassert include.
* FMT_GCC_VERSION is not defined when we include test-assert.h, use __GCC__ instead.
* Don't explicitly suppress GCC's -Wterminate in tests' FMT_ASSERT.
Throwing from a separate function is enough to silence the warning, no need to
explicitly suppress it.
* Remove messages from assertions added in 2f699d2.
* Correct formatting around throw_assertion_failure().
* fix fallback to the runtime API, add FMT_ENABLE_FALLBACK_TO_RUNTIME_API define, add test
* remove `FMT_ENABLE_FALLBACK_TO_RUNTIME_API`
* pass format string to format_to() inside format_to_n() in compile-time API
instead of compiling it inside format_to_n(), to eliminate code duplication
fixes https://github.com/fmtlib/fmt/issues/2140
- some GCC versions decay function pointers to `const void*`, exactly like
MSVC does
- legacy Clang (prior to 7.0) treats function pointers also as `const T*`
pointers, but unable to convert them
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>
Changed the clz implementations to use xor instead of subtraction so that when
count_digits "undoes" the BSR -> CLZ translation, the optimizer is more
willing to recognize the equivalence.
Changed the data array in bsr2log10 to static since otherwise MSVC generates
code to build the array every time the function is called.
* add forgotten template argument to make_format_args which made some uses of FMT_COMPILE not work anymore after 54daa0864afb57e9d1, add more elaborate test cases to compile-test as regression tests
* fix old-style cast which gcc on travis thankfully doesn't accept anymore
* hopefully last forgotten (void*)
* Disable fallthrough attributes for the Intel compilers
On MacOS and Linux the Intel compilers may be identified as the
host compilers (Clang or GNU) but do not support the corresponding
compiler specific fallthrough attributes.
* Rearrange ifdef logic for excluding pre-C++17 fallthrough attributes
This puts Intel and PGI compilers into a separate group
and thus makes the intent and logic more obvious.