mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-30 02:37:36 +02:00
Fix MSVC 2013 build
This commit is contained in:
@ -948,10 +948,10 @@ struct get_type {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename Context>
|
template <typename Context>
|
||||||
FMT_CONSTEXPR uint64_t get_types() { return 0; }
|
FMT_CONSTEXPR unsigned long long get_types() { return 0; }
|
||||||
|
|
||||||
template <typename Context, typename Arg, typename... Args>
|
template <typename Context, typename Arg, typename... Args>
|
||||||
FMT_CONSTEXPR uint64_t get_types() {
|
FMT_CONSTEXPR unsigned long long get_types() {
|
||||||
return get_type<Context, Arg>::value | (get_types<Context, Args...>() << 4);
|
return get_type<Context, Arg>::value | (get_types<Context, Args...>() << 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -995,27 +995,32 @@ class format_arg_store {
|
|||||||
internal::value<Context>, basic_format_arg<Context>>::type value_type;
|
internal::value<Context>, basic_format_arg<Context>>::type value_type;
|
||||||
|
|
||||||
// If the arguments are not packed, add one more element to mark the end.
|
// If the arguments are not packed, add one more element to mark the end.
|
||||||
value_type data_[NUM_ARGS + (IS_PACKED && NUM_ARGS != 0 ? 0 : 1)];
|
static const size_t DATA_SIZE =
|
||||||
|
NUM_ARGS + (IS_PACKED && NUM_ARGS != 0 ? 0 : 1);
|
||||||
|
value_type data_[DATA_SIZE];
|
||||||
|
|
||||||
friend class basic_format_args<Context>;
|
friend class basic_format_args<Context>;
|
||||||
|
|
||||||
static FMT_CONSTEXPR int64_t get_types() {
|
static FMT_CONSTEXPR long long get_types() {
|
||||||
return IS_PACKED ?
|
return IS_PACKED ?
|
||||||
static_cast<int64_t>(internal::get_types<Context, Args...>()) :
|
static_cast<long long>(internal::get_types<Context, Args...>()) :
|
||||||
-static_cast<int64_t>(NUM_ARGS);
|
-static_cast<long long>(NUM_ARGS);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
#if FMT_USE_CONSTEXPR
|
#if FMT_USE_CONSTEXPR
|
||||||
static constexpr int64_t TYPES = get_types();
|
static constexpr long long TYPES = get_types();
|
||||||
#else
|
#else
|
||||||
static const int64_t TYPES;
|
static const long long TYPES;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if FMT_GCC_VERSION && FMT_GCC_VERSION <= 405
|
#if (FMT_GCC_VERSION && FMT_GCC_VERSION <= 405) || \
|
||||||
// Workaround an array initialization bug in gcc 4.5 and earlier.
|
(FMT_MSC_VER && FMT_MSC_VER <= 1800)
|
||||||
|
// Workaround array initialization issues in gcc <= 4.5 and MSVC <= 2013.
|
||||||
format_arg_store(const Args &... args) {
|
format_arg_store(const Args &... args) {
|
||||||
data_ = {internal::make_arg<IS_PACKED, Context>(args)...};
|
value_type init[DATA_SIZE] =
|
||||||
|
{internal::make_arg<IS_PACKED, Context>(args)...};
|
||||||
|
std::memcpy(data_, init, sizeof(init));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
format_arg_store(const Args &... args)
|
format_arg_store(const Args &... args)
|
||||||
@ -1025,7 +1030,7 @@ class format_arg_store {
|
|||||||
|
|
||||||
#if !FMT_USE_CONSTEXPR
|
#if !FMT_USE_CONSTEXPR
|
||||||
template <typename Context, typename ...Args>
|
template <typename Context, typename ...Args>
|
||||||
const int64_t format_arg_store<Context, Args...>::TYPES = get_types();
|
const long long format_arg_store<Context, Args...>::TYPES = get_types();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1057,7 +1062,7 @@ class basic_format_args {
|
|||||||
private:
|
private:
|
||||||
// To reduce compiled code size per formatting function call, types of first
|
// To reduce compiled code size per formatting function call, types of first
|
||||||
// max_packed_args arguments are passed in the types_ field.
|
// max_packed_args arguments are passed in the types_ field.
|
||||||
uint64_t types_;
|
unsigned long long types_;
|
||||||
union {
|
union {
|
||||||
// If the number of arguments is less than max_packed_args, the argument
|
// If the number of arguments is less than max_packed_args, the argument
|
||||||
// values are stored in values_, otherwise they are stored in args_.
|
// values are stored in values_, otherwise they are stored in args_.
|
||||||
@ -1070,7 +1075,7 @@ class basic_format_args {
|
|||||||
|
|
||||||
typename internal::type type(unsigned index) const {
|
typename internal::type type(unsigned index) const {
|
||||||
unsigned shift = index * 4;
|
unsigned shift = index * 4;
|
||||||
uint64_t mask = 0xf;
|
unsigned long long mask = 0xf;
|
||||||
return static_cast<typename internal::type>(
|
return static_cast<typename internal::type>(
|
||||||
(types_ & (mask << shift)) >> shift);
|
(types_ & (mask << shift)) >> shift);
|
||||||
}
|
}
|
||||||
@ -1081,9 +1086,9 @@ class basic_format_args {
|
|||||||
void set_data(const format_arg *args) { args_ = args; }
|
void set_data(const format_arg *args) { args_ = args; }
|
||||||
|
|
||||||
format_arg do_get(size_type index) const {
|
format_arg do_get(size_type index) const {
|
||||||
int64_t signed_types = static_cast<int64_t>(types_);
|
long long signed_types = static_cast<long long>(types_);
|
||||||
if (signed_types < 0) {
|
if (signed_types < 0) {
|
||||||
uint64_t num_args = static_cast<uint64_t>(-signed_types);
|
unsigned long long num_args = static_cast<unsigned long long>(-signed_types);
|
||||||
return index < num_args ? args_[index] : format_arg();
|
return index < num_args ? args_[index] : format_arg();
|
||||||
}
|
}
|
||||||
format_arg arg;
|
format_arg arg;
|
||||||
@ -1119,10 +1124,10 @@ class basic_format_args {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned max_size() const {
|
unsigned max_size() const {
|
||||||
int64_t signed_types = static_cast<int64_t>(types_);
|
long long signed_types = static_cast<long long>(types_);
|
||||||
return static_cast<unsigned>(
|
return static_cast<unsigned>(
|
||||||
signed_types < 0 ?
|
signed_types < 0 ?
|
||||||
-signed_types : static_cast<int64_t>(internal::max_packed_args));
|
-signed_types : static_cast<long long>(internal::max_packed_args));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1293,28 +1293,6 @@ struct align_spec : empty_spec {
|
|||||||
// Format specifiers.
|
// Format specifiers.
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
class basic_format_specs : public align_spec {
|
class basic_format_specs : public align_spec {
|
||||||
private:
|
|
||||||
template <typename FillChar>
|
|
||||||
typename std::enable_if<std::is_same<FillChar, Char>::value ||
|
|
||||||
std::is_same<FillChar, char>::value, void>::type
|
|
||||||
set(fill_spec<FillChar> fill) {
|
|
||||||
fill_ = fill.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
void set(width_spec width) {
|
|
||||||
width_ = width.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
void set(type_spec type) {
|
|
||||||
type_ = type.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Spec, typename... Specs>
|
|
||||||
void set(Spec spec, Specs... tail) {
|
|
||||||
set(spec);
|
|
||||||
set(tail...);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
unsigned flags_;
|
unsigned flags_;
|
||||||
int precision_;
|
int precision_;
|
||||||
@ -1324,12 +1302,6 @@ class basic_format_specs : public align_spec {
|
|||||||
unsigned width = 0, char type = 0, wchar_t fill = ' ')
|
unsigned width = 0, char type = 0, wchar_t fill = ' ')
|
||||||
: align_spec(width, fill), flags_(0), precision_(-1), type_(type) {}
|
: align_spec(width, fill), flags_(0), precision_(-1), type_(type) {}
|
||||||
|
|
||||||
template <typename... FormatSpecs>
|
|
||||||
explicit basic_format_specs(FormatSpecs... specs)
|
|
||||||
: align_spec(0, ' '), flags_(0), precision_(-1), type_(0) {
|
|
||||||
set(specs...);
|
|
||||||
}
|
|
||||||
|
|
||||||
FMT_CONSTEXPR bool flag(unsigned f) const { return (flags_ & f) != 0; }
|
FMT_CONSTEXPR bool flag(unsigned f) const { return (flags_ & f) != 0; }
|
||||||
FMT_CONSTEXPR int precision() const { return precision_; }
|
FMT_CONSTEXPR int precision() const { return precision_; }
|
||||||
FMT_CONSTEXPR Char type() const { return type_; }
|
FMT_CONSTEXPR Char type() const { return type_; }
|
||||||
@ -1576,7 +1548,18 @@ class arg_formatter_base {
|
|||||||
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) {
|
||||||
writer_.write_int(value, specs_);
|
// MSVC2013 fails to compile separate overloads for bool and char_type so
|
||||||
|
// use std::is_same instead.
|
||||||
|
if (std::is_same<T, bool>::value) {
|
||||||
|
if (specs_.type_)
|
||||||
|
return (*this)(value ? 1 : 0);
|
||||||
|
write(value);
|
||||||
|
} else if (std::is_same<T, char_type>::value) {
|
||||||
|
internal::handle_char_specs(
|
||||||
|
specs_, char_spec_handler(*this, static_cast<char_type>(value)));
|
||||||
|
} else {
|
||||||
|
writer_.write_int(value, specs_);
|
||||||
|
}
|
||||||
return out();
|
return out();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1587,13 +1570,6 @@ class arg_formatter_base {
|
|||||||
return out();
|
return out();
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator operator()(bool value) {
|
|
||||||
if (specs_.type_)
|
|
||||||
return (*this)(value ? 1 : 0);
|
|
||||||
write(value);
|
|
||||||
return out();
|
|
||||||
}
|
|
||||||
|
|
||||||
struct char_spec_handler : internal::error_handler {
|
struct char_spec_handler : internal::error_handler {
|
||||||
arg_formatter_base &formatter;
|
arg_formatter_base &formatter;
|
||||||
char_type value;
|
char_type value;
|
||||||
@ -1605,11 +1581,6 @@ class arg_formatter_base {
|
|||||||
void on_char() { formatter.write_char(value); }
|
void on_char() { formatter.write_char(value); }
|
||||||
};
|
};
|
||||||
|
|
||||||
iterator operator()(char_type value) {
|
|
||||||
internal::handle_char_specs(specs_, char_spec_handler(*this, value));
|
|
||||||
return out();
|
|
||||||
}
|
|
||||||
|
|
||||||
struct cstring_spec_handler : internal::error_handler {
|
struct cstring_spec_handler : internal::error_handler {
|
||||||
arg_formatter_base &formatter;
|
arg_formatter_base &formatter;
|
||||||
const char_type *value;
|
const char_type *value;
|
||||||
|
@ -252,23 +252,33 @@ class printf_arg_formatter:
|
|||||||
|
|
||||||
using base::operator();
|
using base::operator();
|
||||||
|
|
||||||
/** Formats an argument of type ``bool``. */
|
template <typename T>
|
||||||
iterator operator()(bool value) {
|
typename std::enable_if<std::is_integral<T>::value, iterator>::type
|
||||||
format_specs &fmt_spec = this->spec();
|
operator()(T value) {
|
||||||
if (fmt_spec.type_ != 's')
|
// MSVC2013 fails to compile separate overloads for bool and char_type so
|
||||||
return (*this)(value ? 1 : 0);
|
// use std::is_same instead.
|
||||||
fmt_spec.type_ = 0;
|
if (std::is_same<T, bool>::value) {
|
||||||
this->write(value);
|
format_specs &fmt_spec = this->spec();
|
||||||
|
if (fmt_spec.type_ != 's')
|
||||||
|
return base::operator()(value ? 1 : 0);
|
||||||
|
fmt_spec.type_ = 0;
|
||||||
|
this->write(value);
|
||||||
|
} else if (std::is_same<T, char_type>::value) {
|
||||||
|
format_specs &fmt_spec = this->spec();
|
||||||
|
if (fmt_spec.type_ && fmt_spec.type_ != 'c')
|
||||||
|
return (*this)(static_cast<int>(value));
|
||||||
|
fmt_spec.flags_ = 0;
|
||||||
|
fmt_spec.align_ = ALIGN_RIGHT;
|
||||||
|
return base::operator()(value);
|
||||||
|
} else {
|
||||||
|
return base::operator()(value);
|
||||||
|
}
|
||||||
return this->out();
|
return this->out();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Formats a character. */
|
template <typename T>
|
||||||
iterator operator()(char_type value) {
|
typename std::enable_if<std::is_floating_point<T>::value, iterator>::type
|
||||||
format_specs &fmt_spec = this->spec();
|
operator()(T value) {
|
||||||
if (fmt_spec.type_ && fmt_spec.type_ != 'c')
|
|
||||||
return (*this)(static_cast<int>(value));
|
|
||||||
fmt_spec.flags_ = 0;
|
|
||||||
fmt_spec.align_ = ALIGN_RIGHT;
|
|
||||||
return base::operator()(value);
|
return base::operator()(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user