Skip to content

Latest commit

 

History

History
104 lines (82 loc) · 3.64 KB

File metadata and controls

104 lines (82 loc) · 3.64 KB

ct_format.hpp

ct_format

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}}

STDX_CT_FORMAT

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 static variables

  • const integral variables

  • template arguments

  • literals

  • types