mirror of
https://github.com/fmtlib/fmt.git
synced 2025-09-13 14:49:37 -04:00
Add FMT_STATIC_FORMAT
This commit is contained in:
parent
a57f196cad
commit
02fb76d69b
@ -525,6 +525,40 @@ void print(const S& fmt, T&&... args) {
|
|||||||
print(stdout, fmt, std::forward<T>(args)...);
|
print(stdout, fmt, std::forward<T>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <size_t N> class static_format_result {
|
||||||
|
private:
|
||||||
|
char data[N];
|
||||||
|
|
||||||
|
public:
|
||||||
|
template <typename S, typename... T,
|
||||||
|
FMT_ENABLE_IF(is_compiled_string<S>::value)>
|
||||||
|
explicit FMT_CONSTEXPR static_format_result(const S& fmt, T&&... args) {
|
||||||
|
*fmt::format_to(data, fmt, std::forward<T>(args)...) = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
auto str() const -> fmt::string_view { return {data, N - 1}; }
|
||||||
|
auto c_str() const -> const char* { return data; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats arguments according to the format string `fmt_str` and produces
|
||||||
|
* a string of the exact required size at compile time. Both the format string
|
||||||
|
* and the arguments must be compile-time expressions.
|
||||||
|
*
|
||||||
|
* The resulting string can be accessed as a C string via `c_str()` or as
|
||||||
|
* a `fmt::string_view` via `str()`.
|
||||||
|
*
|
||||||
|
* **Example**:
|
||||||
|
*
|
||||||
|
* // Produces the static string "42" at compile time.
|
||||||
|
* static constexpr auto result = FMT_STATIC_FORMAT("{}", 42);
|
||||||
|
* const char* s = result.c_str();
|
||||||
|
*/
|
||||||
|
#define FMT_STATIC_FORMAT(fmt_str, ...) \
|
||||||
|
fmt::static_format_result< \
|
||||||
|
fmt::formatted_size(FMT_COMPILE(fmt_str), __VA_ARGS__) + 1>( \
|
||||||
|
FMT_COMPILE(fmt_str), __VA_ARGS__)
|
||||||
|
|
||||||
#if FMT_USE_NONTYPE_TEMPLATE_ARGS
|
#if FMT_USE_NONTYPE_TEMPLATE_ARGS
|
||||||
inline namespace literals {
|
inline namespace literals {
|
||||||
template <detail::fixed_string Str> constexpr auto operator""_cf() {
|
template <detail::fixed_string Str> constexpr auto operator""_cf() {
|
||||||
|
@ -236,6 +236,12 @@ TEST(compile_test, constexpr_formatted_size) {
|
|||||||
fmt::formatted_size(FMT_COMPILE("{:s}"), "abc");
|
fmt::formatted_size(FMT_COMPILE("{:s}"), "abc");
|
||||||
EXPECT_EQ(str_size, 3);
|
EXPECT_EQ(str_size, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(compile_test, static_format) {
|
||||||
|
constexpr auto result = FMT_STATIC_FORMAT("{}", 42);
|
||||||
|
EXPECT_STREQ(result.c_str(), "42");
|
||||||
|
EXPECT_EQ(result.str(), "42");
|
||||||
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
TEST(compile_test, text_and_arg) {
|
TEST(compile_test, text_and_arg) {
|
||||||
@ -423,22 +429,16 @@ TEST(compile_time_formatting_test, multibyte_fill) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if FMT_USE_CONSTEXPR_STRING
|
#if FMT_USE_CONSTEXPR_STRING
|
||||||
|
TEST(compile_test, constexpr_string_format) {
|
||||||
|
constexpr auto result = []() {
|
||||||
|
return fmt::format(FMT_COMPILE("{}"), 42) == "42";
|
||||||
|
}();
|
||||||
|
EXPECT_TRUE(result);
|
||||||
|
|
||||||
TEST(compile_test, constexpr_format) {
|
// Test with a larger string to avoid small string optimization.
|
||||||
{
|
constexpr auto big = []() {
|
||||||
constexpr auto result = []() {
|
return fmt::format(FMT_COMPILE("{:100}"), ' ') == std::string(100, ' ');
|
||||||
return fmt::format(FMT_COMPILE("{}"), 42) == "42";
|
}();
|
||||||
}();
|
EXPECT_TRUE(big);
|
||||||
EXPECT_TRUE(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
// Test with a larger string to avoid small string optimization.
|
|
||||||
constexpr auto result = []() {
|
|
||||||
return fmt::format(FMT_COMPILE("{:100}"), ' ') == std::string(100, ' ');
|
|
||||||
}();
|
|
||||||
EXPECT_TRUE(result);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // FMT_USE_CONSTEXPR_STRING
|
#endif // FMT_USE_CONSTEXPR_STRING
|
||||||
|
Loading…
x
Reference in New Issue
Block a user