Update to upstream 4.1.0.

Change-Id: Ifc8392bb9f914309f47959322c24d4d8237374a7
diff --git a/.travis.yml b/.travis.yml
index d6b81a2..c359852 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,4 +1,5 @@
 language: cpp
+dist: trusty
 sudo: required # the doc target uses sudo to install dependencies
 
 os:
@@ -22,12 +23,5 @@
     - os: osx
       env: BUILD=Doc
 
-addons:
-  apt:
-    sources:
-      - kubuntu-backports # cmake 2.8.12
-    packages:
-      - cmake
-
 script:
   - support/travis-build.py
diff --git a/Android.bp b/Android.bp
index df185fa..6897195 100644
--- a/Android.bp
+++ b/Android.bp
@@ -5,6 +5,8 @@
         "-fno-exceptions",
         "-Wall",
         "-Werror",
+        // If built without exceptions, libfmt uses assert.
+        "-UNDEBUG",
     ],
     sanitize: {
         misc_undefined: ["integer"],
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b08f9cb..d99babd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,6 +2,14 @@
 
 cmake_minimum_required(VERSION 2.8.12)
 
+if (POLICY CMP0048) # Version variables
+  cmake_policy(SET CMP0048 OLD)
+endif ()
+
+if (POLICY CMP0063) # Visibility
+  cmake_policy(SET CMP0063 OLD)
+endif (POLICY CMP0063)
+
 # Determine if fmt is built as a subproject (using add_subdirectory)
 # or if it is the master project.
 set(MASTER_PROJECT OFF)
diff --git a/ChangeLog.rst b/ChangeLog.rst
index f4df68b..86b7a7c 100644
--- a/ChangeLog.rst
+++ b/ChangeLog.rst
@@ -1,3 +1,127 @@
+4.1.1 - TBD
+------------
+ 
+4.1.0 - 2017-12-20
+------------------
+
+* Added ``fmt::to_wstring()`` in addition to ``fmt::to_string()`` (`#559 <https://github.com/fmtlib/fmt/pull/559>`_). Thanks `@alabuzhev (Alex Alabuzhev) <https://github.com/alabuzhev>`_.
+
+* Added support for C++17 ``std::string_view`` (`#571 <https://github.com/fmtlib/fmt/pull/571>`_ and `#578 <https://github.com/fmtlib/fmt/pull/578>`_). Thanks `@thelostt (Mário Feroldi) <https://github.com/thelostt>`_ and `@mwinterb <https://github.com/mwinterb>`_.
+
+* Enabled stream exceptions to catch errors (`#581 <https://github.com/fmtlib/fmt/issues/581>`_). Thanks `@crusader-mike <https://github.com/crusader-mike>`_.
+
+* Allowed formatting of class hierarchies with ``fmt::format_arg()`` (`#547 <https://github.com/fmtlib/fmt/pull/547>`_). Thanks `@rollbear (Björn Fahller) <https://github.com/rollbear>`_.
+
+* Removed limitations on character types
+  (`#563 <https://github.com/fmtlib/fmt/pull/563>`_).
+  Thanks `@Yelnats321 (Elnar Dakeshov) <https://github.com/Yelnats321>`_.
+
+* Conditionally enabled use of ``std::allocator_traits`` (`#583 <https://github.com/fmtlib/fmt/pull/583>`_). Thanks `@mwinterb <https://github.com/mwinterb>`_.
+
+* Added support for ``const`` variadic member function emulation with ``FMT_VARIADIC_CONST`` (`#591 <https://github.com/fmtlib/fmt/pull/591>`_). Thanks `@ludekvodicka (Ludek Vodicka) <https://github.com/ludekvodicka>`_.
+
+* Various bugfixes: bad overflow check, unsupported implicit type conversion when determining formatting function, test segfaults (`#551 <https://github.com/fmtlib/fmt/issues/551>`_), ill-formed macros (`#542 <https://github.com/fmtlib/fmt/pull/542>`_) and ambiguous overloads (`#580 <https://github.com/fmtlib/fmt/issues/580>`_). Thanks `@xylosper (Byoung-young Lee) <https://github.com/xylosper>`_.
+
+* Prevented warnings on MSVC (`#605 <https://github.com/fmtlib/fmt/pull/605>`_, `#602 <https://github.com/fmtlib/fmt/pull/602>`_, and `#545 <https://github.com/fmtlib/fmt/pull/545>`_), clang (`#582 <https://github.com/fmtlib/fmt/pull/582>`_), GCC (`#573 <https://github.com/fmtlib/fmt/issues/573>`_), various conversion warnings (`#609 <https://github.com/fmtlib/fmt/pull/609>`_, `#567 <https://github.com/fmtlib/fmt/pull/567>`_, `#553 <https://github.com/fmtlib/fmt/pull/553>`_ and `#553 <https://github.com/fmtlib/fmt/pull/553>`_), and added ``override`` and ``[[noreturn]]`` (`#549 <https://github.com/fmtlib/fmt/pull/549>`_ and `#555 <https://github.com/fmtlib/fmt/issues/555>`_). Thanks `@alabuzhev (Alex Alabuzhev) <https://github.com/alabuzhev>`_, `@virgiliofornazin (Virgilio Alexandre Fornazin) <https://gihtub.com/virgiliofornazin>`_, `@alexanderbock (Alexander Bock) <https://github.com/alexanderbock>`_, `@yumetodo <https://github.com/yumetodo>`_, `@VaderY (Császár Mátyás) <https://github.com/VaderY>`_, `@jpcima (JP Cimalando) <https://github.com/jpcima>`_, `@thelostt (Mário Feroldi) <https://github.com/thelostt>`_, and `@Manu343726 (Manu Sánchez) <https://github.com/Manu343726>`_.
+
+* Improved CMake: Used GNUInstallDirs to set installation location (`#610 <https://github.com/fmtlib/fmt/pull/610>`_) and fixed warnings (`#536 <https://github.com/fmtlib/fmt/pull/536>`_ and `#556 <https://github.com/fmtlib/fmt/pull/556>`_). Thanks `@mikecrowe (Mike Crowe) <https://github.com/mikecrowe>`_, `@evgen231 <https://github.com/evgen231>`_ and `@henryiii (Henry Schreiner) <https://github.com/henryiii>`_.
+
+4.0.0 - 2017-06-27
+------------------
+
+* Removed old compatibility headers ``cppformat/*.h`` and CMake options (`#527 <https://github.com/fmtlib/fmt/pull/527>`_). Thanks `@maddinat0r (Alex Martin) <https://github.com/maddinat0r>`_.
+
+* Added ``string.h`` containing ``fmt::to_string()`` as alternative to ``std::to_string()`` as well as other string writer functionality (`#326 <https://github.com/fmtlib/fmt/issues/326>`_ and `#441 <https://github.com/fmtlib/fmt/pull/441>`_):
+
+  .. code:: c++
+
+    #include "fmt/string.h"
+  
+    std::string answer = fmt::to_string(42);
+
+  Thanks to `@glebov-andrey (Andrey Glebov) <https://github.com/glebov-andrey>`_.
+
+* Moved ``fmt::printf()`` to new ``printf.h`` header and allowed ``%s`` as generic specifier (`#453 <https://github.com/fmtlib/fmt/pull/453>`_), made ``%.f`` more conformant to regular ``printf()`` (`#490 <https://github.com/fmtlib/fmt/pull/490>`_), added custom writer support (`#476 <https://github.com/fmtlib/fmt/issues/476>`_) and implemented missing custom argument formatting (`#339 <https://github.com/fmtlib/fmt/pull/339>`_ and `#340 <https://github.com/fmtlib/fmt/pull/340>`_):
+
+  .. code:: c++
+
+    #include "fmt/printf.h"
+ 
+    // %s format specifier can be used with any argument type.
+    fmt::printf("%s", 42);
+
+  Thanks `@mojoBrendan <https://github.com/mojoBrendan>`_, `@manylegged (Arthur Danskin) <https://github.com/manylegged>`_ and `@spacemoose (Glen Stark) <https://github.com/spacemoose>`_. See also `#360 <https://github.com/fmtlib/fmt/issues/360>`_, `#335 <https://github.com/fmtlib/fmt/issues/335>`_ and `#331 <https://github.com/fmtlib/fmt/issues/331>`_.
+
+* Added ``container.h`` containing a ``BasicContainerWriter`` to write to containers like ``std::vector`` (`#450 <https://github.com/fmtlib/fmt/pull/450>`_). Thanks `@polyvertex (Jean-Charles Lefebvre) <https://github.com/polyvertex>`_.
+
+* Added ``fmt::join()`` function that takes a range and formats its elements separated by a given string (`#466 <https://github.com/fmtlib/fmt/pull/466>`_):
+
+  .. code:: c++
+
+    #include "fmt/format.h"
+ 
+    std::vector<double> v = {1.2, 3.4, 5.6};
+    // Prints "(+01.20, +03.40, +05.60)".
+    fmt::print("({:+06.2f})", fmt::join(v.begin(), v.end(), ", "));
+
+  Thanks `@olivier80 <https://github.com/olivier80>`_.
+
+* Added support for custom formatting specifications to simplify customization of built-in formatting (`#444 <https://github.com/fmtlib/fmt/pull/444>`_). Thanks `@polyvertex (Jean-Charles Lefebvre) <https://github.com/polyvertex>`_. See also `#439 <https://github.com/fmtlib/fmt/issues/439>`_.
+
+* Added ``fmt::format_system_error()`` for error code formatting (`#323 <https://github.com/fmtlib/fmt/issues/323>`_ and `#526 <https://github.com/fmtlib/fmt/pull/526>`_). Thanks `@maddinat0r (Alex Martin) <https://github.com/maddinat0r>`_.
+
+* Added thread-safe ``fmt::localtime()`` and ``fmt::gmtime()`` as replacement for the standard version to ``time.h`` (`#396 <https://github.com/fmtlib/fmt/pull/396>`_). Thanks `@codicodi <https://github.com/codicodi>`_.
+
+* Internal improvements to ``NamedArg`` and ``ArgLists`` (`#389 <https://github.com/fmtlib/fmt/pull/389>`_ and `#390 <https://github.com/fmtlib/fmt/pull/390>`_). Thanks `@chronoxor <https://github.com/chronoxor>`_.
+
+* Fixed crash due to bug in ``FormatBuf`` (`#493 <https://github.com/fmtlib/fmt/pull/493>`_). Thanks `@effzeh <https://github.com/effzeh>`_. See also `#480 <https://github.com/fmtlib/fmt/issues/480>`_ and `#491 <https://github.com/fmtlib/fmt/issues/491>`_.
+
+* Fixed handling of wide strings in ``fmt::StringWriter``.
+
+* Improved compiler error messages (`#357 <https://github.com/fmtlib/fmt/issues/357>`_).
+
+* Fixed various warnings and issues with various compilers (`#494 <https://github.com/fmtlib/fmt/pull/494>`_, `#499 <https://github.com/fmtlib/fmt/pull/499>`_, `#483 <https://github.com/fmtlib/fmt/pull/483>`_, `#519 <https://github.com/fmtlib/fmt/pull/519>`_, `#485 <https://github.com/fmtlib/fmt/pull/485>`_, `#482 <https://github.com/fmtlib/fmt/pull/482>`_, `#475 <https://github.com/fmtlib/fmt/pull/475>`_, `#473 <https://github.com/fmtlib/fmt/pull/473>`_ and `#414 <https://github.com/fmtlib/fmt/pull/414>`_). Thanks `@chronoxor <https://github.com/chronoxor>`_, `@zhaohuaxishi <https://github.com/zhaohuaxishi>`_, `@pkestene (Pierre Kestener) <https://github.com/pkestene>`_, `@dschmidt (Dominik Schmidt) <https://github.com/dschmidt>`_ and `@0x414c (Alexey Gorishny) <https://github.com/0x414c>`_ .
+
+* Improved CMake: targets are now namespaced (`#511 <https://github.com/fmtlib/fmt/pull/511>`_ and `#513 <https://github.com/fmtlib/fmt/pull/513>`_), supported header-only ``printf.h`` (`#354 <https://github.com/fmtlib/fmt/pull/354>`_), fixed issue with minimal supported library subset (`#418 <https://github.com/fmtlib/fmt/issues/418>`_, `#419 <https://github.com/fmtlib/fmt/pull/419>`_ and `#420 <https://github.com/fmtlib/fmt/pull/420>`_). Thanks `@bjoernthiel (Bjoern Thiel) <https://github.com/bjoernthiel>`_,
+  `@niosHD (Mario Werner) <https://github.com/niosHD>`_, `@LogicalKnight (Sean LK) <https://github.com/LogicalKnight>`_ and `@alabuzhev (Alex Alabuzhev) <https://github.com/alabuzhev>`_.
+
+* Improved documentation. Thanks to `@pwm1234 (Phil) <https://github.com/pwm1234>`_ for `#393 <https://github.com/fmtlib/fmt/pull/393>`_.
+
+3.0.2 - 2017-06-14
+------------------
+
+* Added ``FMT_VERSION`` macro (`#411 <https://github.com/fmtlib/fmt/issues/411>`_).
+
+* Used ``FMT_NULL`` instead of literal ``0`` (`#409 <https://github.com/fmtlib/fmt/pull/409>`_). Thanks `@alabuzhev (Alex Alabuzhev) <https://github.com/alabuzhev>`_.
+
+* Added extern templates for ``format_float`` (`#413 <https://github.com/fmtlib/fmt/issues/413>`_).
+
+* Fixed implicit conversion issue (`#507 <https://github.com/fmtlib/fmt/issues/507>`_).
+
+* Fixed signbit detection (`#423 <https://github.com/fmtlib/fmt/issues/423>`_).
+
+* Fixed naming collision (`#425 <https://github.com/fmtlib/fmt/issues/425>`_).
+
+* Fixed missing intrinsic for C++/CLI (`#457 <https://github.com/fmtlib/fmt/pull/457>`_). Thanks `@calumr (Calum Robinson) <https://github.com/calumr>`_
+
+* Fixed Android detection (`#458 <https://github.com/fmtlib/fmt/pull/458>`_). Thanks `@Gachapen (Magnus Bjerke Vik) <https://github.com/Gachapen>`_.
+
+* Use lean ``windows.h`` if not in header-only mode (`#503 <https://github.com/fmtlib/fmt/pull/503>`_). Thanks `@Quentin01 (Quentin Buathier) <https://github.com/Quentin01>`_.
+
+* Fixed issue with CMake exporting C++11 flag (`#445 <https://github.com/fmtlib/fmt/pull/455>`_). Thanks `@EricWF (Eric) <https://github.com/EricWF>`_.
+
+* Fixed issue with nvcc and MSVC compiler bug and MinGW (`#505 <https://github.com/fmtlib/fmt/issues/505>`_).
+
+* Fixed DLL issues (`#469 <https://github.com/fmtlib/fmt/pull/469>`_ and `#502 <https://github.com/fmtlib/fmt/pull/502>`_). Thanks `@richardeakin (Richard Eakin) <https://github.com/richardeakin>`_ and `@AndreasSchoenle (Andreas Schönle) <https://github.com/AndreasSchoenle>`_.
+
+* Fixed test compilation under FreeBSD (`#433 <https://github.com/fmtlib/fmt/issues/433>`_).
+
+* Fixed various warnings (`#403 <https://github.com/fmtlib/fmt/pull/403>`_, `#410 <https://github.com/fmtlib/fmt/pull/410>`_ and `#510 <https://github.com/fmtlib/fmt/pull/510>`_). Thanks `@Lecetem <https://github.com/Lectem>`_, `@chenhayat (Chen Hayat) <https://github.com/chenhayat>`_ and `@trozen <https://github.com/trozen>`_.
+
+* Removed redundant include (`#479 <https://github.com/fmtlib/fmt/issues/479>`_).
+
+* Fixed documentation issues.
+
 3.0.1 - 2016-11-01
 ------------------
 * Fixed handling of thousands seperator (`#353 <https://github.com/fmtlib/fmt/issues/353>`_)
diff --git a/README.rst b/README.rst
index eb8cae6..32f5025 100644
--- a/README.rst
+++ b/README.rst
@@ -138,6 +138,12 @@
 
 * `CUAUV <http://cuauv.org/>`_: Cornell University's autonomous underwater vehicle
 
+* `Drake <http://drake.mit.edu/>`_: A planning, control, and analysis toolbox for nonlinear dynamical systems (MIT)
+
+* `Envoy <https://lyft.github.io/envoy/>`_: C++ L7 proxy and communication bus (Lyft)
+
+* `FiveM <https://fivem.net/>`_: a modification framework for GTA V
+
 * `HarpyWar/pvpgn <https://github.com/pvpgn/pvpgn-server>`_:
   Player vs Player Gaming Network with tweaks
 
@@ -145,10 +151,14 @@
 
 * `Keypirinha <http://keypirinha.com/>`_: A semantic launcher for Windows
 
+* `Kodi <https://kodi.tv/>`_ (formerly xbmc): Home theater software
+
 * `Lifeline <https://github.com/peter-clark/lifeline>`_: A 2D game
 
 * `MongoDB Smasher <https://github.com/duckie/mongo_smasher>`_: A small tool to generate randomized datasets
 
+* `OpenSpace <http://openspaceproject.com/>`_: An open-source astrovisualization framework
+
 * `PenUltima Online (POL) <http://www.polserver.com/>`_:
   An MMO server, compatible with most Ultima Online clients
 
diff --git a/doc/api.rst b/doc/api.rst
index 5a93b4a..9647c90 100644
--- a/doc/api.rst
+++ b/doc/api.rst
@@ -11,8 +11,8 @@
 Format API
 ==========
 
-The following functions use :ref:`format string syntax <syntax>` similar
-to the one used by Python's `str.format
+The following functions defined in ``fmt/format.h`` use :ref:`format string
+syntax <syntax>` similar to the one used by Python's `str.format
 <http://docs.python.org/3/library/stdtypes.html#str.format>`_ function.
 They take *format_str* and *args* as arguments.
 
@@ -84,6 +84,36 @@
 ``format_arg`` in :file:`fmt/time.h` for an advanced example of how to use
 the ``format_str`` argument to customize the formatted output.
 
+This technique can also be used for formatting class hierarchies::
+
+  namespace local {
+  struct Parent {
+    Parent(int p) : p(p) {}
+    virtual void write(fmt::Writer &w) const {
+      w.write("Parent : p={}", p);
+    }
+    int p;
+  };
+
+  struct Child : Parent {
+    Child(int c, int p) : Parent(p), c(c) {}
+    virtual void write(fmt::Writer &w) const {
+      w.write("Child c={} : ", c);
+      Parent::write(w);
+    }
+    int c;
+  };
+
+  void format_arg(fmt::BasicFormatter<char> &f,
+                  const char *&format_str, const Parent &p) {
+    p.write(f.writer());
+  }
+  }
+  Local::Child c(1,2);
+  Local::Parent &p = c;
+  fmt::print("via ref to base: {}\n", p);
+  fmt::print("direct to child: {}\n", c);
+
 This section shows how to define a custom format function for a user-defined
 type. The next section describes how to get ``fmt`` to use a conventional stream
 output ``operator<<`` when one is defined for a user-defined type.
@@ -120,7 +150,7 @@
   // A custom argument formatter that formats negative integers as unsigned
   // with the ``x`` format specifier.
   class CustomArgFormatter :
-    public fmt::BasicArgFormatter<CustomArgFormatter, char>  {
+    public fmt::BasicArgFormatter<CustomArgFormatter, char> {
     public:
     CustomArgFormatter(fmt::BasicFormatter<char, CustomArgFormatter> &f,
                        fmt::FormatSpec &s, const char *fmt)
@@ -203,6 +233,9 @@
 .. doxygenclass:: fmt::BasicStringWriter
    :members:
 
+.. doxygenclass:: fmt::BasicContainerWriter
+   :members:
+
 .. doxygenfunction:: bin(int)
 
 .. doxygenfunction:: oct(int)
@@ -229,6 +262,8 @@
 
 .. doxygenfunction:: fmt::to_string(const T&)
 
+.. doxygenfunction:: fmt::to_wstring(const T&)
+
 .. doxygenclass:: fmt::BasicStringRef
    :members:
 
diff --git a/doc/basic-bootstrap/layout.html b/doc/basic-bootstrap/layout.html
index 5164e9c..a257b03 100644
--- a/doc/basic-bootstrap/layout.html
+++ b/doc/basic-bootstrap/layout.html
@@ -90,7 +90,8 @@
         VERSION:     '{{ release|e }}',
         COLLAPSE_INDEX: false,
         FILE_SUFFIX: '{{ '' if no_search_suffix else file_suffix }}',
-        HAS_SOURCE:  {{ has_source|lower }}
+        HAS_SOURCE:  {{ has_source|lower }},
+        SOURCELINK_SUFFIX:  '{{ sourcelink_suffix }}'
       };
     </script>
     {%- for scriptfile in script_files %}
diff --git a/doc/build.py b/doc/build.py
index 76d2783..cb8d0c3 100755
--- a/doc/build.py
+++ b/doc/build.py
@@ -6,6 +6,8 @@
 from subprocess import check_call, check_output, CalledProcessError, Popen, PIPE
 from distutils.version import LooseVersion
 
+versions = ['1.0.0', '1.1.0', '2.0.0', '3.0.2', '4.0.0', '4.1.0']
+
 def pip_install(package, commit=None, **kwargs):
   "Install package using pip."
   min_version = kwargs.get('min_version')
@@ -19,7 +21,7 @@
     except DistributionNotFound:
       pass
   if commit:
-    package = 'git+git://github.com/{0}.git@{1}'.format(package, commit)
+    package = 'git+https://github.com/{0}.git@{1}'.format(package, commit)
   print('Installing {0}'.format(package))
   check_call(['pip', 'install', package])
 
@@ -72,7 +74,8 @@
       GENERATE_MAN      = NO
       GENERATE_RTF      = NO
       CASE_SENSE_NAMES  = NO
-      INPUT             = {0}/format.h {0}/ostream.h {0}/printf.h {0}/string.h
+      INPUT             = {0}/container.h {0}/format.h {0}/ostream.h \
+                          {0}/printf.h {0}/string.h
       QUIET             = YES
       JAVADOC_AUTOBRIEF = YES
       AUTOLINK_SUPPORT  = NO
@@ -92,11 +95,11 @@
   if p.returncode != 0:
     raise CalledProcessError(p.returncode, cmd)
   html_dir = os.path.join(work_dir, 'html')
-  versions = ['3.0.0', '2.0.0', '1.1.0']
+  main_versions = reversed(versions[-3:])
   check_call(['sphinx-build',
               '-Dbreathe_projects.format=' + os.path.abspath(doxyxml_dir),
               '-Dversion=' + version, '-Drelease=' + version,
-              '-Aversion=' + version, '-Aversions=' + ','.join(versions),
+              '-Aversion=' + version, '-Aversions=' + ','.join(main_versions),
               '-b', 'html', doc_dir, html_dir])
   try:
     check_call(['lessc', '--clean-css',
diff --git a/doc/index.rst b/doc/index.rst
index ce9b7bf..a00828b 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -143,6 +143,12 @@
 which is represented by ``L'\x42e'`` if we use Unicode) which is rarely what is
 needed.
 
+Note that fmt does not use the value of the ``errno`` global to communicate
+errors to the user, but it may call system functions which set ``errno``. Since
+fmt does not attempt to preserve the value of ``errno``, users should not make
+any assumptions about it and always set it to ``0`` before making any system
+calls that convey error information via ``errno``.
+
 .. _portability:
 
 Portability
diff --git a/doc/syntax.rst b/doc/syntax.rst
index 1051467..ae5a3fd 100644
--- a/doc/syntax.rst
+++ b/doc/syntax.rst
@@ -35,6 +35,8 @@
 they can all be omitted (not just some) and the numbers 0, 1, 2, ... will be
 automatically inserted in that order.
 
+Named arguments can be referred to by their names or indices.
+
 Some simple format string examples::
 
    "First, thou shalt count to {0}" // References the first argument
@@ -335,6 +337,16 @@
    format("{:*^30}", "centered");  // use '*' as a fill char
    // Result: "***********centered***********"
 
+Dynamic width::
+
+   format("{:<{}}", "left aligned", 30);
+   // Result: "left aligned                  "
+
+Dynamic precision::
+
+   format("{:.{}f}", 3.14, 1);
+   // Result: "3.1"
+
 Replacing ``%+f``, ``%-f``, and ``% f`` and specifying a sign::
 
    format("{:+f}; {:+f}", 3.14, -3.14);  // show it always
@@ -350,7 +362,7 @@
    // Result: "int: 42;  hex: 2a;  oct: 52; bin: 101010"
    // with 0x or 0 or 0b as prefix:
    format("int: {0:d};  hex: {0:#x};  oct: {0:#o};  bin: {0:#b}", 42);
-   // Result: "int: 42;  hex: 0x2a;  oct: 052;  bin: 0b101010"
+   // Result: "int: 42;  hex: 0x2a;  oct: 052;  bin: 0b101010"   
 
 .. ifconfig:: False
 
@@ -359,13 +371,6 @@
       format("{:,}", 1234567890);
       '1,234,567,890'
 
-   Expressing a percentage::
-
-      >>> points = 19
-      >>> total = 22
-      Format("Correct answers: {:.2%}") << points/total)
-      'Correct answers: 86.36%'
-
    Using type-specific formatting::
 
       >>> import datetime
diff --git a/doc/usage.rst b/doc/usage.rst
index 3045cb1..4c65f8a 100644
--- a/doc/usage.rst
+++ b/doc/usage.rst
@@ -41,6 +41,10 @@
 Once the library has been built you can invoke :command:`make test` to run
 the tests.
 
+You can control generation of the make ``test`` target with the ``FMT_TEST``
+CMake option. This can be useful if you include fmt as a subdirectory in
+your project but don't want to add fmt's tests to your ``test`` target.
+
 If you use Windows and have Visual Studio installed, a :file:`FORMAT.sln`
 file and several :file:`.vcproj` files will be created. You can then build them
 using Visual Studio or msbuild.
@@ -54,6 +58,23 @@
 
 __ http://en.wikipedia.org/wiki/Library_%28computing%29#Shared_libraries
 
+Header-only usage with CMake
+============================
+
+In order to add ``fmtlib`` into an existing ``CMakeLists.txt`` file, you can add the ``fmt`` library directory into your main project, which will enable the ``fmt`` library::
+
+   add_subdirectory(fmt)
+   
+If you have a project called ``foo`` that you would like to link against the fmt library in a header-only fashion, you can enable with with::
+
+   target_link_libraries(foo PRIVATE fmt::fmt-header-only)
+   
+And then to ensure that the ``fmt`` library does not always get built, you can modify the call to ``add_subdirectory`` to read ::
+
+   add_subdirectory(fmt EXCLUDE_FROM_ALL)
+   
+This will ensure that the ``fmt`` library is exluded from calls to ``make``, ``make all``, or ``cmake --build .``.
+
 Building the documentation
 ==========================
 
diff --git a/fmt/CMakeLists.txt b/fmt/CMakeLists.txt
index 9e491f9..972e8c9 100644
--- a/fmt/CMakeLists.txt
+++ b/fmt/CMakeLists.txt
@@ -1,22 +1,19 @@
 # Define the fmt library, its includes and the needed defines.
 # *.cc are added to FMT_HEADERS for the header-only configuration.
-set(FMT_HEADERS format.h format.cc ostream.h ostream.cc printf.h printf.cc
-                string.h time.h)
+set(FMT_HEADERS container.h format.h format.cc ostream.h ostream.cc printf.h
+                printf.cc string.h time.h)
 if (HAVE_OPEN)
   set(FMT_HEADERS ${FMT_HEADERS} posix.h)
   set(FMT_SOURCES ${FMT_SOURCES} posix.cc)
 endif ()
 
 add_library(fmt ${FMT_SOURCES} ${FMT_HEADERS} ../README.rst ../ChangeLog.rst)
-
-option(FMT_CPPFORMAT "Build cppformat library for backward compatibility." OFF)
-if (FMT_CPPFORMAT)
-  message(WARNING "The cppformat library is deprecated, use fmt instead.")
-  add_library(cppformat ${FMT_SOURCES} ${FMT_HEADERS})
-endif ()
+add_library(fmt::fmt ALIAS fmt)
 
 # Starting with cmake 3.1 the CXX_STANDARD property can be used instead.
-target_compile_options(fmt PUBLIC ${CPP11_FLAG})
+# Note: Don't make -std=c++11 public or interface, since it breaks projects
+# that use C++14.
+target_compile_options(fmt PRIVATE ${CPP11_FLAG})
 if (FMT_PEDANTIC)
   target_compile_options(fmt PRIVATE ${PEDANTIC_COMPILE_FLAGS})
 endif ()
@@ -27,6 +24,7 @@
 
 set_target_properties(fmt PROPERTIES
   VERSION ${FMT_VERSION} SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR})
+set_target_properties(fmt PROPERTIES DEBUG_POSTFIX d)
 
 if (BUILD_SHARED_LIBS)
   if (UNIX AND NOT APPLE)
@@ -41,6 +39,7 @@
 # additionally define a header only library when cmake is new enough
 if (CMAKE_VERSION VERSION_GREATER 3.1.0 OR CMAKE_VERSION VERSION_EQUAL 3.1.0)
   add_library(fmt-header-only INTERFACE)
+  add_library(fmt::fmt-header-only ALIAS fmt-header-only)
 
   target_compile_definitions(fmt-header-only INTERFACE FMT_HEADER_ONLY=1)
 
@@ -51,8 +50,9 @@
 
 # Install targets.
 if (FMT_INSTALL)
+  include(GNUInstallDirs)
   include(CMakePackageConfigHelpers)
-  set(FMT_CMAKE_DIR lib/cmake/fmt CACHE STRING
+  set(FMT_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/fmt CACHE STRING
     "Installation directory for cmake files, relative to ${CMAKE_INSTALL_PREFIX}.")
   set(version_config ${PROJECT_BINARY_DIR}/fmt-config-version.cmake)
   set(project_config ${PROJECT_BINARY_DIR}/fmt-config.cmake)
@@ -63,9 +63,12 @@
     set(INSTALL_TARGETS ${INSTALL_TARGETS} fmt-header-only)
   endif ()
 
-  set(FMT_LIB_DIR lib CACHE STRING
+  set(FMT_LIB_DIR ${CMAKE_INSTALL_LIBDIR} CACHE STRING
     "Installation directory for libraries, relative to ${CMAKE_INSTALL_PREFIX}.")
 
+  set(FMT_INC_DIR ${CMAKE_INSTALL_INCLUDEDIR}/fmt CACHE STRING
+    "Installation directory for include files, relative to ${CMAKE_INSTALL_PREFIX}.")
+
   # Generate the version, config and target files into the build directory.
   write_basic_package_version_file(
     ${version_config}
@@ -75,20 +78,18 @@
     ${PROJECT_SOURCE_DIR}/support/cmake/fmt-config.cmake.in
     ${project_config}
     INSTALL_DESTINATION ${FMT_CMAKE_DIR})
-  export(TARGETS ${INSTALL_TARGETS}
+  export(TARGETS ${INSTALL_TARGETS} NAMESPACE fmt::
          FILE ${PROJECT_BINARY_DIR}/${targets_export_name}.cmake)
 
   # Install version, config and target files.
   install(
     FILES ${project_config} ${version_config}
     DESTINATION ${FMT_CMAKE_DIR})
-  install(EXPORT ${targets_export_name} DESTINATION ${FMT_CMAKE_DIR})
+  install(EXPORT ${targets_export_name} DESTINATION ${FMT_CMAKE_DIR}
+    NAMESPACE fmt::)
 
   # Install the library and headers.
   install(TARGETS ${INSTALL_TARGETS} EXPORT ${targets_export_name}
           DESTINATION ${FMT_LIB_DIR})
-  install(FILES ${FMT_HEADERS} DESTINATION include/fmt)
-  if (FMT_CPPFORMAT)
-    install(TARGETS cppformat DESTINATION ${FMT_LIB_DIR})
-  endif ()
+  install(FILES ${FMT_HEADERS} DESTINATION ${FMT_INC_DIR})
 endif ()
diff --git a/fmt/container.h b/fmt/container.h
new file mode 100644
index 0000000..cb6303f
--- /dev/null
+++ b/fmt/container.h
@@ -0,0 +1,82 @@
+/*
+ Formatting library for C++ - standard container utilities
+
+ Copyright (c) 2012 - 2016, Victor Zverovich
+ All rights reserved.
+
+ For the license information refer to format.h.
+ */
+
+#ifndef FMT_CONTAINER_H_
+#define FMT_CONTAINER_H_
+
+#include "format.h"
+
+namespace fmt {
+
+namespace internal {
+
+/**
+  \rst
+  A "buffer" that appends data to a standard container (e.g. typically a
+  ``std::vector`` or ``std::basic_string``).
+  \endrst
+ */
+template <typename Container>
+class ContainerBuffer : public Buffer<typename Container::value_type> {
+ private:
+  Container& container_;
+
+ protected:
+  virtual void grow(std::size_t size) FMT_OVERRIDE {
+    container_.resize(size);
+    this->ptr_ = &container_[0];
+    this->capacity_ = size;
+  }
+
+ public:
+  explicit ContainerBuffer(Container& container) : container_(container) {
+    this->size_ = container_.size();
+    if (this->size_ > 0) {
+      this->ptr_ = &container_[0];
+      this->capacity_ = this->size_;
+    }
+  }
+};
+}  // namespace internal
+
+/**
+  \rst
+  This class template provides operations for formatting and appending data
+  to a standard *container* like ``std::vector`` or ``std::basic_string``.
+
+  **Example**::
+
+    void vecformat(std::vector<char>& dest, fmt::BasicCStringRef<char> format,
+                   fmt::ArgList args) {
+      fmt::BasicContainerWriter<std::vector<char> > appender(dest);
+      appender.write(format, args);
+    }
+    FMT_VARIADIC(void, vecformat, std::vector<char>&,
+                 fmt::BasicCStringRef<char>);
+  \endrst
+ */
+template <class Container>
+class BasicContainerWriter
+  : public BasicWriter<typename Container::value_type> {
+ private:
+  internal::ContainerBuffer<Container> buffer_;
+
+ public:
+  /**
+    \rst
+    Constructs a :class:`fmt::BasicContainerWriter` object.
+    \endrst
+   */
+  explicit BasicContainerWriter(Container& dest)
+  : BasicWriter<typename Container::value_type>(buffer_), buffer_(dest) {}
+};
+
+} // namespace fmt
+
+#endif  // FMT_CONTAINER_H_
diff --git a/fmt/format.cc b/fmt/format.cc
index b2bb768..2d236bc 100644
--- a/fmt/format.cc
+++ b/fmt/format.cc
@@ -41,6 +41,9 @@
 #endif
 
 #if FMT_USE_WINDOWS_H
+# if !defined(FMT_HEADER_ONLY) && !defined(WIN32_LEAN_AND_MEAN)
+#  define WIN32_LEAN_AND_MEAN
+# endif
 # if defined(NOMINMAX) || defined(FMT_WIN_MINMAX)
 #  include <windows.h>
 # else
@@ -50,8 +53,6 @@
 # endif
 #endif
 
-using fmt::internal::Arg;
-
 #if FMT_EXCEPTIONS
 # define FMT_TRY try
 # define FMT_CATCH(x) catch (x)
@@ -71,9 +72,11 @@
 
 // Dummy implementations of strerror_r and strerror_s called if corresponding
 // system functions are not available.
+FMT_MAYBE_UNUSED
 static inline fmt::internal::Null<> strerror_r(int, char *, ...) {
   return fmt::internal::Null<>();
 }
+FMT_MAYBE_UNUSED
 static inline fmt::internal::Null<> strerror_s(char *, std::size_t, ...) {
   return fmt::internal::Null<>();
 }
@@ -120,7 +123,7 @@
 // Buffer should be at least of size 1.
 int safe_strerror(
     int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT {
-  FMT_ASSERT(buffer != 0 && buffer_size != 0, "invalid buffer");
+  FMT_ASSERT(buffer != FMT_NULL && buffer_size != 0, "invalid buffer");
 
   class StrError {
    private:
@@ -158,6 +161,11 @@
             ERANGE : result;
     }
 
+#ifdef __c2__
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wdeprecated-declarations"
+#endif
+
     // Fallback to strerror if strerror_r and strerror_s are not available.
     int fallback(internal::Null<>) {
       errno = 0;
@@ -165,13 +173,15 @@
       return errno;
     }
 
+#ifdef __c2__
+# pragma clang diagnostic pop
+#endif
+
    public:
     StrError(int err_code, char *&buf, std::size_t buf_size)
       : error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {}
 
     int run() {
-      // Suppress a warning about unused strerror_r.
-      strerror_r(0, FMT_NULL, "");
       return handle(strerror_r(error_code_, buffer_, buffer_size_));
     }
   };
@@ -212,16 +222,6 @@
 }
 }  // namespace
 
