## For instruction on writing tutorials ## http://www.ros.org/wiki/WritingTutorials #################################### ##FILL ME IN #################################### ## for a custom note with links: ## note = ## for the canned note of "This tutorial assumes that you have completed the previous tutorials:" just add the links ## note.0= ## descriptive title for the tutorial ## title = Using Ecl Formatters ## multi-line description to be displayed in search ## description = Introduction to the usage of ecl formatters. ## the next tutorial description (optional) ## next = ## links to next tutorial (optional) ## next.0.link=[[ecl_formatters/Tutorials/Writing a Custom Formatter|Custom Formatters]] ## next.1.link= ## what level user is this tutorial for ## level= IntermediateCategory ## keywords = ecl 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. {{{ #!cplusplus Format format(); // Default format initialisation Format format(8,RightAlign,Hex); // Custom format initialisation }}} === 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 ()`. {{{ #!cplusplus format.base(Hex); 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. {{{ #!cplusplus ostream << format(i) << " " << format(9); }}} For convenience, you can also change the format parameter on the fly (this is recorded permanently). {{{ #!cplusplus 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. {{{ #!cplusplus ostream << format(i,6,CentreAlign,Hex); }}} == Issues == {OK} - use one format call per line when streaming {{{ #!cplusplus ostream << "[" << format(q.x()); ostream << ", " << format(q.y()); ostream << ", " << format(q.z()) << "]"; }}} {X} - do not make several calls per line when streaming {{{ #!cplusplus 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. ## AUTOGENERATED DO NOT DELETE ## TutorialCategory ## FILL IN THE STACK TUTORIAL CATEGORY HERE