diff --git a/CMakeLists.txt b/CMakeLists.txt index d95b0c60..78016a98 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,8 +68,8 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") -Wcast-align -Wnon-virtual-dtor -Wctor-dtor-privacy -Wdisabled-optimization -Winvalid-pch -Wmissing-declarations -Woverloaded-virtual - -Wno-sign-conversion -Wno-shadow -Wno-format-nonliteral - -Wno-dangling-else -Wno-ctor-dtor-privacy) + -Wno-ctor-dtor-privacy -Wno-dangling-else -Wno-float-equal + -Wno-format-nonliteral -Wno-sign-conversion -Wno-shadow) if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6) set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wnoexcept) endif () diff --git a/include/fmt/core.h b/include/fmt/core.h index 5019a295..721216ad 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -336,8 +336,8 @@ class basic_buffer { std::size_t capacity_; protected: - basic_buffer(T *p = FMT_NULL, std::size_t buf_size = 0, std::size_t buf_capacity = 0) - FMT_NOEXCEPT: ptr_(p), size_(buf_size), capacity_(buf_capacity) {} + basic_buffer(T *p = FMT_NULL, std::size_t sz = 0, std::size_t cap = 0) + FMT_NOEXCEPT: ptr_(p), size_(sz), capacity_(cap) {} /** Sets the buffer data and capacity. */ void set(T *buf_data, std::size_t buf_capacity) FMT_NOEXCEPT { diff --git a/include/fmt/format.h b/include/fmt/format.h index 0fd2756d..8b6fadd3 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -169,7 +169,8 @@ FMT_END_NAMESPACE #endif // A workaround for gcc 4.4 that doesn't support union members with ctors. -#if FMT_GCC_VERSION && FMT_GCC_VERSION <= 404 +#if (FMT_GCC_VERSION && FMT_GCC_VERSION <= 404) || \ + (FMT_MSC_VER && FMT_MSC_VER <= 1800) # define FMT_UNION struct #else # define FMT_UNION union @@ -1553,7 +1554,7 @@ class arg_formatter_base { if (std::is_same::value) { if (specs_.type_) return (*this)(value ? 1 : 0); - write(value); + write(value != 0); } else if (std::is_same::value) { internal::handle_char_specs( specs_, char_spec_handler(*this, static_cast(value))); diff --git a/include/fmt/printf.h b/include/fmt/printf.h index ba600ca4..dd2df386 100644 --- a/include/fmt/printf.h +++ b/include/fmt/printf.h @@ -250,8 +250,6 @@ class printf_arg_formatter: : base(back_insert_range>(buffer), spec), context_(ctx) {} - using base::operator(); - template typename std::enable_if::value, iterator>::type operator()(T value) { @@ -262,7 +260,7 @@ class printf_arg_formatter: if (fmt_spec.type_ != 's') return base::operator()(value ? 1 : 0); fmt_spec.type_ = 0; - this->write(value); + this->write(value != 0); } else if (std::is_same::value) { format_specs &fmt_spec = this->spec(); if (fmt_spec.type_ && fmt_spec.type_ != 'c') @@ -304,6 +302,14 @@ class printf_arg_formatter: return this->out(); } + iterator operator()(basic_string_view value) { + return base::operator()(value); + } + + iterator operator()(monostate value) { + return base::operator()(value); + } + /** Formats a pointer. */ iterator operator()(const void *value) { if (value) diff --git a/include/fmt/ranges.h b/include/fmt/ranges.h index 7e9a7f06..df22f389 100644 --- a/include/fmt/ranges.h +++ b/include/fmt/ranges.h @@ -93,12 +93,14 @@ struct conditional_helper {}; template struct is_range_ : std::false_type {}; +#if !FMT_MSC_VER || FMT_MSC_VER > 1800 template -struct is_range_().begin()), - decltype(internal::declval().end())>, - void>::type> : std::true_type {}; +struct is_range_().begin()), + decltype(internal::declval().end())>, + void>::type> : std::true_type {}; +#endif /// tuple_size and tuple_element check. template @@ -146,7 +148,7 @@ using make_index_sequence = make_integer_sequence; #endif template -void for_each(index_sequence, Tuple &&tup, F &&f) noexcept { +void for_each(index_sequence, Tuple &&tup, F &&f) FMT_NOEXCEPT { using std::get; // using free function get(T) now. const int _[] = {0, ((void)f(get(tup)), 0)...}; diff --git a/test/custom-formatter-test.cc b/test/custom-formatter-test.cc index 919291ad..9969ed9b 100644 --- a/test/custom-formatter-test.cc +++ b/test/custom-formatter-test.cc @@ -8,6 +8,9 @@ #include "fmt/format.h" #include "gtest-extra.h" +// MSVC 2013 is known to be broken. +#if !FMT_MSC_VER || FMT_MSC_VER > 1800 + // A custom argument formatter that doesn't print `-` for floating-point values // rounded to 0. class custom_arg_formatter : @@ -22,21 +25,14 @@ class custom_arg_formatter : using base::operator(); iterator operator()(double value) { -#if FMT_GCC_VERSION -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wfloat-equal" -#endif // Comparing a float to 0.0 is safe if (round(value * pow(10, spec().precision())) == 0.0) value = 0; return base::operator()(value); -#if FMT_GCC_VERSION -#pragma GCC diagnostic pop -#endif } }; -static std::string custom_vformat(fmt::string_view format_str, fmt::format_args args) { +std::string custom_vformat(fmt::string_view format_str, fmt::format_args args) { fmt::memory_buffer buffer; // Pass custom argument formatter as a template arg to vwrite. fmt::vformat_to(buffer, format_str, args); @@ -52,3 +48,4 @@ std::string custom_format(const char *format_str, const Args & ... args) { TEST(CustomFormatterTest, Format) { EXPECT_EQ("0.00", custom_format("{:.2f}", -.00001)); } +#endif diff --git a/test/format-test.cc b/test/format-test.cc index 39855ae8..3d692589 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -1423,13 +1423,19 @@ class mock_arg_formatter: EXPECT_CALL(*this, call(42)); } - using base::operator(); - - iterator operator()(int value) { + template + typename std::enable_if::value, iterator>::type + operator()(T value) { call(value); return base::operator()(value); } + template + typename std::enable_if::value, iterator>::type + operator()(T value) { + return base::operator()(value); + } + iterator operator()(fmt::basic_format_arg::handle) { return base::operator()(fmt::monostate()); } diff --git a/test/ostream-test.cc b/test/ostream-test.cc index 88c202d3..4d8303d3 100644 --- a/test/ostream-test.cc +++ b/test/ostream-test.cc @@ -164,6 +164,8 @@ TEST(OStreamTest, Join) { EXPECT_EQ("1, 2, 3", fmt::format("{}", fmt::join(v, v + 3, ", "))); } +#if FMT_USE_CONSTEXPR TEST(OStreamTest, ConstexprString) { EXPECT_EQ("42", format(fmt("{}"), std::string("42"))); } +#endif diff --git a/test/ranges-test.cc b/test/ranges-test.cc index 248985b0..3f02cbf5 100644 --- a/test/ranges-test.cc +++ b/test/ranges-test.cc @@ -11,6 +11,10 @@ #include "fmt/ranges.h" +/// Check if 'if constexpr' is supported. +#if (__cplusplus > 201402L) || \ + (defined(_MSVC_LANG) && _MSVC_LANG > 201402L && _MSC_VER >= 1910) + #include "gtest.h" #include @@ -46,10 +50,6 @@ TEST(RangesTest, FormatTuple) { EXPECT_EQ("(42, 3.14159, \"this is tuple\", 'i')", fmt::format("{}", tu1)); } -/// Check if 'if constexpr' is supported. -#if (__cplusplus > 201402L) || \ - (defined(_MSVC_LANG) && _MSVC_LANG > 201402L && _MSC_VER >= 1910) - struct my_struct { int32_t i; std::string str; // can throw