mirror of
https://github.com/fmtlib/fmt.git
synced 2025-02-06 21:40:54 +00:00
Migrate docs and cleanup
This commit is contained in:
parent
97117cbb51
commit
ab29ef37d9
11
doc/api.md
11
doc/api.md
@ -434,7 +434,7 @@ variable `FMT_ENFORCE_COMPILE_STRING`. When set, functions accepting
|
|||||||
<a id="ranges-api"></a>
|
<a id="ranges-api"></a>
|
||||||
## Range and Tuple Formatting
|
## 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 <fmt/ranges.h>
|
#include <fmt/ranges.h>
|
||||||
|
|
||||||
@ -453,14 +453,17 @@ Using `fmt::join`, you can separate tuple elements with a custom separator:
|
|||||||
|
|
||||||
::: join(It, Sentinel, string_view)
|
::: join(It, Sentinel, string_view)
|
||||||
|
|
||||||
|
::: join(std::initializer_list<T>, string_view)
|
||||||
|
|
||||||
<a id="chrono-api"></a>
|
<a id="chrono-api"></a>
|
||||||
## Date and Time Formatting
|
## Date and Time Formatting
|
||||||
|
|
||||||
`fmt/chrono.h` provides formatters for
|
`fmt/chrono.h` provides formatters for
|
||||||
|
|
||||||
- [std::chrono::duration](https://en.cppreference.com/w/cpp/chrono/duration)
|
- [`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::chrono::time_point`](
|
||||||
- [std::tm](https://en.cppreference.com/w/cpp/chrono/c/tm)
|
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#
|
The format syntax is described in [Chrono Format Specifications](syntax.md#
|
||||||
chrono-format-specifications).
|
chrono-format-specifications).
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
# Format String Syntax
|
# Format String Syntax
|
||||||
|
|
||||||
[Formatting functions](api.md) such as `fmt::format` and [`fmt::print`](
|
[Formatting functions](api.md) such as [`fmt::format`](api.md#format) and
|
||||||
api.md#print) use the same format string syntax described in this section.
|
[`fmt::print`]( api.md#print) use the same format string syntax described
|
||||||
|
in this section.
|
||||||
|
|
||||||
Format strings contain "replacement fields" surrounded by curly braces `{}`.
|
Format strings contain "replacement fields" surrounded by curly braces `{}`.
|
||||||
Anything that is not contained in braces is considered literal text, which is
|
Anything that is not contained in braces is considered literal text, which is
|
||||||
|
@ -96,10 +96,8 @@ FMT_CONSTEXPR auto lossless_integral_conversion(const From from, int& ec)
|
|||||||
return static_cast<To>(from);
|
return static_cast<To>(from);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Converts From to To, without loss. If the dynamic value of from
|
||||||
* converts From to To, without loss. If the dynamic value of from
|
/// can't be converted to To without loss, ec is set.
|
||||||
* can't be converted to To without loss, ec is set.
|
|
||||||
*/
|
|
||||||
template <typename To, typename From,
|
template <typename To, typename From,
|
||||||
FMT_ENABLE_IF(!std::is_same<From, To>::value &&
|
FMT_ENABLE_IF(!std::is_same<From, To>::value &&
|
||||||
std::numeric_limits<From>::is_signed !=
|
std::numeric_limits<From>::is_signed !=
|
||||||
@ -187,9 +185,7 @@ FMT_CONSTEXPR auto safe_float_conversion(const From from, int& ec) -> To {
|
|||||||
return from;
|
return from;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Safe duration cast between integral durations
|
||||||
* safe duration cast between integral durations
|
|
||||||
*/
|
|
||||||
template <typename To, typename FromRep, typename FromPeriod,
|
template <typename To, typename FromRep, typename FromPeriod,
|
||||||
FMT_ENABLE_IF(std::is_integral<FromRep>::value),
|
FMT_ENABLE_IF(std::is_integral<FromRep>::value),
|
||||||
FMT_ENABLE_IF(std::is_integral<typename To::rep>::value)>
|
FMT_ENABLE_IF(std::is_integral<typename To::rep>::value)>
|
||||||
@ -239,9 +235,7 @@ auto safe_duration_cast(std::chrono::duration<FromRep, FromPeriod> from,
|
|||||||
return ec ? To() : To(tocount);
|
return ec ? To() : To(tocount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Safe duration_cast between floating point durations
|
||||||
* safe duration_cast between floating point durations
|
|
||||||
*/
|
|
||||||
template <typename To, typename FromRep, typename FromPeriod,
|
template <typename To, typename FromRep, typename FromPeriod,
|
||||||
FMT_ENABLE_IF(std::is_floating_point<FromRep>::value),
|
FMT_ENABLE_IF(std::is_floating_point<FromRep>::value),
|
||||||
FMT_ENABLE_IF(std::is_floating_point<typename To::rep>::value)>
|
FMT_ENABLE_IF(std::is_floating_point<typename To::rep>::value)>
|
||||||
@ -518,9 +512,9 @@ auto to_time_t(
|
|||||||
FMT_BEGIN_EXPORT
|
FMT_BEGIN_EXPORT
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Converts given time since epoch as ``std::time_t`` value into calendar time,
|
* Converts given time since epoch as `std::time_t` value into calendar time,
|
||||||
expressed in local time. Unlike ``std::localtime``, this function is
|
* expressed in local time. Unlike `std::localtime`, this function is
|
||||||
thread-safe on most platforms.
|
* thread-safe on most platforms.
|
||||||
*/
|
*/
|
||||||
inline auto localtime(std::time_t time) -> std::tm {
|
inline auto localtime(std::time_t time) -> std::tm {
|
||||||
struct dispatcher {
|
struct dispatcher {
|
||||||
@ -567,9 +561,9 @@ inline auto localtime(std::chrono::local_time<Duration> time) -> std::tm {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Converts given time since epoch as ``std::time_t`` value into calendar time,
|
* Converts given time since epoch as `std::time_t` value into calendar time,
|
||||||
expressed in Coordinated Universal Time (UTC). Unlike ``std::gmtime``, this
|
* expressed in Coordinated Universal Time (UTC). Unlike `std::gmtime`, this
|
||||||
function is thread-safe on most platforms.
|
* function is thread-safe on most platforms.
|
||||||
*/
|
*/
|
||||||
inline auto gmtime(std::time_t time) -> std::tm {
|
inline auto gmtime(std::time_t time) -> std::tm {
|
||||||
struct dispatcher {
|
struct dispatcher {
|
||||||
|
@ -227,7 +227,7 @@ struct color_type {
|
|||||||
};
|
};
|
||||||
} // namespace detail
|
} // 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 {
|
class text_style {
|
||||||
public:
|
public:
|
||||||
FMT_CONSTEXPR text_style(emphasis em = emphasis()) noexcept
|
FMT_CONSTEXPR text_style(emphasis em = emphasis()) noexcept
|
||||||
@ -310,13 +310,13 @@ class text_style {
|
|||||||
emphasis ems;
|
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
|
FMT_CONSTEXPR inline auto fg(detail::color_type foreground) noexcept
|
||||||
-> text_style {
|
-> text_style {
|
||||||
return text_style(true, foreground);
|
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
|
FMT_CONSTEXPR inline auto bg(detail::color_type background) noexcept
|
||||||
-> text_style {
|
-> text_style {
|
||||||
return text_style(false, background);
|
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
|
||||||
Formats a string and prints it to the specified file stream using ANSI
|
* escape sequences to specify text formatting.
|
||||||
escape sequences to specify text formatting.
|
*
|
||||||
|
* **Example**:
|
||||||
**Example**:
|
*
|
||||||
|
* fmt::print(fmt::emphasis::bold | fg(fmt::color::red),
|
||||||
fmt::print(fmt::emphasis::bold | fg(fmt::color::red),
|
* "Elapsed time: {0:.2f} seconds", 1.23);
|
||||||
"Elapsed time: {0:.2f} seconds", 1.23);
|
|
||||||
\endrst
|
|
||||||
*/
|
*/
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
void print(FILE* f, const text_style& ts, format_string<T...> fmt,
|
void print(FILE* f, const text_style& ts, format_string<T...> fmt,
|
||||||
@ -491,15 +489,13 @@ void print(FILE* f, const text_style& ts, format_string<T...> fmt,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\rst
|
* Formats a string and prints it to stdout using ANSI escape sequences to
|
||||||
Formats a string and prints it to stdout using ANSI escape sequences to
|
* specify text formatting.
|
||||||
specify text formatting.
|
*
|
||||||
|
* **Example**:
|
||||||
**Example**:
|
*
|
||||||
|
* fmt::print(fmt::emphasis::bold | fg(fmt::color::red),
|
||||||
fmt::print(fmt::emphasis::bold | fg(fmt::color::red),
|
* "Elapsed time: {0:.2f} seconds", 1.23);
|
||||||
"Elapsed time: {0:.2f} seconds", 1.23);
|
|
||||||
\endrst
|
|
||||||
*/
|
*/
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
void print(const text_style& ts, format_string<T...> fmt, T&&... args) {
|
void print(const text_style& ts, format_string<T...> 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
|
||||||
Formats arguments and returns the result as a string using ANSI
|
* sequences to specify text formatting.
|
||||||
escape sequences to specify text formatting.
|
*
|
||||||
|
* **Example**:
|
||||||
**Example**:
|
*
|
||||||
|
* ```
|
||||||
#include <fmt/color.h>
|
* #include <fmt/color.h>
|
||||||
std::string message = fmt::format(fmt::emphasis::bold | fg(fmt::color::red),
|
* std::string message = fmt::format(fmt::emphasis::bold | fg(fmt::color::red),
|
||||||
"The answer is {}", 42);
|
* "The answer is {}", 42);
|
||||||
\endrst
|
* ```
|
||||||
*/
|
*/
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
inline auto format(const text_style& ts, format_string<T...> fmt, T&&... args)
|
inline auto format(const text_style& ts, format_string<T...> fmt, T&&... args)
|
||||||
-> std::string {
|
-> std::string {
|
||||||
return fmt::vformat(ts, fmt, fmt::make_format_args(args...));
|
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 <typename OutputIt,
|
template <typename OutputIt,
|
||||||
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
|
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
|
||||||
auto vformat_to(OutputIt out, const text_style& ts, string_view fmt,
|
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
|
||||||
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.
|
||||||
iterator ``out`` and returns the iterator past the end of the output range.
|
*
|
||||||
|
* **Example**:
|
||||||
**Example**:
|
*
|
||||||
|
* std::vector<char> out;
|
||||||
std::vector<char> out;
|
* fmt::format_to(std::back_inserter(out),
|
||||||
fmt::format_to(std::back_inserter(out),
|
* fmt::emphasis::bold | fg(fmt::color::red), "{}", 42);
|
||||||
fmt::emphasis::bold | fg(fmt::color::red), "{}", 42);
|
*/
|
||||||
\endrst
|
|
||||||
*/
|
|
||||||
template <typename OutputIt, typename... T,
|
template <typename OutputIt, typename... T,
|
||||||
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
|
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
|
||||||
inline auto format_to(OutputIt out, const text_style& ts,
|
inline auto format_to(OutputIt out, const text_style& ts,
|
||||||
@ -599,16 +591,14 @@ struct formatter<detail::styled_arg<T>, Char> : formatter<T, Char> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\rst
|
* Returns an argument that will be formatted using ANSI escape sequences,
|
||||||
Returns an argument that will be formatted using ANSI escape sequences,
|
* to be used in a formatting function.
|
||||||
to be used in a formatting function.
|
*
|
||||||
|
* **Example**:
|
||||||
**Example**:
|
*
|
||||||
|
* fmt::print("Elapsed time: {0:.2f} seconds",
|
||||||
fmt::print("Elapsed time: {0:.2f} seconds",
|
* fmt::styled(1.23, fmt::fg(fmt::color::green) |
|
||||||
fmt::styled(1.23, fmt::fg(fmt::color::green) |
|
* fmt::bg(fmt::color::blue)));
|
||||||
fmt::bg(fmt::color::blue)));
|
|
||||||
\endrst
|
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
FMT_CONSTEXPR auto styled(const T& value, text_style ts)
|
FMT_CONSTEXPR auto styled(const T& value, text_style ts)
|
||||||
|
@ -238,13 +238,12 @@ constexpr size_t parse_text(basic_string_view<Char> str, size_t pos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename Args, size_t POS, int ID, typename S>
|
template <typename Args, size_t POS, int ID, typename S>
|
||||||
constexpr auto compile_format_string(S format_str);
|
constexpr auto compile_format_string(S fmt);
|
||||||
|
|
||||||
template <typename Args, size_t POS, int ID, typename T, typename S>
|
template <typename Args, size_t POS, int ID, typename T, typename S>
|
||||||
constexpr auto parse_tail(T head, S format_str) {
|
constexpr auto parse_tail(T head, S fmt) {
|
||||||
if constexpr (POS !=
|
if constexpr (POS != basic_string_view<typename S::char_type>(fmt).size()) {
|
||||||
basic_string_view<typename S::char_type>(format_str).size()) {
|
constexpr auto tail = compile_format_string<Args, POS, ID>(fmt);
|
||||||
constexpr auto tail = compile_format_string<Args, POS, ID>(format_str);
|
|
||||||
if constexpr (std::is_same<remove_cvref_t<decltype(tail)>,
|
if constexpr (std::is_same<remove_cvref_t<decltype(tail)>,
|
||||||
unknown_format>())
|
unknown_format>())
|
||||||
return tail;
|
return tail;
|
||||||
@ -315,14 +314,13 @@ struct field_type<T, enable_if_t<detail::is_named_arg<T>::value>> {
|
|||||||
|
|
||||||
template <typename T, typename Args, size_t END_POS, int ARG_INDEX, int NEXT_ID,
|
template <typename T, typename Args, size_t END_POS, int ARG_INDEX, int NEXT_ID,
|
||||||
typename S>
|
typename S>
|
||||||
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;
|
using char_type = typename S::char_type;
|
||||||
constexpr auto str = basic_string_view<char_type>(format_str);
|
constexpr auto str = basic_string_view<char_type>(fmt);
|
||||||
constexpr char_type c = END_POS != str.size() ? str[END_POS] : char_type();
|
constexpr char_type c = END_POS != str.size() ? str[END_POS] : char_type();
|
||||||
if constexpr (c == '}') {
|
if constexpr (c == '}') {
|
||||||
return parse_tail<Args, END_POS + 1, NEXT_ID>(
|
return parse_tail<Args, END_POS + 1, NEXT_ID>(
|
||||||
field<char_type, typename field_type<T>::type, ARG_INDEX>(),
|
field<char_type, typename field_type<T>::type, ARG_INDEX>(), fmt);
|
||||||
format_str);
|
|
||||||
} else if constexpr (c != ':') {
|
} else if constexpr (c != ':') {
|
||||||
FMT_THROW(format_error("expected ':'"));
|
FMT_THROW(format_error("expected ':'"));
|
||||||
} else {
|
} else {
|
||||||
@ -335,7 +333,7 @@ constexpr auto parse_replacement_field_then_tail(S format_str) {
|
|||||||
return parse_tail<Args, result.end + 1, result.next_arg_id>(
|
return parse_tail<Args, result.end + 1, result.next_arg_id>(
|
||||||
spec_field<char_type, typename field_type<T>::type, ARG_INDEX>{
|
spec_field<char_type, typename field_type<T>::type, ARG_INDEX>{
|
||||||
result.fmt},
|
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
|
// Compiles a non-empty format string and returns the compiled representation
|
||||||
// or unknown_format() on unrecognized input.
|
// or unknown_format() on unrecognized input.
|
||||||
template <typename Args, size_t POS, int ID, typename S>
|
template <typename Args, size_t POS, int ID, typename S>
|
||||||
constexpr auto compile_format_string(S format_str) {
|
constexpr auto compile_format_string(S fmt) {
|
||||||
using char_type = typename S::char_type;
|
using char_type = typename S::char_type;
|
||||||
constexpr auto str = basic_string_view<char_type>(format_str);
|
constexpr auto str = basic_string_view<char_type>(fmt);
|
||||||
if constexpr (str[POS] == '{') {
|
if constexpr (str[POS] == '{') {
|
||||||
if constexpr (POS + 1 == str.size())
|
if constexpr (POS + 1 == str.size())
|
||||||
FMT_THROW(format_error("unmatched '{' in format string"));
|
FMT_THROW(format_error("unmatched '{' in format string"));
|
||||||
if constexpr (str[POS + 1] == '{') {
|
if constexpr (str[POS + 1] == '{') {
|
||||||
return parse_tail<Args, POS + 2, ID>(make_text(str, POS, 1), format_str);
|
return parse_tail<Args, POS + 2, ID>(make_text(str, POS, 1), fmt);
|
||||||
} else if constexpr (str[POS + 1] == '}' || str[POS + 1] == ':') {
|
} else if constexpr (str[POS + 1] == '}' || str[POS + 1] == ':') {
|
||||||
static_assert(ID != manual_indexing_id,
|
static_assert(ID != manual_indexing_id,
|
||||||
"cannot switch from manual to automatic argument indexing");
|
"cannot switch from manual to automatic argument indexing");
|
||||||
constexpr auto next_id =
|
constexpr auto next_id =
|
||||||
ID != manual_indexing_id ? ID + 1 : manual_indexing_id;
|
ID != manual_indexing_id ? ID + 1 : manual_indexing_id;
|
||||||
return parse_replacement_field_then_tail<get_type<ID, Args>, Args,
|
return parse_replacement_field_then_tail<get_type<ID, Args>, Args,
|
||||||
POS + 1, ID, next_id>(
|
POS + 1, ID, next_id>(fmt);
|
||||||
format_str);
|
|
||||||
} else {
|
} else {
|
||||||
constexpr auto arg_id_result =
|
constexpr auto arg_id_result =
|
||||||
parse_arg_id<ID>(str.data() + POS + 1, str.data() + str.size());
|
parse_arg_id<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<get_type<arg_index, Args>,
|
return parse_replacement_field_then_tail<get_type<arg_index, Args>,
|
||||||
Args, arg_id_end_pos,
|
Args, arg_id_end_pos,
|
||||||
arg_index, manual_indexing_id>(
|
arg_index, manual_indexing_id>(
|
||||||
format_str);
|
fmt);
|
||||||
} else if constexpr (arg_id_result.arg_id.kind == arg_id_kind::name) {
|
} else if constexpr (arg_id_result.arg_id.kind == arg_id_kind::name) {
|
||||||
constexpr auto arg_index =
|
constexpr auto arg_index =
|
||||||
get_arg_index_by_name(arg_id_result.arg_id.val.name, Args{});
|
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;
|
ID != manual_indexing_id ? ID + 1 : manual_indexing_id;
|
||||||
return parse_replacement_field_then_tail<
|
return parse_replacement_field_then_tail<
|
||||||
decltype(get_type<arg_index, Args>::value), Args, arg_id_end_pos,
|
decltype(get_type<arg_index, Args>::value), Args, arg_id_end_pos,
|
||||||
arg_index, next_id>(format_str);
|
arg_index, next_id>(fmt);
|
||||||
} else if constexpr (c == '}') {
|
} else if constexpr (c == '}') {
|
||||||
return parse_tail<Args, arg_id_end_pos + 1, ID>(
|
return parse_tail<Args, arg_id_end_pos + 1, ID>(
|
||||||
runtime_named_field<char_type>{arg_id_result.arg_id.val.name},
|
runtime_named_field<char_type>{arg_id_result.arg_id.val.name},
|
||||||
format_str);
|
fmt);
|
||||||
} else if constexpr (c == ':') {
|
} else if constexpr (c == ':') {
|
||||||
return unknown_format(); // no type info for specs parsing
|
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] == '}') {
|
} else if constexpr (str[POS] == '}') {
|
||||||
if constexpr (POS + 1 == str.size())
|
if constexpr (POS + 1 == str.size())
|
||||||
FMT_THROW(format_error("unmatched '}' in format string"));
|
FMT_THROW(format_error("unmatched '}' in format string"));
|
||||||
return parse_tail<Args, POS + 2, ID>(make_text(str, POS, 1), format_str);
|
return parse_tail<Args, POS + 2, ID>(make_text(str, POS, 1), fmt);
|
||||||
} else {
|
} else {
|
||||||
constexpr auto end = parse_text(str, POS + 1);
|
constexpr auto end = parse_text(str, POS + 1);
|
||||||
if constexpr (end - POS > 1) {
|
if constexpr (end - POS > 1) {
|
||||||
return parse_tail<Args, end, ID>(make_text(str, POS, end - POS),
|
return parse_tail<Args, end, ID>(make_text(str, POS, end - POS), fmt);
|
||||||
format_str);
|
|
||||||
} else {
|
} else {
|
||||||
return parse_tail<Args, end, ID>(code_unit<char_type>{str[POS]},
|
return parse_tail<Args, end, ID>(code_unit<char_type>{str[POS]}, fmt);
|
||||||
format_str);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Args, typename S,
|
template <typename... Args, typename S,
|
||||||
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
|
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
|
||||||
constexpr auto compile(S format_str) {
|
constexpr auto compile(S fmt) {
|
||||||
constexpr auto str = basic_string_view<typename S::char_type>(format_str);
|
constexpr auto str = basic_string_view<typename S::char_type>(fmt);
|
||||||
if constexpr (str.size() == 0) {
|
if constexpr (str.size() == 0) {
|
||||||
return detail::make_text(str, 0, 0);
|
return detail::make_text(str, 0, 0);
|
||||||
} else {
|
} else {
|
||||||
constexpr auto result =
|
constexpr auto result =
|
||||||
detail::compile_format_string<detail::type_list<Args...>, 0, 0>(
|
detail::compile_format_string<detail::type_list<Args...>, 0, 0>(fmt);
|
||||||
format_str);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -490,35 +484,33 @@ FMT_CONSTEXPR OutputIt format_to(OutputIt out, const S&, Args&&... args) {
|
|||||||
|
|
||||||
template <typename OutputIt, typename S, typename... Args,
|
template <typename OutputIt, typename S, typename... Args,
|
||||||
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
|
FMT_ENABLE_IF(detail::is_compiled_string<S>::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<OutputIt> {
|
-> format_to_n_result<OutputIt> {
|
||||||
using traits = detail::fixed_buffer_traits;
|
using traits = detail::fixed_buffer_traits;
|
||||||
auto buf = detail::iterator_buffer<OutputIt, char, traits>(out, n);
|
auto buf = detail::iterator_buffer<OutputIt, char, traits>(out, n);
|
||||||
fmt::format_to(std::back_inserter(buf), format_str,
|
fmt::format_to(std::back_inserter(buf), fmt, std::forward<Args>(args)...);
|
||||||
std::forward<Args>(args)...);
|
|
||||||
return {buf.out(), buf.count()};
|
return {buf.out(), buf.count()};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename S, typename... Args,
|
template <typename S, typename... Args,
|
||||||
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
|
FMT_ENABLE_IF(detail::is_compiled_string<S>::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 {
|
-> size_t {
|
||||||
return fmt::format_to(detail::counting_iterator(), format_str, args...)
|
return fmt::format_to(detail::counting_iterator(), fmt, args...).count();
|
||||||
.count();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename S, typename... Args,
|
template <typename S, typename... Args,
|
||||||
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
|
FMT_ENABLE_IF(detail::is_compiled_string<S>::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;
|
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()});
|
detail::print(f, {buffer.data(), buffer.size()});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename S, typename... Args,
|
template <typename S, typename... Args,
|
||||||
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
|
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
|
||||||
void print(const S& format_str, const Args&... args) {
|
void print(const S& fmt, const Args&... args) {
|
||||||
print(stdout, format_str, args...);
|
print(stdout, fmt, args...);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if FMT_USE_NONTYPE_TEMPLATE_ARGS
|
#if FMT_USE_NONTYPE_TEMPLATE_ARGS
|
||||||
|
@ -4343,7 +4343,7 @@ FMT_API auto vformat(string_view fmt, format_args args) -> std::string;
|
|||||||
*
|
*
|
||||||
* #include <fmt/format.h>
|
* #include <fmt/format.h>
|
||||||
* std::string message = fmt::format("The answer is {}.", 42);
|
* std::string message = fmt::format("The answer is {}.", 42);
|
||||||
*/
|
*/
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
FMT_NODISCARD FMT_INLINE auto format(format_string<T...> fmt, T&&... args)
|
FMT_NODISCARD FMT_INLINE auto format(format_string<T...> fmt, T&&... args)
|
||||||
-> std::string {
|
-> std::string {
|
||||||
|
@ -405,7 +405,8 @@ class file_buffer final : public buffer<char> {
|
|||||||
// occur in Xcode versions 7.2.1 and 8.2.1.
|
// occur in Xcode versions 7.2.1 and 8.2.1.
|
||||||
constexpr detail::buffer_size buffer_size{};
|
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 {
|
class FMT_API ostream {
|
||||||
private:
|
private:
|
||||||
FMT_MSC_WARNING(suppress : 4251)
|
FMT_MSC_WARNING(suppress : 4251)
|
||||||
@ -426,10 +427,8 @@ class FMT_API ostream {
|
|||||||
|
|
||||||
void close() { buffer_.close(); }
|
void close() { buffer_.close(); }
|
||||||
|
|
||||||
/**
|
/// Formats `args` according to specifications in `fmt` and writes the
|
||||||
Formats ``args`` according to specifications in ``fmt`` and writes the
|
/// output to the file.
|
||||||
output to the file.
|
|
||||||
*/
|
|
||||||
template <typename... T> void print(format_string<T...> fmt, T&&... args) {
|
template <typename... T> void print(format_string<T...> fmt, T&&... args) {
|
||||||
vformat_to(appender(buffer_), fmt, fmt::make_format_args(args...));
|
vformat_to(appender(buffer_), fmt, fmt::make_format_args(args...));
|
||||||
}
|
}
|
||||||
|
@ -670,7 +670,7 @@ auto join(It begin, Sentinel end, string_view sep) -> join_view<It, Sentinel> {
|
|||||||
*
|
*
|
||||||
* **Example**:
|
* **Example**:
|
||||||
*
|
*
|
||||||
* std::vector<int> v = {1, 2, 3};
|
* auto v = std::vector<int>{1, 2, 3};
|
||||||
* fmt::print("{}", fmt::join(v, ", "));
|
* fmt::print("{}", fmt::join(v, ", "));
|
||||||
* // Output: 1, 2, 3
|
* // Output: 1, 2, 3
|
||||||
*
|
*
|
||||||
@ -802,15 +802,13 @@ struct formatter<
|
|||||||
FMT_BEGIN_EXPORT
|
FMT_BEGIN_EXPORT
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\rst
|
* Returns an object that formats `std::tuple` with elements separated by `sep`.
|
||||||
Returns an object that formats `tuple` with elements separated by `sep`.
|
*
|
||||||
|
* **Example**:
|
||||||
**Example**:
|
*
|
||||||
|
* auto t = std::tuple<int, char>{1, 'a'};
|
||||||
std::tuple<int, char> t = {1, 'a'};
|
* fmt::print("{}", fmt::join(t, ", "));
|
||||||
fmt::print("{}", fmt::join(t, ", "));
|
* // Output: 1, a
|
||||||
// Output: "1, a"
|
|
||||||
\endrst
|
|
||||||
*/
|
*/
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
FMT_CONSTEXPR auto join(const std::tuple<T...>& tuple, string_view sep)
|
FMT_CONSTEXPR auto join(const std::tuple<T...>& tuple, string_view sep)
|
||||||
@ -819,15 +817,13 @@ FMT_CONSTEXPR auto join(const std::tuple<T...>& tuple, string_view sep)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\rst
|
* Returns an object that formats `std::initializer_list` with elements
|
||||||
Returns an object that formats `initializer_list` with elements separated by
|
* separated by `sep`.
|
||||||
`sep`.
|
*
|
||||||
|
* **Example**:
|
||||||
**Example**:
|
*
|
||||||
|
* fmt::print("{}", fmt::join({1, 2, 3}, ", "));
|
||||||
fmt::print("{}", fmt::join({1, 2, 3}, ", "));
|
* // Output: "1, 2, 3"
|
||||||
// Output: "1, 2, 3"
|
|
||||||
\endrst
|
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
auto join(std::initializer_list<T> list, string_view sep)
|
auto join(std::initializer_list<T> list, string_view sep)
|
||||||
|
@ -10,10 +10,11 @@ from subprocess import CalledProcessError, PIPE, Popen, STDOUT
|
|||||||
class Definition:
|
class Definition:
|
||||||
'''A definition extracted by Doxygen.'''
|
'''A definition extracted by Doxygen.'''
|
||||||
def __init__(self, name: str, kind: Optional[str] = None,
|
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.name = name
|
||||||
self.kind = kind if kind is not None else node.get('kind')
|
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.params = None
|
||||||
self.members = None
|
self.members = None
|
||||||
|
|
||||||
@ -225,7 +226,7 @@ class CxxHandler(BaseHandler):
|
|||||||
if len(desc) == 0:
|
if len(desc) == 0:
|
||||||
continue
|
continue
|
||||||
kind = m.get('kind')
|
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
|
type = m.find('type').text
|
||||||
member.type = type if type else ''
|
member.type = type if type else ''
|
||||||
if kind == 'function':
|
if kind == 'function':
|
||||||
@ -274,9 +275,9 @@ class CxxHandler(BaseHandler):
|
|||||||
elif d.kind == 'define':
|
elif d.kind == 'define':
|
||||||
params = []
|
params = []
|
||||||
for p in node.findall('param'):
|
for p in node.findall('param'):
|
||||||
d = Definition(p.find('defname').text, 'param')
|
param = Definition(p.find('defname').text, kind='param')
|
||||||
d.type = None
|
param.type = None
|
||||||
params.append(d)
|
params.append(param)
|
||||||
d.type = convert_type(node.find('type'))
|
d.type = convert_type(node.find('type'))
|
||||||
d.template_params = convert_template_params(node)
|
d.template_params = convert_template_params(node)
|
||||||
d.params = params
|
d.params = params
|
||||||
|
Loading…
x
Reference in New Issue
Block a user