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.