aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/_templates/layout.html2
-rw-r--r--doc/api.rst115
-rwxr-xr-xdoc/build.py2
-rw-r--r--doc/index.rst50
-rw-r--r--doc/syntax.rst17
-rw-r--r--doc/usage.rst12
6 files changed, 128 insertions, 70 deletions
diff --git a/doc/_templates/layout.html b/doc/_templates/layout.html
index ed19bcd3..d5f4b70d 100644
--- a/doc/_templates/layout.html
+++ b/doc/_templates/layout.html
@@ -84,7 +84,7 @@
<div class="jumbotron">
<div class="tb-container">
<h1>{fmt}</h1>
- <p class="lead">Small, safe and fast formatting library</p>
+ <p class="lead">A modern formatting library</p>
<div class="btn-group" role="group">
{% set name = 'fmt' if version.split('.')[0]|int >= 3 else 'cppformat' %}
<a class="btn btn-success"
diff --git a/doc/api.rst b/doc/api.rst
index b5adf4b3..0834a874 100644
--- a/doc/api.rst
+++ b/doc/api.rst
@@ -10,12 +10,14 @@ The {fmt} library API consists of the following parts:
facilities and a lightweight subset of formatting functions
* :ref:`fmt/format.h <format-api>`: the full format API providing compile-time
format string checks, output iterator and user-defined type support
+* :ref:`fmt/ranges.h <ranges-api>`: additional formatting support for ranges
+ and tuples
* :ref:`fmt/chrono.h <chrono-api>`: date and time formatting
* :ref:`fmt/ostream.h <ostream-api>`: ``std::ostream`` support
* :ref:`fmt/printf.h <printf-api>`: ``printf`` formatting
All functions and types provided by the library reside in namespace ``fmt`` and
-macros have prefix ``FMT_`` or ``fmt``.
+macros have prefix ``FMT_``.
.. _core-api:
@@ -23,7 +25,8 @@ Core API
========
``fmt/core.h`` defines the core API which provides argument handling facilities
-and a lightweight subset of formatting functions.
+and a lightweight subset of formatting functions. In the header-only mode
+include ``fmt/format.h`` instead of ``fmt/core.h``.
The following functions use :ref:`format string syntax <syntax>`
similar to that of Python's `str.format
@@ -49,7 +52,6 @@ participate in an overload resolution if the latter is not a string.
.. doxygenfunction:: print(std::FILE *, const S&, Args&&...)
.. doxygenfunction:: vprint(std::FILE *, string_view, format_args)
-.. doxygenfunction:: vprint(std::FILE *, wstring_view, wformat_args)
Named Arguments
---------------
@@ -94,8 +96,11 @@ string checks, output iterator and user-defined type support.
Compile-time Format String Checks
---------------------------------
+Compile-time checks are supported for built-in and string types as well as
+user-defined types with ``constexpr`` ``parse`` functions in their ``formatter``
+specializations.
+
.. doxygendefine:: FMT_STRING
-.. doxygendefine:: fmt
Formatting User-defined Types
-----------------------------
@@ -107,32 +112,56 @@ template and implement ``parse`` and ``format`` methods::
struct point { double x, y; };
- namespace fmt {
template <>
- struct formatter<point> {
- template <typename ParseContext>
- constexpr auto parse(ParseContext &ctx) { return ctx.begin(); }
+ struct fmt::formatter<point> {
+ // Presentation format: 'f' - fixed, 'e' - exponential.
+ char presentation = 'f';
+
+ // Parses format specifications of the form ['f' | 'e'].
+ constexpr auto parse(format_parse_context& ctx) {
+ // [ctx.begin(), ctx.end()) is a character range that contains a part of
+ // the format string starting from the format specifications to be parsed,
+ // e.g. in
+ //
+ // fmt::format("{:f} - point of interest", point{1, 2});
+ //
+ // the range will contain "f} - point of interest". The formatter should
+ // parse specifiers until '}' or the end of the range. In this example
+ // the formatter should parse the 'f' specifier and return an iterator
+ // pointing to '}'.
+
+ // Parse the presentation format and store it in the formatter:
+ auto it = ctx.begin(), end = ctx.end();
+ if (it != end && (*it == 'f' || *it == 'e')) presentation = *it++;
+
+ // Check if reached the end of the range:
+ if (it != end && *it != '}')
+ throw format_error("invalid format");
+
+ // Return an iterator past the end of the parsed range:
+ return it;
+ }
+ // Formats the point p using the parsed format specification (presentation)
+ // stored in this formatter.
template <typename FormatContext>
- auto format(const point &p, FormatContext &ctx) {
- return format_to(ctx.out(), "({:.1f}, {:.1f})", p.x, p.y);
+ auto format(const point& p, FormatContext& ctx) {
+ // ctx.out() is an output iterator to write to.
+ return format_to(
+ ctx.out(),
+ presentation == 'f' ? "({:.1f}, {:.1f})" : "({:.1e}, {:.1e})",
+ p.x, p.y);
}
};
- }
Then you can pass objects of type ``point`` to any formatting function::
point p = {1, 2};
- std::string s = fmt::format("{}", p);
+ std::string s = fmt::format("{:f}", p);
// s == "(1.0, 2.0)"
-In the example above the ``formatter<point>::parse`` function ignores the
-contents of the format string referred to by ``ctx.begin()`` so the object will
-always be formatted in the same way. See ``formatter<tm>::parse`` in
-:file:`fmt/chrono.h` for an advanced example of how to parse the format string and
-customize the formatted output.
-
-You can also reuse existing formatters, for example::
+You can also reuse existing formatters via inheritance or composition, for
+example::
enum class color {red, green, blue};
@@ -140,7 +169,7 @@ You can also reuse existing formatters, for example::
struct fmt::formatter<color>: formatter<string_view> {
// parse is inherited from formatter<string_view>.
template <typename FormatContext>
- auto format(color c, FormatContext &ctx) {
+ auto format(color c, FormatContext& ctx) {
string_view name = "unknown";
switch (c) {
case color::red: name = "red"; break;
@@ -180,6 +209,9 @@ You can also write a formatter for a hierarchy of classes::
fmt::print("{}", a); // prints "B"
}
+.. doxygenclass:: fmt::basic_format_parse_context
+ :members:
+
Output Iterator Support
-----------------------
@@ -263,7 +295,7 @@ allocator::
template <typename ...Args>
inline custom_string format(custom_allocator alloc,
fmt::string_view format_str,
- const Args & ... args) {
+ const Args& ... args) {
return vformat(alloc, format_str, fmt::make_format_args(args...));
}
@@ -278,21 +310,21 @@ Custom Formatting of Built-in Types
It is possible to change the way arguments are formatted by providing a
custom argument formatter class::
- using arg_formatter =
- fmt::arg_formatter<fmt::back_insert_range<fmt::internal::buffer>>;
+ using arg_formatter = fmt::arg_formatter<fmt::buffer_range<char>>;
// A custom argument formatter that formats negative integers as unsigned
// with the ``x`` format specifier.
class custom_arg_formatter : public arg_formatter {
public:
- custom_arg_formatter(fmt::format_context &ctx,
- fmt::format_specs *spec = nullptr)
- : arg_formatter(ctx, spec) {}
+ custom_arg_formatter(fmt::format_context& ctx,
+ fmt::format_parse_context* parse_ctx = nullptr,
+ fmt::format_specs* spec = nullptr)
+ : arg_formatter(ctx, parse_ctx, spec) {}
using arg_formatter::operator();
auto operator()(int value) {
- if (spec().type() == 'x')
+ if (specs() && specs()->type == 'x')
return (*this)(static_cast<unsigned>(value)); // convert to unsigned and format
return arg_formatter::operator()(value);
}
@@ -307,7 +339,7 @@ custom argument formatter class::
template <typename ...Args>
inline std::string custom_format(
- fmt::string_view format_str, const Args &... args) {
+ fmt::string_view format_str, const Args&... args) {
return custom_vformat(format_str, fmt::make_format_args(args...));
}
@@ -316,6 +348,31 @@ custom argument formatter class::
.. doxygenclass:: fmt::arg_formatter
:members:
+.. _ranges-api:
+
+Ranges and Tuple Formatting
+===========================
+
+The library also supports convenient formatting of ranges and tuples::
+
+ #include <fmt/ranges.h>
+
+ std::tuple<char, int, float> t{'a', 1, 2.0f};
+ // Prints "('a', 1, 2.0)"
+ fmt::print("{}", t);
+
+
+NOTE: currently, the overload of ``fmt::join`` for iterables exists in the main
+``format.h`` header, but expect this to change in the future.
+
+Using ``fmt::join``, you can separate tuple elements with a custom separator::
+
+ #include <fmt/ranges.h>
+
+ std::tuple<int, char> t = {1, 'a'};
+ // Prints "1, a"
+ fmt::print("{}", fmt::join(t, ", "));
+
.. _chrono-api:
Date and Time Formatting
@@ -349,7 +406,7 @@ user-defined types that have overloaded ``operator<<``::
public:
date(int year, int month, int day): year_(year), month_(month), day_(day) {}
- friend std::ostream &operator<<(std::ostream &os, const date &d) {
+ friend std::ostream& operator<<(std::ostream& os, const date& d) {
return os << d.year_ << '-' << d.month_ << '-' << d.day_;
}
};
diff --git a/doc/build.py b/doc/build.py
index fb4f5469..e8f5f396 100755
--- a/doc/build.py
+++ b/doc/build.py
@@ -6,7 +6,7 @@ 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', '5.0.0', '5.1.0', '5.2.0', '5.2.1', '5.3.0', '6.0.0']
+versions = ['1.0.0', '1.1.0', '2.0.0', '3.0.2', '4.0.0', '4.1.0', '5.0.0', '5.1.0', '5.2.0', '5.2.1', '5.3.0', '6.0.0', '6.1.0']
def pip_install(package, commit=None, **kwargs):
"Install package using pip."
diff --git a/doc/index.rst b/doc/index.rst
index 9480ff69..cbc9154d 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -1,17 +1,18 @@
Overview
========
-**fmt** (formerly cppformat) is an open-source formatting library.
-It can be used as a fast and safe alternative to printf and IOStreams.
+**{fmt}** is an open-source formatting library providing a fast and safe
+alternative to C stdio and C++ iostreams.
.. raw:: html
<div class="panel panel-default">
<div class="panel-heading">What users say:</div>
<div class="panel-body">
- Thanks for creating this library. It’s been a hole in C++ for a long
- time. I’ve used both boost::format and loki::SPrintf, and neither felt
- like the right answer. This does.
+ Thanks for creating this library. It’s been a hole in C++ for
+ aa long time. I’ve used both <code>boost::format</code> and
+ <code>loki::SPrintf</code>, and neither felt like the right answer.
+ This does.
</div>
</div>
@@ -20,12 +21,13 @@ It can be used as a fast and safe alternative to printf and IOStreams.
Format API
----------
-The replacement-based Format API provides a safe alternative to ``printf``,
-``sprintf`` and friends with comparable or `better performance
-<http://zverovich.net/2013/09/07/integer-to-string-conversion-in-cplusplus.html>`_.
+The format API is similar in spirit to the C ``printf`` family of function but
+is safer, simpler and serveral times `faster
+<http://zverovich.net/2013/09/07/integer-to-string-conversion-in-cplusplus.html>`_
+than common standard library implementations.
The `format string syntax <syntax.html>`_ is similar to the one used by
-`str.format <http://docs.python.org/3/library/stdtypes.html#str.format>`_
-in Python:
+`str.format <http://docs.python.org/3/library/stdtypes.html#str.format>`_ in
+Python:
.. code:: c++
@@ -60,7 +62,7 @@ The Format API also supports positional arguments useful for localization:
fmt::print("I'd rather be {1} than {0}.", "right", "happy");
Named arguments can be created with ``fmt::arg``. This makes it easier to track
-what goes where when multiple values are being inserted:
+what goes where when multiple arguments are being formatted:
.. code:: c++
@@ -72,21 +74,10 @@ an alternative, slightly terser syntax for named arguments:
.. code:: c++
+ using namespace fmt::literals;
fmt::print("Hello, {name}! The answer is {number}. Goodbye, {name}.",
"name"_a="World", "number"_a=42);
-The ``_format`` suffix may be used to format string literals similar to Python:
-
-.. code:: c++
-
- std::string message = "{0}{1}{0}"_format("abra", "cad");
-
-Other than the placement of the format string on the left of the operator,
-``_format`` is functionally identical to ``fmt::format``. In order to use the
-literal operators, they must be made visible with the directive
-``using namespace fmt::literals;``. Note that this brings in only ``_a`` and
-``_format`` but nothing else from the ``fmt`` namespace.
-
.. _safety:
Safety
@@ -106,11 +97,10 @@ string", because the argument ``"forty-two"`` is a string while the format code
.. code:: c++
- format(fmt("The answer is {:d}"), "forty-two");
+ format(FMT_STRING("The answer is {:d}"), "forty-two");
reports a compile-time error for the same reason on compilers that support
-relaxed ``constexpr``. See `here <api.html#c.fmt>`_ for how to enable
-compile-time checks.
+relaxed ``constexpr``. See `here <api.html#c.fmt>`_ for details.
The following code
@@ -178,13 +168,13 @@ The library is highly portable and relies only on a small set of C++11 features:
* alias templates
These are available since GCC 4.8, Clang 3.0 and MSVC 19.0 (2015). For older
-compilers use fmt `version 4.x
+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
-output of ``printf`` is platform-dependent in this case. For example,
+output of ``printf`` is platform-dependent. For example,
.. code::
@@ -197,9 +187,9 @@ always prints ``inf``.
Ease of Use
-----------
-fmt has a small self-contained code base with the core library consisting of
+{fmt} has a small self-contained code base with the core library consisting of
just three header files and no external dependencies.
-A permissive BSD `license <https://github.com/fmtlib/fmt#license>`_ allows
+A permissive MIT `license <https://github.com/fmtlib/fmt#license>`_ allows
using the library both in open-source and commercial projects.
.. raw:: html
diff --git a/doc/syntax.rst b/doc/syntax.rst
index a6bddf6b..1f25dacf 100644
--- a/doc/syntax.rst
+++ b/doc/syntax.rst
@@ -101,11 +101,6 @@ The meaning of the various alignment options is as follows:
| ``'>'`` | Forces the field to be right-aligned within the |
| | available space (this is the default for numbers). |
+---------+----------------------------------------------------------+
-| ``'='`` | Forces the padding to be placed after the sign (if any) |
-| | but before the digits. This is used for printing fields |
-| | in the form '+000000120'. This alignment option is only |
-| | valid for numeric types. |
-+---------+----------------------------------------------------------+
| ``'^'`` | Forces the field to be centered within the available |
| | space. |
+---------+----------------------------------------------------------+
@@ -154,9 +149,11 @@ conversions, trailing zeros are not removed from the result.
*width* is a decimal integer defining the minimum field width. If not
specified, then the field width will be determined by the content.
-Preceding the *width* field by a zero (``'0'``) character enables
-sign-aware zero-padding for numeric types. This is equivalent to a *fill*
-character of ``'0'`` with an *alignment* type of ``'='``.
+Preceding the *width* field by a zero (``'0'``) character enables sign-aware
+zero-padding for numeric types. It forces the padding to be placed after the
+sign or base (if any) but before the digits. This is used for printing fields in
+the form '+000000120'. This option is only valid for numeric types and it has no
+effect on formatting of infinity and NaN.
The *precision* is a decimal number indicating how many digits should be
displayed after the decimal point for a floating-point value formatted with
@@ -264,6 +261,10 @@ The available presentation types for floating-point values are:
| | ``'E'`` if the number gets too large. The |
| | representations of infinity and NaN are uppercased, too. |
+---------+----------------------------------------------------------+
+| ``'n'`` | Number. This is the same as ``'g'``, except that it uses |
+| | the current locale setting to insert the appropriate |
+| | number separator characters. |
++---------+----------------------------------------------------------+
| ``'%'`` | Fixed point as a percentage. This is similar to ``'f'``, |
| | but the argument is multiplied by 100 and a percent sign |
| | ``%`` is appended. |
diff --git a/doc/usage.rst b/doc/usage.rst
index e71629c5..dacb4f03 100644
--- a/doc/usage.rst
+++ b/doc/usage.rst
@@ -103,7 +103,17 @@ the previous section. Then compile the ``doc`` target/project, for example::
make doc
This will generate the HTML documentation in ``doc/html``.
-
+
+Conda
+=====
+
+fmt can be installed on Linux, macOS and Windows with
+`Conda <https://docs.conda.io/en/latest/>`__, using its
+`conda-forge <https://conda-forge.org>`__
+`package <https://github.com/conda-forge/fmt-feedstock>`__, as follows::
+
+ conda install -c conda-forge fmt
+
Android NDK
===========