[Documentation] [TitleIndex] [WordIndex

(!) Please ask about problems and questions regarding this tutorial on answers.ros.org. Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags.

Using Ecl Formatters

Description: Introduction to the usage of ecl formatters.

Keywords: ecl formatters

Tutorial Level: INTERMEDIATE

Next Tutorial: Custom Formatters

Instantiation & Configuration

Construction

Formatters are functors - functions with state. You instantiate a formatter type and then make use of it as if it were a function call. Each formatter typically comes with a few format parameters that can be used to modify the format of the output (e.g. text width, no. of decimal points etc). These can be supplied at instantiation if the default set is not suitable.

   1 Format<int> format(); // Default format initialisation
   2 Format<int> format(8,RightAlign,Hex); // Custom format initialisation
   3 

Modifying Format Configuration

The format parameters can be changed singly with appropriately named setters, or collectively via:: a bundled operator () call. Sometimes common combinations are also provided with a convenient setter via the operator ().

   1 format.base(Hex);
   2 format(8,RightAlign,Dec);

Changing the format parameters in this way will set the default formatting for any input values given to the formatter in the future.

Streaming

The formatters are primarily intended to be used with streams. For convenience they have been designed to be used with any stream that implemenents the << operator. Subsequently they are useful with either TextStreams from ecl_streams or the usual c++ streams. When used in conjunction with TextStreams they provide a very fast streaming interface.

Permanent Formatting

To format with the parameters stored in the formatter, you simply provide the formatter with the input value. Note that the formatter will only accept a value of the type specified in the formatter's template argument.

   1 ostream << format(i) << " " << format(9);

For convenience, you can also change the format parameter on the fly (this is recorded permanently).

   1 ostream << format.base(Hex)(i) << " " << format(10,LeftAlign,Dec)(9);

Temporary Formatting

Occasionally you will only need to change the format for one instance. To effect a temporary change in this way, supply the input value along with the specified formatting options.

   1 ostream << format(i,6,CentreAlign,Hex);

Issues

{OK} - use one format call per line when streaming

   1 ostream << "[" << format(q.x());
   2 ostream << ", " << format(q.y());
   3 ostream << ", " << format(q.z()) << "]";

{X} - do not make several calls per line when streaming

   1 ostream << "[" << format(q.x()) << ", " << format(q.y()) ostream << ", " << format(q.z()) << "]";

The ecl in debug mode (-DNDEBUG is not defined) will utilise an exception throwing assert to check that multiple formatters aren't used in one line when streaming.

The why - there are some awkward aspects of streaming that make it difficult for the formatters to function perfectly. Without going into the details, this means it is impossible to format several objects on the same line differently, and expect the result to come back in the correct order. I haven't currently got a solution for this, so there are two options:

  1. Leave the formatters as they are and ensure that only one formatter is used on each line (abort/throw if this occurs)
  2. Push the formatters back into TextStream.

The second option is no good - it just turns TextStream into a heavyweight iostream. A priority for us is fast logging, so we must keep TextStream lightweight and since the first option is merely a coding style issue, that's easy to handle so long as we are aware of it.


2019-12-07 12:35