Mercurial > embed
changeset 27:f7353f16bc70
fmt: upgrade to 3.0.1
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 01 Dec 2016 12:59:19 +0100 |
parents | 12bf6de5b67a |
children | c374a84a1fa9 |
files | VERSION.fmt.txt fmt/format.cc fmt/format.h |
diffstat | 3 files changed, 102 insertions(+), 46 deletions(-) [+] |
line wrap: on
line diff
--- a/VERSION.fmt.txt Thu Dec 01 12:54:08 2016 +0100 +++ b/VERSION.fmt.txt Thu Dec 01 12:59:19 2016 +0100 @@ -1,1 +1,1 @@ -3.0.0 +3.0.1
--- a/fmt/format.cc Thu Dec 01 12:54:08 2016 +0100 +++ b/fmt/format.cc Thu Dec 01 12:59:19 2016 +0100 @@ -79,6 +79,11 @@ } namespace fmt { + +FMT_FUNC internal::RuntimeError::~RuntimeError() throw() {} +FMT_FUNC FormatError::~FormatError() throw() {} +FMT_FUNC SystemError::~SystemError() throw() {} + namespace { #ifndef _MSC_VER
--- a/fmt/format.h Thu Dec 01 12:54:08 2016 +0100 +++ b/fmt/format.h Thu Dec 01 12:59:19 2016 +0100 @@ -50,7 +50,13 @@ # include <iterator> #endif -#if defined(_MSC_VER) && _MSC_VER <= 1500 +#ifdef _MSC_VER +# define FMT_MSC_VER _MSC_VER +#else +# define FMT_MSC_VER 0 +#endif + +#if FMT_MSC_VER && FMT_MSC_VER <= 1500 typedef unsigned __int32 uint32_t; typedef unsigned __int64 uint64_t; typedef __int64 intmax_t; @@ -99,7 +105,8 @@ #if defined(__clang__) && !defined(FMT_ICC_VERSION) # pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wdocumentation" +# pragma clang diagnostic ignored "-Wdocumentation-unknown-command" +# pragma clang diagnostic ignored "-Wpadded" #endif #ifdef __GNUC_LIBSTD__ @@ -130,7 +137,7 @@ // since version 2013. # define FMT_USE_VARIADIC_TEMPLATES \ (FMT_HAS_FEATURE(cxx_variadic_templates) || \ - (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1800) + (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1800) #endif #ifndef FMT_USE_RVALUE_REFERENCES @@ -141,7 +148,7 @@ # else # define FMT_USE_RVALUE_REFERENCES \ (FMT_HAS_FEATURE(cxx_rvalue_references) || \ - (FMT_GCC_VERSION >= 403 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1600) + (FMT_GCC_VERSION >= 403 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1600) # endif #endif @@ -153,7 +160,7 @@ #if defined(__GNUC__) && !defined(__EXCEPTIONS) # define FMT_EXCEPTIONS 0 #endif -#if defined(_MSC_VER) && !_HAS_EXCEPTIONS +#if FMT_MSC_VER && !_HAS_EXCEPTIONS # define FMT_EXCEPTIONS 0 #endif #ifndef FMT_EXCEPTIONS @@ -177,7 +184,7 @@ # if FMT_EXCEPTIONS # if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \ (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || \ - _MSC_VER >= 1900 + FMT_MSC_VER >= 1900 # define FMT_NOEXCEPT noexcept # else # define FMT_NOEXCEPT throw() @@ -187,6 +194,17 @@ # endif #endif +#ifndef FMT_OVERRIDE +# if FMT_USE_OVERRIDE || FMT_HAS_FEATURE(cxx_override) || \ + (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || \ + FMT_MSC_VER >= 1900 +# define FMT_OVERRIDE override +# else +# define FMT_OVERRIDE +# endif +#endif + + // A macro to disallow the copy constructor and operator= functions // This should be used in the private: declarations for a class #ifndef FMT_USE_DELETED_FUNCTIONS @@ -194,7 +212,7 @@ #endif #if FMT_USE_DELETED_FUNCTIONS || FMT_HAS_FEATURE(cxx_deleted_functions) || \ - (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1800 + (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1800 # define FMT_DELETED_OR_UNDEFINED = delete # define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName) \ TypeName(const TypeName&) = delete; \ @@ -214,7 +232,7 @@ # define FMT_USE_USER_DEFINED_LITERALS \ FMT_USE_VARIADIC_TEMPLATES && FMT_USE_RVALUE_REFERENCES && \ (FMT_HAS_FEATURE(cxx_user_literals) || \ - (FMT_GCC_VERSION >= 407 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1900) && \ + (FMT_GCC_VERSION >= 407 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1900) && \ (!defined(FMT_ICC_VERSION) || FMT_ICC_VERSION >= 1500) #endif @@ -222,7 +240,6 @@ # define FMT_ASSERT(condition, message) assert((condition) && message) #endif - #if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clz) # define FMT_BUILTIN_CLZ(n) __builtin_clz(n) #endif @@ -231,11 +248,11 @@ # define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n) #endif -// Some compilers masquerade as both MSVC and GCC-likes or +// Some compilers masquerade as both MSVC and GCC-likes or // otherwise support __builtin_clz and __builtin_clzll, so // only define FMT_BUILTIN_CLZ using the MSVC intrinsics // if the clz and clzll builtins are not available. -#if defined(_MSC_VER) && !defined(FMT_BUILTIN_CLZLL) +#if FMT_MSC_VER && !defined(FMT_BUILTIN_CLZLL) # include <intrin.h> // _BitScanReverse, _BitScanReverse64 namespace fmt { @@ -247,7 +264,7 @@ assert(x != 0); // Static analysis complains about using uninitialized data - // "r", but the only way that can happen is if "x" is 0, + // "r", but the only way that can happen is if "x" is 0, // which the callers guarantee to not happen. # pragma warning(suppress: 6102) return 31 - r; @@ -273,7 +290,7 @@ assert(x != 0); // Static analysis complains about using uninitialized data - // "r", but the only way that can happen is if "x" is 0, + // "r", but the only way that can happen is if "x" is 0, // which the callers guarantee to not happen. # pragma warning(suppress: 6102) return 63 - r; @@ -303,7 +320,7 @@ // A helper function to suppress bogus "conditional expression is constant" // warnings. template <typename T> -inline T check(T value) { return value; } +inline T const_check(T value) { return value; } } } // namespace fmt @@ -322,8 +339,8 @@ using namespace fmt::internal; // The resolution "priority" is: // isinf macro > std::isinf > ::isinf > fmt::internal::isinf - if (check(sizeof(isinf(x)) == sizeof(bool) || - sizeof(isinf(x)) == sizeof(int))) { + if (const_check(sizeof(isinf(x)) == sizeof(bool) || + sizeof(isinf(x)) == sizeof(int))) { return isinf(x) != 0; } return !_finite(static_cast<double>(x)); @@ -333,8 +350,8 @@ template <typename T> static bool isnotanumber(T x) { using namespace fmt::internal; - if (check(sizeof(isnan(x)) == sizeof(bool) || - sizeof(isnan(x)) == sizeof(int))) { + if (const_check(sizeof(isnan(x)) == sizeof(bool) || + sizeof(isnan(x)) == sizeof(int))) { return isnan(x) != 0; } return _isnan(static_cast<double>(x)) != 0; @@ -343,7 +360,7 @@ // Portable version of signbit. static bool isnegative(double x) { using namespace fmt::internal; - if (check(sizeof(signbit(x)) == sizeof(int))) + if (const_check(sizeof(signbit(x)) == sizeof(int))) return signbit(x) != 0; if (x < 0) return true; if (!isnotanumber(x)) return false; @@ -525,13 +542,12 @@ typedef BasicCStringRef<char> CStringRef; typedef BasicCStringRef<wchar_t> WCStringRef; -/** - A formatting error such as invalid format string. -*/ +/** A formatting error such as invalid format string. */ class FormatError : public std::runtime_error { public: explicit FormatError(CStringRef message) : std::runtime_error(message.c_str()) {} + ~FormatError() throw(); }; namespace internal { @@ -657,8 +673,8 @@ namespace internal { -// A memory buffer for trivially copyable/constructible types with the first SIZE -// elements stored in the object itself. +// A memory buffer for trivially copyable/constructible types with the first +// SIZE elements stored in the object itself. template <typename T, std::size_t SIZE, typename Allocator = std::allocator<T> > class MemoryBuffer : private Allocator, public Buffer<T> { private: @@ -670,7 +686,7 @@ } protected: - void grow(std::size_t size); + void grow(std::size_t size) FMT_OVERRIDE; public: explicit MemoryBuffer(const Allocator &alloc = Allocator()) @@ -830,6 +846,16 @@ static const char DIGITS[]; }; +#ifndef FMT_USE_EXTERN_TEMPLATES +// Clang doesn't have a feature check for extern templates so we check +// for variadic templates which were introduced in the same version. +# define FMT_USE_EXTERN_TEMPLATES (__clang__ && FMT_USE_VARIADIC_TEMPLATES) +#endif + +#if FMT_USE_EXTERN_TEMPLATES && !defined(FMT_HEADER_ONLY) +extern template struct BasicData<void>; +#endif + typedef BasicData<> Data; #ifdef FMT_BUILTIN_CLZLL @@ -918,6 +944,7 @@ } unsigned index = static_cast<unsigned>(value * 2); *--buffer = Data::DIGITS[index + 1]; + thousands_sep(buffer); *--buffer = Data::DIGITS[index]; } @@ -1105,6 +1132,21 @@ template<> struct Not<false> { enum { value = 1 }; }; +template<typename T, T> struct LConvCheck { + LConvCheck(int) {} +}; + +// Returns the thousands separator for the current locale. +// We check if ``lconv`` contains ``thousands_sep`` because on Android +// ``lconv`` is stubbed as an empty struct. +template <typename LConv> +inline StringRef thousands_sep( + LConv *lc, LConvCheck<char *LConv::*, &LConv::thousands_sep> = 0) { + return lc->thousands_sep; +} + +inline fmt::StringRef thousands_sep(...) { return ""; } + // Makes an Arg object from any type. template <typename Formatter> class MakeValue : public Arg { @@ -1126,7 +1168,7 @@ // characters and strings into narrow strings as in // fmt::format("{}", L"test"); // To fix this, use a wide format string: fmt::format(L"{}", L"test"). -#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) +#if !FMT_MSC_VER || defined(_NATIVE_WCHAR_T_DEFINED) MakeValue(typename WCharHelper<wchar_t, Char>::Unsupported); #endif MakeValue(typename WCharHelper<wchar_t *, Char>::Unsupported); @@ -1172,7 +1214,7 @@ MakeValue(long value) { // To minimize the number of types we need to deal with, long is // translated either to int or to long long depending on its size. - if (check(sizeof(long) == sizeof(int))) + if (const_check(sizeof(long) == sizeof(int))) int_value = static_cast<int>(value); else long_long_value = value; @@ -1182,7 +1224,7 @@ } MakeValue(unsigned long value) { - if (check(sizeof(unsigned long) == sizeof(unsigned))) + if (const_check(sizeof(unsigned long) == sizeof(unsigned))) uint_value = static_cast<unsigned>(value); else ulong_long_value = value; @@ -1214,7 +1256,9 @@ FMT_MAKE_VALUE(char *, string.value, CSTRING) FMT_MAKE_VALUE(const char *, string.value, CSTRING) + FMT_MAKE_VALUE(signed char *, sstring.value, CSTRING) FMT_MAKE_VALUE(const signed char *, sstring.value, CSTRING) + FMT_MAKE_VALUE(unsigned char *, ustring.value, CSTRING) FMT_MAKE_VALUE(const unsigned char *, ustring.value, CSTRING) FMT_MAKE_STR_VALUE(const std::string &, STRING) FMT_MAKE_STR_VALUE(StringRef, STRING) @@ -1268,7 +1312,7 @@ MakeArg() { type = Arg::NONE; } - + template <typename T> MakeArg(const T &value) : Arg(MakeValue<Formatter>(value)) { @@ -1288,6 +1332,7 @@ class RuntimeError : public std::runtime_error { protected: RuntimeError() : std::runtime_error("") {} + ~RuntimeError() throw(); }; template <typename Char> @@ -1487,9 +1532,10 @@ */ Result visit(const Arg &arg) { switch (arg.type) { - default: + case Arg::NONE: + case Arg::NAMED_ARG: FMT_ASSERT(false, "invalid argument type"); - return Result(); + break; case Arg::INT: return FMT_DISPATCH(visit_int(arg.int_value)); case Arg::UINT: @@ -1517,6 +1563,7 @@ case Arg::CUSTOM: return FMT_DISPATCH(visit_custom(arg.custom)); } + return Result(); } }; @@ -1822,21 +1869,21 @@ typedef typename BasicWriter<Char>::CharPtr CharPtr; Char fill = internal::CharTraits<Char>::cast(spec_.fill()); CharPtr out = CharPtr(); - const unsigned CHAR_WIDTH = 1; - if (spec_.width_ > CHAR_WIDTH) { + const unsigned CHAR_SIZE = 1; + if (spec_.width_ > CHAR_SIZE) { out = writer_.grow_buffer(spec_.width_); if (spec_.align_ == ALIGN_RIGHT) { - std::uninitialized_fill_n(out, spec_.width_ - CHAR_WIDTH, fill); - out += spec_.width_ - CHAR_WIDTH; + std::uninitialized_fill_n(out, spec_.width_ - CHAR_SIZE, fill); + out += spec_.width_ - CHAR_SIZE; } else if (spec_.align_ == ALIGN_CENTER) { out = writer_.fill_padding(out, spec_.width_, - internal::check(CHAR_WIDTH), fill); + internal::const_check(CHAR_SIZE), fill); } else { - std::uninitialized_fill_n(out + CHAR_WIDTH, - spec_.width_ - CHAR_WIDTH, fill); + std::uninitialized_fill_n(out + CHAR_SIZE, + spec_.width_ - CHAR_SIZE, fill); } } else { - out = writer_.grow_buffer(CHAR_WIDTH); + out = writer_.grow_buffer(CHAR_SIZE); } *out = internal::CharTraits<Char>::cast(value); } @@ -2063,7 +2110,7 @@ template <unsigned N> struct ArgArray<N, true/*IsPacked*/> { typedef Value Type[N > 0 ? N : 1]; - + template <typename Formatter, typename T> static Value make(const T &value) { #ifdef __clang__ @@ -2258,6 +2305,8 @@ } FMT_VARIADIC_CTOR(SystemError, init, int, CStringRef) + ~SystemError() throw(); + int error_code() const { return error_code_; } }; @@ -2588,7 +2637,6 @@ if (str_size == 0) { if (!str_value) { FMT_THROW(FormatError("string pointer is null")); - return; } } std::size_t precision = static_cast<std::size_t>(spec.precision_); @@ -2753,9 +2801,12 @@ } case 'n': { unsigned num_digits = internal::count_digits(abs_value); - fmt::StringRef sep = std::localeconv()->thousands_sep; + fmt::StringRef sep = ""; +#ifndef ANDROID + sep = internal::thousands_sep(std::localeconv()); +#endif unsigned size = static_cast<unsigned>( - num_digits + sep.size() * (num_digits - 1) / 3); + num_digits + sep.size() * ((num_digits - 1) / 3)); CharPtr p = prepare_int_buffer(size, spec, prefix, prefix_size) + 1; internal::format_decimal(get(p), abs_value, 0, internal::ThousandsSep(sep)); break; @@ -2780,7 +2831,7 @@ case 'e': case 'f': case 'g': case 'a': break; case 'F': -#ifdef _MSC_VER +#if FMT_MSC_VER // MSVC's printf doesn't support 'F'. type = 'f'; #endif @@ -2873,7 +2924,7 @@ Char *start = 0; for (;;) { std::size_t buffer_size = buffer_.capacity() - offset; -#ifdef _MSC_VER +#if FMT_MSC_VER // MSVC's vsnprintf_s doesn't work with zero size, so reserve // space for at least one extra character to make the size non-zero. // Note that the buffer's capacity will increase by more than 1.