-namespace internal {
-
-// This method is used to preserve binary compatibility with fmt 3.0.
-// It can be removed in 4.0.
-FMT_FUNC void format_system_error(
-  Writer &out, int error_code, StringRef message) FMT_NOEXCEPT {
-  fmt::format_system_error(out, error_code, message);
-}
-}  // namespace internal
-
 FMT_FUNC void SystemError::init(
     int err_code, CStringRef format_str, ArgList args) {
   error_code_ = err_code;
@@ -406,63 +406,18 @@
 }
 
 template <typename Char>
-void internal::ArgMap<Char>::init(const ArgList &args) {
-  if (!map_.empty())
-    return;
-  typedef internal::NamedArg<Char> NamedArg;
-  const NamedArg *named_arg = FMT_NULL;
-  bool use_values =
-      args.type(ArgList::MAX_PACKED_ARGS - 1) == internal::Arg::NONE;
-  if (use_values) {
-    for (unsigned i = 0;/*nothing*/; ++i) {
-      internal::Arg::Type arg_type = args.type(i);
-      switch (arg_type) {
-      case internal::Arg::NONE:
-        return;
-      case internal::Arg::NAMED_ARG:
-        named_arg = static_cast<const NamedArg*>(args.values_[i].pointer);
-        map_.push_back(Pair(named_arg->name, *named_arg));
-        break;
-      default:
-        /*nothing*/;
-      }
-    }
-    return;
-  }
-  for (unsigned i = 0; i != ArgList::MAX_PACKED_ARGS; ++i) {
-    internal::Arg::Type arg_type = args.type(i);
-    if (arg_type == internal::Arg::NAMED_ARG) {
-      named_arg = static_cast<const NamedArg*>(args.args_[i].pointer);
-      map_.push_back(Pair(named_arg->name, *named_arg));
-    }
-  }
-  for (unsigned i = ArgList::MAX_PACKED_ARGS;/*nothing*/; ++i) {
-    switch (args.args_[i].type) {
-    case internal::Arg::NONE:
-      return;
-    case internal::Arg::NAMED_ARG:
-      named_arg = static_cast<const NamedArg*>(args.args_[i].pointer);
-      map_.push_back(Pair(named_arg->name, *named_arg));
-      break;
-    default:
-      /*nothing*/;
-    }
-  }
-}
-
-template <typename Char>
 void internal::FixedBuffer<Char>::grow(std::size_t) {
   FMT_THROW(std::runtime_error("buffer overflow"));
 }
 
