forked from fmtlib/fmt
Fix MSVC build, take 2
This commit is contained in:
@@ -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 {
|
|||||||
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
|
|||||||
#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 {
|
|||||||
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:
|
|||||||
: 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:
|
|||||||
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:
|
|||||||
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 {};
|
|||||||
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>;
|
|||||||
#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 @@
|
|||||||
#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 :
|
|||||||
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) {
|
|||||||
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:
|
|||||||
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) {
|
|||||||
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 @@
|
|||||||
|
|
||||||
#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) {
|
|||||||
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
|
||||||
|
Reference in New Issue
Block a user