diff --git a/doc/api.md b/doc/api.md
index 7b26df47..95bd258a 100644
--- a/doc/api.md
+++ b/doc/api.md
@@ -41,7 +41,7 @@ in Python. They take *fmt* and *args* as arguments.
*fmt* is a format string that contains literal text and replacement fields
surrounded by braces `{}`. The fields are replaced with formatted arguments
-in the resulting string. [`fmt::format_string`](#format_string) is a format
+in the resulting string. [`fmt::format_string`](#format_string) is a format
string which can be implicitly constructed from a string literal or a
`constexpr` string and is checked at compile time in C++20. To pass a runtime
format string wrap it in [fmt::runtime](#runtime).
@@ -434,7 +434,7 @@ variable `FMT_ENFORCE_COMPILE_STRING`. When set, functions accepting
## Range and Tuple Formatting
-The library also supports convenient formatting of ranges and tuples:
+`fmt/ranges.h` provides formatting support for ranges and tuples:
#include
@@ -453,14 +453,17 @@ Using `fmt::join`, you can separate tuple elements with a custom separator:
::: join(It, Sentinel, string_view)
+::: join(std::initializer_list, string_view)
+
## Date and Time Formatting
`fmt/chrono.h` provides formatters for
-- [std::chrono::duration](https://en.cppreference.com/w/cpp/chrono/duration)
-- [std::chrono::time_point](https://en.cppreference.com/w/cpp/chrono/time_point)
-- [std::tm](https://en.cppreference.com/w/cpp/chrono/c/tm)
+- [`std::chrono::duration`](https://en.cppreference.com/w/cpp/chrono/duration)
+- [`std::chrono::time_point`](
+ https://en.cppreference.com/w/cpp/chrono/time_point)
+- [`std::tm`](https://en.cppreference.com/w/cpp/chrono/c/tm)
The format syntax is described in [Chrono Format Specifications](syntax.md#
chrono-format-specifications).
diff --git a/doc/syntax.md b/doc/syntax.md
index 6d5ee566..f10550e6 100644
--- a/doc/syntax.md
+++ b/doc/syntax.md
@@ -1,7 +1,8 @@
# Format String Syntax
-[Formatting functions](api.md) such as `fmt::format` and [`fmt::print`](
-api.md#print) use the same format string syntax described in this section.
+[Formatting functions](api.md) such as [`fmt::format`](api.md#format) and
+[`fmt::print`]( api.md#print) use the same format string syntax described
+in this section.
Format strings contain "replacement fields" surrounded by curly braces `{}`.
Anything that is not contained in braces is considered literal text, which is
diff --git a/include/fmt/base.h b/include/fmt/base.h
index d050fb27..6b1d8140 100644
--- a/include/fmt/base.h
+++ b/include/fmt/base.h
@@ -2992,7 +2992,7 @@ FMT_API void vprintln(FILE* f, string_view fmt, format_args args);
* to `stdout`.
*
* **Example**:
- *
+ *
* fmt::print("The answer is {}.", 42);
*/
template
diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h
index aac422d1..200c0455 100644
--- a/include/fmt/chrono.h
+++ b/include/fmt/chrono.h
@@ -96,10 +96,8 @@ FMT_CONSTEXPR auto lossless_integral_conversion(const From from, int& ec)
return static_cast(from);
}
-/**
- * converts From to To, without loss. If the dynamic value of from
- * can't be converted to To without loss, ec is set.
- */
+/// Converts From to To, without loss. If the dynamic value of from
+/// can't be converted to To without loss, ec is set.
template ::value &&
std::numeric_limits::is_signed !=
@@ -187,9 +185,7 @@ FMT_CONSTEXPR auto safe_float_conversion(const From from, int& ec) -> To {
return from;
}
-/**
- * safe duration cast between integral durations
- */
+/// Safe duration cast between integral durations
template ::value),
FMT_ENABLE_IF(std::is_integral::value)>
@@ -239,9 +235,7 @@ auto safe_duration_cast(std::chrono::duration from,
return ec ? To() : To(tocount);
}
-/**
- * safe duration_cast between floating point durations
- */
+/// Safe duration_cast between floating point durations
template ::value),
FMT_ENABLE_IF(std::is_floating_point::value)>
@@ -518,9 +512,9 @@ auto to_time_t(
FMT_BEGIN_EXPORT
/**
- Converts given time since epoch as ``std::time_t`` value into calendar time,
- expressed in local time. Unlike ``std::localtime``, this function is
- thread-safe on most platforms.
+ * Converts given time since epoch as `std::time_t` value into calendar time,
+ * expressed in local time. Unlike `std::localtime`, this function is
+ * thread-safe on most platforms.
*/
inline auto localtime(std::time_t time) -> std::tm {
struct dispatcher {
@@ -567,9 +561,9 @@ inline auto localtime(std::chrono::local_time time) -> std::tm {
#endif
/**
- Converts given time since epoch as ``std::time_t`` value into calendar time,
- expressed in Coordinated Universal Time (UTC). Unlike ``std::gmtime``, this
- function is thread-safe on most platforms.
+ * Converts given time since epoch as `std::time_t` value into calendar time,
+ * expressed in Coordinated Universal Time (UTC). Unlike `std::gmtime`, this
+ * function is thread-safe on most platforms.
*/
inline auto gmtime(std::time_t time) -> std::tm {
struct dispatcher {
diff --git a/include/fmt/color.h b/include/fmt/color.h
index 5addb18e..f0e9dd94 100644
--- a/include/fmt/color.h
+++ b/include/fmt/color.h
@@ -227,7 +227,7 @@ struct color_type {
};
} // namespace detail
-/** A text style consisting of foreground and background colors and emphasis. */
+/// A text style consisting of foreground and background colors and emphasis.
class text_style {
public:
FMT_CONSTEXPR text_style(emphasis em = emphasis()) noexcept
@@ -310,13 +310,13 @@ class text_style {
emphasis ems;
};
-/** Creates a text style from the foreground (text) color. */
+/// Creates a text style from the foreground (text) color.
FMT_CONSTEXPR inline auto fg(detail::color_type foreground) noexcept
-> text_style {
return text_style(true, foreground);
}
-/** Creates a text style from the background color. */
+/// Creates a text style from the background color.
FMT_CONSTEXPR inline auto bg(detail::color_type background) noexcept
-> text_style {
return text_style(false, background);
@@ -474,15 +474,13 @@ inline void vprint(FILE* f, const text_style& ts, string_view fmt,
}
/**
- \rst
- Formats a string and prints it to the specified file stream using ANSI
- escape sequences to specify text formatting.
-
- **Example**:
-
- fmt::print(fmt::emphasis::bold | fg(fmt::color::red),
- "Elapsed time: {0:.2f} seconds", 1.23);
- \endrst
+ * Formats a string and prints it to the specified file stream using ANSI
+ * escape sequences to specify text formatting.
+ *
+ * **Example**:
+ *
+ * fmt::print(fmt::emphasis::bold | fg(fmt::color::red),
+ * "Elapsed time: {0:.2f} seconds", 1.23);
*/
template
void print(FILE* f, const text_style& ts, format_string fmt,
@@ -491,15 +489,13 @@ void print(FILE* f, const text_style& ts, format_string fmt,
}
/**
- \rst
- Formats a string and prints it to stdout using ANSI escape sequences to
- specify text formatting.
-
- **Example**:
-
- fmt::print(fmt::emphasis::bold | fg(fmt::color::red),
- "Elapsed time: {0:.2f} seconds", 1.23);
- \endrst
+ * Formats a string and prints it to stdout using ANSI escape sequences to
+ * specify text formatting.
+ *
+ * **Example**:
+ *
+ * fmt::print(fmt::emphasis::bold | fg(fmt::color::red),
+ * "Elapsed time: {0:.2f} seconds", 1.23);
*/
template
void print(const text_style& ts, format_string fmt, T&&... args) {
@@ -514,26 +510,24 @@ inline auto vformat(const text_style& ts, string_view fmt, format_args args)
}
/**
- \rst
- Formats arguments and returns the result as a string using ANSI
- escape sequences to specify text formatting.
-
- **Example**:
-
- #include
- std::string message = fmt::format(fmt::emphasis::bold | fg(fmt::color::red),
- "The answer is {}", 42);
- \endrst
-*/
+ * Formats arguments and returns the result as a string using ANSI escape
+ * sequences to specify text formatting.
+ *
+ * **Example**:
+ *
+ * ```
+ * #include
+ * std::string message = fmt::format(fmt::emphasis::bold | fg(fmt::color::red),
+ * "The answer is {}", 42);
+ * ```
+ */
template
inline auto format(const text_style& ts, format_string fmt, T&&... args)
-> std::string {
return fmt::vformat(ts, fmt, fmt::make_format_args(args...));
}
-/**
- Formats a string with the given text_style and writes the output to ``out``.
- */
+/// Formats a string with the given text_style and writes the output to `out`.
template ::value)>
auto vformat_to(OutputIt out, const text_style& ts, string_view fmt,
@@ -544,17 +538,15 @@ auto vformat_to(OutputIt out, const text_style& ts, string_view fmt,
}
/**
- \rst
- Formats arguments with the given text_style, writes the result to the output
- iterator ``out`` and returns the iterator past the end of the output range.
-
- **Example**:
-
- std::vector out;
- fmt::format_to(std::back_inserter(out),
- fmt::emphasis::bold | fg(fmt::color::red), "{}", 42);
- \endrst
-*/
+ * Formats arguments with the given text style, writes the result to the output
+ * iterator `out` and returns the iterator past the end of the output range.
+ *
+ * **Example**:
+ *
+ * std::vector out;
+ * fmt::format_to(std::back_inserter(out),
+ * fmt::emphasis::bold | fg(fmt::color::red), "{}", 42);
+ */
template ::value)>
inline auto format_to(OutputIt out, const text_style& ts,
@@ -599,16 +591,14 @@ struct formatter, Char> : formatter {
};
/**
- \rst
- Returns an argument that will be formatted using ANSI escape sequences,
- to be used in a formatting function.
-
- **Example**:
-
- fmt::print("Elapsed time: {0:.2f} seconds",
- fmt::styled(1.23, fmt::fg(fmt::color::green) |
- fmt::bg(fmt::color::blue)));
- \endrst
+ * Returns an argument that will be formatted using ANSI escape sequences,
+ * to be used in a formatting function.
+ *
+ * **Example**:
+ *
+ * fmt::print("Elapsed time: {0:.2f} seconds",
+ * fmt::styled(1.23, fmt::fg(fmt::color::green) |
+ * fmt::bg(fmt::color::blue)));
*/
template
FMT_CONSTEXPR auto styled(const T& value, text_style ts)
diff --git a/include/fmt/compile.h b/include/fmt/compile.h
index 95691b63..9f69fcbb 100644
--- a/include/fmt/compile.h
+++ b/include/fmt/compile.h
@@ -238,13 +238,12 @@ constexpr size_t parse_text(basic_string_view str, size_t pos) {
}
template
-constexpr auto compile_format_string(S format_str);
+constexpr auto compile_format_string(S fmt);
template
-constexpr auto parse_tail(T head, S format_str) {
- if constexpr (POS !=
- basic_string_view(format_str).size()) {
- constexpr auto tail = compile_format_string(format_str);
+constexpr auto parse_tail(T head, S fmt) {
+ if constexpr (POS != basic_string_view(fmt).size()) {
+ constexpr auto tail = compile_format_string(fmt);
if constexpr (std::is_same,
unknown_format>())
return tail;
@@ -315,14 +314,13 @@ struct field_type::value>> {
template
-constexpr auto parse_replacement_field_then_tail(S format_str) {
+constexpr auto parse_replacement_field_then_tail(S fmt) {
using char_type = typename S::char_type;
- constexpr auto str = basic_string_view(format_str);
+ constexpr auto str = basic_string_view(fmt);
constexpr char_type c = END_POS != str.size() ? str[END_POS] : char_type();
if constexpr (c == '}') {
return parse_tail(
- field::type, ARG_INDEX>(),
- format_str);
+ field::type, ARG_INDEX>(), fmt);
} else if constexpr (c != ':') {
FMT_THROW(format_error("expected ':'"));
} else {
@@ -335,7 +333,7 @@ constexpr auto parse_replacement_field_then_tail(S format_str) {
return parse_tail(
spec_field::type, ARG_INDEX>{
result.fmt},
- format_str);
+ fmt);
}
}
}
@@ -343,22 +341,21 @@ constexpr auto parse_replacement_field_then_tail(S format_str) {
// Compiles a non-empty format string and returns the compiled representation
// or unknown_format() on unrecognized input.
template
-constexpr auto compile_format_string(S format_str) {
+constexpr auto compile_format_string(S fmt) {
using char_type = typename S::char_type;
- constexpr auto str = basic_string_view(format_str);
+ constexpr auto str = basic_string_view(fmt);
if constexpr (str[POS] == '{') {
if constexpr (POS + 1 == str.size())
FMT_THROW(format_error("unmatched '{' in format string"));
if constexpr (str[POS + 1] == '{') {
- return parse_tail(make_text(str, POS, 1), format_str);
+ return parse_tail(make_text(str, POS, 1), fmt);
} else if constexpr (str[POS + 1] == '}' || str[POS + 1] == ':') {
static_assert(ID != manual_indexing_id,
"cannot switch from manual to automatic argument indexing");
constexpr auto next_id =
ID != manual_indexing_id ? ID + 1 : manual_indexing_id;
return parse_replacement_field_then_tail, Args,
- POS + 1, ID, next_id>(
- format_str);
+ POS + 1, ID, next_id>(fmt);
} else {
constexpr auto arg_id_result =
parse_arg_id(str.data() + POS + 1, str.data() + str.size());
@@ -374,7 +371,7 @@ constexpr auto compile_format_string(S format_str) {
return parse_replacement_field_then_tail,
Args, arg_id_end_pos,
arg_index, manual_indexing_id>(
- format_str);
+ fmt);
} else if constexpr (arg_id_result.arg_id.kind == arg_id_kind::name) {
constexpr auto arg_index =
get_arg_index_by_name(arg_id_result.arg_id.val.name, Args{});
@@ -383,11 +380,11 @@ constexpr auto compile_format_string(S format_str) {
ID != manual_indexing_id ? ID + 1 : manual_indexing_id;
return parse_replacement_field_then_tail<
decltype(get_type::value), Args, arg_id_end_pos,
- arg_index, next_id>(format_str);
+ arg_index, next_id>(fmt);
} else if constexpr (c == '}') {
return parse_tail(
runtime_named_field{arg_id_result.arg_id.val.name},
- format_str);
+ fmt);
} else if constexpr (c == ':') {
return unknown_format(); // no type info for specs parsing
}
@@ -396,29 +393,26 @@ constexpr auto compile_format_string(S format_str) {
} else if constexpr (str[POS] == '}') {
if constexpr (POS + 1 == str.size())
FMT_THROW(format_error("unmatched '}' in format string"));
- return parse_tail(make_text(str, POS, 1), format_str);
+ return parse_tail(make_text(str, POS, 1), fmt);
} else {
constexpr auto end = parse_text(str, POS + 1);
if constexpr (end - POS > 1) {
- return parse_tail(make_text(str, POS, end - POS),
- format_str);
+ return parse_tail(make_text(str, POS, end - POS), fmt);
} else {
- return parse_tail(code_unit{str[POS]},
- format_str);
+ return parse_tail(code_unit{str[POS]}, fmt);
}
}
}
template ::value)>
-constexpr auto compile(S format_str) {
- constexpr auto str = basic_string_view(format_str);
+constexpr auto compile(S fmt) {
+ constexpr auto str = basic_string_view(fmt);
if constexpr (str.size() == 0) {
return detail::make_text(str, 0, 0);
} else {
constexpr auto result =
- detail::compile_format_string, 0, 0>(
- format_str);
+ detail::compile_format_string, 0, 0>(fmt);
return result;
}
}
@@ -490,35 +484,33 @@ FMT_CONSTEXPR OutputIt format_to(OutputIt out, const S&, Args&&... args) {
template ::value)>
-auto format_to_n(OutputIt out, size_t n, const S& format_str, Args&&... args)
+auto format_to_n(OutputIt out, size_t n, const S& fmt, Args&&... args)
-> format_to_n_result {
using traits = detail::fixed_buffer_traits;
auto buf = detail::iterator_buffer(out, n);
- fmt::format_to(std::back_inserter(buf), format_str,
- std::forward(args)...);
+ fmt::format_to(std::back_inserter(buf), fmt, std::forward(args)...);
return {buf.out(), buf.count()};
}
template ::value)>
-FMT_CONSTEXPR20 auto formatted_size(const S& format_str, const Args&... args)
+FMT_CONSTEXPR20 auto formatted_size(const S& fmt, const Args&... args)
-> size_t {
- return fmt::format_to(detail::counting_iterator(), format_str, args...)
- .count();
+ return fmt::format_to(detail::counting_iterator(), fmt, args...).count();
}
template ::value)>
-void print(std::FILE* f, const S& format_str, const Args&... args) {
+void print(std::FILE* f, const S& fmt, const Args&... args) {
memory_buffer buffer;
- fmt::format_to(std::back_inserter(buffer), format_str, args...);
+ fmt::format_to(std::back_inserter(buffer), fmt, args...);
detail::print(f, {buffer.data(), buffer.size()});
}
template ::value)>
-void print(const S& format_str, const Args&... args) {
- print(stdout, format_str, args...);
+void print(const S& fmt, const Args&... args) {
+ print(stdout, fmt, args...);
}
#if FMT_USE_NONTYPE_TEMPLATE_ARGS
diff --git a/include/fmt/format.h b/include/fmt/format.h
index b43fc34a..d3e196c9 100644
--- a/include/fmt/format.h
+++ b/include/fmt/format.h
@@ -4343,7 +4343,7 @@ FMT_API auto vformat(string_view fmt, format_args args) -> std::string;
*
* #include
* std::string message = fmt::format("The answer is {}.", 42);
-*/
+ */
template
FMT_NODISCARD FMT_INLINE auto format(format_string fmt, T&&... args)
-> std::string {
diff --git a/include/fmt/os.h b/include/fmt/os.h
index 9c03b5ed..44350646 100644
--- a/include/fmt/os.h
+++ b/include/fmt/os.h
@@ -405,7 +405,8 @@ class file_buffer final : public buffer {
// occur in Xcode versions 7.2.1 and 8.2.1.
constexpr detail::buffer_size buffer_size{};
-/** A fast output stream which is not thread-safe. */
+/// A fast output stream for writing from a single thread. Writing from
+/// multiple threads without external synchronization may result in a data race.
class FMT_API ostream {
private:
FMT_MSC_WARNING(suppress : 4251)
@@ -426,10 +427,8 @@ class FMT_API ostream {
void close() { buffer_.close(); }
- /**
- Formats ``args`` according to specifications in ``fmt`` and writes the
- output to the file.
- */
+ /// Formats `args` according to specifications in `fmt` and writes the
+ /// output to the file.
template void print(format_string fmt, T&&... args) {
vformat_to(appender(buffer_), fmt, fmt::make_format_args(args...));
}
diff --git a/include/fmt/ranges.h b/include/fmt/ranges.h
index a3fb6b62..49eede2a 100644
--- a/include/fmt/ranges.h
+++ b/include/fmt/ranges.h
@@ -668,9 +668,9 @@ auto join(It begin, Sentinel end, string_view sep) -> join_view {
/**
* Returns a view that formats `range` with elements separated by `sep`.
*
- * **Example**:
+ * **Example**:
*
- * std::vector v = {1, 2, 3};
+ * auto v = std::vector{1, 2, 3};
* fmt::print("{}", fmt::join(v, ", "));
* // Output: 1, 2, 3
*
@@ -802,15 +802,13 @@ struct formatter<
FMT_BEGIN_EXPORT
/**
- \rst
- Returns an object that formats `tuple` with elements separated by `sep`.
-
- **Example**:
-
- std::tuple t = {1, 'a'};
- fmt::print("{}", fmt::join(t, ", "));
- // Output: "1, a"
- \endrst
+ * Returns an object that formats `std::tuple` with elements separated by `sep`.
+ *
+ * **Example**:
+ *
+ * auto t = std::tuple{1, 'a'};
+ * fmt::print("{}", fmt::join(t, ", "));
+ * // Output: 1, a
*/
template
FMT_CONSTEXPR auto join(const std::tuple& tuple, string_view sep)
@@ -819,15 +817,13 @@ FMT_CONSTEXPR auto join(const std::tuple& tuple, string_view sep)
}
/**
- \rst
- Returns an object that formats `initializer_list` with elements separated by
- `sep`.
-
- **Example**:
-
- fmt::print("{}", fmt::join({1, 2, 3}, ", "));
- // Output: "1, 2, 3"
- \endrst
+ * Returns an object that formats `std::initializer_list` with elements
+ * separated by `sep`.
+ *
+ * **Example**:
+ *
+ * fmt::print("{}", fmt::join({1, 2, 3}, ", "));
+ * // Output: "1, 2, 3"
*/
template
auto join(std::initializer_list list, string_view sep)
diff --git a/support/mkdocstrings_handlers/cxx/__init__.py b/support/mkdocstrings_handlers/cxx/__init__.py
index 0420291f..c538456b 100644
--- a/support/mkdocstrings_handlers/cxx/__init__.py
+++ b/support/mkdocstrings_handlers/cxx/__init__.py
@@ -10,10 +10,11 @@ from subprocess import CalledProcessError, PIPE, Popen, STDOUT
class Definition:
'''A definition extracted by Doxygen.'''
def __init__(self, name: str, kind: Optional[str] = None,
- node: Optional[et.Element] = None):
+ node: Optional[et.Element] = None,
+ is_member: bool = False):
self.name = name
self.kind = kind if kind is not None else node.get('kind')
- self.id = node.get('id') if node is not None else None
+ self.id = name if not is_member else None
self.params = None
self.members = None
@@ -225,7 +226,7 @@ class CxxHandler(BaseHandler):
if len(desc) == 0:
continue
kind = m.get('kind')
- member = Definition(name if name else '', kind)
+ member = Definition(name if name else '', kind=kind, is_member=True)
type = m.find('type').text
member.type = type if type else ''
if kind == 'function':
@@ -274,9 +275,9 @@ class CxxHandler(BaseHandler):
elif d.kind == 'define':
params = []
for p in node.findall('param'):
- d = Definition(p.find('defname').text, 'param')
- d.type = None
- params.append(d)
+ param = Definition(p.find('defname').text, kind='param')
+ param.type = None
+ params.append(param)
d.type = convert_type(node.find('type'))
d.template_params = convert_template_params(node)
d.params = params