Skip to content

Commit

Permalink
Update included fmt library to version 11.0.2
Browse files Browse the repository at this point in the history
  • Loading branch information
joto committed Sep 16, 2024
1 parent 0b3271e commit 47fe675
Show file tree
Hide file tree
Showing 17 changed files with 5,471 additions and 4,774 deletions.
File renamed without changes.
2 changes: 1 addition & 1 deletion contrib/fmt/README.contrib
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Source: https://github.com/fmtlib/fmt
Revision: v10.2.1
Revision: v11.0.2
80 changes: 37 additions & 43 deletions contrib/fmt/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,27 @@ that help victims of the war in Ukraine: <https://www.stopputin.net/>.
Q&A: ask questions on [StackOverflow with the tag
fmt](https://stackoverflow.com/questions/tagged/fmt).

Try {fmt} in [Compiler Explorer](https://godbolt.org/z/Eq5763).
Try {fmt} in [Compiler Explorer](https://godbolt.org/z/8Mx1EW73v).

# Features

- Simple [format API](https://fmt.dev/latest/api.html) with positional
- Simple [format API](https://fmt.dev/latest/api/) with positional
arguments for localization
- Implementation of [C++20
std::format](https://en.cppreference.com/w/cpp/utility/format) and
[C++23 std::print](https://en.cppreference.com/w/cpp/io/print)
- [Format string syntax](https://fmt.dev/latest/syntax.html) similar
- [Format string syntax](https://fmt.dev/latest/syntax/) similar
to Python\'s
[format](https://docs.python.org/3/library/stdtypes.html#str.format)
- Fast IEEE 754 floating-point formatter with correct rounding,
shortness and round-trip guarantees using the
[Dragonbox](https://github.com/jk-jeon/dragonbox) algorithm
- Portable Unicode support
- Safe [printf
implementation](https://fmt.dev/latest/api.html#printf-formatting)
implementation](https://fmt.dev/latest/api/#printf-formatting)
including the POSIX extension for positional arguments
- Extensibility: [support for user-defined
types](https://fmt.dev/latest/api.html#formatting-user-defined-types)
types](https://fmt.dev/latest/api/#formatting-user-defined-types)
- High performance: faster than common standard library
implementations of `(s)printf`, iostreams, `to_string` and
`to_chars`, see [Speed tests](#speed-tests) and [Converting a
Expand All @@ -58,8 +58,8 @@ Try {fmt} in [Compiler Explorer](https://godbolt.org/z/Eq5763).
buffer overflow errors
- Ease of use: small self-contained code base, no external
dependencies, permissive MIT
[license](https://github.com/fmtlib/fmt/blob/master/LICENSE.rst)
- [Portability](https://fmt.dev/latest/index.html#portability) with
[license](https://github.com/fmtlib/fmt/blob/master/LICENSE)
- [Portability](https://fmt.dev/latest/#portability) with
consistent output across platforms and support for older compilers
- Clean warning-free codebase even on high warning levels such as
`-Wall -Wextra -pedantic`
Expand Down Expand Up @@ -203,43 +203,38 @@ and [ryu](https://github.com/ulfjack/ryu):

## Compile time and code bloat

The script
[bloat-test.py](https://github.com/fmtlib/format-benchmark/blob/master/bloat-test.py)
from [format-benchmark](https://github.com/fmtlib/format-benchmark)
tests compile time and code bloat for nontrivial projects. It generates
100 translation units and uses `printf()` or its alternative five times
in each to simulate a medium-sized project. The resulting executable
size and compile time (Apple LLVM version 8.1.0 (clang-802.0.42), macOS
Sierra, best of three) is shown in the following tables.
The script [bloat-test.py][test] from [format-benchmark][bench] tests compile
time and code bloat for nontrivial projects. It generates 100 translation units
and uses `printf()` or its alternative five times in each to simulate a
medium-sized project. The resulting executable size and compile time (Apple
clang version 15.0.0 (clang-1500.1.0.2.5), macOS Sonoma, best of three) is shown
in the following tables.

[test]: https://github.com/fmtlib/format-benchmark/blob/master/bloat-test.py
[bench]: https://github.com/fmtlib/format-benchmark

**Optimized build (-O3)**

| Method | Compile Time, s | Executable size, KiB | Stripped size, KiB |
|---------------|-----------------|----------------------|--------------------|
| printf | 2.6 | 29 | 26 |
| printf+string | 16.4 | 29 | 26 |
| iostreams | 31.1 | 59 | 55 |
| {fmt} | 19.0 | 37 | 34 |
| Boost Format | 91.9 | 226 | 203 |
| Folly Format | 115.7 | 101 | 88 |

As you can see, {fmt} has 60% less overhead in terms of resulting binary
code size compared to iostreams and comes pretty close to `printf`.
Boost Format and Folly Format have the largest overheads.
| printf | 1.6 | 54 | 50 |
| IOStreams | 25.9 | 98 | 84 |
| fmt 83652df | 4.8 | 54 | 50 |
| tinyformat | 29.1 | 161 | 136 |
| Boost Format | 55.0 | 530 | 317 |

`printf+string` is the same as `printf` but with an extra `<string>`
include to measure the overhead of the latter.
{fmt} is fast to compile and is comparable to `printf` in terms of per-call
binary size (within a rounding error on this system).

**Non-optimized build**

| Method | Compile Time, s | Executable size, KiB | Stripped size, KiB |
|---------------|-----------------|----------------------|--------------------|
| printf | 2.2 | 33 | 30 |
| printf+string | 16.0 | 33 | 30 |
| iostreams | 28.3 | 56 | 52 |
| {fmt} | 18.2 | 59 | 50 |
| Boost Format | 54.1 | 365 | 303 |
| Folly Format | 79.9 | 445 | 430 |
| printf | 1.4 | 54 | 50 |
| IOStreams | 23.4 | 92 | 68 |
| {fmt} 83652df | 4.4 | 89 | 85 |
| tinyformat | 24.5 | 204 | 161 |
| Boost Format | 36.4 | 831 | 462 |

`libc`, `lib(std)c++`, and `libfmt` are all linked as shared libraries
to compare formatting function overhead only. Boost Format is a
Expand All @@ -248,7 +243,7 @@ header-only library so it doesn\'t provide any linkage options.
## Running the tests

Please refer to [Building the
library](https://fmt.dev/latest/usage.html#building-the-library) for
library](https://fmt.dev/latest/get-started/#building-from-source) for
instructions on how to build the library and run the unit tests.

Benchmarks reside in a separate repository,
Expand All @@ -270,8 +265,7 @@ or the bloat test:

# Migrating code

[clang-tidy](https://clang.llvm.org/extra/clang-tidy/) v17 (not yet
released) provides the
[clang-tidy](https://clang.llvm.org/extra/clang-tidy/) v18 provides the
[modernize-use-std-print](https://clang.llvm.org/extra/clang-tidy/checks/modernize/use-std-print.html)
check that is capable of converting occurrences of `printf` and
`fprintf` to `fmt::print` if configured to do so. (By default it
Expand Down Expand Up @@ -303,7 +297,7 @@ converts to `std::print`.)
underwater vehicle
- [Drake](https://drake.mit.edu/): a planning, control, and analysis
toolbox for nonlinear dynamical systems (MIT)
- [Envoy](https://lyft.github.io/envoy/): C++ L7 proxy and
- [Envoy](https://github.com/envoyproxy/envoy): C++ L7 proxy and
communication bus (Lyft)
- [FiveM](https://fivem.net/): a modification framework for GTA V
- [fmtlog](https://github.com/MengRao/fmtlog): a performant
Expand Down Expand Up @@ -343,7 +337,7 @@ converts to `std::print`.)
- [Quill](https://github.com/odygrd/quill): asynchronous low-latency
logging library
- [QKW](https://github.com/ravijanjam/qkw): generalizing aliasing to
simplify navigation, and executing complex multi-line terminal
simplify navigation, and execute complex multi-line terminal
command sequences
- [redis-cerberus](https://github.com/HunanTV/redis-cerberus): a Redis
cluster proxy
Expand Down Expand Up @@ -432,7 +426,7 @@ code bloat issues (see [Benchmarks](#benchmarks)).
## FastFormat
This is an interesting library that is fast, safe, and has positional
This is an interesting library that is fast, safe and has positional
arguments. However, it has significant limitations, citing its author:
> Three features that have no hope of being accommodated within the
Expand All @@ -442,8 +436,8 @@ arguments. However, it has significant limitations, citing its author:
> - Octal/hexadecimal encoding
> - Runtime width/alignment specification
It is also quite big and has a heavy dependency, STLSoft, which might be
too restrictive for using it in some projects.
It is also quite big and has a heavy dependency, on STLSoft, which might be
too restrictive for use in some projects.
## Boost Spirit.Karma
Expand All @@ -462,7 +456,7 @@ second](http://www.zverovich.net/2020/06/13/fast-int-to-string-revisited.html).
# Documentation License
The [Format String Syntax](https://fmt.dev/latest/syntax.html) section
The [Format String Syntax](https://fmt.dev/latest/syntax/) section
in the documentation is based on the one from Python [string module
documentation](https://docs.python.org/3/library/string.html#module-string).
For this reason, the documentation is distributed under the Python
Expand All @@ -486,5 +480,5 @@ To report a security issue, please disclose it at [security
advisory](https://github.com/fmtlib/fmt/security/advisories/new).
This project is maintained by a team of volunteers on a
reasonable-effort basis. As such, please give us at least 90 days to
reasonable-effort basis. As such, please give us at least *90* days to
work on a fix before public exposure.
115 changes: 54 additions & 61 deletions contrib/fmt/include/fmt/args.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@
#ifndef FMT_ARGS_H_
#define FMT_ARGS_H_

#include <functional> // std::reference_wrapper
#include <memory> // std::unique_ptr
#include <vector>
#ifndef FMT_MODULE
# include <functional> // std::reference_wrapper
# include <memory> // std::unique_ptr
# include <vector>
#endif

#include "core.h"
#include "format.h" // std_string_view

FMT_BEGIN_NAMESPACE

Expand All @@ -28,15 +30,18 @@ auto unwrap(const std::reference_wrapper<T>& v) -> const T& {
return static_cast<const T&>(v);
}

class dynamic_arg_list {
// Workaround for clang's -Wweak-vtables. Unlike for regular classes, for
// templates it doesn't complain about inability to deduce single translation
// unit for placing vtable. So storage_node_base is made a fake template.
template <typename = void> struct node {
virtual ~node() = default;
std::unique_ptr<node<>> next;
};
// node is defined outside dynamic_arg_list to workaround a C2504 bug in MSVC
// 2022 (v17.10.0).
//
// Workaround for clang's -Wweak-vtables. Unlike for regular classes, for
// templates it doesn't complain about inability to deduce single translation
// unit for placing vtable. So node is made a fake template.
template <typename = void> struct node {
virtual ~node() = default;
std::unique_ptr<node<>> next;
};

class dynamic_arg_list {
template <typename T> struct typed_node : node<> {
T value;

Expand All @@ -62,14 +67,10 @@ class dynamic_arg_list {
} // namespace detail

/**
\rst
A dynamic version of `fmt::format_arg_store`.
It's equipped with a storage to potentially temporary objects which lifetimes
could be shorter than the format arguments object.
It can be implicitly converted into `~fmt::basic_format_args` for passing
into type-erased formatting functions such as `~fmt::vformat`.
\endrst
* A dynamic list of formatting arguments with storage.
*
* It can be implicitly converted into `fmt::basic_format_args` for passing
* into type-erased formatting functions such as `fmt::vformat`.
*/
template <typename Context>
class dynamic_format_arg_store
Expand Down Expand Up @@ -147,22 +148,20 @@ class dynamic_format_arg_store
constexpr dynamic_format_arg_store() = default;

/**
\rst
Adds an argument into the dynamic store for later passing to a formatting
function.
Note that custom types and string types (but not string views) are copied
into the store dynamically allocating memory if necessary.
**Example**::
fmt::dynamic_format_arg_store<fmt::format_context> store;
store.push_back(42);
store.push_back("abc");
store.push_back(1.5f);
std::string result = fmt::vformat("{} and {} and {}", store);
\endrst
*/
* Adds an argument into the dynamic store for later passing to a formatting
* function.
*
* Note that custom types and string types (but not string views) are copied
* into the store dynamically allocating memory if necessary.
*
* **Example**:
*
* fmt::dynamic_format_arg_store<fmt::format_context> store;
* store.push_back(42);
* store.push_back("abc");
* store.push_back(1.5f);
* std::string result = fmt::vformat("{} and {} and {}", store);
*/
template <typename T> void push_back(const T& arg) {
if (detail::const_check(need_copy<T>::value))
emplace_arg(dynamic_args_.push<stored_type<T>>(arg));
Expand All @@ -171,20 +170,18 @@ class dynamic_format_arg_store
}

/**
\rst
Adds a reference to the argument into the dynamic store for later passing to
a formatting function.
**Example**::
fmt::dynamic_format_arg_store<fmt::format_context> store;
char band[] = "Rolling Stones";
store.push_back(std::cref(band));
band[9] = 'c'; // Changing str affects the output.
std::string result = fmt::vformat("{}", store);
// result == "Rolling Scones"
\endrst
*/
* Adds a reference to the argument into the dynamic store for later passing
* to a formatting function.
*
* **Example**:
*
* fmt::dynamic_format_arg_store<fmt::format_context> store;
* char band[] = "Rolling Stones";
* store.push_back(std::cref(band));
* band[9] = 'c'; // Changing str affects the output.
* std::string result = fmt::vformat("{}", store);
* // result == "Rolling Scones"
*/
template <typename T> void push_back(std::reference_wrapper<T> arg) {
static_assert(
need_copy<T>::value,
Expand All @@ -193,10 +190,10 @@ class dynamic_format_arg_store
}

/**
Adds named argument into the dynamic store for later passing to a formatting
function. ``std::reference_wrapper`` is supported to avoid copying of the
argument. The name is always copied into the store.
*/
* Adds named argument into the dynamic store for later passing to a
* formatting function. `std::reference_wrapper` is supported to avoid
* copying of the argument. The name is always copied into the store.
*/
template <typename T>
void push_back(const detail::named_arg<char_type, T>& arg) {
const char_type* arg_name =
Expand All @@ -209,19 +206,15 @@ class dynamic_format_arg_store
}
}

/** Erase all elements from the store */
/// Erase all elements from the store.
void clear() {
data_.clear();
named_info_.clear();
dynamic_args_ = detail::dynamic_arg_list();
}

/**
\rst
Reserves space to store at least *new_cap* arguments including
*new_cap_named* named arguments.
\endrst
*/
/// Reserves space to store at least `new_cap` arguments including
/// `new_cap_named` named arguments.
void reserve(size_t new_cap, size_t new_cap_named) {
FMT_ASSERT(new_cap >= new_cap_named,
"Set of arguments includes set of named arguments");
Expand Down
Loading

0 comments on commit 47fe675

Please sign in to comment.