BDE 4.14.0 Production release
|
Provide a mechanism to implement standard print
methods.
print
methodsThis component provides a mechanism class, bslim::Printer
, that, in many cases, simplifies the implementation of types providing a print
method with the signature:
Note that all value-semantic types are expected to provide this method. bslim::Printer
also supports generic containers, including those in BSL's standard library implementation, through use of standard conforming iterators and the bslalg::HasStlIterators
trait. Use of the Printer
mechanism provides a uniform style of output formatting:
bdlt::Date
, the names of attributes, equal sign, and brackets may be omitted, with the entire value represented on a single line in a custom format. For example, the bdlt::Date::print
method emits the date value in the format: 01JAN2001.For example, consider a class having two attributes, ticker
, represented by a bsl::string
, and price
, represented by a double
. The output for a print
method that produces standardized output for print(bsl::cout, 0, -4)
(single-line output) is shown below:
Output for print(bsl::cout, 0, 4)
(multi-line output) is shown below:
The Printer
mechanism provides methods and method templates to format data as described above. Printer
objects are instantiated with the target stream to be written to, and the values of the indentation level of the data, level
, and the spaces per level, spacesPerLevel
. The methods provided by Printer
, printAttribute
, printValue
, printOrNull
, printHexAddr
and printForeign
, use these values for formatting. The start
and end
methods print the enclosing brackets of the output. In order to generate the standard output format, start
should be called before any of the other methods, and end
should be called after all the other methods have been called.
In the following examples, we examine the implementation of the print
method of different types of classes using Printer
.
In this example, we demonstrate how to use Printer
to implement the standard print
function of a value-semantic class having multiple attributes. Suppose we have a class, StockTrade
, that provides a container for a fixed set of attributes. A StockTrade
object has four attributes, ticker
, price
, quantity
, and optional notes
:
Sample output for StockTrade::print(bsl::cout, 0, -4)
:
Sample output for StockTrade::print(bsl::cout, 0, 4)
:
In this example, we discuss the implementation of print
for a mechanism class. A mechanism class does not have any salient attributes that define its value (as a mechanism does not have a "value"). However, the print
method may be implemented to output the internal state of an object of such a type, e.g., for debugging purposes.
For example, consider a memory manager class, BlockList
, that maintains a linked list of memory blocks:
For the purposes of debugging, it may be useful to print the starting address of every memory block in a BlockList
, which can be done using the printHexAddr
method of the Printer
class:
Sample output for 'BlockList::print(bsl::cout, 0, -4):
Sample output for 'BlockList::print(bsl::cout, 0, 4):
In this example, we use a Printer
object to help format the properties of a class supplied by a third-party that does not implement the standard print
method. Consider a struct, ThirdPartyStruct
, defined in /usr/include/thirdparty.h
that has no standard print
method. We will be using this struct within another class Customer
, storing some Customer
objects in a map, and printing the map.
We create a struct MyThirdPartyStructPrintUtil
:
We create a class Customer
that has a ThirdPartyStruct
in it:
We then create some Customer
objects and put them in a map:
Now we print the map
The following is written to stdout
:
In this examples we demonstrate two capabilities of a bslim::Printer
object: printing a range of elements using iterators and printing a pointer type.
The printValue
or printAttribute
methods of bslim::Printer
will print out all of the elements in the range specified by a pair of iterator arguments, which can be of any type that provides appropriately behaving operators ++
, *
, and ==
(a non-void pointer would qualify).
When bslim
encounters a single pointer of type TYPE *
, where TYPE
is neither void
nor char
, the pointer value is printed out in hex followed by printing out the value of TYPE
. A compile error will occur if bslim is unable to print out TYPE
.
As an example, we print out a range of pointers to sets.
First we create 3 sets and populate them with different values.
Then, we store the addresses to those 3 sets into a fixed-length array:
Next we use printValue
to print a range of values by supplying an iterator to the beginning and end of the range, in the address of setArray
and the address one past the end of setArray
:
The expected output is:
For very simple classes, it may be desirable always to format the attributes on a single line. In this example, we discuss the print
method formatting for such a low-level value-semantic class.
Usually, single-line or multi-line formatting options are specified by the value of the spacesPerLevel
argument, but for a simple class that always prints on a single line, the only difference between the single- and multi-line cases is that a newline character is printed at the end of the output for the multi-line case. For such classes, the "name" of the attribute and the enclosing brackets may be omitted as well.
For example, consider a class, DateTz
, having as attributes a local date and a time offset:
The Printer
class may be used in this case to print the start and end indentation by passing a suppressBracket
flag to the start
and end
methods. The value itself can be written to the stream directly without using Printer
. Note that to ensure correct formatting of the value in the presence of a call to setw
on the stream, the output must be written to a bsl::ostringstream
first; the string containing the output can then be written to the specified stream
:
Sample output for 'DateTz::print(bsl::cout, 0, -4):
Sample output for 'DateTz::print(bsl::cout, 0, 4):