Merge branch 'master' of https://github.com/fmtlib/fmt
This commit is contained in:
commit
48415bc740
@ -95,8 +95,8 @@ function(add_headers VAR)
|
||||
endfunction()
|
||||
|
||||
# Define the fmt library, its includes and the needed defines.
|
||||
add_headers(FMT_HEADERS core.h format.h format-inl.h locale.h ostream.h printf.h
|
||||
time.h ranges.h)
|
||||
add_headers(FMT_HEADERS core.h format.h format-inl.h ostream.h printf.h time.h
|
||||
ranges.h)
|
||||
set(FMT_SOURCES src/format.cc)
|
||||
if (HAVE_OPEN)
|
||||
add_headers(FMT_HEADERS posix.h)
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
.. code:: c++
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
std::string s = format(fmt("{:d}"), "foo");
|
||||
|
||||
gives a compile-time error because ``d`` is an invalid specifier for strings
|
||||
@ -133,7 +134,9 @@
|
||||
vreport_error(format, fmt::make_format_args(args...));
|
||||
}
|
||||
|
||||
* Added the ``make_printf_args`` function for capturing ``printf`` arguments.
|
||||
* Added the ``make_printf_args`` function for capturing ``printf`` arguments (
|
||||
`#687 <https://github.com/fmtlib/fmt/issues/687>`_,
|
||||
`#694 <https://github.com/fmtlib/fmt/pull/694>`_).
|
||||
Thanks `@Kronuz (Germán Méndez Bravo) <https://github.com/Kronuz>`_.
|
||||
|
||||
* Added prefix ``v`` to non-variadic functions taking ``format_args`` to
|
||||
@ -146,6 +149,34 @@
|
||||
template <typename... Args>
|
||||
std::string format(string_view format_str, const Args & ... args);
|
||||
|
||||
* Added experimental support for formatting ranges, containers and tuple-like
|
||||
types in ``fmt/ranges.h`` (`#735 <https://github.com/fmtlib/fmt/pull/735>`_):
|
||||
|
||||
.. code:: c++
|
||||
|
||||
#include <fmt/ranges.h>
|
||||
|
||||
std::vector<int> v = {1, 2, 3};
|
||||
fmt::print("{}", v); // prints {1, 2, 3}
|
||||
|
||||
Thanks `@Remotion (Remo) <https://github.com/Remotion>`_.
|
||||
|
||||
* Implemented ``wchar_t`` date and time formatting
|
||||
(`#712 <https://github.com/fmtlib/fmt/pull/712>`_):
|
||||
|
||||
.. code:: c++
|
||||
|
||||
#include <fmt/time.h>
|
||||
|
||||
std::time_t t = std::time(nullptr);
|
||||
auto s = fmt::format(L"The date is {:%Y-%m-%d}.", *std::localtime(&t));
|
||||
|
||||
Thanks `@DanielaE (Daniela Engert) <https://github.com/DanielaE>`_.
|
||||
|
||||
* Provided more wide string overloads
|
||||
(`#724 <https://github.com/fmtlib/fmt/pull/724>`_).
|
||||
Thanks `@DanielaE (Daniela Engert) <https://github.com/DanielaE>`_.
|
||||
|
||||
* Switched from a custom null-terminated string view class to ``string_view``
|
||||
in the format API and provided ``fmt::string_view`` which implements a subset
|
||||
of ``std::string_view`` API for pre-C++17 systems.
|
||||
@ -188,6 +219,8 @@
|
||||
|
||||
* Implemented more efficient handling of large number of format arguments.
|
||||
|
||||
* Introduced an inline namespace for symbol versioning.
|
||||
|
||||
* Added debug postfix ``d`` to the `fmt`` library name
|
||||
(`#636 <https://github.com/fmtlib/fmt/issues/636>`_).
|
||||
|
||||
@ -229,12 +262,21 @@
|
||||
`#656 <https://github.com/fmtlib/fmt/pull/656>`_,
|
||||
`#679 <https://github.com/fmtlib/fmt/pull/679>`_,
|
||||
`#681 <https://github.com/fmtlib/fmt/pull/681>`_,
|
||||
`#705 <https://github.com/fmtlib/fmt/pull/705>`_).
|
||||
`#705 <https://github.com/fmtlib/fmt/pull/705>`_,
|
||||
`#715 <https://github.com/fmtlib/fmt/issues/715>`_,
|
||||
`#717 <https://github.com/fmtlib/fmt/pull/717>`_,
|
||||
`#720 <https://github.com/fmtlib/fmt/pull/720>`_,
|
||||
`#723 <https://github.com/fmtlib/fmt/pull/723>`_,
|
||||
`#726 <https://github.com/fmtlib/fmt/pull/726>`_,
|
||||
`#730 <https://github.com/fmtlib/fmt/pull/730>`_,
|
||||
`#739 <https://github.com/fmtlib/fmt/pull/739>`_).
|
||||
Thanks `@peterbell10 <https://github.com/peterbell10>`_,
|
||||
`@LarsGullik <https://github.com/LarsGullik>`_,
|
||||
`@foonathan (Jonathan Müller) <https://github.com/foonathan>`_,
|
||||
`@eliaskosunen (Elias Kosunen) <https://github.com/eliaskosunen>`_, and
|
||||
`@christianparpart (Christian Parpart) <https://github.com/christianparpart>`_.
|
||||
`@eliaskosunen (Elias Kosunen) <https://github.com/eliaskosunen>`_,
|
||||
`@christianparpart (Christian Parpart) <https://github.com/christianparpart>`_,
|
||||
`@DanielaE (Daniela Engert) <https://github.com/DanielaE>`_,
|
||||
and `@mwinterb <https://github.com/mwinterb>`_.
|
||||
|
||||
* Worked around an MSVC bug and fixed several warnings
|
||||
(`#653 <https://github.com/fmtlib/fmt/pull/653>`_).
|
||||
@ -260,10 +302,17 @@
|
||||
(`#660 <https://github.com/fmtlib/fmt/pull/660>`_).
|
||||
Thanks `@hubslave <https://github.com/hubslave>`_.
|
||||
|
||||
* Fixed compilation on FreeBSD 12
|
||||
(`#732 <https://github.com/fmtlib/fmt/pull/732>`_).
|
||||
Thanks `@dankm <https://github.com/dankm>`_.
|
||||
|
||||
* Fixed compilation when there is a mismatch between ``-std`` options between
|
||||
the library and user code
|
||||
(`#664 <https://github.com/fmtlib/fmt/issues/664>`_).
|
||||
|
||||
* Fixed compilation with GCC 7 and ``-std=c++11``
|
||||
(`#734 <https://github.com/fmtlib/fmt/issues/734>`_).
|
||||
|
||||
* Improved generated binary code on GCC 7 and older
|
||||
(`#668 <https://github.com/fmtlib/fmt/issues/668>`_).
|
||||
|
||||
@ -286,6 +335,17 @@
|
||||
* Fixed compile checks for mixing narrow and wide strings
|
||||
(`#690 <https://github.com/fmtlib/fmt/issues/690>`_).
|
||||
|
||||
* Disabled unsafe implicit conversion to ``std::string``
|
||||
(`#729 <https://github.com/fmtlib/fmt/issues/729>`_).
|
||||
|
||||
* Fixed handling of reused format specs (as in ``fmt::join``) for pointers
|
||||
(`#725 <https://github.com/fmtlib/fmt/pull/725>`_).
|
||||
Thanks `@mwinterb <https://github.com/mwinterb>`_.
|
||||
|
||||
* Fixed installation of ``fmt/ranges.h``
|
||||
(`#738 <https://github.com/fmtlib/fmt/pull/738>`_).
|
||||
Thanks `@sv1990 <https://github.com/sv1990>`_.
|
||||
|
||||
4.1.0 - 2017-12-20
|
||||
------------------
|
||||
|
||||
|
||||
@ -164,6 +164,10 @@ Utilities
|
||||
System errors
|
||||
-------------
|
||||
|
||||
fmt does not use ``errno`` to communicate errors to the user, but it may call
|
||||
system functions which set ``errno``. Users should not make any assumptions about
|
||||
the value of ``errno`` being preserved by library functions.
|
||||
|
||||
.. doxygenclass:: fmt::system_error
|
||||
:members:
|
||||
|
||||
|
||||
@ -2,8 +2,7 @@ Overview
|
||||
========
|
||||
|
||||
**fmt** (formerly cppformat) is an open-source formatting library.
|
||||
It can be used as a safe alternative to printf or as a fast
|
||||
alternative to C++ IOStreams.
|
||||
It can be used as a fast and safe alternative to printf and IOStreams.
|
||||
|
||||
.. raw:: html
|
||||
|
||||
@ -30,9 +29,9 @@ in Python:
|
||||
|
||||
.. code:: c++
|
||||
|
||||
fmt::format("The answer is {}", 42);
|
||||
fmt::format("The answer is {}.", 42);
|
||||
|
||||
The ``fmt::format`` function returns a string "The answer is 42". You can use
|
||||
The ``fmt::format`` function returns a string "The answer is 42.". You can use
|
||||
``fmt::memory_buffer`` to avoid constructing ``std::string``:
|
||||
|
||||
.. code:: c++
|
||||
@ -94,19 +93,25 @@ Safety
|
||||
------
|
||||
|
||||
The library is fully type safe, automatic memory management prevents buffer
|
||||
overflow, errors in format strings are reported using exceptions. For example,
|
||||
the code
|
||||
overflow, errors in format strings are reported using exceptions or at compile
|
||||
tim. For example, the code
|
||||
|
||||
.. code:: c++
|
||||
|
||||
fmt::format("The answer is {:d}", "forty-two");
|
||||
|
||||
throws a ``format_error`` exception with description
|
||||
"unknown format code 'd' for string", because the argument
|
||||
``"forty-two"`` is a string while the format code ``d``
|
||||
only applies to integers.
|
||||
throws a ``format_error`` exception with description "unknown format code 'd' for
|
||||
string", because the argument ``"forty-two"`` is a string while the format code
|
||||
``d`` only applies to integers, while
|
||||
|
||||
Where possible, errors are caught at compile time. For example, the code
|
||||
.. code:: c++
|
||||
|
||||
format(fmt("The answer is {:d}"), "forty-two");
|
||||
|
||||
reports a compile-time error for the same reason on compilers that support
|
||||
relaxed ``constexpr``.
|
||||
|
||||
The following code
|
||||
|
||||
.. code:: c++
|
||||
|
||||
@ -124,16 +129,10 @@ 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``.
|
||||
|
||||
Compact binary code
|
||||
-------------------
|
||||
|
||||
Each call to a formatting function results in a compact binary code. For example
|
||||
The library is designed to produce compact per-call compiled code. For example
|
||||
(`godbolt <https://godbolt.org/g/TZU4KF>`_),
|
||||
|
||||
.. code:: c++
|
||||
@ -167,33 +166,19 @@ compiles to just
|
||||
Portability
|
||||
-----------
|
||||
|
||||
The library is highly portable. Here is an incomplete list of operating systems
|
||||
and compilers where it has been tested and known to work:
|
||||
The library is highly portable and relies only on a small set of C++11 features:
|
||||
|
||||
* 64-bit (amd64) GNU/Linux with GCC 4.4.3,
|
||||
`4.6.3 <https://travis-ci.org/fmtlib/fmt>`_, 4.7.2, 4.8.1, and Intel C++
|
||||
Compiler (ICC) 14.0.2
|
||||
* variadic templates
|
||||
* type traits
|
||||
* rvalue references
|
||||
* decltype
|
||||
* trailing return types
|
||||
* deleted functions
|
||||
|
||||
* 32-bit (i386) GNU/Linux with GCC 4.4.3, 4.6.3
|
||||
|
||||
* Mac OS X with GCC 4.2.1 and Clang 4.2, 5.1.0
|
||||
|
||||
* 64-bit Windows with Visual C++ 2010, 2013 and
|
||||
`2015 <https://ci.appveyor.com/project/vitaut/fmt>`_
|
||||
|
||||
* 32-bit Windows with Visual C++ 2010
|
||||
|
||||
Although the library uses C++11 features when available, it also works with
|
||||
older compilers and standard library implementations. The only thing to keep in
|
||||
mind for C++98 portability:
|
||||
|
||||
* Variadic templates: minimum GCC 4.4, Clang 2.9 or VS2013. This feature allows
|
||||
the Format API to accept an unlimited number of arguments. With older
|
||||
compilers the maximum is 15.
|
||||
|
||||
* User-defined literals: minimum GCC 4.7, Clang 3.1 or VS2015. The suffixes
|
||||
``_format`` and ``_a`` are functionally equivalent to the functions
|
||||
``fmt::format`` and ``fmt::arg``.
|
||||
These are available since GCC 4.4, Clang 2.9 and MSVC 18.0 (2013). For older
|
||||
compilers use fmt `version 4.x
|
||||
<https://github.com/fmtlib/fmt/releases/tag/4.1.0>`_ which continues to be
|
||||
maintained and only requires C++98.
|
||||
|
||||
The output of all formatting functions is consistent across platforms. In
|
||||
particular, formatting a floating-point infinity always gives ``inf`` while the
|
||||
@ -211,7 +196,7 @@ Ease of Use
|
||||
-----------
|
||||
|
||||
fmt has a small self-contained code base with the core library consisting of
|
||||
a single header file and a single source file and no external dependencies.
|
||||
just three header files and no external dependencies.
|
||||
A permissive BSD `license <https://github.com/fmtlib/fmt#license>`_ allows
|
||||
using the library both in open-source and commercial projects.
|
||||
|
||||
|
||||
@ -616,7 +616,8 @@ FMT_MAKE_VALUE(pointer_type, std::nullptr_t, const void*)
|
||||
// formatting of "[const] volatile char *" which is printed as bool by
|
||||
// iostreams.
|
||||
template <typename C, typename T>
|
||||
typed_value<C, pointer_type> make_value(const T *) {
|
||||
typename std::enable_if<!std::is_same<T, typename C::char_type>::value>::type
|
||||
make_value(const T *) {
|
||||
static_assert(!sizeof(T), "formatting of non-void pointers is disallowed");
|
||||
}
|
||||
|
||||
@ -1240,12 +1241,12 @@ inline std::string format(string_view format_str, const Args & ... args) {
|
||||
// This should be just
|
||||
// return vformat(format_str, make_format_args(args...));
|
||||
// but gcc has trouble optimizing the latter, so break it down.
|
||||
format_arg_store<format_context, Args...> as(args...);
|
||||
format_arg_store<format_context, Args...> as{args...};
|
||||
return vformat(format_str, as);
|
||||
}
|
||||
template <typename... Args>
|
||||
inline std::wstring format(wstring_view format_str, const Args & ... args) {
|
||||
format_arg_store<wformat_context, Args...> as(args...);
|
||||
format_arg_store<wformat_context, Args...> as{args...};
|
||||
return vformat(format_str, as);
|
||||
}
|
||||
|
||||
@ -1286,7 +1287,7 @@ FMT_API void vprint(wstring_view format_str, wformat_args args);
|
||||
*/
|
||||
template <typename... Args>
|
||||
inline void print(string_view format_str, const Args & ... args) {
|
||||
format_arg_store<format_context, Args...> as(args...);
|
||||
format_arg_store<format_context, Args...> as{args...};
|
||||
vprint(format_str, as);
|
||||
}
|
||||
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
#define FMT_FORMAT_INL_H_
|
||||
|
||||
#include "format.h"
|
||||
#include "locale.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@ -19,6 +18,7 @@
|
||||
#include <cmath>
|
||||
#include <cstdarg>
|
||||
#include <cstddef> // for std::ptrdiff_t
|
||||
#include <locale>
|
||||
|
||||
#if defined(_WIN32) && defined(__MINGW32__)
|
||||
# include <cstring>
|
||||
@ -205,6 +205,15 @@ void report_error(FormatFunc func, int error_code,
|
||||
}
|
||||
} // namespace
|
||||
|
||||
class locale {
|
||||
private:
|
||||
std::locale locale_;
|
||||
|
||||
public:
|
||||
explicit locale(std::locale loc = std::locale()) : locale_(loc) {}
|
||||
std::locale get() { return locale_; }
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
FMT_FUNC Char internal::thousands_sep(locale_provider *lp) {
|
||||
std::locale loc = lp ? lp->locale().get() : std::locale();
|
||||
|
||||
@ -304,7 +304,7 @@ fp operator*(fp x, fp y);
|
||||
// Compute k such that its cached power c_k = c_k.f * pow(2, c_k.e) satisfies
|
||||
// min_exponent <= c_k.e + e <= min_exponent + 3.
|
||||
inline int compute_cached_power_index(int e, int min_exponent) {
|
||||
constexpr double one_over_log2_10 = 0.30102999566398114; // 1 / log2(10)
|
||||
const double one_over_log2_10 = 0.30102999566398114; // 1 / log2(10)
|
||||
return static_cast<int>(std::ceil((min_exponent - e + 63) * one_over_log2_10));
|
||||
}
|
||||
|
||||
@ -2236,7 +2236,9 @@ void handle_dynamic_spec(
|
||||
/** The default argument formatter. */
|
||||
template <typename Range>
|
||||
class arg_formatter:
|
||||
public internal::function<void>, public internal::arg_formatter_base<Range> {
|
||||
public internal::function<
|
||||
typename internal::arg_formatter_base<Range>::iterator>,
|
||||
public internal::arg_formatter_base<Range> {
|
||||
private:
|
||||
typedef typename Range::value_type char_type;
|
||||
typedef internal::arg_formatter_base<Range> base;
|
||||
|
||||
@ -1,25 +0,0 @@
|
||||
// Formatting library for C++ - locale support
|
||||
//
|
||||
// Copyright (c) 2012 - 2016, Victor Zverovich
|
||||
// All rights reserved.
|
||||
//
|
||||
// For the license information refer to format.h.
|
||||
|
||||
#ifndef FMT_LOCALE_H_
|
||||
#define FMT_LOCALE_H_
|
||||
|
||||
#include "format.h"
|
||||
#include <locale>
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
class locale {
|
||||
private:
|
||||
std::locale locale_;
|
||||
|
||||
public:
|
||||
explicit locale(std::locale loc = std::locale()) : locale_(loc) {}
|
||||
std::locale get() { return locale_; }
|
||||
};
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#endif // FMT_LOCALE_
|
||||
@ -140,13 +140,13 @@ inline void vprint(std::basic_ostream<Char> &os,
|
||||
template <typename... Args>
|
||||
inline void print(std::ostream &os, string_view format_str,
|
||||
const Args & ... args) {
|
||||
vprint(os, format_str, make_format_args<format_context>(args...));
|
||||
vprint<char>(os, format_str, make_format_args<format_context>(args...));
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void print(std::wostream &os, wstring_view format_str,
|
||||
const Args & ... args) {
|
||||
vprint(os, format_str, make_format_args<wformat_context>(args...));
|
||||
vprint<wchar_t>(os, format_str, make_format_args<wformat_context>(args...));
|
||||
}
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
|
||||
@ -215,7 +215,9 @@ class basic_printf_context;
|
||||
*/
|
||||
template <typename Range>
|
||||
class printf_arg_formatter:
|
||||
public internal::function<void>, public internal::arg_formatter_base<Range> {
|
||||
public internal::function<
|
||||
typename internal::arg_formatter_base<Range>::iterator>,
|
||||
public internal::arg_formatter_base<Range> {
|
||||
private:
|
||||
typedef typename Range::value_type char_type;
|
||||
typedef decltype(internal::declval<Range>().begin()) iterator;
|
||||
@ -627,7 +629,7 @@ template <typename... Args>
|
||||
inline int fprintf(std::FILE *f, string_view format_str, const Args & ... args) {
|
||||
auto vargs = make_format_args<
|
||||
typename printf_context<internal::buffer>::type>(args...);
|
||||
return vfprintf(f, format_str, vargs);
|
||||
return vfprintf<char>(f, format_str, vargs);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
|
||||
@ -34,18 +34,20 @@ template <typename Char, typename Enable = void>
|
||||
struct formatting_range : formatting_base<Char> {
|
||||
static FMT_CONSTEXPR_DECL const std::size_t range_length_limit =
|
||||
FMT_RANGE_OUTPUT_LENGTH_LIMIT; // output only up to N items from the range.
|
||||
Char prefix = '{';
|
||||
Char delimiter = ',';
|
||||
Char postfix = '}';
|
||||
Char prefix;
|
||||
Char delimiter;
|
||||
Char postfix;
|
||||
formatting_range() : prefix('{'), delimiter(','), postfix('}') {}
|
||||
static FMT_CONSTEXPR_DECL const bool add_delimiter_spaces = true;
|
||||
static FMT_CONSTEXPR_DECL const bool add_prepostfix_space = false;
|
||||
};
|
||||
|
||||
template <typename Char, typename Enable = void>
|
||||
struct formatting_tuple : formatting_base<Char> {
|
||||
Char prefix = '(';
|
||||
Char delimiter = ',';
|
||||
Char postfix = ')';
|
||||
Char prefix;
|
||||
Char delimiter;
|
||||
Char postfix;
|
||||
formatting_tuple() : prefix('('), delimiter(','), postfix(')') {}
|
||||
static FMT_CONSTEXPR_DECL const bool add_delimiter_spaces = true;
|
||||
static FMT_CONSTEXPR_DECL const bool add_prepostfix_space = false;
|
||||
};
|
||||
@ -54,9 +56,8 @@ namespace internal {
|
||||
|
||||
template <typename RangeT, typename OutputIterator>
|
||||
void copy(const RangeT &range, OutputIterator out) {
|
||||
for (const auto &it : range) {
|
||||
*out++ = it;
|
||||
}
|
||||
for (auto it = range.begin(), end = range.end(); it != end; ++it)
|
||||
*out++ = *it;
|
||||
}
|
||||
|
||||
template <typename OutputIterator>
|
||||
@ -83,7 +84,7 @@ class is_like_std_string {
|
||||
|
||||
public:
|
||||
static FMT_CONSTEXPR_DECL const bool value =
|
||||
!std::is_void<decltype(check<T>(nullptr))>::value;
|
||||
!std::is_void<decltype(check<T>(FMT_NULL))>::value;
|
||||
};
|
||||
|
||||
template <typename... Ts>
|
||||
@ -95,8 +96,8 @@ struct is_range_ : std::false_type {};
|
||||
template <typename T>
|
||||
struct is_range_<T,typename std::conditional<
|
||||
false,
|
||||
conditional_helper<decltype(std::declval<T>().begin()),
|
||||
decltype(std::declval<T>().end())>,
|
||||
conditional_helper<decltype(internal::declval<T>().begin()),
|
||||
decltype(internal::declval<T>().end())>,
|
||||
void>::type> : std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
@ -111,13 +112,13 @@ class is_tuple_like_ {
|
||||
template <typename U>
|
||||
static auto check(U *p) ->
|
||||
decltype(std::tuple_size<U>::value,
|
||||
std::declval<typename std::tuple_element<0, U>::type>(), int());
|
||||
internal::declval<typename std::tuple_element<0, U>::type>(), int());
|
||||
template <typename>
|
||||
static void check(...);
|
||||
|
||||
public:
|
||||
static FMT_CONSTEXPR_DECL const bool value =
|
||||
!std::is_void<decltype(check<T>(nullptr))>::value;
|
||||
!std::is_void<decltype(check<T>(FMT_NULL))>::value;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
@ -125,7 +126,16 @@ struct is_tuple_like {
|
||||
static FMT_CONSTEXPR_DECL const bool value =
|
||||
is_tuple_like_<T>::value && !is_range_<T>::value;
|
||||
};
|
||||
} // namespace internal
|
||||
|
||||
#if FMT_HAS_FEATURE(__cpp_lib_integer_sequence)
|
||||
# define FMT_USE_INTEGER_SEQUENCE 1
|
||||
#else
|
||||
# define FMT_USE_INTEGER_SEQUENCE 0
|
||||
#endif
|
||||
|
||||
#if FMT_USE_INTEGER_SEQUENCE
|
||||
namespace internal {
|
||||
template <size_t... Is, class Tuple, class F>
|
||||
void for_each(std::index_sequence<Is...>, Tuple &&tup, F &&f) noexcept {
|
||||
using std::get;
|
||||
@ -183,6 +193,7 @@ struct formatter<TupleT, Char,
|
||||
return ctx.out();
|
||||
}
|
||||
};
|
||||
#endif // FMT_USE_INTEGER_SEQUENCE
|
||||
|
||||
template <typename RangeT, typename Char>
|
||||
struct formatter< RangeT, Char,
|
||||
@ -196,11 +207,12 @@ struct formatter< RangeT, Char,
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
auto format(const RangeT &values, FormatContext &ctx) -> decltype(ctx.out()) {
|
||||
typename FormatContext::iterator format(
|
||||
const RangeT &values, FormatContext &ctx) {
|
||||
auto out = ctx.out();
|
||||
internal::copy(formatting.prefix, out);
|
||||
std::size_t i = 0;
|
||||
for (const auto &it : values) {
|
||||
for (auto it = values.begin(), end = values.end(); it != end; ++it) {
|
||||
if (i > 0) {
|
||||
if (formatting.add_prepostfix_space) {
|
||||
*out++ = ' ';
|
||||
@ -208,9 +220,9 @@ struct formatter< RangeT, Char,
|
||||
internal::copy(formatting.delimiter, out);
|
||||
}
|
||||
if (formatting.add_delimiter_spaces && i > 0) {
|
||||
format_to(out, " {}", it);
|
||||
format_to(out, " {}", *it);
|
||||
} else {
|
||||
format_to(out, "{}", it);
|
||||
format_to(out, "{}", *it);
|
||||
}
|
||||
if (++i > formatting.range_length_limit) {
|
||||
format_to(out, " ... <other elements>");
|
||||
|
||||
@ -223,9 +223,9 @@ buffered_file file::fdopen(const char *mode) {
|
||||
if (!f)
|
||||
FMT_THROW(system_error(errno,
|
||||
"cannot associate stream with file descriptor"));
|
||||
buffered_file file(f);
|
||||
buffered_file bf(f);
|
||||
fd_ = -1;
|
||||
return file;
|
||||
return bf;
|
||||
}
|
||||
|
||||
long getpagesize() {
|
||||
|
||||
@ -1394,7 +1394,8 @@ TEST(FormatTest, FixedEnum) {
|
||||
typedef fmt::back_insert_range<fmt::internal::buffer> buffer_range;
|
||||
|
||||
class mock_arg_formatter:
|
||||
public fmt::internal::function<void>,
|
||||
public fmt::internal::function<
|
||||
fmt::internal::arg_formatter_base<buffer_range>::iterator>,
|
||||
public fmt::internal::arg_formatter_base<buffer_range> {
|
||||
private:
|
||||
MOCK_METHOD1(call, void (int value));
|
||||
|
||||
@ -30,6 +30,7 @@ TEST(RangesTest, FormatVector2) {
|
||||
EXPECT_EQ("{{1, 2}, {3, 5}, {7, 11}}", ivf);
|
||||
}
|
||||
|
||||
#if FMT_USE_INTEGER_SEQUENCE
|
||||
TEST(RangesTest, FormatMap) {
|
||||
std::map<std::string, int32_t> simap{{"one", 1}, {"two", 2}};
|
||||
EXPECT_EQ("{(one, 1), (two, 2)}", fmt::format("{}", simap));
|
||||
@ -46,7 +47,7 @@ TEST(RangesTest, FormatTuple) {
|
||||
EXPECT_EQ("(42, 3.14159, this is tuple)", fmt::format("{}", tu1));
|
||||
}
|
||||
|
||||
/// check if 'if constexpr' is supported.
|
||||
/// Check if 'if constexpr' is supported.
|
||||
#if (__cplusplus > 201402L) || \
|
||||
(defined(_MSVC_LANG) && _MSVC_LANG > 201402L && _MSC_VER >= 1910)
|
||||
|
||||
@ -86,3 +87,4 @@ TEST(RangesTest, FormatStruct) {
|
||||
|
||||
#endif // (__cplusplus > 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >
|
||||
// 201402L && _MSC_VER >= 1910)
|
||||
#endif // FMT_USE_INTEGER_SEQUENCE
|
||||
|
||||
@ -17,7 +17,6 @@
|
||||
# include <type_traits>
|
||||
#endif
|
||||
|
||||
#include "fmt/locale.h"
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest-extra.h"
|
||||
#include "mock-allocator.h"
|
||||
@ -397,13 +396,14 @@ TEST(FixedBufferTest, BufferOverflow) {
|
||||
EXPECT_THROW_MSG(buffer.resize(11), std::runtime_error, "buffer overflow");
|
||||
}
|
||||
|
||||
struct uint32_pair {
|
||||
uint32_t u[2];
|
||||
};
|
||||
|
||||
TEST(UtilTest, BitCast) {
|
||||
struct S {
|
||||
uint32_t u[2];
|
||||
};
|
||||
auto s = fmt::internal::bit_cast<S>(uint64_t(42));
|
||||
auto s = fmt::internal::bit_cast<uint32_pair>(uint64_t{42});
|
||||
EXPECT_EQ(fmt::internal::bit_cast<uint64_t>(s), 42u);
|
||||
s = fmt::internal::bit_cast<S>(uint64_t(~0ull));
|
||||
s = fmt::internal::bit_cast<uint32_pair>(uint64_t(~0ull));
|
||||
EXPECT_EQ(fmt::internal::bit_cast<uint64_t>(s), ~0ull);
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user