Boost logo

Boost :

Subject: [boost] Sequence Printer (usually part or all of a container) using type_erasure
From: Paul A. Bristow (pbristow_at_[hidden])
Date: 2012-08-24 12:41:12

With the recent acceptance of type erasure as a Boost library, I have continued experiments with the
sequence printer provided as an example by Steven Watanbe.
This seems to me to have very general usefulness, providing a way of safely, neatly and painlessly
printing the contents of a container of any type.
To give a flavour of what can be done, given some items in a container, one can print the whole
  double da[] = {1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12. };
  decor_printer line_printer; // Using all decor_printer defaults.
  line_printer.print(da, std::cout); // "1 2 3 4 5 6 7 8 9 10 11 12"
// Prints all on one line, space separator and newline at the end.
Instead of providing several printer types (as Steven did),
I have concentrated just one printer class decor_printer derived from his abstract printer. But I
have added to it several constructor parameters to control the number of columns, the width of the
columns, and string to prefix, separate, suffix and final terminator.
// Construct a printer for 3 ragged columns, and comma as separator.
  decor_printer plain_printer(3, 0, "\n", ", ", "\n", "\n");
  plain_printer.print(da, std::cout);
which outputs:
1, 2, 3,
4, 5, 6,
7, 8, 9,
10, 11, 12
We can also apply this to std::vector (and all the other STL container types) and a more complex
type like quantity<length, measurement<double> >
(where there is a measurement value and estimate of its uncertainty (+/-).
   // Array of Boost.Units quantity with an uncertain type.
    quantity<length, measurement<double> > q[] =
      measurement<double>(45210.0, 1234.0) * meters,
      measurement<double>(765.3, 2.5) * meters,
      measurement<double>(12.34, 12.5) * meters,
      measurement<double>(5.67, 2.5) * meters,
      measurement<double>(0.789, 2.7e-2) * meters,
      measurement<double>(7890, 2.5e-2) * meters,
      measurement<double>(5.78e-4, 2.5e-4) * meters,
      measurement<double>(765.3, 2.5) * meters,
      measurement<double>(0.0789, 2.7e-4) * meters,
      measurement<double>(7890, 2.5e-1) * meters,
      measurement<double>(5.78e-7, 2.5e-8) * meters,
      measurement<double>(76.3, 2.5) * meters,
      measurement<double>(53.8e6, 2.34e5) * meters
To list this neatly we may need a column width of 25.
decor_ printer fancy_printer(4, 25, "\n", ", ", "\n"); // 4 columns, 25 char wide
fancy_printer.print(q, std::cout);
which outputs:
         45.21(+/-1.234) km, 765.3(+/-2.5) m, 12.34(+/-12.5) m,
5.67(+/-2.5) m,
              789(+/-27) mm, 7.89(+/-2.5e-005) km, 578(+/-250) um,
765.3(+/-2.5) m,
           78.9(+/-0.27) mm, 7.89(+/-0.00025) km, 578(+/-25) nm,
76.3(+/-2.5) m,
          53.8(+/-0.234) Mm
(Unless the email destroys the layout L )
Note the cool autoprefixing of quantities so the units change from m to km, mm, Mm as appropriate.
Finally, the parameter to the printer is a *range*, so *part* of any container can nearly as easily
be printed.
Does anyone share my enthusiasm for this?
PS I have also re-ordered the abstract_printer parameters in the hope of providing std::cout as
default, so one can write just
  line_printer.print(da); // "1 2 3 4 5 6"
But so far I can't get it to find the charT and traits parameters, despite providing defaults. Two
files attached (and need the sandbox version of type erase library.
Can anyone more expert get this to work?

Paul A. Bristow,
Prizet Farmhouse, Kendal LA8 8AB  UK
+44 1539 561830  07714330204

Boost list run by bdawes at, gregod at, cpdaniel at, john at