Fix compilation errors on gcc 4.4

This commit is contained in:
Victor Zverovich 2018-03-01 03:45:25 -08:00
parent 45518c3fe1
commit 1d2adef28d
2 changed files with 37 additions and 10 deletions

View File

@ -170,8 +170,10 @@
namespace fmt { namespace fmt {
// An implementation of declval for pre-C++11 compilers such as gcc 4. // An implementation of declval for pre-C++11 compilers such as gcc 4.
namespace internal {
template <typename T> template <typename T>
typename std::add_rvalue_reference<T>::type declval() FMT_NOEXCEPT; typename std::add_rvalue_reference<T>::type declval() FMT_NOEXCEPT;
}
/** /**
\rst \rst
@ -962,8 +964,15 @@ class arg_store {
public: public:
static const uint64_t TYPES; static const uint64_t TYPES;
#if FMT_GCC_VERSION && FMT_GCC_VERSION <= 405 && !defined(__clang__)
// Workaround an array initialization bug in gcc 4.5 and earlier.
arg_store(const Args &... args) {
data_ = {internal::make_arg<IS_PACKED, Context>(args)...};
}
#else
arg_store(const Args &... args) arg_store(const Args &... args)
: data_{internal::make_arg<IS_PACKED, Context>(args)...} {} : data_{internal::make_arg<IS_PACKED, Context>(args)...} {}
#endif
basic_format_args<Context> operator*() const { return *this; } basic_format_args<Context> operator*() const { return *this; }

View File

@ -212,6 +212,19 @@ inline uint32_t clzll(uint64_t x) {
namespace fmt { namespace fmt {
namespace internal { namespace internal {
// An implementation of begin and end for pre-C++11 compilers such as gcc 4.
template <typename C>
FMT_CONSTEXPR auto begin(const C &c) -> decltype(c.begin()) {
return c.begin();
}
template <typename T, std::size_t N>
FMT_CONSTEXPR T *begin(T (&array)[N]) FMT_NOEXCEPT { return array; }
template <typename C>
FMT_CONSTEXPR auto end(const C &c) -> decltype(c.end()) { return c.end(); }
template <typename T, std::size_t N>
FMT_CONSTEXPR T *end(T (&array)[N]) FMT_NOEXCEPT { return array + N; }
struct dummy_int { struct dummy_int {
int data[2]; int data[2];
operator int() const { return 0; } operator int() const { return 0; }
@ -2093,7 +2106,7 @@ template <typename Range>
class arg_formatter: public internal::arg_formatter_base<Range> { class arg_formatter: public internal::arg_formatter_base<Range> {
private: private:
typedef typename Range::value_type char_type; typedef typename Range::value_type char_type;
typedef decltype(declval<Range>().begin()) iterator; typedef decltype(internal::declval<Range>().begin()) iterator;
typedef internal::arg_formatter_base<Range> base; typedef internal::arg_formatter_base<Range> base;
typedef basic_context<iterator, char_type> context_type; typedef basic_context<iterator, char_type> context_type;
@ -2191,7 +2204,7 @@ template <typename Range>
class basic_writer { class basic_writer {
public: public:
typedef typename Range::value_type char_type; typedef typename Range::value_type char_type;
typedef decltype(declval<Range>().begin()) iterator; typedef decltype(internal::declval<Range>().begin()) iterator;
typedef basic_format_specs<char_type> format_specs; typedef basic_format_specs<char_type> format_specs;
private: private:
@ -2660,10 +2673,15 @@ void basic_writer<Range>::write_double(T value, const format_specs &spec) {
sign = spec.flag(PLUS_FLAG) ? '+' : ' '; sign = spec.flag(PLUS_FLAG) ? '+' : ' ';
} }
auto write_inf_or_nan = [this, &spec, sign](const char *str) { struct write_inf_or_nan_t {
this->write_padded(INF_SIZE + (sign ? 1 : 0), spec, basic_writer &writer;
format_specs spec;
char sign;
void operator()(const char *str) const {
writer.write_padded(INF_SIZE + (sign ? 1 : 0), spec,
inf_or_nan_writer{sign, str}); inf_or_nan_writer{sign, str});
}; }
} write_inf_or_nan = {*this, spec, sign};
// Format NaN and ininity ourselves because sprintf's output is not consistent // Format NaN and ininity ourselves because sprintf's output is not consistent
// across platforms. // across platforms.
@ -3235,14 +3253,14 @@ arg_join<It, wchar_t> join(It begin, It end, wstring_view sep) {
#if FMT_USE_TRAILING_RETURN #if FMT_USE_TRAILING_RETURN
template <typename Range> template <typename Range>
auto join(const Range &range, string_view sep) auto join(const Range &range, string_view sep)
-> arg_join<decltype(std::begin(range)), char> { -> arg_join<decltype(internal::begin(range)), char> {
return join(std::begin(range), std::end(range), sep); return join(internal::begin(range), internal::end(range), sep);
} }
template <typename Range> template <typename Range>
auto join(const Range &range, wstring_view sep) auto join(const Range &range, wstring_view sep)
-> arg_join<decltype(std::begin(range)), wchar_t> { -> arg_join<decltype(internal::begin(range)), wchar_t> {
return join(std::begin(range), std::end(range), sep); return join(internal::begin(range), internal::end(range), sep);
} }
#endif #endif