ct_format.hpp
provides ct_format, a compile-time function for formatting strings.
|
Note
|
Like ct_string, ct_format is
available only in C++20 and later.
|
|
Important
|
ct_format is limited on freestanding implementations: format
specifiers are limited to {} and {:x}.
|
The format string is provided as a template argument, and the arguments to be formatted as regular function arguments.
The result type is a stdx::format_result containing two members: the
ct_string (wrapped in a cts_t) and a
tuple of the format arguments.
auto s = stdx::ct_format<"Hello {} {}">(42, 17);
// s is stdx::format_result{"Hello {} {}"_ctst, stdx::tuple{42, 17}}When format arguments are available at compile-time, wrapping them in
CX_VALUE(…) means they will get compile-time formatted.
auto s = stdx::ct_format<"Hello {} {}">(CX_VALUE(42), 17);
// s is stdx::format_result{"Hello 42 {}"_ctst, stdx::tuple{17}}If there are no runtime arguments, the result is a format_result with an empty tuple…
auto s = stdx::ct_format<"Hello {} {}">(CX_VALUE(42), CX_VALUE(17));
// s is stdx::format_result{"Hello 42 17"_ctst, stdx::tuple{}}…and a format_result like this without an runtime arguments is implicitly convertible back
to a ct_string, or explicitly convertible using unary operator+:
template <stdx::ct_string S> auto f() { ... };
f<stdx::ct_format<"Hello {}">(CX_VALUE(42))>(); // equivalent to f<"Hello 42">()
+stdx::ct_format<"Hello {}">(CX_VALUE(42)); // equivalent to stdx::ct_string{"Hello 42"}|
Note
|
Using operator+ on a format_result that has a non-empty tuple of
runtime arguments is a compilation error.
|
Types and compile-time enumeration values are stringified thus:
enum struct E { value };
auto s = stdx::ct_format<"Hello {} {}">(CX_VALUE(int), CX_VALUE(E::value));
// s is stdx::format_result{"Hello int value"_ctst, stdx::tuple{}}|
Note
|
Compile-time formatting is done with fmtlib and supports the same formatting DSL. Positional arguments are not supported. |
When formatting a compile-time stdx::format_result, the strings and argument
tuples are collapsed to a single stdx::format_result:
constexpr static auto a = stdx::ct_format<"The answer is {}">(42);
// a is stdx::format_result{"The answer is {}"_ctst, stdx::tuple{42}}
constexpr static auto q = stdx::ct_format<"{}. But what is the question?">(CX_VALUE(a));
// q is stdx::format_result{"The answer is {}. But what is the question?"_ctst, stdx::tuple{42}}The macro STDX_CT_FORMAT will automatically wrap compile-time-friendly
arguments, so manual wrapping with CX_VALUE is not required.
auto s = STDX_CT_FORMAT("Hello {} {}", 42, int);
// equivalent to stdx::ct_format<"Hello {} {}">(CX_VALUE(42), CX_VALUE(int));
// s is stdx::format_result{"Hello 42 int"_ctst, stdx::tuple{}}If any arguments are not available at compile time, they will be "regular" runtime format arguments.
auto x = 42;
auto s = STDX_CT_FORMAT("Hello {} {}", x, int);
// equivalent to stdx::ct_format<"Hello {} {}">(x, CX_VALUE(int));
// s is stdx::format_result{"Hello {} int"_ctst, stdx::tuple{42}}Things that are "compile-time-friendly" include:
-
constexpr staticvariables -
constintegral variables -
template arguments
-
literals
-
types