Skip to content

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.

Clone this wiki locally