forked from microsoft/xlang
-
Notifications
You must be signed in to change notification settings - Fork 2
How to make something writable
Raymond Chen edited this page Mar 23, 2019
·
3 revisions
There are two ways to make it possible to write something to a writer_base
.
The first way is to add an overload for the write
method to your custom writer.
struct location
{
int x, y;
};
struct struct_writer : xlang::text::writer_base<struct_writer>
{
using writer_base::write;
void write(location const& loc)
{
write("{ %, % }", loc.x, loc.y);
}
};
struct math_writer : xlang::text::writer_base<math_writer>
{
using writer_base::write;
void write(location const& loc)
{
write("(%, %)", loc.x, loc.y);
}
};
void write_as_struct(struct_writer& w, location const& l)
{
w.write("var loc = %\n", l);
}
void write_as_math(math_writer& w, location const& l)
{
w.write("let $l = %$.\n", l);
}
The overloaded write
technique has the advantage of putting all writable things in one place.
Another way is to give each writable object an operator()(my_writer& w)
method.
struct location
{
int x, y;
// for struct_writer.write()
operator()(struct_writer& w) const
{
w.write("{ %, % }", x, y);
}
// for math_writer.write()
operator()(math_writer& w) const
{
w.write("(%, %)", x, y);
}
// for all other writer_base<T>.write()
template<typename T>
operator()(xlang::text::writer_base<T>& w) const
{
w.write("%, %", x, y);
}
};
void write_as_struct(struct_writer& w, location const& l)
{
w.write("var loc = %", l); // "var loc = { 1, 2 }"
}
void write_as_math(math_writer& w, location const& l)
{
w.write("let $l = %$.", l); // "let $l = (1, 2)$."
}
void write_as_something(other_writer& w, location const& l)
{
w.write("Hello, %", l); // "Hello, 1, 2"
}
The custom operator()(my_writer&)
technique has the advantage of keeping the formatting with the object. It also permits the formatting to use private methods, and it lets you write a fallback writer that applies to all writer_base
objects.
In the case of a conflict between writer::write(object const&)
and object::operator()(writer&)
, the explicit write
method will be used.