rapidyaml 0.14.0
parse and emit YAML, and do it fast
Loading...
Searching...
No Matches
format: formatted string interpolation

Functions

template<class Arg, class... Args>
size_t c4::format (substr buf, csubstr fmt, Arg const &a, Args const &...more)
 Using a format string, serialize the arguments into the given fixed-size buffer.
template<class... Args>
substr c4::format_sub (substr buf, csubstr fmt, Args const &...args)
 like c4::format() but return a substr instead of a size
template<class CharOwningContainer, class... Args>
void c4::formatrs (CharOwningContainer *cont, csubstr fmt, Args const &...args)
 format+resize: like c4::format(), but receives a container, and resizes it as needed to contain the result.
template<class CharOwningContainer, class... Args>
CharOwningContainer c4::formatrs (csubstr fmt, Args const &...args)
 format+resize: like c4::format(), but create a new container with the result.
template<class CharOwningContainer, class... Args>
csubstr c4::formatrs_append (CharOwningContainer *cont, csubstr fmt, Args const &...args)
 format+resize+append: like c4::format(), but receives a container, and appends the arguments, resizing the container as needed to contain the result.

Detailed Description

Function Documentation

◆ format()

template<class Arg, class... Args>
size_t c4::format ( substr buf,
csubstr fmt,
Arg const & a,
Args const &... more )

Using a format string, serialize the arguments into the given fixed-size buffer.

The buffer size is strictly respected: no writes will occur beyond its end. In the format string, each argument is marked with a compact curly-bracket pair "{}". This pair does not take any interior sequence numbers or extra formatting arguments inside it (contrary to eg the C++20 std::format implementation or the Python formatting facilities). To enable argument customization, use the formatting facilities in Format specifiers wrapping the arguments passed to this function.

Returns
the number of bytes needed to write into the buffer.
See also
c4::formatrs() if instead of a fixed-size buffer, a resizeable container is desired
c4::unformat() for the inverse function
c4::cat() if no format or separator is needed
c4::catsep() if no format is needed, but a separator must be used

For example:

c4::format(buf, "the {} drank {} {}", "partier", 5, "beers"); // the partier drank 5 beers
c4::format(buf, "the {} drank {} {}", "programmer", 6, "coffees"); // the programmer drank 6 coffees
size_t format(substr buf, csubstr fmt, Arg const &a, Args const &...more)
Using a format string, serialize the arguments into the given fixed-size buffer.
Definition format.hpp:936

Using Format specifiers enables control of the result. For example:

