|
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):