more elaborate format example

master
Daniel Kolesa 2017-02-26 15:35:17 +01:00
parent 9f286f88f3
commit 5beecdf370
1 changed files with 100 additions and 15 deletions

View File

@ -20,12 +20,15 @@ struct format_traits<Foo> {
static void to_format(Foo const &, R &writer, format_spec const &fs) { static void to_format(Foo const &, R &writer, format_spec const &fs) {
switch (fs.spec()) { switch (fs.spec()) {
case 'i': case 'i':
range_put_all(writer, "Foo1"_sr); range_put_all(writer, "Foo_i"_sr);
break; break;
default: default:
range_put_all(writer, "Foo2"_sr); range_put_all(writer, "Foo_s"_sr);
break; break;
} }
if (fs.flags() & FMT_FLAG_AT) {
range_put_all(writer, "_esc"_sr);
}
} }
}; };
@ -39,19 +42,23 @@ int main() {
* you need to specify a complicated manual delimiter, you can use the * you need to specify a complicated manual delimiter, you can use the
* "FORMAT%|DELIMITER" syntax, where %(%s, %) equals %(%s%|, %) * "FORMAT%|DELIMITER" syntax, where %(%s, %) equals %(%s%|, %)
*/ */
writeln("-- range format --");
writefln("[%(%s|%)]", x); writefln("[%(%s|%)]", x);
/* prints a range with default format {item, item, item, ...} /* prints a range with default format {item, item, item, ...}
* you can enable item escaping by passing the @ flag * you can enable item escaping by passing the @ flag
*/ */
writeln("\n-- range default format --");
writefln("%s", x); writefln("%s", x);
int y[] = { 2, 4, 8, 16, 32 }; int y[] = { 2, 4, 8, 16, 32 };
/* prints { 2, 4, 8, 16, 32 } using ", " as the delimiter */ /* prints { 2, 4, 8, 16, 32 } using ", " as the delimiter */
writeln("\n-- range format of static array --");
writefln("{ %(%s, %) }", y); writefln("{ %(%s, %) }", y);
/* nested range printing - prints each item of the main /* nested range printing - prints each item of the main
* range with [ %(%s, %) ] and ",\n" as the delimiter * range with [ %(%s, %) ] and ",\n" as the delimiter
*/ */
writeln("\n-- range format of nested range --");
writefln("[\n%([ %(%s, %) ]%|,\n%)\n]", map(range(10), [](int v) { writefln("[\n%([ %(%s, %) ]%|,\n%)\n]", map(range(10), [](int v) {
return range(v + 1); return range(v + 1);
})); }));
@ -65,62 +72,140 @@ int main() {
* the tuple is expanded into two formats (using the # flag) and the * the tuple is expanded into two formats (using the # flag) and the
* items are escaped with the @ flag (applies to strings and chars) * items are escaped with the @ flag (applies to strings and chars)
*/ */
writeln("\n-- range format of hash table --");
writefln("{ %#(%@s: %d, %) }", m); writefln("{ %#(%@s: %d, %) }", m);
/* not escaped, you get { baz: 15, bar: 10, foo: 5} */ /* not escaped, you get { baz: 15, bar: 10, foo: 5} */
writeln("\n-- range format of hash table (no escape) --");
writefln("{ %#(%s: %d, %) }", m); writefln("{ %#(%s: %d, %) }", m);
/* no expansion of the items, print entire tuple with default format, /* no expansion of the items, print entire tuple with default format,
* gets you something like { <"baz", 15>, <"bar", 10>, <"foo", 5> } * gets you something like { <"baz", 15>, <"bar", 10>, <"foo", 5> }
* because the default tuple format is <item, item, item, ...> * because the default tuple format is <item, item, item, ...>
*/ */
writefln("{ %(%s, %) }", m); writeln("\n-- range format of hash table (no item expansion) --");
writefln("{ %(%@s, %) }", m);
/* as the @ flag enables escaping on strings and chars, /* as the @ flag enables escaping on strings and chars,
* you can use it standalone outside of range/tuple format * you can use it standalone outside of range/tuple format
*/ */
writeln("\n-- format item escaping --");
writefln("not escaped: %s, escaped: %@s", "foo", "bar"); writefln("not escaped: %s, escaped: %@s", "foo", "bar");
std::tuple<std::string, int, float, std::string> tup{
"hello world", 1337, 3.14f, "test"
};
/* you can expand tuples similarly to ranges, with %<CONTENTS%> where /* you can expand tuples similarly to ranges, with %<CONTENTS%> where
* CONTENTS is a regular format string like if the tuple was formatted * CONTENTS is a regular format string like if the tuple was formatted
* separately with each item of the tuple passed as a separate argument * separately with each item of the tuple passed as a separate argument
*/ */
std::tuple<std::string, int, float, std::string> tup{ writeln("\n-- tuple format --");
"hello world", 1337, 3.14f, "test"
};
writefln("the tuple contains %<%@s, %d, %f, %s%>.", tup); writefln("the tuple contains %<%@s, %d, %f, %s%>.", tup);
writeln("\n-- tuple default format --");
writefln("auto tuple: %s", tup); writefln("auto tuple: %s", tup);
writeln("\n-- tuple default format (escaped) --");
writefln("auto tuple with escape: %@s", tup); writefln("auto tuple with escape: %@s", tup);
/* formatting a range of tuples, with each tuple expanded using #
*/
std::tuple<int, float, char const *> xt[] = { std::tuple<int, float, char const *> xt[] = {
std::make_tuple(5, 3.14f, "foo"), std::make_tuple(5, 3.14f, "foo"),
std::make_tuple(3, 1.23f, "bar"), std::make_tuple(3, 1.23f, "bar"),
std::make_tuple(9, 8.66f, "baz") std::make_tuple(9, 8.66f, "baz")
}; };
/* formatting a range of tuples, with each tuple expanded using #
*/
writeln("\n-- range of tuples format --");
writefln("[ %#(<%d|%f|%@s>%|, %) ]", xt); writefln("[ %#(<%d|%f|%@s>%|, %) ]", xt);
/* formatting custom objects, the information about the format mark /* formatting custom objects, the information about the format mark
* is passed into the to_format function and the object can read it * is passed into the to_format function and the object can read it
*/ */
writeln("\n-- custom object format --");
writefln("%s", Foo{}); writefln("%s", Foo{});
writefln("%i", Foo{}); writefln("%i", Foo{});
writefln("%@s", Foo{});
writefln("%@i", Foo{});
auto s = appender_range<std::string>{};
/* formatting into a string sink (can be any output range, but /* formatting into a string sink (can be any output range, but
* appender makes sure the capacity is unlimited so it's safe) * appender makes sure the capacity is unlimited so it's safe)
*/ */
auto s = appender_range<std::string>{}; writeln("\n-- format into a string --");
format(s, "hello %s", "world"); format(s, "hello %s", "world");
writeln(s.get()); writeln(s.get());
/* locale specific formatting */ /* locale specific formatting */
writeln("\n-- number format with C locale --");
writefln( writefln(
"C locale: \"%d\", \"%f\", \"%X\"", "\"%d\", \"%f\", \"%X\"", 123456789, 12345.6789123, 0x123456789ABCDEF
123456789, 12345.6789123, 0x123456789ABCDEF
); );
std::setlocale(LC_ALL, ""); std::locale::global(std::locale{""});
out.imbue(std::locale{std::setlocale(LC_NUMERIC, nullptr)}); out.imbue(std::locale{});
writefln("\n-- number format with system locale --");
writefln( writefln(
"%s locale: \"%d\", \"%f\", \"%X\"", out.getloc().name(), "\"%d\", \"%f\", \"%X\"", 123456789, 12345.6789123, 0x123456789ABCDEF
123456789, 12345.6789123, 0x123456789ABCDEF
); );
} }
/* output:
-- range format --
[5|10|15|20]
-- range default format --
{5, 10, 15, 20}
-- range format of static array --
{ 2, 4, 8, 16, 32 }
-- range format of nested range --
[
[ 0 ],
[ 0, 1 ],
[ 0, 1, 2 ],
[ 0, 1, 2, 3 ],
[ 0, 1, 2, 3, 4 ],
[ 0, 1, 2, 3, 4, 5 ],
[ 0, 1, 2, 3, 4, 5, 6 ],
[ 0, 1, 2, 3, 4, 5, 6, 7 ],
[ 0, 1, 2, 3, 4, 5, 6, 7, 8 ],
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
]
-- range format of hash table --
{ "baz": 15, "bar": 10, "foo": 5 }
-- range format of hash table (no escape) --
{ baz: 15, bar: 10, foo: 5 }
-- range format of hash table (no item expansion) --
{ <"baz", 15>, <"bar", 10>, <"foo", 5> }
-- format item escaping --
not escaped: foo, escaped: "bar"
-- tuple format --
the tuple contains "hello world", 1337, 3.140000, test.
-- tuple default format --
auto tuple: <hello world, 1337, 3.14, test>
-- tuple default format (escaped) --
auto tuple with escape: <"hello world", 1337, 3.14, "test">
-- range of tuples format --
[ <5|3.140000|"foo">, <3|1.230000|"bar">, <9|8.660000|"baz"> ]
-- custom object format --
Foo_s
Foo_i
Foo_s_esc
Foo_i_esc
-- format into a string --
hello world
-- number format with C locale --
"123456789", "12345.678912", "123456789ABCDEF"
-- number format with system locale --
"123 456 789", "12 345,678912", "123 456 789 ABC DEF"
*/