Channels ▼

Matthew Wilson

Dr. Dobb's Bloggers

FastFormat's format_iterator in Dr. Dobb's

June 02, 2010

The design and implementation of the FastFormat library's format_iterator() component features in my recent article published in Dr. Dobb's. In this post, I'll provide tutorial information and links to additional resources for any interested readers.

The new article, "C++ and format_iterator", describes how FastFormat's flexiblity, expressiveness and 100% type-safety has been combined with the output iterator concept to produce the fastformat::format_iterator component.

Applying STL-extension techniques described in Extended STL, volume 1, the format_iterator() component is able to create an output iterator that can receive arbitrate types, apply a format string or arbitrary complexity, and write to an arbitrary sink.

Let's consider a few examples. First, assume inclusion of the following set of FastFormat header files:

#include <fastformat/ff.hpp>
#include <fastformat/iterators/format_iterator.hpp>
#include <fastformat/sinks/ostream.hpp>

Now, let's imagine we have a sequence of strings. For simplicity, I'll just use an array of pointers to C-style strings:

char const*  strings[] = { "abcde", "f", "ghi" };

If we want to write this sequence to std::cout, we can use std::ostream_iterator:

std::copy(
  strings, strings + 3
, std::output_iterator<char const*>(std::cout));

This will produce the output

abcdefghi

If we want to write each item to a separate line we can apply a suffix:

std::copy(
  strings, strings + 3
, std::output_iterator<char const*>(std::cout, "\n"));

This will produce the output

abcde
f
ghi

Unfortunately, that's where the flexibility of the standard component ends. As discussed in "C++ and format_iterator"'s prequel, "An Enhanced ostream_iterator" (itself an extracted chapter from Extended STL, volume 1), if you want to apply a prefix and a suffix - perhaps TAB and LF - you cannot reliably do so with std::ostream_iterator.

The next level of flexibility is to instead use STLSoft's stlsoft::ostream_iterator, which allows for both suffix and prefix (and is a syntactic-compatible replacement for std::ostream_iterator). Using it, we can provide the required tabbing:

std::copy(
  strings, strings + 3
, stlsoft::output_iterator<char const*>(std::cout, "\t", "\n"));

This will produce the output:

        abcde
        f
        ghi

Although that's helpful in a lot of cases, it's still restrictive. Any more sophistication to the formatting and you're forced to explicitly iterate over the sequence. Furthermore, both of these still require that the type - char const* in this case - is specified to the creator function. That's just more eye-strain and unnecessary typing.

Using FastFormat's fastformat::format_iterator obviates both of these issues. First, it doesn't need to have the item type specified - any type that is understood by the FastFormat API can be processed:

std::copy(
  strings, strings + 3
, <strong>ff::format_iterator</strong>(std::cout, "{0}"));

This will produce the output

abcdefghi

It can incorporate other literal components within the required format string:

std::copy(
  strings, strings + 3
, <strong>ff::format_iterator</strong>(std::cout, "[{0}]"));

This will produce the output

[abcde][f][ghi]

It can incorporate special formatting instructions, such as making each field at least 3 and at most 4 characters wide, and left-aligned:

std::copy(
  strings, strings + 3
, <strong>ff::format_iterator</strong>(std::cout, "[{0,3,4,<}]"));

This will produce the output

[abcd][f  ][ghi]

And it can include additional arguments (again, of arbitrary type) from the local execution context:

std::string  prefix = "\t";
char const*  suffix = "\n";
std::copy(
  strings, strings + 3
, <strong>ff::format_iterator</strong>(std::cout, "{1}{0}{2}", prefix, suffix));

This will produce the output

        abcde
        f
        ghi

And putting it all together:

std::copy(
  strings, strings + 3
, <strong>ff::format_iterator</strong>(std::cout, "{1}[{0,3,4,<}]{2}", prefix, suffix));

This will produce the output

        [abcd]
        [f  ]
        [ghi]

I hope that's helpful, and provides some of the Hows to go along with the Whys given in "the article". If you have any questions, requests, criticisms, please feel free to post on the FastFormat project Help Forum.

Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 


Video