c4::format(buf, "the {} drank {} {}", "partier", c4::fmt::real(5, 3), "beers"); // the partier drank 5.000 beers
c4::format(buf, "the {} drank {} {}", "partier", c4::fmt::zpad(5, 3), "beers"); // the partier drank 005 beers
c4::format(buf, "the {} drank {} {}", "partier", c4::fmt::bin(5), "beers"); // the partier drank 0b101 beers
c4::format(buf, "the {} drank {} {}", "partier", c4::fmt::oct(5), "beers"); // the partier drank 0o6 beers
c4::format(buf, "the {} drank {} {}", "partier", c4::fmt::hex(5), "beers"); // the partier drank 0x6 beers
c4::format(buf, "the {} drank {} {}", "programmer", c4::fmt::real(6, 3), "coffees"); // the programmer drank 6.000 coffees
c4::format(buf, "the {} drank {} {}", "programmer", c4::fmt::zpad(6, 3), "coffees"); // the programmer drank 006 coffees
c4::format(buf, "the {} drank {} {}", "programmer", c4::fmt::bin(6), "coffees"); // the programmer drank 0b110 coffees
c4::format(buf, "the {} drank {} {}", "programmer", c4::fmt::oct(6), "coffees"); // the programmer drank 0o6 coffees
c4::format(buf, "the {} drank {} {}", "programmer", c4::fmt::hex(6), "coffees"); // the programmer drank 0x6 coffees
integral_< intptr_t > hex(std::nullptr_t)
format null as an hexadecimal value
Definition format.hpp:160
integral_< intptr_t > oct(std::nullptr_t)
format null as an octal value
Definition format.hpp:185
integral_< intptr_t > bin(std::nullptr_t)
format null as a binary 0-1 value
Definition format.hpp:212
real_< T > real(T val, int precision, RealFormat_e fmt=FTOA_FLOAT)
Definition format.hpp:362
integral_padded_< T > zpad(T val, size_t num_digits)
pad the argument with zeroes on the left, with decimal radix
Definition format.hpp:232
Note
Arguments beyond the last curly bracket pair are silently ignored. Curly bracket pairs without a corresponding argument are printed as part of the result.
// note "and nothing else" being ignored
c4::format(buf, "the {} drank {} {}", "partier", 5, "beers", "and nothing else"); // the partier drank 5 beers
// note "this is ignored {}" being part of the result
c4::format(buf, "the {} drank {} {} this is ignored: {}", "programmer", 6, "coffees"); // the programmer drank 6 coffees this is ignored: {}
The curly bracket pair cannot be escaped, but can of course be placed into the result by passing an "{}" argument in its place, or if it is provided beyond the last argument passed to the function (see prior note).
// as above: no argument given, so no substitution made:
c4::format(buf, "let's show {} on the result"); // let's show {} on the result
// or just pass "{}" as an argument to force the substitution:
c4::format(buf, "let's show {} on the result and then {}", "{}", "this"); // let's show {} on the result and then this
The arguments to format are restricted (legal because they are rvalues). This may require a workaround when arguments of type char[]/const char[] are passed repeatedly to the function. For example,
const char str[] = "Hi! ";
cat(buf, str, str, str); // compile error: 'passing argument 2 to ‘restrict’-qualified parameter aliases with arguments 3, 4'
size_t cat(substr buf, Arg const &a, Args const &...more)
serialize the arguments, concatenating them to the given fixed-size buffer.
Definition format.hpp:649
It is possible to work around the problem by suppressing -Wrestrict or by using the decayed type char* or const char*, or even wrapping the argument in a csubstr():
const char str[] = "Hi! ";
csubstr ss = to_csubstr(str);
cat(buf, ss, ss, ss); // ok! compiles cleanly
csubstr to_csubstr(const char(&s)[N]) noexcept
Definition substr.hpp:2381
basic_substring< const char > csubstr
an immutable string view
Definition substr.hpp:2357

Definition at line 936 of file format.hpp.