-FMT_FUNC Arg internal::FormatterBase::do_get_arg(
+FMT_FUNC internal::Arg internal::FormatterBase::do_get_arg(
     unsigned arg_index, const char *&error) {
-  Arg arg = args_[arg_index];
+  internal::Arg arg = args_[arg_index];
   switch (arg.type) {
-  case Arg::NONE:
+  case internal::Arg::NONE:
     error = "argument index out of range";
     break;
-  case Arg::NAMED_ARG:
+  case internal::Arg::NAMED_ARG:
     arg = *static_cast<const internal::Arg*>(arg.pointer);
     break;
   default:
@@ -511,13 +466,11 @@
 
 template void internal::FixedBuffer<char>::grow(std::size_t);
 
-template void internal::ArgMap<char>::init(const ArgList &args);
-
-template int internal::CharTraits<char>::format_float(
+template FMT_API int internal::CharTraits<char>::format_float(
     char *buffer, std::size_t size, const char *format,
     unsigned width, int precision, double value);
 
-template int internal::CharTraits<char>::format_float(
+template FMT_API int internal::CharTraits<char>::format_float(
     char *buffer, std::size_t size, const char *format,
     unsigned width, int precision, long double value);
 
@@ -525,13 +478,11 @@
 
 template void internal::FixedBuffer<wchar_t>::grow(std::size_t);
 
-template void internal::ArgMap<wchar_t>::init(const ArgList &args);
-
-template int internal::CharTraits<wchar_t>::format_float(
+template FMT_API int internal::CharTraits<wchar_t>::format_float(
     wchar_t *buffer, std::size_t size, const wchar_t *format,
     unsigned width, int precision, double value);
 
-template int internal::CharTraits<wchar_t>::format_float(
+template FMT_API int internal::CharTraits<wchar_t>::format_float(
     wchar_t *buffer, std::size_t size, const wchar_t *format,
     unsigned width, int precision, long double value);
 
diff --git a/fmt/format.h b/fmt/format.h
index b871397..6a8fa66 100644
--- a/fmt/format.h
+++ b/fmt/format.h
@@ -25,9 +25,15 @@
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+// transition helper
+#ifdef FMT_FORMAT_PROVIDE_PRINTF
+#include "printf.h"
+#endif
+
 #ifndef FMT_FORMAT_H_
 #define FMT_FORMAT_H_
 
+#define FMT_INCLUDE
 #include <cassert>
 #include <clocale>
 #include <cmath>
@@ -38,12 +44,34 @@
 #include <stdexcept>
 #include <string>
 #include <vector>
-#include <utility>
+#include <utility>  // for std::pair
+#undef FMT_INCLUDE
 
 // The fmt library version in the form major * 10000 + minor * 100 + patch.
-#define FMT_VERSION 30002
+#define FMT_VERSION 40101
 
-#ifdef _SECURE_SCL
+#if defined(__has_include)
+# define FMT_HAS_INCLUDE(x) __has_include(x)
+#else
+# define FMT_HAS_INCLUDE(x) 0
+#endif
+
+#if (FMT_HAS_INCLUDE(<string_view>) && __cplusplus > 201402L) || \
+    (defined(_MSVC_LANG) && _MSVC_LANG > 201402L && _MSC_VER >= 1910)
+# include <string_view>
+# define FMT_HAS_STRING_VIEW 1
+# define FMT_HAS_EXPERIMENTAL_STRING_VIEW 0
+#else
+# define FMT_HAS_STRING_VIEW 0
+# if (FMT_HAS_INCLUDE(<experimental/string_view>) && __cplusplus >= 201402L)
+#  include <experimental/string_view>
+#  define FMT_HAS_EXPERIMENTAL_STRING_VIEW 1
+# else
+#  define FMT_HAS_EXPERIMENTAL_STRING_VIEW 0
+# endif
+#endif
+
+#if defined _SECURE_SCL && _SECURE_SCL
 # define FMT_SECURE_SCL _SECURE_SCL
 #else
 # define FMT_SECURE_SCL 0
@@ -97,7 +125,9 @@
 #  define FMT_HAS_GXX_CXX11 1
 # endif
 #else
+# define FMT_GCC_VERSION 0
 # define FMT_GCC_EXTENSION
+# define FMT_HAS_GXX_CXX11 0
 #endif
 
 #if defined(__INTEL_COMPILER)
@@ -107,6 +137,7 @@
 #endif
 
 #if defined(__clang__) && !defined(FMT_ICC_VERSION)
+# define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__)
 # pragma clang diagnostic push
 # pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
 # pragma clang diagnostic ignored "-Wpadded"
@@ -134,6 +165,32 @@
 # define FMT_HAS_CPP_ATTRIBUTE(x) 0
 #endif
 
+#if FMT_HAS_CPP_ATTRIBUTE(maybe_unused)
+# define FMT_HAS_CXX17_ATTRIBUTE_MAYBE_UNUSED
+// VC++ 1910 support /std: option and that will set _MSVC_LANG macro
+// Clang with Microsoft CodeGen doesn't define _MSVC_LANG macro
+#elif defined(_MSVC_LANG) && _MSVC_LANG > 201402 && _MSC_VER >= 1910
+# define FMT_HAS_CXX17_ATTRIBUTE_MAYBE_UNUSED
+#endif
+
+#ifdef FMT_HAS_CXX17_ATTRIBUTE_MAYBE_UNUSED
+# define FMT_MAYBE_UNUSED [[maybe_unused]]
+// g++/clang++ also support [[gnu::unused]]. However, we don't use it.
+#elif defined(__GNUC__)
+# define FMT_MAYBE_UNUSED __attribute__((unused))
+#else
+# define FMT_MAYBE_UNUSED
+#endif
+
+// Use the compiler's attribute noreturn
+#if defined(__MINGW32__) || defined(__MINGW64__)
+# define FMT_NORETURN __attribute__((noreturn))
+#elif FMT_HAS_CPP_ATTRIBUTE(noreturn) && __cplusplus >= 201103L
+# define FMT_NORETURN [[noreturn]]
+#else
+# define FMT_NORETURN
+#endif
+
 #ifndef FMT_USE_VARIADIC_TEMPLATES
 // Variadic templates are available in GCC since version 4.4
 // (http://gcc.gnu.org/projects/cxx0x.html) and in Visual C++
@@ -155,8 +212,10 @@
 # endif
 #endif
 
-#if FMT_USE_RVALUE_REFERENCES
-# include <utility>  // for std::move
+#if __cplusplus >= 201103L || FMT_MSC_VER >= 1700
+# define FMT_USE_ALLOCATOR_TRAITS 1
+#else
+# define FMT_USE_ALLOCATOR_TRAITS 0
 #endif
 
 // Check if exceptions are disabled.
@@ -246,25 +305,38 @@
     TypeName& operator=(const TypeName&)
 #endif
 
+#ifndef FMT_USE_DEFAULTED_FUNCTIONS
+# define FMT_USE_DEFAULTED_FUNCTIONS 0
+#endif
+
+#ifndef FMT_DEFAULTED_COPY_CTOR
+# if FMT_USE_DEFAULTED_FUNCTIONS || FMT_HAS_FEATURE(cxx_defaulted_functions) || \
+   (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1800
+#  define FMT_DEFAULTED_COPY_CTOR(TypeName) \
+    TypeName(const TypeName&) = default;
+# else
+#  define FMT_DEFAULTED_COPY_CTOR(TypeName)
+# endif
+#endif
+
 #ifndef FMT_USE_USER_DEFINED_LITERALS
 // All compilers which support UDLs also support variadic templates. This
 // makes the fmt::literals implementation easier. However, an explicit check
 // for variadic templates is added here just in case.
 // For Intel's compiler both it and the system gcc/msc must support UDLs.
-# define FMT_USE_USER_DEFINED_LITERALS \
-   FMT_USE_VARIADIC_TEMPLATES && FMT_USE_RVALUE_REFERENCES && \
+# if FMT_USE_VARIADIC_TEMPLATES && FMT_USE_RVALUE_REFERENCES && \
    (FMT_HAS_FEATURE(cxx_user_literals) || \
      (FMT_GCC_VERSION >= 407 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1900) && \
    (!defined(FMT_ICC_VERSION) || FMT_ICC_VERSION >= 1500)
+#  define FMT_USE_USER_DEFINED_LITERALS 1
+# else
+#  define FMT_USE_USER_DEFINED_LITERALS 0
+# endif
 #endif
 
 #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.
-// For GCC according to cppreference.com they were introduced in 3.3.
 # define FMT_USE_EXTERN_TEMPLATES \
-    ((__clang__ && FMT_USE_VARIADIC_TEMPLATES) || \
-     (FMT_GCC_VERSION >= 303 && FMT_HAS_GXX_CXX11))
+    (FMT_CLANG_VERSION >= 209 || (FMT_GCC_VERSION >= 303 && FMT_HAS_GXX_CXX11))
 #endif
 
 #ifdef FMT_HEADER_ONLY
@@ -277,24 +349,31 @@
 # 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
+// __builtin_clz is broken in clang with Microsoft CodeGen:
+// https://github.com/fmtlib/fmt/issues/519
+#ifndef _MSC_VER
+# if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clz)
+#  define FMT_BUILTIN_CLZ(n) __builtin_clz(n)
+# endif
 
-#if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clzll)
-# define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n)
+# if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clzll)
+#  define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n)
+# endif
 #endif
 
 // 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 FMT_MSC_VER && !defined(FMT_BUILTIN_CLZLL)
+#if FMT_MSC_VER && !defined(FMT_BUILTIN_CLZLL) && !defined(_MANAGED)
 # include <intrin.h>  // _BitScanReverse, _BitScanReverse64
 
 namespace fmt {
 namespace internal {
-# pragma intrinsic(_BitScanReverse)
+// avoid Clang with Microsoft CodeGen's -Wunknown-pragmas warning
+# ifndef __clang__
+#  pragma intrinsic(_BitScanReverse)
+# endif
 inline uint32_t clz(uint32_t x) {
   unsigned long r = 0;
   _BitScanReverse(&r, x);
@@ -308,7 +387,8 @@
 }
 # define FMT_BUILTIN_CLZ(n) fmt::internal::clz(n)
 
-# ifdef _WIN64
+// avoid Clang with Microsoft CodeGen's -Wunknown-pragmas warning
+# if defined(_WIN64) && !defined(__clang__)
 #  pragma intrinsic(_BitScanReverse64)
 # endif
 
@@ -376,8 +456,7 @@
     using namespace fmt::internal;
     // The resolution "priority" is:
     // isinf macro > std::isinf > ::isinf > fmt::internal::isinf
-    if (const_check(sizeof(isinf(x)) == sizeof(bool) ||
-                    sizeof(isinf(x)) == sizeof(int))) {
+    if (const_check(sizeof(isinf(x)) != sizeof(fmt::internal::DummyInt))) {
       return isinf(x) != 0;
     }
     return !_finite(static_cast<double>(x));
@@ -387,8 +466,7 @@
   template <typename T>
   static bool isnotanumber(T x) {
     using namespace fmt::internal;
-    if (const_check(sizeof(isnan(x)) == sizeof(bool) ||
-                    sizeof(isnan(x)) == sizeof(int))) {
+    if (const_check(sizeof(isnan(x)) != sizeof(fmt::internal::DummyInt))) {
       return isnan(x) != 0;
     }
     return _isnan(static_cast<double>(x)) != 0;
@@ -397,8 +475,7 @@
   // Portable version of signbit.
   static bool isnegative(double x) {
     using namespace fmt::internal;
-    if (const_check(sizeof(signbit(x)) == sizeof(bool) ||
-                    sizeof(signbit(x)) == sizeof(int))) {
+    if (const_check(sizeof(signbit(x)) != sizeof(fmt::internal::DummyInt))) {
       return signbit(x) != 0;
     }
     if (x < 0) return true;
@@ -431,7 +508,9 @@
 template <typename Char>
 class ArgFormatter;
 
-template <typename Impl, typename Char>
+struct FormatSpec;
+
+template <typename Impl, typename Char, typename Spec = fmt::FormatSpec>
 class BasicPrintfArgFormatter;
 
 template <typename CharType,
@@ -492,6 +571,46 @@
       const std::basic_string<Char, std::char_traits<Char>, Allocator> &s)
   : data_(s.c_str()), size_(s.size()) {}
 
+#if FMT_HAS_STRING_VIEW
+  /**
+    \rst
+    Constructs a string reference from a ``std::basic_string_view`` object.
+    \endrst
+   */
+  BasicStringRef(
+      const std::basic_string_view<Char, std::char_traits<Char>> &s)
+  : data_(s.data()), size_(s.size()) {}
+
+  /**
+   \rst
+   Converts a string reference to an ``std::string_view`` object.
+   \endrst
+  */
+  explicit operator std::basic_string_view<Char>() const FMT_NOEXCEPT {
+    return std::basic_string_view<Char>(data_, size_);
+  }
+#endif
+
+#if FMT_HAS_EXPERIMENTAL_STRING_VIEW
+  /**
+  \rst
+  Constructs a string reference from a ``std::experimental::basic_string_view`` object.
+  \endrst
+  */
+  BasicStringRef(
+	  const std::experimental::basic_string_view<Char, std::char_traits<Char>> &s)
+	  : data_(s.data()), size_(s.size()) {}
+
+  /**
+  \rst
+  Converts a string reference to an ``std::string_view`` object.
+  \endrst
+  */
+  explicit operator std::experimental::basic_string_view<Char>() const FMT_NOEXCEPT {
+	  return std::experimental::basic_string_view<Char>(data_, size_);
+  }
+#endif
+
   /**
     \rst
     Converts a string reference to an ``std::string`` object.
@@ -596,7 +715,7 @@
   explicit FormatError(CStringRef message)
   : std::runtime_error(message.c_str()) {}
   FormatError(const FormatError &ferr) : std::runtime_error(ferr) {}
-  ~FormatError() FMT_DTOR_NOEXCEPT;
+  FMT_API ~FormatError() FMT_DTOR_NOEXCEPT FMT_OVERRIDE;
 };
 
 namespace internal {
@@ -712,7 +831,8 @@
 template <typename T>
 template <typename U>
 void Buffer<T>::append(const U *begin, const U *end) {
-  std::size_t new_size = size_ + internal::to_unsigned(end - begin);
+  FMT_ASSERT(end >= begin, "negative value");
+  std::size_t new_size = size_ + static_cast<std::size_t>(end - begin);
   if (new_size > capacity_)
     grow(new_size);
   std::uninitialized_copy(begin, end,
@@ -740,7 +860,7 @@
  public:
   explicit MemoryBuffer(const Allocator &alloc = Allocator())
       : Allocator(alloc), Buffer<T>(data_, SIZE) {}
-  ~MemoryBuffer() { deallocate(); }
+  ~MemoryBuffer() FMT_OVERRIDE { deallocate(); }
 
 #if FMT_USE_RVALUE_REFERENCES
  private:
@@ -784,7 +904,12 @@
   std::size_t new_capacity = this->capacity_ + this->capacity_ / 2;
   if (size > new_capacity)
       new_capacity = size;
+#if FMT_USE_ALLOCATOR_TRAITS
+  T *new_ptr =
+      std::allocator_traits<Allocator>::allocate(*this, new_capacity, FMT_NULL);
+#else
   T *new_ptr = this->allocate(new_capacity, FMT_NULL);
+#endif
   // The following code doesn't throw, so the raw pointer above doesn't leak.
   std::uninitialized_copy(this->ptr_, this->ptr_ + this->size_,
                           make_ptr(new_ptr, new_capacity));
@@ -902,7 +1027,7 @@
     TypeSelector<std::numeric_limits<T>::digits <= 32>::Type MainType;
 };
 
-FMT_API void report_unknown_type(char code, const char *type);
+FMT_API FMT_NORETURN void report_unknown_type(char code, const char *type);
 
 // Static data is placed in this class template to allow header-only
 // configuration.
@@ -1141,17 +1266,17 @@
 Yes &convert(fmt::ULongLong);
 No &convert(...);
 
-template<typename T, bool ENABLE_CONVERSION>
+template <typename T, bool ENABLE_CONVERSION>
 struct ConvertToIntImpl {
   enum { value = ENABLE_CONVERSION };
 };
 
-template<typename T, bool ENABLE_CONVERSION>
+template <typename T, bool ENABLE_CONVERSION>
 struct ConvertToIntImpl2 {
   enum { value = false };
 };
 
-template<typename T>
+template <typename T>
 struct ConvertToIntImpl2<T, true> {
   enum {
     // Don't convert numeric types.
@@ -1159,7 +1284,7 @@
   };
 };
 
-template<typename T>
+template <typename T>
 struct ConvertToInt {
   enum {
     enable_conversion = sizeof(fmt::internal::convert(get<T>())) == sizeof(Yes)
@@ -1176,16 +1301,16 @@
 FMT_DISABLE_CONVERSION_TO_INT(double);
 FMT_DISABLE_CONVERSION_TO_INT(long double);
 
-template<bool B, class T = void>
+template <bool B, class T = void>
 struct EnableIf {};
 
-template<class T>
+template <class T>
 struct EnableIf<true, T> { typedef T type; };
 
-template<bool B, class T, class F>
+template <bool B, class T, class F>
 struct Conditional { typedef T type; };
 
-template<class T, class F>
+template <class T, class F>
 struct Conditional<false, T, F> { typedef F type; };
 
 // For bcc32 which doesn't understand ! in template arguments.
@@ -1196,7 +1321,7 @@
 struct Not<false> { enum { value = 1 }; };
 
 template <typename T>
-struct False { enum { value = 0 }; };
+struct FalseType { enum { value = 0 }; };
 
 template <typename T, T> struct LConvCheck {
   LConvCheck(int) {}
@@ -1234,9 +1359,9 @@
   typedef int FMT_CONCAT_(Assert, __LINE__)[(cond) ? 1 : -1] FMT_UNUSED
 #endif
 
-template <typename Formatter, typename Char, typename T>
-void format_arg(Formatter &, const Char *, const T &) {
-  FMT_STATIC_ASSERT(False<T>::value,
+template <typename Formatter>
+void format_arg(Formatter&, ...) {
+  FMT_STATIC_ASSERT(FalseType<Formatter>::value,
                     "Cannot format argument. To enable the use of ostream "
                     "operator<< include fmt/ostream.h. Otherwise provide "
                     "an overload of format_arg.");
@@ -1269,6 +1394,12 @@
   MakeValue(typename WCharHelper<wchar_t *, Char>::Unsupported);
   MakeValue(typename WCharHelper<const wchar_t *, Char>::Unsupported);
   MakeValue(typename WCharHelper<const std::wstring &, Char>::Unsupported);
+#if FMT_HAS_STRING_VIEW
+  MakeValue(typename WCharHelper<const std::wstring_view &, Char>::Unsupported);
+#endif
+#if FMT_HAS_EXPERIMENTAL_STRING_VIEW
+  MakeValue(typename WCharHelper<const std::experimental::wstring_view &, Char>::Unsupported);
+#endif
   MakeValue(typename WCharHelper<WStringRef, Char>::Unsupported);
 
   void set_string(StringRef str) {
@@ -1338,6 +1469,20 @@
   FMT_MAKE_VALUE(unsigned char, uint_value, UINT)
   FMT_MAKE_VALUE(char, int_value, CHAR)
 
+#if __cplusplus >= 201103L
+  template <
+    typename T,
+    typename = typename std::enable_if<
+      std::is_enum<T>::value && ConvertToInt<T>::value>::type>
+   MakeValue(T value) { int_value = value; }
+
+  template <
+    typename T,
+    typename = typename std::enable_if<
+      std::is_enum<T>::value && ConvertToInt<T>::value>::type>
+  static uint64_t type(T) { return Arg::INT; }
+#endif
+
 #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
   MakeValue(typename WCharHelper<wchar_t, Char>::Supported value) {
     int_value = value;
@@ -1356,6 +1501,12 @@
   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)
+#if FMT_HAS_STRING_VIEW
+  FMT_MAKE_STR_VALUE(const std::string_view &, STRING)
+#endif
+#if FMT_HAS_EXPERIMENTAL_STRING_VIEW
+  FMT_MAKE_STR_VALUE(const std::experimental::string_view &, STRING)
+#endif
   FMT_MAKE_STR_VALUE(StringRef, STRING)
   FMT_MAKE_VALUE_(CStringRef, string.value, CSTRING, value.c_str())
 
@@ -1368,6 +1519,12 @@
   FMT_MAKE_WSTR_VALUE(wchar_t *, WSTRING)
   FMT_MAKE_WSTR_VALUE(const wchar_t *, WSTRING)
   FMT_MAKE_WSTR_VALUE(const std::wstring &, WSTRING)
+#if FMT_HAS_STRING_VIEW
+  FMT_MAKE_WSTR_VALUE(const std::wstring_view &, WSTRING)
+#endif
+#if FMT_HAS_EXPERIMENTAL_STRING_VIEW
+  FMT_MAKE_WSTR_VALUE(const std::experimental::wstring_view &, WSTRING)
+#endif
   FMT_MAKE_WSTR_VALUE(WStringRef, WSTRING)
 
   FMT_MAKE_VALUE(void *, pointer, POINTER)
@@ -1382,14 +1539,9 @@
   }
 
   template <typename T>
-  MakeValue(const T &value,
-            typename EnableIf<ConvertToInt<T>::value, int>::type = 0) {
-    int_value = value;
-  }
-
-  template <typename T>
-  static uint64_t type(const T &) {
-    return ConvertToInt<T>::value ? Arg::INT : Arg::CUSTOM;
+  static typename EnableIf<Not<ConvertToInt<T>::value>::value, uint64_t>::type
+      type(const T &) {
+    return Arg::CUSTOM;
   }
 
   // Additional template param `Char_` is needed here because make_type always
@@ -1438,7 +1590,7 @@
  protected:
   RuntimeError() : std::runtime_error("") {}
   RuntimeError(const RuntimeError &rerr) : std::runtime_error(rerr) {}
-  ~RuntimeError() FMT_DTOR_NOEXCEPT;
+  FMT_API ~RuntimeError() FMT_DTOR_NOEXCEPT FMT_OVERRIDE;
 };
 
 template <typename Char>
@@ -1697,6 +1849,7 @@
   int precision() const { return -1; }
   bool flag(unsigned) const { return false; }
   char type() const { return TYPE; }
+  char type_prefix() const { return TYPE; }
   char fill() const { return ' '; }
 };
 
@@ -1732,6 +1885,7 @@
 
   bool flag(unsigned) const { return false; }
   char type() const { return TYPE; }
+  char type_prefix() const { return TYPE; }
 };
 
 // A full format specifier.
@@ -1747,6 +1901,7 @@
   bool flag(unsigned f) const { return (flags_ & f) != 0; }
   int precision() const { return precision_; }
   char type() const { return type_; }
+  char type_prefix() const { return type_; }
 };
 
 // An integer format specifier.
@@ -1909,7 +2064,7 @@
   MapType map_;
 
  public:
-  FMT_API void init(const ArgList &args);
+  void init(const ArgList &args);
 
   const internal::Arg *find(const fmt::BasicStringRef<Char> &name) const {
     // The list is unsorted, so just return the first matching name.
@@ -1922,11 +2077,56 @@
   }
 };
 
-template <typename Impl, typename Char>
+template <typename Char>
+void ArgMap<Char>::init(const ArgList &args) {
+  if (!map_.empty())
+    return;
+  typedef internal::NamedArg<Char> NamedArg;
+  const NamedArg *named_arg = FMT_NULL;
+  bool use_values =
+      args.type(ArgList::MAX_PACKED_ARGS - 1) == internal::Arg::NONE;
+  if (use_values) {
+    for (unsigned i = 0;/*nothing*/; ++i) {
+      internal::Arg::Type arg_type = args.type(i);
+      switch (arg_type) {
+      case internal::Arg::NONE:
+        return;
+      case internal::Arg::NAMED_ARG:
+        named_arg = static_cast<const NamedArg*>(args.values_[i].pointer);
+        map_.push_back(Pair(named_arg->name, *named_arg));
+        break;
+      default:
+        /*nothing*/;
+      }
+    }
+    return;
+  }
+  for (unsigned i = 0; i != ArgList::MAX_PACKED_ARGS; ++i) {
+    internal::Arg::Type arg_type = args.type(i);
+    if (arg_type == internal::Arg::NAMED_ARG) {
+      named_arg = static_cast<const NamedArg*>(args.args_[i].pointer);
+      map_.push_back(Pair(named_arg->name, *named_arg));
+    }
+  }
+  for (unsigned i = ArgList::MAX_PACKED_ARGS;/*nothing*/; ++i) {
+    switch (args.args_[i].type) {
+    case internal::Arg::NONE:
+      return;
+    case internal::Arg::NAMED_ARG:
+      named_arg = static_cast<const NamedArg*>(args.args_[i].pointer);
+      map_.push_back(Pair(named_arg->name, *named_arg));
+      break;
+    default:
+      /*nothing*/;
+    }
+  }
+}
+
+template <typename Impl, typename Char, typename Spec = fmt::FormatSpec>
 class ArgFormatterBase : public ArgVisitor<Impl, void> {
  private:
   BasicWriter<Char> &writer_;
-  FormatSpec &spec_;
+  Spec &spec_;
 
   FMT_DISALLOW_COPY_AND_ASSIGN(ArgFormatterBase);
 
@@ -1936,9 +2136,12 @@
     writer_.write_int(reinterpret_cast<uintptr_t>(p), spec_);
   }
 
+  // workaround MSVC two-phase lookup issue
+  typedef internal::Arg Arg;
+
  protected:
   BasicWriter<Char> &writer() { return writer_; }
-  FormatSpec &spec() { return spec_; }
+  Spec &spec() { return spec_; }
 
   void write(bool value) {
     const char *str_value = value ? "true" : "false";
@@ -1952,7 +2155,9 @@
   }
 
  public:
-  ArgFormatterBase(BasicWriter<Char> &w, FormatSpec &s)
+  typedef Spec SpecType;
+
+  ArgFormatterBase(BasicWriter<Char> &w, Spec &s)
   : writer_(w), spec_(s) {}
 
   template <typename T>
@@ -2005,13 +2210,14 @@
     write(value);
   }
 
-  void visit_string(Arg::StringValue<char> value) {
+  // Qualification with "internal" here and below is a workaround for nvcc.
+  void visit_string(internal::Arg::StringValue<char> value) {
     writer_.write_str(value, spec_);
   }
 
   using ArgVisitor<Impl, void>::visit_wstring;
 
-  void visit_wstring(Arg::StringValue<Char> value) {
+  void visit_wstring(internal::Arg::StringValue<Char> value) {
     writer_.write_str(value, spec_);
   }
 
@@ -2086,8 +2292,8 @@
   will be called.
   \endrst
  */
-template <typename Impl, typename Char>
-class BasicArgFormatter : public internal::ArgFormatterBase<Impl, Char> {
+template <typename Impl, typename Char, typename Spec = fmt::FormatSpec>
+class BasicArgFormatter : public internal::ArgFormatterBase<Impl, Char, Spec> {
  private:
   BasicFormatter<Char, Impl> &formatter_;
   const Char *format_;
@@ -2102,8 +2308,8 @@
     \endrst
    */
   BasicArgFormatter(BasicFormatter<Char, Impl> &formatter,
-                    FormatSpec &spec, const Char *fmt)
-  : internal::ArgFormatterBase<Impl, Char>(formatter.writer(), spec),
+                    Spec &spec, const Char *fmt)
+  : internal::ArgFormatterBase<Impl, Char, Spec>(formatter.writer(), spec),
     formatter_(formatter), format_(fmt) {}
 
   /** Formats an argument of a custom (user-defined) type. */
@@ -2114,12 +2320,14 @@
 
 /** The default argument formatter. */
 template <typename Char>
-class ArgFormatter : public BasicArgFormatter<ArgFormatter<Char>, Char> {
+class ArgFormatter :
+    public BasicArgFormatter<ArgFormatter<Char>, Char, FormatSpec> {
  public:
   /** Constructs an argument formatter object. */
   ArgFormatter(BasicFormatter<Char> &formatter,
                FormatSpec &spec, const Char *fmt)
-  : BasicArgFormatter<ArgFormatter<Char>, Char>(formatter, spec, fmt) {}
+  : BasicArgFormatter<ArgFormatter<Char>,
+                      Char, FormatSpec>(formatter, spec, fmt) {}
 };
 
 /** This template formats data and writes the output to a writer. */
@@ -2195,12 +2403,13 @@
   return MakeValue< BasicFormatter<char> >::type(arg);
 }
 
-template <unsigned N, bool/*IsPacked*/= (N < ArgList::MAX_PACKED_ARGS)>
+template <std::size_t N, bool/*IsPacked*/= (N < ArgList::MAX_PACKED_ARGS)>
 struct ArgArray;
 
-template <unsigned N>
+template <std::size_t N>
 struct ArgArray<N, true/*IsPacked*/> {
-  typedef Value Type[N > 0 ? N : 1];
+  // '+' is used to silence GCC -Wduplicated-branches warning.
+  typedef Value Type[N > 0 ? N : +1];
 
   template <typename Formatter, typename T>
   static Value make(const T &value) {
@@ -2216,7 +2425,7 @@
   }
 };
 
-template <unsigned N>
+template <std::size_t N>
 struct ArgArray<N, false/*IsPacked*/> {
   typedef Arg Type[N + 1]; // +1 for the list end Arg::NONE
 
@@ -2356,7 +2565,7 @@
 */
 class SystemError : public internal::RuntimeError {
  private:
-  void init(int err_code, CStringRef format_str, ArgList args);
+  FMT_API void init(int err_code, CStringRef format_str, ArgList args);
 
  protected:
   int error_code_;
@@ -2387,9 +2596,10 @@
   SystemError(int error_code, CStringRef message) {
     init(error_code, message, ArgList());
   }
+  FMT_DEFAULTED_COPY_CTOR(SystemError)
   FMT_VARIADIC_CTOR(SystemError, init, int, CStringRef)
 
-  ~SystemError() FMT_DTOR_NOEXCEPT;
+  FMT_API ~SystemError() FMT_DTOR_NOEXCEPT FMT_OVERRIDE;
 
   int error_code() const { return error_code_; }
 };
@@ -2501,16 +2711,16 @@
   void write_int(T value, Spec spec);
 
   // Formats a floating-point number (double or long double).
-  template <typename T>
-  void write_double(T value, const FormatSpec &spec);
+  template <typename T, typename Spec>
+  void write_double(T value, const Spec &spec);
 
   // Writes a formatted string.
   template <typename StrChar>
   CharPtr write_str(const StrChar *s, std::size_t size, const AlignSpec &spec);
 
-  template <typename StrChar>
+  template <typename StrChar, typename Spec>
   void write_str(const internal::Arg::StringValue<StrChar> &str,
-                 const FormatSpec &spec);
+                 const Spec &spec);
 
   // This following methods are private to disallow writing wide characters
   // and strings to a char stream. If you want to print a wide string as a
@@ -2529,10 +2739,10 @@
   template<typename T>
   void append_float_length(Char *&, T) {}
 
-  template <typename Impl, typename Char_>
+  template <typename Impl, typename Char_, typename Spec_>
   friend class internal::ArgFormatterBase;
 
-  template <typename Impl, typename Char_>
+  template <typename Impl, typename Char_, typename Spec_>
   friend class BasicPrintfArgFormatter;
 
  protected:
@@ -2729,9 +2939,9 @@
 }
 
 template <typename Char>
-template <typename StrChar>
+template <typename StrChar, typename Spec>
 void BasicWriter<Char>::write_str(
-    const internal::Arg::StringValue<StrChar> &s, const FormatSpec &spec) {
+    const internal::Arg::StringValue<StrChar> &s, const Spec &spec) {
   // Check if StrChar is convertible to Char.
   internal::CharTraits<Char>::convert(StrChar());
   if (spec.type_ && spec.type_ != 's')
@@ -2790,13 +3000,13 @@
       CharPtr p = grow_buffer(fill_size);
       std::uninitialized_fill(p, p + fill_size, fill);
     }
-    CharPtr result = prepare_int_buffer(
-        num_digits, subspec, prefix, prefix_size);
+    std::ptrdiff_t offset = get(prepare_int_buffer(
+        num_digits, subspec, prefix, prefix_size)) - &buffer_[0];
     if (align == ALIGN_LEFT) {
       CharPtr p = grow_buffer(fill_size);
       std::uninitialized_fill(p, p + fill_size, fill);
     }
-    return result;
+    return internal::make_ptr(&buffer_[0], buffer_.size()) + offset;
   }
   unsigned size = prefix_size + num_digits;
   if (width <= size) {
@@ -2855,7 +3065,7 @@
     UnsignedType n = abs_value;
     if (spec.flag(HASH_FLAG)) {
       prefix[prefix_size++] = '0';
-      prefix[prefix_size++] = spec.type();
+      prefix[prefix_size++] = spec.type_prefix();
     }
     unsigned num_digits = 0;
     do {
@@ -2875,7 +3085,7 @@
     UnsignedType n = abs_value;
     if (spec.flag(HASH_FLAG)) {
       prefix[prefix_size++] = '0';
-      prefix[prefix_size++] = spec.type();
+      prefix[prefix_size++] = spec.type_prefix();
     }
     unsigned num_digits = 0;
     do {
@@ -2906,7 +3116,7 @@
   case 'n': {
     unsigned num_digits = internal::count_digits(abs_value);
     fmt::StringRef sep = "";
-#ifndef ANDROID
+#if !(defined(ANDROID) || defined(__ANDROID__))
     sep = internal::thousands_sep(std::localeconv());
 #endif
     unsigned size = static_cast<unsigned>(
@@ -2923,8 +3133,8 @@
 }
 
 template <typename Char>
-template <typename T>
-void BasicWriter<Char>::write_double(T value, const FormatSpec &spec) {
+template <typename T, typename Spec>
+void BasicWriter<Char>::write_double(T value, const Spec &spec) {
   // Check type.
   char type = spec.type();
   bool upper = false;
@@ -3462,10 +3672,10 @@
 #define FMT_GET_ARG_NAME(type, index) arg##index
 
 #if FMT_USE_VARIADIC_TEMPLATES
-# define FMT_VARIADIC_(Char, ReturnType, func, call, ...) \
+# define FMT_VARIADIC_(Const, Char, ReturnType, func, call, ...) \
   template <typename... Args> \
   ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \
-      const Args & ... args) { \
+      const Args & ... args) Const { \
     typedef fmt::internal::ArgArray<sizeof...(Args)> ArgArray; \
     typename ArgArray::Type array{ \
       ArgArray::template make<fmt::BasicFormatter<Char> >(args)...}; \
@@ -3475,35 +3685,35 @@
 #else
 // Defines a wrapper for a function taking __VA_ARGS__ arguments
 // and n additional arguments of arbitrary types.
-# define FMT_WRAP(Char, ReturnType, func, call, n, ...) \
+# define FMT_WRAP(Const, Char, ReturnType, func, call, n, ...) \
   template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \
   inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \
-      FMT_GEN(n, FMT_MAKE_ARG)) { \
+      FMT_GEN(n, FMT_MAKE_ARG)) Const { \
     fmt::internal::ArgArray<n>::Type arr; \
     FMT_GEN(n, FMT_ASSIGN_##Char); \
     call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), fmt::ArgList( \
       fmt::internal::make_type(FMT_GEN(n, FMT_MAKE_REF2)), arr)); \
   }
 
-# define FMT_VARIADIC_(Char, ReturnType, func, call, ...) \
-  inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__)) { \
+# define FMT_VARIADIC_(Const, Char, ReturnType, func, call, ...) \
+  inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__)) Const { \
     call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), fmt::ArgList()); \
   } \
-  FMT_WRAP(Char, ReturnType, func, call, 1, __VA_ARGS__) \
-  FMT_WRAP(Char, ReturnType, func, call, 2, __VA_ARGS__) \
-  FMT_WRAP(Char, ReturnType, func, call, 3, __VA_ARGS__) \
-  FMT_WRAP(Char, ReturnType, func, call, 4, __VA_ARGS__) \
-  FMT_WRAP(Char, ReturnType, func, call, 5, __VA_ARGS__) \
-  FMT_WRAP(Char, ReturnType, func, call, 6, __VA_ARGS__) \
-  FMT_WRAP(Char, ReturnType, func, call, 7, __VA_ARGS__) \
-  FMT_WRAP(Char, ReturnType, func, call, 8, __VA_ARGS__) \
-  FMT_WRAP(Char, ReturnType, func, call, 9, __VA_ARGS__) \
-  FMT_WRAP(Char, ReturnType, func, call, 10, __VA_ARGS__) \
-  FMT_WRAP(Char, ReturnType, func, call, 11, __VA_ARGS__) \
-  FMT_WRAP(Char, ReturnType, func, call, 12, __VA_ARGS__) \
-  FMT_WRAP(Char, ReturnType, func, call, 13, __VA_ARGS__) \
-  FMT_WRAP(Char, ReturnType, func, call, 14, __VA_ARGS__) \
-  FMT_WRAP(Char, ReturnType, func, call, 15, __VA_ARGS__)
+  FMT_WRAP(Const, Char, ReturnType, func, call, 1, __VA_ARGS__) \
+  FMT_WRAP(Const, Char, ReturnType, func, call, 2, __VA_ARGS__) \
+  FMT_WRAP(Const, Char, ReturnType, func, call, 3, __VA_ARGS__) \
+  FMT_WRAP(Const, Char, ReturnType, func, call, 4, __VA_ARGS__) \
+  FMT_WRAP(Const, Char, ReturnType, func, call, 5, __VA_ARGS__) \
+  FMT_WRAP(Const, Char, ReturnType, func, call, 6, __VA_ARGS__) \
+  FMT_WRAP(Const, Char, ReturnType, func, call, 7, __VA_ARGS__) \
+  FMT_WRAP(Const, Char, ReturnType, func, call, 8, __VA_ARGS__) \
+  FMT_WRAP(Const, Char, ReturnType, func, call, 9, __VA_ARGS__) \
+  FMT_WRAP(Const, Char, ReturnType, func, call, 10, __VA_ARGS__) \
+  FMT_WRAP(Const, Char, ReturnType, func, call, 11, __VA_ARGS__) \
+  FMT_WRAP(Const, Char, ReturnType, func, call, 12, __VA_ARGS__) \
+  FMT_WRAP(Const, Char, ReturnType, func, call, 13, __VA_ARGS__) \
+  FMT_WRAP(Const, Char, ReturnType, func, call, 14, __VA_ARGS__) \
+  FMT_WRAP(Const, Char, ReturnType, func, call, 15, __VA_ARGS__)
 #endif  // FMT_USE_VARIADIC_TEMPLATES
 
 /**
@@ -3534,10 +3744,16 @@
   \endrst
  */
 #define FMT_VARIADIC(ReturnType, func, ...) \
-  FMT_VARIADIC_(char, ReturnType, func, return func, __VA_ARGS__)
+  FMT_VARIADIC_(, char, ReturnType, func, return func, __VA_ARGS__)
+
+#define FMT_VARIADIC_CONST(ReturnType, func, ...) \
+  FMT_VARIADIC_(const, char, ReturnType, func, return func, __VA_ARGS__)
 
 #define FMT_VARIADIC_W(ReturnType, func, ...) \
-  FMT_VARIADIC_(wchar_t, ReturnType, func, return func, __VA_ARGS__)
+  FMT_VARIADIC_(, wchar_t, ReturnType, func, return func, __VA_ARGS__)
+
+#define FMT_VARIADIC_CONST_W(ReturnType, func, ...) \
+  FMT_VARIADIC_(const, wchar_t, ReturnType, func, return func, __VA_ARGS__)
 
 #define FMT_CAPTURE_ARG_(id, index) ::fmt::arg(#id, id)
 
@@ -3580,17 +3796,19 @@
 unsigned parse_nonnegative_int(const Char *&s) {
   assert('0' <= *s && *s <= '9');
   unsigned value = 0;
-  do {
-    unsigned new_value = value * 10 + (*s++ - '0');
-    // Check if value wrapped around.
-    if (new_value < value) {
-      value = (std::numeric_limits<unsigned>::max)();
-      break;
-    }
-    value = new_value;
-  } while ('0' <= *s && *s <= '9');
   // Convert to unsigned to prevent a warning.
   unsigned max_int = (std::numeric_limits<int>::max)();
+  unsigned big = max_int / 10;
+  do {
+    // Check for overflow.
+    if (value > big) {
+      value = max_int + 1;
+      break;
+    }
+    value = value * 10 + (*s - '0');
+    ++s;
+  } while ('0' <= *s && *s <= '9');
+  // Convert to unsigned to prevent a warning.
   if (value > max_int)
     FMT_THROW(FormatError("number is too big"));
   return value;
@@ -3661,7 +3879,7 @@
     const Char *&format_str, const internal::Arg &arg) {
   using internal::Arg;
   const Char *s = format_str;
-  FormatSpec spec;
+  typename ArgFormatter::SpecType spec;
   if (*s == ':') {
     if (arg.type == Arg::CUSTOM) {
       arg.custom.format(this, arg.custom.value, &s);
@@ -3762,7 +3980,8 @@
       default:
         FMT_THROW(FormatError("width is not integer"));
       }
-      if (value > (std::numeric_limits<int>::max)())
+      unsigned max_int = (std::numeric_limits<int>::max)();
+      if (value > max_int)
         FMT_THROW(FormatError("number is too big"));
       spec.width_ = static_cast<int>(value);
     }
@@ -3800,7 +4019,8 @@
           default:
             FMT_THROW(FormatError("precision is not integer"));
         }
-        if (value > (std::numeric_limits<int>::max)())
+        unsigned max_int = (std::numeric_limits<int>::max)();
+        if (value > max_int)
           FMT_THROW(FormatError("number is too big"));
         spec.precision_ = static_cast<int>(value);
       } else {
@@ -3847,6 +4067,70 @@
   }
   write(writer_, start, s);
 }
+
+template <typename Char, typename It>
+struct ArgJoin {
+  It first;
+  It last;
+  BasicCStringRef<Char> sep;
+
+  ArgJoin(It first, It last, const BasicCStringRef<Char>& sep) :
+    first(first),
+    last(last),
+    sep(sep) {}
+};
+
+template <typename It>
+ArgJoin<char, It> join(It first, It last, const BasicCStringRef<char>& sep) {
+  return ArgJoin<char, It>(first, last, sep);
+}
+
+template <typename It>
+ArgJoin<wchar_t, It> join(It first, It last, const BasicCStringRef<wchar_t>& sep) {
+  return ArgJoin<wchar_t, It>(first, last, sep);
+}
+
+#if FMT_HAS_GXX_CXX11
+template <typename Range>
+auto join(const Range& range, const BasicCStringRef<char>& sep)
+    -> ArgJoin<char, decltype(std::begin(range))> {
+  return join(std::begin(range), std::end(range), sep);
+}
+
+template <typename Range>
+auto join(const Range& range, const BasicCStringRef<wchar_t>& sep)
+    -> ArgJoin<wchar_t, decltype(std::begin(range))> {
+  return join(std::begin(range), std::end(range), sep);
+}
+#endif
+
+template <typename ArgFormatter, typename Char, typename It>
+void format_arg(fmt::BasicFormatter<Char, ArgFormatter> &f,
+    const Char *&format_str, const ArgJoin<Char, It>& e) {
+  const Char* end = format_str;
+  int brace_level = 1;
+  while (*end) {
+    if (*end == '}' && --brace_level == 0)
+      break;
+    if (*end == '{')
+      ++brace_level;
+    ++end;
+  }
+  if (*end != '}')
+    FMT_THROW(FormatError("missing '}' in format string"));
+
+  It it = e.first;
+  if (it != e.last) {
+    const Char* save = format_str;
+    f.format(format_str, internal::MakeArg<fmt::BasicFormatter<Char, ArgFormatter> >(*it++));
+    while (it != e.last) {
+      f.writer().write(e.sep);
+      format_str = save;
+      f.format(format_str, internal::MakeArg<fmt::BasicFormatter<Char, ArgFormatter> >(*it++));
+    }
+  }
+  format_str = end + 1;
+}
 }  // namespace fmt
 
 #if FMT_USE_USER_DEFINED_LITERALS
diff --git a/fmt/ostream.h b/fmt/ostream.h
index 4e8c6d8..6848aac 100644
--- a/fmt/ostream.h
+++ b/fmt/ostream.h
@@ -24,28 +24,27 @@
   typedef typename std::basic_streambuf<Char>::traits_type traits_type;
 
   Buffer<Char> &buffer_;
-  Char *start_;
 
  public:
-  FormatBuf(Buffer<Char> &buffer) : buffer_(buffer), start_(&buffer[0]) {
-    this->setp(start_, start_ + buffer_.capacity());
-  }
+  FormatBuf(Buffer<Char> &buffer) : buffer_(buffer) {}
 
-  int_type overflow(int_type ch = traits_type::eof()) {
-    if (!traits_type::eq_int_type(ch, traits_type::eof())) {
-      size_t buf_size = size();
-      buffer_.resize(buf_size);
-      buffer_.reserve(buf_size * 2);
+ protected:
+  // The put-area is actually always empty. This makes the implementation
+  // simpler and has the advantage that the streambuf and the buffer are always
+  // in sync and sputc never writes into uninitialized memory. The obvious
+  // disadvantage is that each call to sputc always results in a (virtual) call
+  // to overflow. There is no disadvantage here for sputn since this always
+  // results in a call to xsputn.
 
-      start_ = &buffer_[0];
-      start_[buf_size] = traits_type::to_char_type(ch);
-      this->setp(start_+ buf_size + 1, start_ + buf_size * 2);
-    }
+  int_type overflow(int_type ch = traits_type::eof()) FMT_OVERRIDE {
+    if (!traits_type::eq_int_type(ch, traits_type::eof()))
+      buffer_.push_back(static_cast<Char>(ch));
     return ch;
   }
 
-  size_t size() const {
-    return to_unsigned(this->pptr() - start_);
+  std::streamsize xsputn(const Char *s, std::streamsize count) FMT_OVERRIDE {
+    buffer_.append(s, s + count);
+    return count;
   }
 };
 
@@ -53,13 +52,15 @@
 
 struct DummyStream : std::ostream {
   DummyStream();  // Suppress a bogus warning in MSVC.
+
   // Hide all operator<< overloads from std::ostream.
-  void operator<<(Null<>);
+  template <typename T>
+  typename EnableIf<sizeof(T) == 0>::type operator<<(const T &);
 };
 
 No &operator<<(std::ostream &, int);
 
-template<typename T>
+template <typename T>
 struct ConvertToIntImpl<T, true> {
   // Convert to int only if T doesn't have an overloaded operator<<.
   enum {
@@ -68,20 +69,21 @@
 };
 
 // Write the content of w to os.
-void write(std::ostream &os, Writer &w);
+FMT_API void write(std::ostream &os, Writer &w);
 }  // namespace internal
 
 // Formats a value.
-template <typename Char, typename ArgFormatter, typename T>
-void format_arg(BasicFormatter<Char, ArgFormatter> &f,
+template <typename Char, typename ArgFormatter_, typename T>
+void format_arg(BasicFormatter<Char, ArgFormatter_> &f,
                 const Char *&format_str, const T &value) {
   internal::MemoryBuffer<Char, internal::INLINE_BUFFER_SIZE> buffer;
 
   internal::FormatBuf<Char> format_buf(buffer);
   std::basic_ostream<Char> output(&format_buf);
+  output.exceptions(std::ios_base::failbit | std::ios_base::badbit);
   output << value;
 
-  BasicStringRef<Char> str(&buffer[0], format_buf.size());
+  BasicStringRef<Char> str(&buffer[0], buffer.size());
   typedef internal::MakeArg< BasicFormatter<Char> > MakeArg;
   format_str = f.format(format_str, MakeArg(str));
 }
diff --git a/fmt/posix.cc b/fmt/posix.cc
index d86578f..356668c 100644
--- a/fmt/posix.cc
+++ b/fmt/posix.cc
@@ -21,6 +21,9 @@
 #ifndef _WIN32
 # include <unistd.h>
 #else
+# ifndef WIN32_LEAN_AND_MEAN
+#  define WIN32_LEAN_AND_MEAN
+# endif
 # include <windows.h>
 # include <io.h>
 
diff --git a/fmt/posix.h b/fmt/posix.h
index f31f3b1..88512de 100644
--- a/fmt/posix.h
+++ b/fmt/posix.h
@@ -91,7 +91,7 @@
   BufferedFile() FMT_NOEXCEPT : file_(FMT_NULL) {}
 
   // Destroys the object closing the file it represents if any.
-  ~BufferedFile() FMT_NOEXCEPT;
+  FMT_API ~BufferedFile() FMT_NOEXCEPT;
 
 #if !FMT_USE_RVALUE_REFERENCES
   // Emulate a move constructor and a move assignment operator if rvalue
@@ -154,17 +154,17 @@
 #endif
 
   // Opens a file.
-  BufferedFile(CStringRef filename, CStringRef mode);
+  FMT_API BufferedFile(CStringRef filename, CStringRef mode);
 
   // Closes the file.
-  void close();
+  FMT_API void close();
 
   // Returns the pointer to a FILE object representing this file.
   FILE *get() const FMT_NOEXCEPT { return file_; }
 
   // We place parentheses around fileno to workaround a bug in some versions
   // of MinGW that define fileno as a macro.
-  int (fileno)() const;
+  FMT_API int (fileno)() const;
 
   void print(CStringRef format_str, const ArgList &args) {
     fmt::print(file_, format_str, args);
@@ -197,7 +197,7 @@
   File() FMT_NOEXCEPT : fd_(-1) {}
 
   // Opens a file and constructs a File object representing this file.
-  File(CStringRef path, int oflag);
+  FMT_API File(CStringRef path, int oflag);
 
 #if !FMT_USE_RVALUE_REFERENCES
   // Emulate a move constructor and a move assignment operator if rvalue
@@ -260,43 +260,43 @@
 #endif
 
   // Destroys the object closing the file it represents if any.
-  ~File() FMT_NOEXCEPT;
+  FMT_API ~File() FMT_NOEXCEPT;
 
   // Returns the file descriptor.
   int descriptor() const FMT_NOEXCEPT { return fd_; }
 
   // Closes the file.
-  void close();
+  FMT_API void close();
 
   // Returns the file size. The size has signed type for consistency with
   // stat::st_size.
-  LongLong size() const;
+  FMT_API LongLong size() const;
 
   // Attempts to read count bytes from the file into the specified buffer.
-  std::size_t read(void *buffer, std::size_t count);
+  FMT_API std::size_t read(void *buffer, std::size_t count);
 
   // Attempts to write count bytes from the specified buffer to the file.
-  std::size_t write(const void *buffer, std::size_t count);
+  FMT_API std::size_t write(const void *buffer, std::size_t count);
 
   // Duplicates a file descriptor with the dup function and returns
   // the duplicate as a file object.
-  static File dup(int fd);
+  FMT_API static File dup(int fd);
 
   // Makes fd be the copy of this file descriptor, closing fd first if
   // necessary.
-  void dup2(int fd);
+  FMT_API void dup2(int fd);
 
   // Makes fd be the copy of this file descriptor, closing fd first if
   // necessary.
-  void dup2(int fd, ErrorCode &ec) FMT_NOEXCEPT;
+  FMT_API void dup2(int fd, ErrorCode &ec) FMT_NOEXCEPT;
 
   // Creates a pipe setting up read_end and write_end file objects for reading
   // and writing respectively.
-  static void pipe(File &read_end, File &write_end);
+  FMT_API static void pipe(File &read_end, File &write_end);
 
   // Creates a BufferedFile object associated with this file and detaches
   // this File object from the file.
-  BufferedFile fdopen(const char *mode);
+  FMT_API BufferedFile fdopen(const char *mode);
 };
 
 // Returns the memory page size.
diff --git a/fmt/printf.h b/fmt/printf.h
index 80d2244..46205a7 100644
--- a/fmt/printf.h
+++ b/fmt/printf.h
@@ -61,6 +61,24 @@
   bool visit_any_int(T value) { return value == 0; }
 };
 
+// returns the default type for format specific "%s"
+class DefaultType : public ArgVisitor<DefaultType, char> {
+ public:
+  char visit_char(int) { return 'c'; }
+
+  char visit_bool(bool) { return 's'; }
+
+  char visit_pointer(const void *) { return 'p'; }
+
+  template <typename T>
+  char visit_any_int(T) { return 'd'; }
+
+  template <typename T>
+  char visit_any_double(T) { return 'g'; }
+
+  char visit_unhandled_arg() { return 's'; }
+};
+
 template <typename T, typename U>
 struct is_same {
   enum { value = 0 };
@@ -92,13 +110,22 @@
       visit_any_int(value);
   }
 
+  void visit_char(int value) {
+    if (type_ != 's')
+      visit_any_int(value);
+  }
+
   template <typename U>
   void visit_any_int(U value) {
     bool is_signed = type_ == 'd' || type_ == 'i';
+    if (type_ == 's') {
+      is_signed = std::numeric_limits<U>::is_signed;
+    }
+
     using internal::Arg;
     typedef typename internal::Conditional<
         is_same<T, void>::value, U, T>::type TargetType;
-    if (sizeof(TargetType) <= sizeof(int)) {
+    if (const_check(sizeof(TargetType) <= sizeof(int))) {
       // Extra casts are used to silence warnings.
       if (is_signed) {
         arg_.type = Arg::INT;
@@ -189,15 +216,16 @@
   superclass will be called.
   \endrst
  */
-template <typename Impl, typename Char>
-class BasicPrintfArgFormatter : public internal::ArgFormatterBase<Impl, Char> {
+template <typename Impl, typename Char, typename Spec>
+class BasicPrintfArgFormatter :
+    public internal::ArgFormatterBase<Impl, Char, Spec> {
  private:
   void write_null_pointer() {
     this->spec().type_ = 0;
     this->write("(nil)");
   }
 
-  typedef internal::ArgFormatterBase<Impl, Char> Base;
+  typedef internal::ArgFormatterBase<Impl, Char, Spec> Base;
 
  public:
   /**
@@ -207,12 +235,12 @@
     specifier information for standard argument types.
     \endrst
    */
-  BasicPrintfArgFormatter(BasicWriter<Char> &w, FormatSpec &s)
-  : internal::ArgFormatterBase<Impl, Char>(w, s) {}
+  BasicPrintfArgFormatter(BasicWriter<Char> &w, Spec &s)
+  : internal::ArgFormatterBase<Impl, Char, Spec>(w, s) {}
 
   /** Formats an argument of type ``bool``. */
   void visit_bool(bool value) {
-    FormatSpec &fmt_spec = this->spec();
+    Spec &fmt_spec = this->spec();
     if (fmt_spec.type_ != 's')
       return this->visit_any_int(value);
     fmt_spec.type_ = 0;
@@ -221,7 +249,7 @@
 
   /** Formats a character. */
   void visit_char(int value) {
-    const FormatSpec &fmt_spec = this->spec();
+    const Spec &fmt_spec = this->spec();
     BasicWriter<Char> &w = this->writer();
     if (fmt_spec.type_ && fmt_spec.type_ != 'c')
       w.write_int(value, fmt_spec);
@@ -271,12 +299,12 @@
 
 /** The default printf argument formatter. */
 template <typename Char>
-class PrintfArgFormatter
-    : public BasicPrintfArgFormatter<PrintfArgFormatter<Char>, Char> {
+class PrintfArgFormatter :
+    public BasicPrintfArgFormatter<PrintfArgFormatter<Char>, Char, FormatSpec> {
  public:
   /** Constructs an argument formatter object. */
   PrintfArgFormatter(BasicWriter<Char> &w, FormatSpec &s)
-  : BasicPrintfArgFormatter<PrintfArgFormatter<Char>, Char>(w, s) {}
+  : BasicPrintfArgFormatter<PrintfArgFormatter<Char>, Char, FormatSpec>(w, s) {}
 };
 
 /** This template formats data and writes the output to a writer. */
@@ -308,7 +336,7 @@
     : FormatterBase(al), writer_(w) {}
 
   /** Formats stored arguments and writes the output to the writer. */
-  FMT_API void format(BasicCStringRef<Char> format_str);
+  void format(BasicCStringRef<Char> format_str);
 };
 
 template <typename Char, typename AF>
@@ -411,6 +439,8 @@
       } else if (*s == '*') {
         ++s;
         spec.precision_ = internal::PrecisionHandler().visit(get_arg(s));
+      } else {
+        spec.precision_ = 0;
       }
     }
 
@@ -462,6 +492,12 @@
     if (!*s)
       FMT_THROW(FormatError("invalid format string"));
     spec.type_ = static_cast<char>(*s++);
+
+    if (spec.type_ == 's') {
+      // set the format type to the default if 's' is specified
+      spec.type_ = internal::DefaultType().visit(arg);
+    }
+
     if (arg.type <= Arg::LAST_INTEGER_TYPE) {
       // Normalize type.
       switch (spec.type_) {
@@ -483,10 +519,15 @@
   write(writer_, start, s);
 }
 
-template <typename Char>
-void printf(BasicWriter<Char> &w, BasicCStringRef<Char> format, ArgList args) {
-  PrintfFormatter<Char>(args, w).format(format);
+inline void printf(Writer &w, CStringRef format, ArgList args) {
+  PrintfFormatter<char>(args, w).format(format);
 }
+FMT_VARIADIC(void, printf, Writer &, CStringRef)
+
+inline void printf(WWriter &w, WCStringRef format, ArgList args) {
+  PrintfFormatter<wchar_t>(args, w).format(format);
+}
+FMT_VARIADIC(void, printf, WWriter &, WCStringRef)
 
 /**
   \rst
diff --git a/fmt/string.h b/fmt/string.h
index ccf46ee..05996eb 100644
--- a/fmt/string.h
+++ b/fmt/string.h
@@ -7,6 +7,10 @@
  For the license information refer to format.h.
  */
 
+#ifdef FMT_INCLUDE
+# error "Add the fmt's parent directory and not fmt itself to includes."
+#endif
+
 #ifndef FMT_STRING_H_
 #define FMT_STRING_H_
 
@@ -121,6 +125,24 @@
   w << value;
   return w.str();
 }
+
+/**
+  \rst
+  Converts *value* to ``std::wstring`` using the default format for type *T*.
+
+  **Example**::
+
+    #include "fmt/string.h"
+
+    std::wstring answer = fmt::to_wstring(42);
+  \endrst
+ */
+template <typename T>
+std::wstring to_wstring(const T &value) {
+  fmt::WMemoryWriter w;
+  w << value;
+  return w.str();
+}
 }
 
 #endif  // FMT_STRING_H_
diff --git a/support/README b/support/README
index 468f548..e7fbacc 100644
--- a/support/README
+++ b/support/README
@@ -2,3 +2,5 @@
 
 * CMake modules
 * Build scripts
+* qmake (static build with dynamic libc only)
+
diff --git a/support/cmake/cxx11.cmake b/support/cmake/cxx11.cmake
index 02795a9..21d1254 100644
--- a/support/cmake/cxx11.cmake
+++ b/support/cmake/cxx11.cmake
@@ -20,7 +20,14 @@
     check_cxx_source_compiles("
       #include <unistd.h>
       int main() {}" FMT_CPP11_UNISTD_H)
-    if (FMT_CPP11_CMATH AND FMT_CPP11_UNISTD_H)
+    # Check if snprintf works with -std=c++11. It may not in MinGW.
+    check_cxx_source_compiles("
+      #include <stdio.h>
+      int main() {
+        char buffer[10];
+        snprintf(buffer, 10, \"foo\");
+      }" FMT_CPP11_SNPRINTF)
+    if (FMT_CPP11_CMATH AND FMT_CPP11_UNISTD_H AND FMT_CPP11_SNPRINTF)
       set(CPP11_FLAG -std=c++11)
     else ()
       check_cxx_compiler_flag(-std=gnu++11 HAVE_STD_GNUPP11_FLAG)
diff --git a/support/fmt.pro b/support/fmt.pro
new file mode 100644
index 0000000..0fb09d1
--- /dev/null
+++ b/support/fmt.pro
@@ -0,0 +1,29 @@
+# Staticlib configuration for qmake builds
+# For some reason qmake 3.1 fails to identify source dependencies and excludes format.cc and printf.cc
+# from compilation so it _MUST_ be called as qmake -nodepend
+# A workaround is implemented below: a custom compiler is defined which does not track dependencies
+
+TEMPLATE = lib
+
+TARGET = fmt
+
+QMAKE_EXT_CPP = .cc
+
+CONFIG = staticlib warn_on c++11
+
+FMT_SOURCES = \
+    ../fmt/format.cc \
+    ../fmt/ostream.cc \
+    ../fmt/posix.cc \
+    ../fmt/printf.cc
+
+fmt.name = libfmt
+fmt.input = FMT_SOURCES
+fmt.output = ${QMAKE_FILE_BASE}$$QMAKE_EXT_OBJ
+fmt.clean = ${QMAKE_FILE_BASE}$$QMAKE_EXT_OBJ
+fmt.depends = ${QMAKE_FILE_IN}
+# QMAKE_RUN_CXX will not be expanded
+fmt.commands = $$QMAKE_CXX -c $$QMAKE_CXXFLAGS $$QMAKE_CXXFLAGS_WARN_ON $$QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO $$QMAKE_CXXFLAGS_CXX11 ${QMAKE_FILE_IN}
+fmt.variable_out = OBJECTS
+fmt.CONFIG = no_dependencies no_link
+QMAKE_EXTRA_COMPILERS += fmt
diff --git a/support/manage.py b/support/manage.py
index 1da371d..6b2ceb0 100755
--- a/support/manage.py
+++ b/support/manage.py
@@ -8,7 +8,7 @@
 """
 
 from __future__ import print_function
-import datetime, docopt, fileinput, json, os
+import datetime, docopt, errno, fileinput, json, os
 import re, requests, shutil, sys, tempfile
 from contextlib import contextmanager
 from distutils.version import LooseVersion
@@ -80,6 +80,7 @@
     import build
 
     env.build_dir = 'build'
+    env.versions = build.versions
 
     # Virtualenv and repos are cached to speed up builds.
     build.create_build_env(os.path.join(env.build_dir, 'virtualenv'))
@@ -113,7 +114,7 @@
     doc_repo = Git(os.path.join(env.build_dir, 'fmtlib.github.io'))
     doc_repo.update('git@github.com:fmtlib/fmtlib.github.io')
 
-    for version in ['1.0.0', '1.1.0', '2.0.0', '3.0.0']:
+    for version in env.versions:
         clean_checkout(env.fmt_repo, version)
         target_doc_dir = os.path.join(env.fmt_repo.dir, 'doc')
         # Remove the old theme.
@@ -140,6 +141,7 @@
                 b.data = re.sub(pattern, r'doxygenfunction:: \1(int)', b.data)
                 b.data = b.data.replace('std::FILE*', 'std::FILE *')
                 b.data = b.data.replace('unsigned int', 'unsigned')
+                b.data = b.data.replace('operator""_', 'operator"" _')
         # Fix a broken link in index.rst.
         index = os.path.join(target_doc_dir, 'index.rst')
         with rewrite(index) as b:
@@ -165,7 +167,11 @@
                 os.symlink(target, link)
         # Copy docs to the website.
         version_doc_dir = os.path.join(doc_repo.dir, version)
-        shutil.rmtree(version_doc_dir)
+        try:
+            shutil.rmtree(version_doc_dir)
+        except OSError as e:
+            if e.errno != errno.ENOENT:
+                raise
         shutil.move(html_dir, version_doc_dir)
 
 
@@ -204,27 +210,45 @@
             line = '-' * title_len + '\n'
             title_len = 0
         sys.stdout.write(line)
-    # TODO: add new version to manage.py
+
+    # Add the version to the build script.
+    script = os.path.join('doc', 'build.py')
+    script_path = os.path.join(fmt_repo.dir, script)
+    for line in fileinput.input(script_path, inplace=True):
+      m = re.match(r'( *versions = )\[(.+)\]', line)
+      if m:
+        line = '{}[{}, \'{}\']\n'.format(m.group(1), m.group(2), version)
+      sys.stdout.write(line)
+
     fmt_repo.checkout('-B', 'release')
-    fmt_repo.add(changelog, cmakelists)
+    fmt_repo.add(changelog, cmakelists, script)
     fmt_repo.commit('-m', 'Update version')
 
     # Build the docs and package.
     run = Runner(fmt_repo.dir)
     run('cmake', '.')
     run('make', 'doc', 'package_source')
-
     update_site(env)
 
     # Create a release on GitHub.
     fmt_repo.push('origin', 'release')
+    params = {'access_token': os.getenv('FMT_TOKEN')}
     r = requests.post('https://api.github.com/repos/fmtlib/fmt/releases',
-                      params={'access_token': os.getenv('FMT_TOKEN')},
+                      params=params,
                       data=json.dumps({'tag_name': version,
                                        'target_commitish': 'release',
                                        'body': changes, 'draft': True}))
     if r.status_code != 201:
         raise Exception('Failed to create a release ' + str(r))
+    id = r.json()['id']
+    uploads_url = 'https://uploads.github.com/repos/fmtlib/fmt/releases'
+    package = 'fmt-{}.zip'.format(version)
+    with open('build/fmt/' + package, 'rb') as f:
+        r = requests.post(
+            '{}/{}/assets?name={}'.format(uploads_url, id, package),
+            params=params, files={package: f})
+        if r.status_code != 201:
+            raise Exception('Failed to upload an asset ' + str(r))
 
 
 if __name__ == '__main__':
diff --git a/support/travis-build.py b/support/travis-build.py
index 9101779..c4b8daf 100755
--- a/support/travis-build.py
+++ b/support/travis-build.py
@@ -30,7 +30,7 @@
                '| sudo tee /etc/apt/sources.list.d/nodesource.list', shell=True)
     check_call(['sudo', 'apt-get', 'update'])
     check_call(['sudo', 'apt-get', 'install', 'python-virtualenv', 'nodejs'])
-    check_call(['npm', 'install', '-g', 'less', 'less-plugin-clean-css'])
+    check_call(['sudo', 'npm', 'install', '-g', 'less@2.6.1', 'less-plugin-clean-css'])
     deb_file = 'doxygen_1.8.6-2_amd64.deb'
     urllib.urlretrieve('http://mirrors.kernel.org/ubuntu/pool/main/d/doxygen/' +
                        deb_file, deb_file)
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index b805955..1b25948 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -11,6 +11,12 @@
 target_compile_definitions(gmock PUBLIC GTEST_HAS_STD_WSTRING=1)
 target_include_directories(gmock PUBLIC .)
 
+# Workaround for Cygwin to make google-tests compile and run because the macro
+# _POSIX_C_SOURCE must be defined to allow fileno(), strdup(), fdopen() calls.
+if (CYGWIN)
+  target_compile_definitions(gmock PUBLIC _POSIX_C_SOURCE=200809)
+endif ()
+
 find_package(Threads)
 if (Threads_FOUND)
   target_link_libraries(gmock ${CMAKE_THREAD_LIBS_INIT})
@@ -80,6 +86,7 @@
 endfunction()
 
 add_fmt_test(assert-test)
+add_fmt_test(container-test)
 add_fmt_test(gtest-extra-test)
 add_fmt_test(format-test)
 add_fmt_test(format-impl-test)
@@ -139,7 +146,7 @@
     "${CMAKE_CURRENT_BINARY_DIR}/compile-test"
     --build-generator ${CMAKE_GENERATOR}
     --build-makeprogram ${CMAKE_MAKE_PROGRAM}
-    --build-options 
+    --build-options
     "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}"
     "-DCPP11_FLAG=${CPP11_FLAG}"
     "-DSUPPORTS_USER_DEFINED_LITERALS=${SUPPORTS_USER_DEFINED_LITERALS}")
diff --git a/test/add-subdirectory-test/CMakeLists.txt b/test/add-subdirectory-test/CMakeLists.txt
index 5460363..d1edd8a 100644
--- a/test/add-subdirectory-test/CMakeLists.txt
+++ b/test/add-subdirectory-test/CMakeLists.txt
@@ -5,9 +5,9 @@
 add_subdirectory(../.. fmt)
 
 add_executable(library-test "main.cc")
-target_link_libraries(library-test fmt)
+target_link_libraries(library-test fmt::fmt)
 
-if (TARGET fmt-header-only)
+if (TARGET fmt::fmt-header-only)
   add_executable(header-only-test "main.cc")
-  target_link_libraries(header-only-test fmt-header-only)
+  target_link_libraries(header-only-test fmt::fmt-header-only)
 endif ()
diff --git a/test/container-test.cc b/test/container-test.cc
new file mode 100644
index 0000000..8cafb3d
--- /dev/null
+++ b/test/container-test.cc
@@ -0,0 +1,94 @@
+/*
+ Tests of container utilities
+
+ Copyright (c) 2012 - 2016, Victor Zverovich
+ All rights reserved.
+
+ For the license information refer to format.h.
+ */
+
+#include "fmt/container.h"
+#include "gtest/gtest.h"
+
+using fmt::internal::ContainerBuffer;
+
+TEST(ContainerBufferTest, Empty) {
+  std::string data;
+  ContainerBuffer<std::string> buffer(data);
+  EXPECT_EQ(0u, buffer.size());
+  EXPECT_EQ(0u, buffer.capacity());
+}
+
+TEST(ContainerBufferTest, Reserve) {
+  std::string data;
+  ContainerBuffer<std::string> buffer(data);
+  std::size_t capacity = std::string().capacity() + 10;
+  buffer.reserve(capacity);
+  EXPECT_EQ(0u, buffer.size());
+  EXPECT_EQ(capacity, buffer.capacity());
+}
+
+TEST(ContainerBufferTest, Resize) {
+  std::string data;
+  ContainerBuffer<std::string> buffer(data);
+  std::size_t size = std::string().capacity() + 10;
+  buffer.resize(size);
+  EXPECT_EQ(size, buffer.size());
+  EXPECT_EQ(size, buffer.capacity());
+}
+
+TEST(ContainerBufferTest, Append) {
+  std::string data("Why so");
+  const std::string serious(" serious");
+  ContainerBuffer<std::string> buffer(data);
+  buffer.append(serious.c_str(), serious.c_str() + serious.length());
+  EXPECT_EQ("Why so serious", data);
+  EXPECT_EQ(data.length(), buffer.size());
+}
+
+TEST(BasicContainerWriterTest, String) {
+  std::string data;
+  fmt::BasicContainerWriter<std::string> out(data);
+  out << "The answer is " << 42 << "\n";
+  EXPECT_EQ("The answer is 42\n", data);
+  EXPECT_EQ(17u, out.size());
+}
+
+TEST(BasicContainerWriterTest, WString) {
+  std::wstring data;
+  fmt::BasicContainerWriter<std::wstring> out(data);
+  out << "The answer is " << 42 << "\n";
+  EXPECT_EQ(L"The answer is 42\n", data);
+  EXPECT_EQ(17u, out.size());
+}
+
+TEST(BasicContainerWriterTest, Vector) {
+  std::vector<char> data;
+  fmt::BasicContainerWriter<std::vector<char> > out(data);
+  out << "The answer is " << 42 << "\n";
+  EXPECT_EQ(17u, data.size());
+  EXPECT_EQ(out.size(), data.size());
+}
+
+TEST(BasicContainerWriterTest, StringAppend) {
+  std::string data("The");
+  fmt::BasicContainerWriter<std::string> out(data);
+  EXPECT_EQ(3u, data.size());
+  EXPECT_EQ(3u, out.size());
+  out << " answer is " << 42 << "\n";
+  EXPECT_EQ("The answer is 42\n", data);
+  EXPECT_EQ(17u, out.size());
+}
+
+TEST(BasicContainerWriterTest, VectorAppend) {
+  std::vector<char> data;
+  data.push_back('T');
+  data.push_back('h');
+  data.push_back('e');
+  fmt::BasicContainerWriter<std::vector<char> > out(data);
+  EXPECT_EQ(3u, data.size());
+  EXPECT_EQ(3u, out.size());
+  out << " answer is " << 42 << "\n";
+  EXPECT_EQ(17u, data.size());
+  EXPECT_EQ(17u, out.size());
+}
diff --git a/test/find-package-test/CMakeLists.txt b/test/find-package-test/CMakeLists.txt
index 1f28c30..40c0756 100644
--- a/test/find-package-test/CMakeLists.txt
+++ b/test/find-package-test/CMakeLists.txt
@@ -5,9 +5,9 @@
 find_package(FMT REQUIRED)
 
 add_executable(library-test main.cc)
-target_link_libraries(library-test fmt)
+target_link_libraries(library-test fmt::fmt)
 
-if (TARGET fmt-header-only)
+if (TARGET fmt::fmt-header-only)
   add_executable(header-only-test main.cc)
-  target_link_libraries(header-only-test fmt-header-only)
+  target_link_libraries(header-only-test fmt::fmt-header-only)
 endif ()
diff --git a/test/format-impl-test.cc b/test/format-impl-test.cc
index 9fe2a7e..1eb5e91 100644
--- a/test/format-impl-test.cc
+++ b/test/format-impl-test.cc
@@ -26,6 +26,7 @@
  */
 
 #define FMT_NOEXCEPT
+#undef FMT_SHARED
 #include "test-assert.h"
 
 // Include *.cc instead of *.h to test implementation-specific stuff.
diff --git a/test/format-test.cc b/test/format-test.cc
index c812b06..ec232e8 100644
--- a/test/format-test.cc
+++ b/test/format-test.cc
@@ -151,16 +151,46 @@
 
   EXPECT_STREQ("defg", StringRef(std::string("defg")).data());
   EXPECT_EQ(4u, StringRef(std::string("defg")).size());
+
+#if FMT_HAS_STRING_VIEW
+  EXPECT_STREQ("hijk", StringRef(std::string_view("hijk")).data());
+  EXPECT_EQ(4u, StringRef(std::string_view("hijk")).size());
+#endif
+
+#if FMT_HAS_EXPERIMENTAL_STRING_VIEW
+  EXPECT_STREQ("hijk", StringRef(std::experimental::string_view("hijk")).data());
+  EXPECT_EQ(4u, StringRef(std::experimental::string_view("hijk")).size());
+#endif
 }
 
 TEST(StringRefTest, ConvertToString) {
   std::string s = StringRef("abc").to_string();
   EXPECT_EQ("abc", s);
+
+#if FMT_HAS_STRING_VIEW
+  StringRef str_ref("defg");
+  std::string_view sv = static_cast<std::string_view>(str_ref);
+  EXPECT_EQ("defg", sv);
+#endif
+
+#if FMT_HAS_EXPERIMENTAL_STRING_VIEW
+  StringRef str_ref("defg");
+  std::experimental::string_view sv = static_cast<std::experimental::string_view>(str_ref);
+  EXPECT_EQ("defg", sv);
+#endif
 }
 
 TEST(CStringRefTest, Ctor) {
   EXPECT_STREQ("abc", CStringRef("abc").c_str());
   EXPECT_STREQ("defg", CStringRef(std::string("defg")).c_str());
+
+#if FMT_HAS_STRING_VIEW
+  EXPECT_STREQ("hijk", CStringRef(std::string_view("hijk")).c_str());
+#endif
+
+#if FMT_HAS_EXPERIMENTAL_STRING_VIEW
+  EXPECT_STREQ("hijk", CStringRef(std::experimental::string_view("hijk")).c_str());
+#endif
 }
 
 #if FMT_USE_TYPE_TRAITS
@@ -1234,6 +1264,16 @@
   EXPECT_EQ("1--234--567", format("{:n}", 1234567));
 }
 
+struct ConvertibleToLongLong {
+  operator fmt::LongLong() const {
+    return fmt::LongLong(1) << 32;
+  }
+};
+
+TEST(FormatterTest, FormatConvertibleToLongLong) {
+  EXPECT_EQ("100000000", format("{:x}", ConvertibleToLongLong()));
+}
+
 TEST(FormatterTest, FormatFloat) {
   EXPECT_EQ("392.500000", format("{0:f}", 392.5f));
 }
@@ -1368,6 +1408,18 @@
   EXPECT_EQ("test", format("{0}", CStringRef("test")));
 }
 
+#if FMT_HAS_STRING_VIEW
+TEST(FormatterTest, FormatStringView) {
+  EXPECT_EQ("test", format("{0}", std::string_view("test")));
+}
+#endif
+
+#if FMT_HAS_EXPERIMENTAL_STRING_VIEW
+TEST(FormatterTest, FormatExperimentalStringView) {
+	EXPECT_EQ("test", format("{0}", std::experimental::string_view("test")));
+}
+#endif
+
 void format_arg(fmt::BasicFormatter<char> &f, const char *, const Date &d) {
   f.writer() << d.year() << '-' << d.month() << '-' << d.day();
 }
@@ -1552,6 +1604,29 @@
   EXPECT_EQ(L"abc1", format(L"{}c{}", L"ab", 1));
 }
 
+TEST(FormatTest, JoinArg) {
+  using fmt::join;
+  int v1[3] = { 1, 2, 3 };
+  std::vector<float> v2;
+  v2.push_back(1.2f);
+  v2.push_back(3.4f);
+
+  EXPECT_EQ("(1, 2, 3)", format("({})", join(v1, v1 + 3, ", ")));
+  EXPECT_EQ("(1)", format("({})", join(v1, v1 + 1, ", ")));
+  EXPECT_EQ("()", format("({})", join(v1, v1, ", ")));
+  EXPECT_EQ("(001, 002, 003)", format("({:03})", join(v1, v1 + 3, ", ")));
+  EXPECT_EQ("(+01.20, +03.40)",
+            format("({:+06.2f})", join(v2.begin(), v2.end(), ", ")));
+
+  EXPECT_EQ(L"(1, 2, 3)", format(L"({})", join(v1, v1 + 3, L", ")));
+  EXPECT_EQ("1, 2, 3", format("{0:{1}}", join(v1, v1 + 3, ", "), 1)); 
+
+#if FMT_HAS_GXX_CXX11
+  EXPECT_EQ("(1, 2, 3)", format("({})", join(v1, ", ")));
+  EXPECT_EQ("(+01.20, +03.40)", format("({:+06.2f})", join(v2, ", ")));
+#endif
+}
+
 template <typename T>
 std::string str(const T &value) {
   return fmt::format("{}", value);
@@ -1578,6 +1653,24 @@
       format_message(42, "{} happened", "something"));
 }
 
+class test_class
+{
+public:
+  std::string format_message(int id, const char *format,const fmt::ArgList &args) const {
+    MemoryWriter w;
+    w.write("[{}] ", id);
+    w.write(format, args);
+    return w.str();
+  }
+  FMT_VARIADIC_CONST(std::string, format_message, int, const char *)
+};
+
+TEST(FormatTest, ConstFormatMessage) {
+  test_class c;
+  EXPECT_EQ("[42] something happened",
+    c.format_message(42, "{} happened", "something"));
+}
+
 #if FMT_USE_VARIADIC_TEMPLATES
 template<typename... Args>
 void print_error(const char *file, int line, const char *format,
@@ -1629,6 +1722,14 @@
   EXPECT_EQ("0", fmt::format("{}", A));
 }
 
+#if __cplusplus >= 201103L
+enum TestFixedEnum : short { B };
+
+TEST(FormatTest, FixedEnum) {
+  EXPECT_EQ("0", fmt::format("{}", B));
+}
+#endif
+
 class MockArgFormatter :
     public fmt::internal::ArgFormatterBase<MockArgFormatter, char> {
  public:
@@ -1661,3 +1762,6 @@
   fmt::format("{}", 42);
 }
 
+TEST(FormatTest, Regression) {
+  fmt::format("...........{:<77777.7p}", "foo");
+}
diff --git a/test/gtest/gtest.h b/test/gtest/gtest.h
index 4f3804f..52d2ed6 100644
--- a/test/gtest/gtest.h
+++ b/test/gtest/gtest.h
@@ -2823,7 +2823,11 @@
 inline int IsATTY(int fd) { return _isatty(fd); }
 #  endif  // GTEST_OS_WINDOWS_MOBILE
 inline int StrCaseCmp(const char* s1, const char* s2) {
-  return _stricmp(s1, s2);
+#  if _EMULATE_GLIBC
+    return strcasecmp(s1, s2);
+#  else
+    return _stricmp(s1, s2);
+#  endif
 }
 inline char* StrDup(const char* src) { return _strdup(src); }
 # endif  // __BORLANDC__
diff --git a/test/mock-allocator.h b/test/mock-allocator.h
index 34b9c11..5f0f0bc 100644
--- a/test/mock-allocator.h
+++ b/test/mock-allocator.h
@@ -36,7 +36,7 @@
   MockAllocator() {}
   MockAllocator(const MockAllocator &) {}
   typedef T value_type;
-  MOCK_METHOD2_T(allocate, T *(std::size_t n, const T *h));
+  MOCK_METHOD2_T(allocate, T *(std::size_t n, const void *h));
   MOCK_METHOD2_T(deallocate, void (T *p, std::size_t n));
 };
 
@@ -78,8 +78,12 @@
 
   Allocator *get() const { return alloc_; }
 
-  value_type *allocate(std::size_t n,  const value_type *h) {
+  value_type *allocate(std::size_t n,  const void *h) {
+#if FMT_USE_ALLOCATOR_TRAITS
+    return std::allocator_traits<Allocator>::allocate(*alloc_, n, h);
+#else
     return alloc_->allocate(n, h);
+#endif
   }
   void deallocate(value_type *p, std::size_t n) { alloc_->deallocate(p, n); }
 };
diff --git a/test/ostream-test.cc b/test/ostream-test.cc
index 4081b43..486981b 100644
--- a/test/ostream-test.cc
+++ b/test/ostream-test.cc
@@ -172,3 +172,18 @@
   } while (size != 0);
   fmt::internal::write(os, w);
 }
+
+struct ConvertibleToInt {
+  template <typename ValueType>
+  operator ValueType() const {
+    return 0;
+  }
+
+  friend std::ostream &operator<<(std::ostream &o, ConvertibleToInt) {
+    return o << "foo";
+  }
+};
+
+TEST(FormatTest, FormatConvertibleToInt) {
+  EXPECT_EQ("foo", fmt::format("{}", ConvertibleToInt()));
+}
diff --git a/test/printf-test.cc b/test/printf-test.cc
index 6bba02e..81a041d 100644
--- a/test/printf-test.cc
+++ b/test/printf-test.cc
@@ -202,6 +202,8 @@
 
 TEST(PrintfTest, Width) {
   EXPECT_PRINTF("  abc", "%5s", "abc");
+  EXPECT_PRINTF("  -42", "%5s", "-42");
+  EXPECT_PRINTF("  0.123456", "%10s", 0.123456);
 
   // Width cannot be specified twice.
   EXPECT_THROW_MSG(fmt::sprintf("%5-5d", 42), FormatError,
@@ -381,11 +383,13 @@
 TEST(PrintfTest, Int) {
   EXPECT_PRINTF("-42", "%d", -42);
   EXPECT_PRINTF("-42", "%i", -42);
+  EXPECT_PRINTF("-42", "%s", -42);
   unsigned u = 0 - 42u;
   EXPECT_PRINTF(fmt::format("{}", u), "%u", -42);
   EXPECT_PRINTF(fmt::format("{:o}", u), "%o", -42);
   EXPECT_PRINTF(fmt::format("{:x}", u), "%x", -42);
   EXPECT_PRINTF(fmt::format("{:X}", u), "%X", -42);
+  EXPECT_PRINTF(fmt::format("{}", u), "%s", u);
 }
 
 TEST(PrintfTest, LongLong) {
@@ -397,7 +401,11 @@
 
 TEST(PrintfTest, Float) {
   EXPECT_PRINTF("392.650000", "%f", 392.65);
+  EXPECT_PRINTF("392.65", "%.2f", 392.65);
+  EXPECT_PRINTF("392.6", "%.1f", 392.65);
+  EXPECT_PRINTF("393", "%.f", 392.65);
   EXPECT_PRINTF("392.650000", "%F", 392.65);
+  EXPECT_PRINTF("392.65", "%s", 392.65);
   char buffer[BUFFER_SIZE];
   safe_sprintf(buffer, "%e", 392.65);
   EXPECT_PRINTF(buffer, "%e", 392.65);
@@ -422,6 +430,7 @@
 
 TEST(PrintfTest, Char) {
   EXPECT_PRINTF("x", "%c", 'x');
+  EXPECT_PRINTF("x", "%s", 'x');
   int max = std::numeric_limits<int>::max();
   EXPECT_PRINTF(fmt::format("{}", static_cast<char>(max)), "%c", max);
   //EXPECT_PRINTF("x", "%lc", L'x');
@@ -440,13 +449,17 @@
   int n;
   void *p = &n;
   EXPECT_PRINTF(fmt::format("{}", p), "%p", p);
+  EXPECT_PRINTF(fmt::format("{}", p), "%s", p);
   p = 0;
   EXPECT_PRINTF("(nil)", "%p", p);
   EXPECT_PRINTF("     (nil)", "%10p", p);
+  EXPECT_PRINTF("(nil)", "%s", p);
+  EXPECT_PRINTF("     (nil)", "%10s", p);
   const char *s = "test";
   EXPECT_PRINTF(fmt::format("{:p}", s), "%p", s);
   const char *null_str = 0;
   EXPECT_PRINTF("(nil)", "%p", null_str);
+  EXPECT_PRINTF("(null)", "%s", null_str);
 }
 
 TEST(PrintfTest, Location) {
@@ -490,3 +503,9 @@
   EXPECT_EQ("Don't panic!", os.str());
   EXPECT_EQ(12, ret);
 }
+
+TEST(PrintfTest, Writer) {
+  fmt::MemoryWriter writer;
+  printf(writer, "%d", 42);
+  EXPECT_EQ("42", writer.str());
+}
diff --git a/test/string-test.cc b/test/string-test.cc
index 10e537b..06f55f6 100644
--- a/test/string-test.cc
+++ b/test/string-test.cc
@@ -78,3 +78,7 @@
 TEST(StringTest, ToString) {
   EXPECT_EQ("42", fmt::to_string(42));
 }
+
+TEST(StringTest, ToWString) {
+  EXPECT_EQ(L"42", fmt::to_wstring(42));
+}
diff --git a/test/time-test.cc b/test/time-test.cc
index d66f0cb..8b6c361 100644
--- a/test/time-test.cc
+++ b/test/time-test.cc
@@ -6,6 +6,9 @@
 
  For the license information refer to format.h.
  */
+#ifdef WIN32
+#define _CRT_SECURE_NO_WARNINGS
+#endif
 
 #include "gmock/gmock.h"
 #include "fmt/time.h"
diff --git a/test/util-test.cc b/test/util-test.cc
index a388255..6617b85 100644
--- a/test/util-test.cc
+++ b/test/util-test.cc
@@ -837,8 +837,21 @@
   fmt::format_system_error(message, EDOM, "test");
   EXPECT_EQ(fmt::format("test: {}", get_system_error(EDOM)), message.str());
   message.clear();
-  fmt::format_system_error(
-        message, EDOM, fmt::StringRef(0, std::numeric_limits<size_t>::max()));
+
+  // Check if std::allocator throws on allocating max size_t / 2 chars.
+  size_t max_size = std::numeric_limits<size_t>::max() / 2;
+  bool throws_on_alloc = false;
+  try {
+    std::allocator<char> alloc;
+    alloc.deallocate(alloc.allocate(max_size), max_size);
+  } catch (std::bad_alloc) {
+    throws_on_alloc = true;
+  }
+  if (!throws_on_alloc) {
+    fmt::print("warning: std::allocator allocates {} chars", max_size);
+    return;
+  }
+  fmt::format_system_error(message, EDOM, fmt::StringRef(0, max_size));
   EXPECT_EQ(fmt::format("error {}", EDOM), message.str());
 }