Skip to content

Text writer binding helpers

Raymond Chen edited this page Mar 21, 2019 · 2 revisions

The xlang::text binding helpers assist in producing formatted output with a writer derived from xlang::text::writer_base.

All of the binding helpers return a functor that is intended to be passed immediately as a parameter to write_base::write. Do not save the result of a binding helper in a variable, because it captures the bind parameters by reference.

bind

template<auto F, typename... Args>
auto bind(Args&&... args); // (1)

template<typename F, typename... Args>
auto bind(F fwrite, Args const&... args); // (2)

The bind function permits you to call a function in the middle of a formatted write operation.

In the first version of bind, the explicit template parameter F is a function pointer. The function returns a functor which, when invoked, calls the function as follows:

F(writer, args...);

In the second version of bind, the function argument is a functor. The function returns another functor which, when invoked, calls the passed-in functor as follows:

fwrite(writer, args...);

Examples:

struct my_writer : xlang::text::writer_base<my_writer> { };

void write_separator(my_writer&w, bool fancy);

    my_writer w;

    // Example 1
    w.write("1%2", bind<write_separator>(true));

    // Example 2
    w.write("1%2", bind([](my_writer& w, bool fancy) { write_separator(w, fancy); }, true));

In the first example, the write method does the following:

  • writes 1 to the buffer,
  • calls write_separator(w, true), and then
  • writes 2 to the buffer.

The second example accomplishes the same thing with a lambda rather than a free function.

In practice, the bound function typically writes more data to the writer based on the additional parameters.

bind_each

template<auto F, typename List, typename... Args>
auto bind_each(List const& list, Args const&... args); // (1)

template<typename F, typename List, typename... Args>
auto bind_each(F fwrite, List const& list, Args const&... args); // (2)

template<typename List, typename... Args>
auto bind_each(List const& list, Args const&... args); // (3)

The bind_each function permits you to call a function repeatedly for each item in a collection, in the middle of a formatted write operation.

In the first version of bind_each, the explicit template parameter F is a function pointer. The function returns a functor which, when invoked, calls the function once for each item in the list, as follows:

F(writer, item, args...);

In the second version of bind_each, the function argument is a functor. The function returns another functor which, when invoked, calls the passed-in functor once for each item in the list, as follows:

fwrite(writer, item, args...);

In the third version of bind_each, the function returns a functor which, when invkoed, writes each item to the writer as follows:

writer.write(item, args...);

Examples:

struct my_writer : xlang::text::writer_base<my_writer> { };

void write_widget(my_writer& w, const widget& widget, bool fancy);

    std::vector<widget> v;

    my_writer w;

    // Example 1
    w.write("1%2", bind_each<write_widget>(v, true));

    // Example 2
    w.write("1%2", bind_each([](my_writer& w, const widget& widget, bool fancy) { write_widget(w, widget, fancy); }, true));

    // Example 3
    w.write("1%2", bind_each(v));

In the first example, the write method does the following:

  • writes 1 to the buffer,
  • calls write_widget(w, widget, true) repeatedly, once for each widget in the vector, and then
  • writes 2 to the buffer.

The second example accomplishes the same thing with a lambda rather than a free function.

The third example write 1 to the buffer, then calls w.write(widget) for each widget in the vector, then writes 2 to the buffer.

bind_list

template<auto F, typename T, typename... Args>
auto bind_list(std::string_view const& delimiter, T const& list, Args const&... args); // (1)

template<typename T>
auto bind_list(std::string_view const& delimiter, T const& list); // (2)

The bind_list function permits you to call a function repeatedly for each item in a collection, in the middle of a formatted write operation, with a specified delimiter between each call. No delimiter is written before the first item or after the last item.

In the first version of bind_list, the explicit template parameter F is a function pointer. The function returns a functor which, when invoked, calls the function once for each item in the collection, as follows:

F(writer, item, args...);

Between each call, the delimiter is written.

In the third version of bind_list, the function returns a functor which, when invkoed, writes each item to the writer as follows:

writer.write(item);

Between each call, the delimiter is written.

Examples:

struct my_writer : xlang::text::writer_base<my_writer> { };

void write_widget(my_writer& w, const widget& widget, bool fancy);

    std::vector<widget> v;

    my_writer w;

    // Example 1
    w.write("1%2", bind_list<write_widget>(", ", v, true));

    // Example 2
    w.write("1%2", bind_list(", ", v));

In the first example, the write method does the following:

  • writes 1 to the buffer,
  • calls write_widget(w, widget, true) function repeatedly, once for each widget in the vector, printing a comma and space between each call, and then
  • writes 2 to the buffer.

In the second example, the write method does the following:

  • writes 1 to the buffer,
  • calls w.write(widget) repeatedly, once for each widget in the vector, printing a comma and space between each call, and then
  • writes 2 to the buffer.
Clone this wiki locally