937{
938 size_t pos = fmt.find("{}");
939 if(C4_UNLIKELY(pos == csubstr::npos))
940 return to_chars(buf, fmt);
941 size_t num = to_chars(buf, fmt.first(pos));
942 size_t out = num;
943 buf = buf.len >= num ? buf.sub(num) : substr{};
944 num = to_chars(buf, a);
945 out += num;
946 buf = buf.len >= num ? buf.sub(num) : substr{};
947 num = format(buf, fmt.sub(pos + 2), more...);
948 out += num;
949 return out;
950}
basic_substring< char > substr
a mutable string view
Definition substr.hpp:2356
size_t to_chars(substr buf, uint8_t v) noexcept
size_t len
the length of the substring
Definition substr.hpp:218
basic_substring sub(size_t first) const noexcept
return [first,len[
Definition substr.hpp:503

◆ format_sub()

template<class... Args>
substr c4::format_sub ( substr buf,
csubstr fmt,
Args const &... args )

like c4::format() but return a substr instead of a size

See also
c4::format()
c4::catsep(). c4::uncatsep() is the inverse of c4::catsep().

Definition at line 956 of file format.hpp.

957{
958 size_t sz = c4::format(buf, fmt, args...);
959 C4_CHECK(sz <= buf.len);
960 return {buf.str, sz <= buf.len ? sz : buf.len};
961}
C * str
a restricted pointer to the first character of the substring
Definition substr.hpp:216

◆ formatrs() [1/2]

template<class CharOwningContainer, class... Args>
void c4::formatrs ( CharOwningContainer * cont,
csubstr fmt,
Args const &... args )
inline

format+resize: like c4::format(), but receives a container, and resizes it as needed to contain the result.

The container is overwritten. To append to the container use c4::formatrs_append().

See also
c4::format()
c4::formatrs_append()
Note
The arguments to format are restricted (legal because they are rvalues). This may require a workaround when arguments of type char[]/const char[] are passed repeatedly to the function. For example,
const char str[] = "Hi! ";
cat(buf, str, str, str); // compile error: 'passing argument 2 to ‘restrict’-qualified parameter aliases with arguments 3, 4'
It is possible to work around the problem by suppressing -Wrestrict or by using the decayed type char* or const char*, or even wrapping the argument in a csubstr():
const char str[] = "Hi! ";
csubstr ss = to_csubstr(str);
cat(buf, ss, ss, ss); // ok! compiles cleanly

Definition at line 1263 of file format.hpp.

1264{
1265 cont->resize(cont->capacity()); // improve the odds of fitting in the original buffer
1266retry:
1267 substr buf = to_substr(*cont);
1268 size_t ret = format(buf, fmt, args...);
1269 cont->resize(ret);
1270 if(ret > buf.len)
1271 goto retry;
1272}
substr to_substr(char(&s)[N]) noexcept
Definition substr.hpp:2377

◆ formatrs() [2/2]

template<class CharOwningContainer, class... Args>
CharOwningContainer c4::formatrs ( csubstr fmt,
Args const &... args )
inline

format+resize: like c4::format(), but create a new container with the result.

Returns
the requested container
Note
The arguments to format are restricted (legal because they are rvalues). This may require a workaround when arguments of type char[]/const char[] are passed repeatedly to the function. For example,
const char str[] = "Hi! ";
cat(buf, str, str, str); // compile error: 'passing argument 2 to ‘restrict’-qualified parameter aliases with arguments 3, 4'
It is possible to work around the problem by suppressing -Wrestrict or by using the decayed type char* or const char*, or even wrapping the argument in a csubstr():
const char str[] = "Hi! ";
csubstr ss = to_csubstr(str);
cat(buf, ss, ss, ss); // ok! compiles cleanly

Definition at line 1298 of file format.hpp.

1299{
1300 CharOwningContainer cont;
1301 formatrs(&cont, fmt, args...);
1302 return cont;
1303}
void formatrs(CharOwningContainer *cont, csubstr fmt, Args const &...args)
format+resize: like c4::format(), but receives a container, and resizes it as needed to contain the r...
Definition format.hpp:1263

◆ formatrs_append()

template<class CharOwningContainer, class... Args>
csubstr c4::formatrs_append ( CharOwningContainer * cont,
csubstr fmt,
Args const &... args )
inline

format+resize+append: like c4::format(), but receives a container, and appends the arguments, resizing the container as needed to contain the result.

The buffer is appended to.

Returns
the region newly appended to the original container
Note
The arguments to format are restricted (legal because they are rvalues). This may require a workaround when arguments of type char[]/const char[] are passed repeatedly to the function. For example,
const char str[] = "Hi! ";
cat(buf, str, str, str); // compile error: 'passing argument 2 to ‘restrict’-qualified parameter aliases with arguments 3, 4'
It is possible to work around the problem by suppressing -Wrestrict or by using the decayed type char* or const char*, or even wrapping the argument in a csubstr():
const char str[] = "Hi! ";
csubstr ss = to_csubstr(str);
cat(buf, ss, ss, ss); // ok! compiles cleanly

Definition at line 1330 of file format.hpp.

1331{
1332 const size_t pos = cont->size();
1333 C4_SUPPRESS_WARNING_GCC_WITH_PUSH("-Warray-bounds")
1334 cont->resize(cont->capacity()); // improve the odds of fitting in the original buffer
1335 C4_SUPPRESS_WARNING_GCC_POP
1336retry:
1337 substr buf = to_substr(*cont).sub(pos);
1338 size_t ret = format(buf, fmt, args...);
1339 cont->resize(pos + ret);
1340 if(ret > buf.len)
1341 goto retry;
1342 return to_csubstr(*cont).range(pos, cont->size());
1343}