From ab29ef37d9b973579ec9e8d889044d9d1c38e0f8 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sun, 2 Jun 2024 13:17:04 -0700 Subject: [PATCH] Migrate docs and cleanup --- doc/api.md | 13 ++- doc/syntax.md | 5 +- include/fmt/base.h | 2 +- include/fmt/chrono.h | 26 ++--- include/fmt/color.h | 102 ++++++++---------- include/fmt/compile.h | 66 +++++------- include/fmt/format.h | 2 +- include/fmt/os.h | 9 +- include/fmt/ranges.h | 36 +++---- support/mkdocstrings_handlers/cxx/__init__.py | 13 +-- 10 files changed, 125 insertions(+), 149 deletions(-) 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