Commit 479ee2a8 authored by Victor Zverovich's avatar Victor Zverovich

Fix MSVC build, take 2

parent e928b672
...@@ -68,8 +68,8 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") ...@@ -68,8 +68,8 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
-Wcast-align -Wnon-virtual-dtor -Wcast-align -Wnon-virtual-dtor
-Wctor-dtor-privacy -Wdisabled-optimization -Wctor-dtor-privacy -Wdisabled-optimization
-Winvalid-pch -Wmissing-declarations -Woverloaded-virtual -Winvalid-pch -Wmissing-declarations -Woverloaded-virtual
-Wno-sign-conversion -Wno-shadow -Wno-format-nonliteral -Wno-ctor-dtor-privacy -Wno-dangling-else -Wno-float-equal
-Wno-dangling-else -Wno-ctor-dtor-privacy) -Wno-format-nonliteral -Wno-sign-conversion -Wno-shadow)
if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6) if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6)
set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wnoexcept) set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wnoexcept)
endif () endif ()
......
...@@ -336,8 +336,8 @@ class basic_buffer { ...@@ -336,8 +336,8 @@ class basic_buffer {
std::size_t capacity_; std::size_t capacity_;
protected: protected:
basic_buffer(T *p = FMT_NULL, std::size_t buf_size = 0, std::size_t buf_capacity = 0) basic_buffer(T *p = FMT_NULL, std::size_t sz = 0, std::size_t cap = 0)
FMT_NOEXCEPT: ptr_(p), size_(buf_size), capacity_(buf_capacity) {} FMT_NOEXCEPT: ptr_(p), size_(sz), capacity_(cap) {}
/** Sets the buffer data and capacity. */ /** Sets the buffer data and capacity. */
void set(T *buf_data, std::size_t buf_capacity) FMT_NOEXCEPT { void set(T *buf_data, std::size_t buf_capacity) FMT_NOEXCEPT {
......
...@@ -169,7 +169,8 @@ FMT_END_NAMESPACE ...@@ -169,7 +169,8 @@ FMT_END_NAMESPACE
#endif #endif
// A workaround for gcc 4.4 that doesn't support union members with ctors. // 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 # define FMT_UNION struct
#else #else
# define FMT_UNION union # define FMT_UNION union
...@@ -1553,7 +1554,7 @@ class arg_formatter_base { ...@@ -1553,7 +1554,7 @@ class arg_formatter_base {
if (std::is_same<T, bool>::value) { if (std::is_same<T, bool>::value) {
if (specs_.type_) if (specs_.type_)
return (*this)(value ? 1 : 0); return (*this)(value ? 1 : 0);
write(value); write(value != 0);
} else if (std::is_same<T, char_type>::value) { } else if (std::is_same<T, char_type>::value) {
internal::handle_char_specs( internal::handle_char_specs(
specs_, char_spec_handler(*this, static_cast<char_type>(value))); specs_, char_spec_handler(*this, static_cast<char_type>(value)));
......
...@@ -250,8 +250,6 @@ class printf_arg_formatter: ...@@ -250,8 +250,6 @@ class printf_arg_formatter:
: base(back_insert_range<internal::basic_buffer<char_type>>(buffer), spec), : base(back_insert_range<internal::basic_buffer<char_type>>(buffer), spec),
context_(ctx) {} context_(ctx) {}
using base::operator();
template <typename T> template <typename T>
typename std::enable_if<std::is_integral<T>::value, iterator>::type typename std::enable_if<std::is_integral<T>::value, iterator>::type
operator()(T value) { operator()(T value) {
...@@ -262,7 +260,7 @@ class printf_arg_formatter: ...@@ -262,7 +260,7 @@ class printf_arg_formatter:
if (fmt_spec.type_ != 's') if (fmt_spec.type_ != 's')
return base::operator()(value ? 1 : 0); return base::operator()(value ? 1 : 0);
fmt_spec.type_ = 0; fmt_spec.type_ = 0;
this->write(value); this->write(value != 0);
} else if (std::is_same<T, char_type>::value) { } else if (std::is_same<T, char_type>::value) {
format_specs &fmt_spec = this->spec(); format_specs &fmt_spec = this->spec();
if (fmt_spec.type_ && fmt_spec.type_ != 'c') if (fmt_spec.type_ && fmt_spec.type_ != 'c')
...@@ -304,6 +302,14 @@ class printf_arg_formatter: ...@@ -304,6 +302,14 @@ class printf_arg_formatter:
return this->out(); return this->out();
} }
iterator operator()(basic_string_view<char_type> value) {
return base::operator()(value);
}
iterator operator()(monostate value) {
return base::operator()(value);
}
/** Formats a pointer. */ /** Formats a pointer. */
iterator operator()(const void *value) { iterator operator()(const void *value) {
if (value) if (value)
......
...@@ -93,12 +93,14 @@ struct conditional_helper {}; ...@@ -93,12 +93,14 @@ struct conditional_helper {};
template <typename T, typename _ = void> template <typename T, typename _ = void>
struct is_range_ : std::false_type {}; struct is_range_ : std::false_type {};
#if !FMT_MSC_VER || FMT_MSC_VER > 1800
template <typename T> template <typename T>
struct is_range_<T,typename std::conditional< struct is_range_<T, typename std::conditional<
false, false,
conditional_helper<decltype(internal::declval<T>().begin()), conditional_helper<decltype(internal::declval<T>().begin()),
decltype(internal::declval<T>().end())>, decltype(internal::declval<T>().end())>,
void>::type> : std::true_type {}; void>::type> : std::true_type {};
#endif
/// tuple_size and tuple_element check. /// tuple_size and tuple_element check.
template <typename T> template <typename T>
...@@ -146,7 +148,7 @@ using make_index_sequence = make_integer_sequence<std::size_t, N>; ...@@ -146,7 +148,7 @@ using make_index_sequence = make_integer_sequence<std::size_t, N>;
#endif #endif
template <class Tuple, class F, size_t... Is> template <class Tuple, class F, size_t... Is>
void for_each(index_sequence<Is...>, Tuple &&tup, F &&f) noexcept { void for_each(index_sequence<Is...>, Tuple &&tup, F &&f) FMT_NOEXCEPT {
using std::get; using std::get;
// using free function get<I>(T) now. // using free function get<I>(T) now.
const int _[] = {0, ((void)f(get<Is>(tup)), 0)...}; const int _[] = {0, ((void)f(get<Is>(tup)), 0)...};
......
...@@ -8,6 +8,9 @@ ...@@ -8,6 +8,9 @@
#include "fmt/format.h" #include "fmt/format.h"
#include "gtest-extra.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 // A custom argument formatter that doesn't print `-` for floating-point values
// rounded to 0. // rounded to 0.
class custom_arg_formatter : class custom_arg_formatter :
...@@ -22,21 +25,14 @@ class custom_arg_formatter : ...@@ -22,21 +25,14 @@ class custom_arg_formatter :
using base::operator(); using base::operator();
iterator operator()(double value) { 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 // Comparing a float to 0.0 is safe
if (round(value * pow(10, spec().precision())) == 0.0) if (round(value * pow(10, spec().precision())) == 0.0)
value = 0; value = 0;
return base::operator()(value); 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; fmt::memory_buffer buffer;
// Pass custom argument formatter as a template arg to vwrite. // Pass custom argument formatter as a template arg to vwrite.
fmt::vformat_to<custom_arg_formatter>(buffer, format_str, args); fmt::vformat_to<custom_arg_formatter>(buffer, format_str, args);
...@@ -52,3 +48,4 @@ std::string custom_format(const char *format_str, const Args & ... args) { ...@@ -52,3 +48,4 @@ std::string custom_format(const char *format_str, const Args & ... args) {
TEST(CustomFormatterTest, Format) { TEST(CustomFormatterTest, Format) {
EXPECT_EQ("0.00", custom_format("{:.2f}", -.00001)); EXPECT_EQ("0.00", custom_format("{:.2f}", -.00001));
} }
#endif
...@@ -1423,13 +1423,19 @@ class mock_arg_formatter: ...@@ -1423,13 +1423,19 @@ class mock_arg_formatter:
EXPECT_CALL(*this, call(42)); EXPECT_CALL(*this, call(42));
} }
using base::operator(); template <typename T>
typename std::enable_if<std::is_integral<T>::value, iterator>::type
iterator operator()(int value) { operator()(T value) {
call(value); call(value);
return base::operator()(value); return base::operator()(value);
} }
template <typename T>
typename std::enable_if<!std::is_integral<T>::value, iterator>::type
operator()(T value) {
return base::operator()(value);
}
iterator operator()(fmt::basic_format_arg<fmt::format_context>::handle) { iterator operator()(fmt::basic_format_arg<fmt::format_context>::handle) {
return base::operator()(fmt::monostate()); return base::operator()(fmt::monostate());
} }
......
...@@ -164,6 +164,8 @@ TEST(OStreamTest, Join) { ...@@ -164,6 +164,8 @@ TEST(OStreamTest, Join) {
EXPECT_EQ("1, 2, 3", fmt::format("{}", fmt::join(v, v + 3, ", "))); EXPECT_EQ("1, 2, 3", fmt::format("{}", fmt::join(v, v + 3, ", ")));
} }
#if FMT_USE_CONSTEXPR
TEST(OStreamTest, ConstexprString) { TEST(OStreamTest, ConstexprString) {
EXPECT_EQ("42", format(fmt("{}"), std::string("42"))); EXPECT_EQ("42", format(fmt("{}"), std::string("42")));
} }
#endif
...@@ -11,6 +11,10 @@ ...@@ -11,6 +11,10 @@
#include "fmt/ranges.h" #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 "gtest.h"
#include <vector> #include <vector>
...@@ -46,10 +50,6 @@ TEST(RangesTest, FormatTuple) { ...@@ -46,10 +50,6 @@ TEST(RangesTest, FormatTuple) {
EXPECT_EQ("(42, 3.14159, \"this is tuple\", 'i')", fmt::format("{}", tu1)); 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 { struct my_struct {
int32_t i; int32_t i;
std::string str; // can throw std::string str; // can throw
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment