externals: Update fmt subtree to 4.10
Merge commit '097203968f0a9b17628062f4adca63ea5cb97aa2' into HEAD
This commit is contained in:
commit
7639f6ebdc
21 changed files with 481 additions and 141 deletions
8
externals/fmt/CMakeLists.txt
vendored
8
externals/fmt/CMakeLists.txt
vendored
|
@ -2,6 +2,14 @@ message(STATUS "CMake version: ${CMAKE_VERSION}")
|
|||
|
||||
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)
|
||||
|
|
27
externals/fmt/ChangeLog.rst
vendored
27
externals/fmt/ChangeLog.rst
vendored
|
@ -1,7 +1,32 @@
|
|||
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/pull/527>`_). Thanks `@maddinat0r (Alex Martin) <https://github.com/maddinat0r>`_.
|
||||
* 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>`_):
|
||||
|
||||
|
|
4
externals/fmt/README.rst
vendored
4
externals/fmt/README.rst
vendored
|
@ -142,6 +142,8 @@ Projects using this library
|
|||
|
||||
* `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
|
||||
|
||||
|
@ -155,6 +157,8 @@ Projects using this library
|
|||
|
||||
* `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
|
||||
|
||||
|
|
32
externals/fmt/doc/api.rst
vendored
32
externals/fmt/doc/api.rst
vendored
|
@ -84,6 +84,36 @@ Note in the example above the ``format_arg`` function ignores the contents of
|
|||
``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.
|
||||
|
@ -232,6 +262,8 @@ Utilities
|
|||
|
||||
.. doxygenfunction:: fmt::to_string(const T&)
|
||||
|
||||
.. doxygenfunction:: fmt::to_wstring(const T&)
|
||||
|
||||
.. doxygenclass:: fmt::BasicStringRef
|
||||
:members:
|
||||
|
||||
|
|
6
externals/fmt/doc/build.py
vendored
6
externals/fmt/doc/build.py
vendored
|
@ -6,6 +6,8 @@ import errno, os, shutil, sys, tempfile
|
|||
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')
|
||||
|
@ -93,11 +95,11 @@ def build_docs(version='dev', **kwargs):
|
|||
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',
|
||||
|
|
6
externals/fmt/doc/index.rst
vendored
6
externals/fmt/doc/index.rst
vendored
|
@ -143,6 +143,12 @@ its numeric value being written to the stream (i.e. 1070 instead of letter 'ю'
|
|||
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
|
||||
|
|
17
externals/fmt/doc/syntax.rst
vendored
17
externals/fmt/doc/syntax.rst
vendored
|
@ -335,6 +335,16 @@ Aligning the text and specifying a width::
|
|||
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
|
||||
|
@ -359,13 +369,6 @@ Replacing ``%x`` and ``%o`` and converting the value to different bases::
|
|||
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
|
||||
|
|
4
externals/fmt/doc/usage.rst
vendored
4
externals/fmt/doc/usage.rst
vendored
|
@ -41,6 +41,10 @@ current directory. Now you can build the library by running :command:`make`.
|
|||
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.
|
||||
|
|
10
externals/fmt/fmt/CMakeLists.txt
vendored
10
externals/fmt/fmt/CMakeLists.txt
vendored
|
@ -49,8 +49,9 @@ endif ()
|
|||
|
||||
# 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)
|
||||
|
@ -61,9 +62,12 @@ if (FMT_INSTALL)
|
|||
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}
|
||||
|
@ -86,5 +90,5 @@ if (FMT_INSTALL)
|
|||
# Install the library and headers.
|
||||
install(TARGETS ${INSTALL_TARGETS} EXPORT ${targets_export_name}
|
||||
DESTINATION ${FMT_LIB_DIR})
|
||||
install(FILES ${FMT_HEADERS} DESTINATION include/fmt)
|
||||
install(FILES ${FMT_HEADERS} DESTINATION ${FMT_INC_DIR})
|
||||
endif ()
|
||||
|
|
64
externals/fmt/fmt/format.cc
vendored
64
externals/fmt/fmt/format.cc
vendored
|
@ -72,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<>();
|
||||
}
|
||||
|
@ -121,7 +123,7 @@ typedef void (*FormatFunc)(Writer &, int, StringRef);
|
|||
// 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:
|
||||
|
@ -159,6 +161,11 @@ int safe_strerror(
|
|||
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;
|
||||
|
@ -166,13 +173,15 @@ int safe_strerror(
|
|||
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_));
|
||||
}
|
||||
};
|
||||
|
@ -396,51 +405,6 @@ FMT_FUNC void format_system_error(
|
|||
fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32.
|
||||
}
|
||||
|
||||
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"));
|
||||
|
@ -502,8 +466,6 @@ template struct internal::BasicData<void>;
|
|||
|
||||
template void internal::FixedBuffer<char>::grow(std::size_t);
|
||||
|
||||
template void internal::ArgMap<char>::init(const ArgList &args);
|
||||
|
||||
template FMT_API int internal::CharTraits<char>::format_float(
|
||||
char *buffer, std::size_t size, const char *format,
|
||||
unsigned width, int precision, double value);
|
||||
|
@ -516,8 +478,6 @@ template FMT_API int internal::CharTraits<char>::format_float(
|
|||
|
||||
template void internal::FixedBuffer<wchar_t>::grow(std::size_t);
|
||||
|
||||
template void internal::ArgMap<wchar_t>::init(const ArgList &args);
|
||||
|
||||
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);
|
||||
|
|
277
externals/fmt/fmt/format.h
vendored
277
externals/fmt/fmt/format.h
vendored
|
@ -28,6 +28,7 @@
|
|||
#ifndef FMT_FORMAT_H_
|
||||
#define FMT_FORMAT_H_
|
||||
|
||||
#define FMT_INCLUDE
|
||||
#include <cassert>
|
||||
#include <clocale>
|
||||
#include <cmath>
|
||||
|
@ -39,11 +40,26 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
#include <utility> // for std::pair
|
||||
#undef FMT_INCLUDE
|
||||
|
||||
// The fmt library version in the form major * 10000 + minor * 100 + patch.
|
||||
#define FMT_VERSION 40000
|
||||
#define FMT_VERSION 40100
|
||||
|
||||
#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
|
||||
#else
|
||||
# define FMT_HAS_STRING_VIEW 0
|
||||
#endif
|
||||
|
||||
#if defined _SECURE_SCL && _SECURE_SCL
|
||||
# define FMT_SECURE_SCL _SECURE_SCL
|
||||
#else
|
||||
# define FMT_SECURE_SCL 0
|
||||
|
@ -97,7 +113,9 @@ typedef __int64 intmax_t;
|
|||
# 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)
|
||||
|
@ -135,6 +153,32 @@ typedef __int64 intmax_t;
|
|||
# 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++
|
||||
|
@ -156,6 +200,12 @@ typedef __int64 intmax_t;
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#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.
|
||||
#if defined(__GNUC__) && !defined(__EXCEPTIONS)
|
||||
# define FMT_EXCEPTIONS 0
|
||||
|
@ -262,11 +312,14 @@ typedef __int64 intmax_t;
|
|||
// 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
|
||||
|
@ -305,7 +358,10 @@ typedef __int64 intmax_t;
|
|||
|
||||
namespace fmt {
|
||||
namespace internal {
|
||||
// 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);
|
||||
|
@ -319,7 +375,8 @@ inline uint32_t clz(uint32_t x) {
|
|||
}
|
||||
# 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
|
||||
|
||||
|
@ -505,6 +562,26 @@ class BasicStringRef {
|
|||
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
|
||||
|
||||
/**
|
||||
\rst
|
||||
Converts a string reference to an ``std::string`` object.
|
||||
|
@ -609,7 +686,7 @@ class FormatError : public std::runtime_error {
|
|||
explicit FormatError(CStringRef message)
|
||||
: std::runtime_error(message.c_str()) {}
|
||||
FormatError(const FormatError &ferr) : std::runtime_error(ferr) {}
|
||||
FMT_API ~FormatError() FMT_DTOR_NOEXCEPT;
|
||||
FMT_API ~FormatError() FMT_DTOR_NOEXCEPT FMT_OVERRIDE;
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
|
@ -726,7 +803,7 @@ template <typename T>
|
|||
template <typename U>
|
||||
void Buffer<T>::append(const U *begin, const U *end) {
|
||||
FMT_ASSERT(end >= begin, "negative value");
|
||||
std::size_t new_size = size_ + (end - begin);
|
||||
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,
|
||||
|
@ -754,7 +831,7 @@ class MemoryBuffer : private Allocator, public Buffer<T> {
|
|||
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:
|
||||
|
@ -798,7 +875,12 @@ void MemoryBuffer<T, SIZE, Allocator>::grow(std::size_t size) {
|
|||
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));
|
||||
|
@ -916,7 +998,7 @@ struct IntTraits {
|
|||
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.
|
||||
|
@ -1155,17 +1237,17 @@ T &get();
|
|||
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.
|
||||
|
@ -1173,7 +1255,7 @@ struct ConvertToIntImpl2<T, true> {
|
|||
};
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
struct ConvertToInt {
|
||||
enum {
|
||||
enable_conversion = sizeof(fmt::internal::convert(get<T>())) == sizeof(Yes)
|
||||
|
@ -1190,16 +1272,16 @@ FMT_DISABLE_CONVERSION_TO_INT(float);
|
|||
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.
|
||||
|
@ -1248,9 +1330,9 @@ inline fmt::StringRef thousands_sep(...) { return ""; }
|
|||
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(FalseType<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.");
|
||||
|
@ -1283,6 +1365,9 @@ class MakeValue : public Arg {
|
|||
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
|
||||
MakeValue(typename WCharHelper<WStringRef, Char>::Unsupported);
|
||||
|
||||
void set_string(StringRef str) {
|
||||
|
@ -1352,6 +1437,20 @@ class MakeValue : public Arg {
|
|||
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;
|
||||
|
@ -1370,6 +1469,9 @@ class MakeValue : public Arg {
|
|||
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
|
||||
FMT_MAKE_STR_VALUE(StringRef, STRING)
|
||||
FMT_MAKE_VALUE_(CStringRef, string.value, CSTRING, value.c_str())
|
||||
|
||||
|
@ -1382,6 +1484,9 @@ class MakeValue : public Arg {
|
|||
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
|
||||
FMT_MAKE_WSTR_VALUE(WStringRef, WSTRING)
|
||||
|
||||
FMT_MAKE_VALUE(void *, pointer, POINTER)
|
||||
|
@ -1447,7 +1552,7 @@ class RuntimeError : public std::runtime_error {
|
|||
protected:
|
||||
RuntimeError() : std::runtime_error("") {}
|
||||
RuntimeError(const RuntimeError &rerr) : std::runtime_error(rerr) {}
|
||||
FMT_API ~RuntimeError() FMT_DTOR_NOEXCEPT;
|
||||
FMT_API ~RuntimeError() FMT_DTOR_NOEXCEPT FMT_OVERRIDE;
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
|
@ -1921,7 +2026,7 @@ class ArgMap {
|
|||
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.
|
||||
|
@ -1934,6 +2039,51 @@ class ArgMap {
|
|||
}
|
||||
};
|
||||
|
||||
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:
|
||||
|
@ -2220,7 +2370,8 @@ struct ArgArray;
|
|||
|
||||
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) {
|
||||
|
@ -2410,7 +2561,7 @@ class SystemError : public internal::RuntimeError {
|
|||
FMT_DEFAULTED_COPY_CTOR(SystemError)
|
||||
FMT_VARIADIC_CTOR(SystemError, init, int, CStringRef)
|
||||
|
||||
FMT_API ~SystemError() FMT_DTOR_NOEXCEPT;
|
||||
FMT_API ~SystemError() FMT_DTOR_NOEXCEPT FMT_OVERRIDE;
|
||||
|
||||
int error_code() const { return error_code_; }
|
||||
};
|
||||
|
@ -3483,10 +3634,10 @@ void arg(WStringRef, const internal::NamedArg<Char>&) FMT_DELETED_OR_UNDEFINED;
|
|||
#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)...}; \
|
||||
|
@ -3496,35 +3647,35 @@ void arg(WStringRef, const internal::NamedArg<Char>&) FMT_DELETED_OR_UNDEFINED;
|
|||
#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
|
||||
|
||||
/**
|
||||
|
@ -3555,10 +3706,16 @@ void arg(WStringRef, const internal::NamedArg<Char>&) FMT_DELETED_OR_UNDEFINED;
|
|||
\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)
|
||||
|
||||
|
@ -3601,17 +3758,19 @@ template <typename Char>
|
|||
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;
|
||||
|
@ -3783,7 +3942,8 @@ const Char *BasicFormatter<Char, ArgFormatter>::format(
|
|||
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);
|
||||
}
|
||||
|
@ -3821,7 +3981,8 @@ const Char *BasicFormatter<Char, ArgFormatter>::format(
|
|||
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 {
|
||||
|
|
7
externals/fmt/fmt/ostream.h
vendored
7
externals/fmt/fmt/ostream.h
vendored
|
@ -52,13 +52,15 @@ Yes &convert(std::ostream &);
|
|||
|
||||
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 {
|
||||
|
@ -78,6 +80,7 @@ void format_arg(BasicFormatter<Char, ArgFormatter_> &f,
|
|||
|
||||
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], buffer.size());
|
||||
|
|
4
externals/fmt/fmt/printf.h
vendored
4
externals/fmt/fmt/printf.h
vendored
|
@ -110,7 +110,7 @@ class ArgConverter : public ArgVisitor<ArgConverter<T>, void> {
|
|||
visit_any_int(value);
|
||||
}
|
||||
|
||||
void visit_char(char value) {
|
||||
void visit_char(int value) {
|
||||
if (type_ != 's')
|
||||
visit_any_int(value);
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ class ArgConverter : public ArgVisitor<ArgConverter<T>, void> {
|
|||
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;
|
||||
|
|
22
externals/fmt/fmt/string.h
vendored
22
externals/fmt/fmt/string.h
vendored
|
@ -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 @@ std::string to_string(const T &value) {
|
|||
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_
|
||||
|
|
35
externals/fmt/support/manage.py
vendored
35
externals/fmt/support/manage.py
vendored
|
@ -8,7 +8,7 @@ Usage:
|
|||
"""
|
||||
|
||||
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 @@ def create_build_env():
|
|||
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 @@ def update_site(env):
|
|||
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.
|
||||
|
@ -165,7 +166,11 @@ def update_site(env):
|
|||
os.symlink(target, link)
|
||||
# Copy docs to the website.
|
||||
version_doc_dir = os.path.join(doc_repo.dir, version)
|
||||
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 +209,45 @@ def release(args):
|
|||
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__':
|
||||
|
|
2
externals/fmt/support/travis-build.py
vendored
2
externals/fmt/support/travis-build.py
vendored
|
@ -30,7 +30,7 @@ def install_dependencies():
|
|||
'| 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)
|
||||
|
|
47
externals/fmt/test/format-test.cc
vendored
47
externals/fmt/test/format-test.cc
vendored
|
@ -151,16 +151,31 @@ TEST(StringRefTest, Ctor) {
|
|||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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_USE_TYPE_TRAITS
|
||||
|
@ -1378,6 +1393,12 @@ TEST(FormatterTest, FormatCStringRef) {
|
|||
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
|
||||
|
||||
void format_arg(fmt::BasicFormatter<char> &f, const char *, const Date &d) {
|
||||
f.writer() << d.year() << '-' << d.month() << '-' << d.day();
|
||||
}
|
||||
|
@ -1609,6 +1630,24 @@ TEST(FormatTest, FormatMessageExample) {
|
|||
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,
|
||||
|
@ -1660,6 +1699,14 @@ TEST(FormatTest, Enum) {
|
|||
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:
|
||||
|
|
8
externals/fmt/test/mock-allocator.h
vendored
8
externals/fmt/test/mock-allocator.h
vendored
|
@ -36,7 +36,7 @@ class MockAllocator {
|
|||
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 @@ class AllocatorRef {
|
|||
|
||||
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); }
|
||||
};
|
||||
|
|
15
externals/fmt/test/ostream-test.cc
vendored
15
externals/fmt/test/ostream-test.cc
vendored
|
@ -172,3 +172,18 @@ TEST(OStreamTest, WriteToOStreamMaxSize) {
|
|||
} 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()));
|
||||
}
|
||||
|
|
4
externals/fmt/test/string-test.cc
vendored
4
externals/fmt/test/string-test.cc
vendored
|
@ -78,3 +78,7 @@ TEST(StringWriterTest, WString) {
|
|||
TEST(StringTest, ToString) {
|
||||
EXPECT_EQ("42", fmt::to_string(42));
|
||||
}
|
||||
|
||||
TEST(StringTest, ToWString) {
|
||||
EXPECT_EQ(L"42", fmt::to_wstring(42));
|
||||
}
|
||||
|
|
17
externals/fmt/test/util-test.cc
vendored
17
externals/fmt/test/util-test.cc
vendored
|
@ -837,8 +837,21 @@ TEST(UtilTest, FormatSystemError) {
|
|||
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());
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue