api.rst 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. .. _string-formatting-api:
  2. *************
  3. API Reference
  4. *************
  5. The {fmt} library API consists of the following parts:
  6. * :ref:`fmt/core.h <core-api>`: the core API providing main formatting functions
  7. for ``char``/UTF-8 with C++20 compile-time checks and minimal dependencies
  8. * :ref:`fmt/format.h <format-api>`: the full format API providing additional
  9. formatting functions and locale support
  10. * :ref:`fmt/ranges.h <ranges-api>`: formatting of ranges and tuples
  11. * :ref:`fmt/chrono.h <chrono-api>`: date and time formatting
  12. * :ref:`fmt/std.h <std-api>`: formatters for standard library types
  13. * :ref:`fmt/compile.h <compile-api>`: format string compilation
  14. * :ref:`fmt/color.h <color-api>`: terminal color and text style
  15. * :ref:`fmt/os.h <os-api>`: system APIs
  16. * :ref:`fmt/ostream.h <ostream-api>`: ``std::ostream`` support
  17. * :ref:`fmt/args.h <args-api>`: dynamic argument lists
  18. * :ref:`fmt/printf.h <printf-api>`: ``printf`` formatting
  19. * :ref:`fmt/xchar.h <xchar-api>`: optional ``wchar_t`` support
  20. All functions and types provided by the library reside in namespace ``fmt`` and
  21. macros have prefix ``FMT_``.
  22. .. _core-api:
  23. Core API
  24. ========
  25. ``fmt/core.h`` defines the core API which provides main formatting functions
  26. for ``char``/UTF-8 with C++20 compile-time checks. It has minimal include
  27. dependencies for better compile times. This header is only beneficial when
  28. using {fmt} as a library (the default) and not in the header-only mode.
  29. It also provides ``formatter`` specializations for built-in and string types.
  30. The following functions use :ref:`format string syntax <syntax>`
  31. similar to that of Python's `str.format
  32. <https://docs.python.org/3/library/stdtypes.html#str.format>`_.
  33. They take *fmt* and *args* as arguments.
  34. *fmt* is a format string that contains literal text and replacement fields
  35. surrounded by braces ``{}``. The fields are replaced with formatted arguments
  36. in the resulting string. `~fmt::format_string` is a format string which can be
  37. implicitly constructed from a string literal or a ``constexpr`` string and is
  38. checked at compile time in C++20. To pass a runtime format string wrap it in
  39. `fmt::runtime`.
  40. *args* is an argument list representing objects to be formatted.
  41. I/O errors are reported as `std::system_error
  42. <https://en.cppreference.com/w/cpp/error/system_error>`_ exceptions unless
  43. specified otherwise.
  44. .. _format:
  45. .. doxygenfunction:: format(format_string<T...> fmt, T&&... args) -> std::string
  46. .. doxygenfunction:: vformat(string_view fmt, format_args args) -> std::string
  47. .. doxygenfunction:: format_to(OutputIt out, format_string<T...> fmt, T&&... args) -> OutputIt
  48. .. doxygenfunction:: format_to_n(OutputIt out, size_t n, format_string<T...> fmt, T&&... args) -> format_to_n_result<OutputIt>
  49. .. doxygenfunction:: formatted_size(format_string<T...> fmt, T&&... args) -> size_t
  50. .. doxygenstruct:: fmt::format_to_n_result
  51. :members:
  52. .. _print:
  53. .. doxygenfunction:: fmt::print(format_string<T...> fmt, T&&... args)
  54. .. doxygenfunction:: fmt::vprint(string_view fmt, format_args args)
  55. .. doxygenfunction:: print(std::FILE *f, format_string<T...> fmt, T&&... args)
  56. .. doxygenfunction:: vprint(std::FILE *f, string_view fmt, format_args args)
  57. Compile-Time Format String Checks
  58. ---------------------------------
  59. Compile-time format string checks are enabled by default on compilers
  60. that support C++20 ``consteval``. On older compilers you can use the
  61. :ref:`FMT_STRING <legacy-checks>`: macro defined in ``fmt/format.h`` instead.
  62. Unused arguments are allowed as in Python's `str.format` and ordinary functions.
  63. .. doxygenclass:: fmt::basic_format_string
  64. :members:
  65. .. doxygentypedef:: fmt::format_string
  66. .. doxygenfunction:: fmt::runtime(string_view) -> runtime_format_string<>
  67. .. _udt:
  68. Formatting User-Defined Types
  69. -----------------------------
  70. The {fmt} library provides formatters for many standard C++ types.
  71. See :ref:`fmt/ranges.h <ranges-api>` for ranges and tuples including standard
  72. containers such as ``std::vector``, :ref:`fmt/chrono.h <chrono-api>` for date
  73. and time formatting and :ref:`fmt/std.h <std-api>` for other standard library
  74. types.
  75. There are two ways to make a user-defined type formattable: providing a
  76. ``format_as`` function or specializing the ``formatter`` struct template.
  77. Use ``format_as`` if you want to make your type formattable as some other type
  78. with the same format specifiers. The ``format_as`` function should take an
  79. object of your type and return an object of a formattable type. It should be
  80. defined in the same namespace as your type.
  81. Example (https://godbolt.org/z/nvME4arz8)::
  82. #include <fmt/format.h>
  83. namespace kevin_namespacy {
  84. enum class film {
  85. house_of_cards, american_beauty, se7en = 7
  86. };
  87. auto format_as(film f) { return fmt::underlying(f); }
  88. }
  89. int main() {
  90. fmt::print("{}\n", kevin_namespacy::film::se7en); // prints "7"
  91. }
  92. Using specialization is more complex but gives you full control over parsing and
  93. formatting. To use this method specialize the ``formatter`` struct template for
  94. your type and implement ``parse`` and ``format`` methods.
  95. The recommended way of defining a formatter is by reusing an existing one via
  96. inheritance or composition. This way you can support standard format specifiers
  97. without implementing them yourself. For example::
  98. // color.h:
  99. #include <fmt/core.h>
  100. enum class color {red, green, blue};
  101. template <> struct fmt::formatter<color>: formatter<string_view> {
  102. // parse is inherited from formatter<string_view>.
  103. auto format(color c, format_context& ctx) const;
  104. };
  105. // color.cc:
  106. #include "color.h"
  107. #include <fmt/format.h>
  108. auto fmt::formatter<color>::format(color c, format_context& ctx) const {
  109. string_view name = "unknown";
  110. switch (c) {
  111. case color::red: name = "red"; break;
  112. case color::green: name = "green"; break;
  113. case color::blue: name = "blue"; break;
  114. }
  115. return formatter<string_view>::format(name, ctx);
  116. }
  117. Note that ``formatter<string_view>::format`` is defined in ``fmt/format.h`` so
  118. it has to be included in the source file. Since ``parse`` is inherited from
  119. ``formatter<string_view>`` it will recognize all string format specifications,
  120. for example
  121. .. code-block:: c++
  122. fmt::format("{:>10}", color::blue)
  123. will return ``" blue"``.
  124. The experimental ``nested_formatter`` provides an easy way of applying a
  125. formatter to one or more subobjects.
  126. For example::
  127. #include <fmt/format.h>
  128. struct point {
  129. double x, y;
  130. };
  131. template <>
  132. struct fmt::formatter<point> : nested_formatter<double> {
  133. auto format(point p, format_context& ctx) const {
  134. return write_padded(ctx, [=](auto out) {
  135. return format_to(out, "({}, {})", nested(p.x), nested(p.y));
  136. });
  137. }
  138. };
  139. int main() {
  140. fmt::print("[{:>20.2f}]", point{1, 2});
  141. }
  142. prints::
  143. [ (1.00, 2.00)]
  144. Notice that fill, align and width are applied to the whole object which is the
  145. recommended behavior while the remaining specifiers apply to elements.
  146. In general the formatter has the following form::
  147. template <> struct fmt::formatter<T> {
  148. // Parses format specifiers and stores them in the formatter.
  149. //
  150. // [ctx.begin(), ctx.end()) is a, possibly empty, character range that
  151. // contains a part of the format string starting from the format
  152. // specifications to be parsed, e.g. in
  153. //
  154. // fmt::format("{:f} continued", ...);
  155. //
  156. // the range will contain "f} continued". The formatter should parse
  157. // specifiers until '}' or the end of the range. In this example the
  158. // formatter should parse the 'f' specifier and return an iterator
  159. // pointing to '}'.
  160. constexpr auto parse(format_parse_context& ctx)
  161. -> format_parse_context::iterator;
  162. // Formats value using the parsed format specification stored in this
  163. // formatter and writes the output to ctx.out().
  164. auto format(const T& value, format_context& ctx) const
  165. -> format_context::iterator;
  166. };
  167. It is recommended to at least support fill, align and width that apply to the
  168. whole object and have the same semantics as in standard formatters.
  169. You can also write a formatter for a hierarchy of classes::
  170. // demo.h:
  171. #include <type_traits>
  172. #include <fmt/core.h>
  173. struct A {
  174. virtual ~A() {}
  175. virtual std::string name() const { return "A"; }
  176. };
  177. struct B : A {
  178. virtual std::string name() const { return "B"; }
  179. };
  180. template <typename T>
  181. struct fmt::formatter<T, std::enable_if_t<std::is_base_of<A, T>::value, char>> :
  182. fmt::formatter<std::string> {
  183. auto format(const A& a, format_context& ctx) const {
  184. return fmt::formatter<std::string>::format(a.name(), ctx);
  185. }
  186. };
  187. // demo.cc:
  188. #include "demo.h"
  189. #include <fmt/format.h>
  190. int main() {
  191. B b;
  192. A& a = b;
  193. fmt::print("{}", a); // prints "B"
  194. }
  195. Providing both a ``formatter`` specialization and a ``format_as`` overload is
  196. disallowed.
  197. Named Arguments
  198. ---------------
  199. .. doxygenfunction:: fmt::arg(const S&, const T&)
  200. Named arguments are not supported in compile-time checks at the moment.
  201. Argument Lists
  202. --------------
  203. You can create your own formatting function with compile-time checks and small
  204. binary footprint, for example (https://godbolt.org/z/vajfWEG4b):
  205. .. code:: c++
  206. #include <fmt/core.h>
  207. void vlog(const char* file, int line, fmt::string_view format,
  208. fmt::format_args args) {
  209. fmt::print("{}: {}: ", file, line);
  210. fmt::vprint(format, args);
  211. }
  212. template <typename... T>
  213. void log(const char* file, int line, fmt::format_string<T...> format, T&&... args) {
  214. vlog(file, line, format, fmt::make_format_args(args...));
  215. }
  216. #define MY_LOG(format, ...) log(__FILE__, __LINE__, format, __VA_ARGS__)
  217. MY_LOG("invalid squishiness: {}", 42);
  218. Note that ``vlog`` is not parameterized on argument types which improves compile
  219. times and reduces binary code size compared to a fully parameterized version.
  220. .. doxygenfunction:: fmt::make_format_args(const Args&...)
  221. .. doxygenclass:: fmt::format_arg_store
  222. :members:
  223. .. doxygenclass:: fmt::basic_format_args
  224. :members:
  225. .. doxygentypedef:: fmt::format_args
  226. .. doxygenclass:: fmt::basic_format_arg
  227. :members:
  228. .. doxygenclass:: fmt::basic_format_parse_context
  229. :members:
  230. .. doxygenclass:: fmt::basic_format_context
  231. :members:
  232. .. doxygentypedef:: fmt::format_context
  233. .. _args-api:
  234. Dynamic Argument Lists
  235. ----------------------
  236. The header ``fmt/args.h`` provides ``dynamic_format_arg_store``, a builder-like
  237. API that can be used to construct format argument lists dynamically.
  238. .. doxygenclass:: fmt::dynamic_format_arg_store
  239. :members:
  240. Compatibility
  241. -------------
  242. .. doxygenclass:: fmt::basic_string_view
  243. :members:
  244. .. doxygentypedef:: fmt::string_view
  245. .. _format-api:
  246. Format API
  247. ==========
  248. ``fmt/format.h`` defines the full format API providing additional formatting
  249. functions and locale support.
  250. Literal-Based API
  251. -----------------
  252. The following user-defined literals are defined in ``fmt/format.h``.
  253. .. doxygenfunction:: operator""_a()
  254. Utilities
  255. ---------
  256. .. doxygenfunction:: fmt::ptr(T p) -> const void*
  257. .. doxygenfunction:: fmt::ptr(const std::unique_ptr<T, Deleter> &p) -> const void*
  258. .. doxygenfunction:: fmt::ptr(const std::shared_ptr<T> &p) -> const void*
  259. .. doxygenfunction:: fmt::underlying(Enum e) -> typename std::underlying_type<Enum>::type
  260. .. doxygenfunction:: fmt::to_string(const T &value) -> std::string
  261. .. doxygenfunction:: fmt::join(Range &&range, string_view sep) -> join_view<detail::iterator_t<Range>, detail::sentinel_t<Range>>
  262. .. doxygenfunction:: fmt::join(It begin, Sentinel end, string_view sep) -> join_view<It, Sentinel>
  263. .. doxygenfunction:: fmt::group_digits(T value) -> group_digits_view<T>
  264. .. doxygenclass:: fmt::detail::buffer
  265. :members:
  266. .. doxygenclass:: fmt::basic_memory_buffer
  267. :protected-members:
  268. :members:
  269. System Errors
  270. -------------
  271. {fmt} does not use ``errno`` to communicate errors to the user, but it may call
  272. system functions which set ``errno``. Users should not make any assumptions
  273. about the value of ``errno`` being preserved by library functions.
  274. .. doxygenfunction:: fmt::system_error
  275. .. doxygenfunction:: fmt::format_system_error
  276. Custom Allocators
  277. -----------------
  278. The {fmt} library supports custom dynamic memory allocators.
  279. A custom allocator class can be specified as a template argument to
  280. :class:`fmt::basic_memory_buffer`::
  281. using custom_memory_buffer =
  282. fmt::basic_memory_buffer<char, fmt::inline_buffer_size, custom_allocator>;
  283. It is also possible to write a formatting function that uses a custom
  284. allocator::
  285. using custom_string =
  286. std::basic_string<char, std::char_traits<char>, custom_allocator>;
  287. custom_string vformat(custom_allocator alloc, fmt::string_view format_str,
  288. fmt::format_args args) {
  289. auto buf = custom_memory_buffer(alloc);
  290. fmt::vformat_to(std::back_inserter(buf), format_str, args);
  291. return custom_string(buf.data(), buf.size(), alloc);
  292. }
  293. template <typename ...Args>
  294. inline custom_string format(custom_allocator alloc,
  295. fmt::string_view format_str,
  296. const Args& ... args) {
  297. return vformat(alloc, format_str, fmt::make_format_args(args...));
  298. }
  299. The allocator will be used for the output container only. Formatting functions
  300. normally don't do any allocations for built-in and string types except for
  301. non-default floating-point formatting that occasionally falls back on
  302. ``sprintf``.
  303. Locale
  304. ------
  305. All formatting is locale-independent by default. Use the ``'L'`` format
  306. specifier to insert the appropriate number separator characters from the
  307. locale::
  308. #include <fmt/core.h>
  309. #include <locale>
  310. std::locale::global(std::locale("en_US.UTF-8"));
  311. auto s = fmt::format("{:L}", 1000000); // s == "1,000,000"
  312. ``fmt/format.h`` provides the following overloads of formatting functions that
  313. take ``std::locale`` as a parameter. The locale type is a template parameter to
  314. avoid the expensive ``<locale>`` include.
  315. .. doxygenfunction:: format(const Locale& loc, format_string<T...> fmt, T&&... args) -> std::string
  316. .. doxygenfunction:: format_to(OutputIt out, const Locale& loc, format_string<T...> fmt, T&&... args) -> OutputIt
  317. .. doxygenfunction:: formatted_size(const Locale& loc, format_string<T...> fmt, T&&... args) -> size_t
  318. .. _legacy-checks:
  319. Legacy Compile-Time Format String Checks
  320. ----------------------------------------
  321. ``FMT_STRING`` enables compile-time checks on older compilers. It requires C++14
  322. or later and is a no-op in C++11.
  323. .. doxygendefine:: FMT_STRING
  324. To force the use of legacy compile-time checks, define the preprocessor variable
  325. ``FMT_ENFORCE_COMPILE_STRING``. When set, functions accepting ``FMT_STRING``
  326. will fail to compile with regular strings.
  327. .. _ranges-api:
  328. Range and Tuple Formatting
  329. ==========================
  330. The library also supports convenient formatting of ranges and tuples::
  331. #include <fmt/ranges.h>
  332. std::tuple<char, int, float> t{'a', 1, 2.0f};
  333. // Prints "('a', 1, 2.0)"
  334. fmt::print("{}", t);
  335. NOTE: currently, the overload of ``fmt::join`` for iterables exists in the main
  336. ``format.h`` header, but expect this to change in the future.
  337. Using ``fmt::join``, you can separate tuple elements with a custom separator::
  338. #include <fmt/ranges.h>
  339. std::tuple<int, char> t = {1, 'a'};
  340. // Prints "1, a"
  341. fmt::print("{}", fmt::join(t, ", "));
  342. .. _chrono-api:
  343. Date and Time Formatting
  344. ========================
  345. ``fmt/chrono.h`` provides formatters for
  346. * `std::chrono::duration <https://en.cppreference.com/w/cpp/chrono/duration>`_
  347. * `std::chrono::time_point
  348. <https://en.cppreference.com/w/cpp/chrono/time_point>`_
  349. * `std::tm <https://en.cppreference.com/w/cpp/chrono/c/tm>`_
  350. The format syntax is described in :ref:`chrono-specs`.
  351. **Example**::
  352. #include <fmt/chrono.h>
  353. int main() {
  354. std::time_t t = std::time(nullptr);
  355. // Prints "The date is 2020-11-07." (with the current date):
  356. fmt::print("The date is {:%Y-%m-%d}.", fmt::localtime(t));
  357. using namespace std::literals::chrono_literals;
  358. // Prints "Default format: 42s 100ms":
  359. fmt::print("Default format: {} {}\n", 42s, 100ms);
  360. // Prints "strftime-like format: 03:15:30":
  361. fmt::print("strftime-like format: {:%H:%M:%S}\n", 3h + 15min + 30s);
  362. }
  363. .. doxygenfunction:: localtime(std::time_t time)
  364. .. doxygenfunction:: gmtime(std::time_t time)
  365. .. _std-api:
  366. Standard Library Types Formatting
  367. =================================
  368. ``fmt/std.h`` provides formatters for:
  369. * `std::filesystem::path <https://en.cppreference.com/w/cpp/filesystem/path>`_
  370. * `std::thread::id <https://en.cppreference.com/w/cpp/thread/thread/id>`_
  371. * `std::monostate <https://en.cppreference.com/w/cpp/utility/variant/monostate>`_
  372. * `std::variant <https://en.cppreference.com/w/cpp/utility/variant/variant>`_
  373. * `std::optional <https://en.cppreference.com/w/cpp/utility/optional>`_
  374. Formatting Variants
  375. -------------------
  376. A ``std::variant`` is only formattable if every variant alternative is formattable, and requires the
  377. ``__cpp_lib_variant`` `library feature <https://en.cppreference.com/w/cpp/feature_test>`_.
  378. **Example**::
  379. #include <fmt/std.h>
  380. std::variant<char, float> v0{'x'};
  381. // Prints "variant('x')"
  382. fmt::print("{}", v0);
  383. std::variant<std::monostate, char> v1;
  384. // Prints "variant(monostate)"
  385. .. _compile-api:
  386. Format String Compilation
  387. =========================
  388. ``fmt/compile.h`` provides format string compilation enabled via the
  389. ``FMT_COMPILE`` macro or the ``_cf`` user-defined literal. Format strings
  390. marked with ``FMT_COMPILE`` or ``_cf`` are parsed, checked and converted into
  391. efficient formatting code at compile-time. This supports arguments of built-in
  392. and string types as well as user-defined types with ``format`` functions taking
  393. the format context type as a template parameter in their ``formatter``
  394. specializations. For example::
  395. template <> struct fmt::formatter<point> {
  396. constexpr auto parse(format_parse_context& ctx);
  397. template <typename FormatContext>
  398. auto format(const point& p, FormatContext& ctx) const;
  399. };
  400. Format string compilation can generate more binary code compared to the default
  401. API and is only recommended in places where formatting is a performance
  402. bottleneck.
  403. .. doxygendefine:: FMT_COMPILE
  404. .. doxygenfunction:: operator""_cf()
  405. .. _color-api:
  406. Terminal Color and Text Style
  407. =============================
  408. ``fmt/color.h`` provides support for terminal color and text style output.
  409. .. doxygenfunction:: print(const text_style &ts, const S &format_str, const Args&... args)
  410. .. doxygenfunction:: fg(detail::color_type)
  411. .. doxygenfunction:: bg(detail::color_type)
  412. .. doxygenfunction:: styled(const T& value, text_style ts)
  413. .. _os-api:
  414. System APIs
  415. ===========
  416. .. doxygenclass:: fmt::ostream
  417. :members:
  418. .. doxygenfunction:: fmt::windows_error
  419. .. _ostream-api:
  420. ``std::ostream`` Support
  421. ========================
  422. ``fmt/ostream.h`` provides ``std::ostream`` support including formatting of
  423. user-defined types that have an overloaded insertion operator (``operator<<``).
  424. In order to make a type formattable via ``std::ostream`` you should provide a
  425. ``formatter`` specialization inherited from ``ostream_formatter``::
  426. #include <fmt/ostream.h>
  427. struct date {
  428. int year, month, day;
  429. friend std::ostream& operator<<(std::ostream& os, const date& d) {
  430. return os << d.year << '-' << d.month << '-' << d.day;
  431. }
  432. };
  433. template <> struct fmt::formatter<date> : ostream_formatter {};
  434. std::string s = fmt::format("The date is {}", date{2012, 12, 9});
  435. // s == "The date is 2012-12-9"
  436. .. doxygenfunction:: streamed(const T &)
  437. .. doxygenfunction:: print(std::ostream &os, format_string<T...> fmt, T&&... args)
  438. .. _printf-api:
  439. ``printf`` Formatting
  440. =====================
  441. The header ``fmt/printf.h`` provides ``printf``-like formatting functionality.
  442. The following functions use `printf format string syntax
  443. <https://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html>`_ with
  444. the POSIX extension for positional arguments. Unlike their standard
  445. counterparts, the ``fmt`` functions are type-safe and throw an exception if an
  446. argument type doesn't match its format specification.
  447. .. doxygenfunction:: printf(string_view fmt, const T&... args) -> int
  448. .. doxygenfunction:: fprintf(std::FILE *f, const S &fmt, const T&... args) -> int
  449. .. doxygenfunction:: sprintf(const S&, const T&...)
  450. .. _xchar-api:
  451. ``wchar_t`` Support
  452. ===================
  453. The optional header ``fmt/xchar.h`` provides support for ``wchar_t`` and exotic
  454. character types.
  455. .. doxygenstruct:: fmt::is_char
  456. .. doxygentypedef:: fmt::wstring_view
  457. .. doxygentypedef:: fmt::wformat_context
  458. .. doxygenfunction:: fmt::to_wstring(const T &value)
  459. Compatibility with C++20 ``std::format``
  460. ========================================
  461. {fmt} implements nearly all of the `C++20 formatting library
  462. <https://en.cppreference.com/w/cpp/utility/format>`_ with the following
  463. differences:
  464. * Names are defined in the ``fmt`` namespace instead of ``std`` to avoid
  465. collisions with standard library implementations.
  466. * Width calculation doesn't use grapheme clusterization. The latter has been
  467. implemented in a separate branch but hasn't been integrated yet.
  468. * Most C++20 chrono types are not supported yet.