Previous fileTop of DocumentContentsIndex pageNext file
Apache C++ Standard Library User's Guide

25.4 Using a Stream's Facet

Here is a more advanced example that uses a std::time_put facet to print a date. Let us assume we have a date and want to print it this way:

//1A date object is created. It is of type std::tm, which is the time structure defined in <ctime>.
//2The date object is initialized with a particular date, September 1, 1989.
//3Let's assume our program is supposed to run in a German-speaking canton of Switzerland. Hence, we imbue the standard output stream with a German-Swiss locale.
//4The date is printed in German to the standard output stream.

The output is: 1. September 1989

As there is no operator<<() defined in the C++ Standard Library for the time structure tm from the C library, we must provide this inserter ourselves. The following code suggests a way this can be done. If you are not familiar with iostreams, please refer to the iostreams part of this User's Guide.

To keep it simple, the handling of exceptions thrown during the formatting is omitted.

//1This is a typical signature of a stream inserter; it takes a reference to an output stream and a constant reference to the object to be printed, and returns a reference to the same stream.
//2The stream's locale object is obtained via the stream's member function getloc(). This is the locale object where we expect to find a time-formatting facet object.
//3We define a type for an output iterator to a stream buffer. Time-formatting facet objects write the formatted output via an iterator into an output container (see the sections on containers and iterators in the C++ Standard Library User's Guide). In principle, this can be an arbitrary container that has an output iterator, such as a string or a C++ array. Here we want the time-formatting facet object to bypass the stream's formatting layer and write directly to the output stream's underlying stream buffer. Therefore, the output container shall be a stream buffer.
//4We define a variable that will hold a reference to the locale object's std::time_put facet object. The time formatting facet class std::time_put has two template parameters:
  • The first template parameter is the character type used for output. Here we provide the stream's character type as the template argument.

  • The second template parameter is the output iterator type. Here we provide the stream buffer iterator type outIter_t that we had defined as before.

//5Here we get the time-formatting facet object from the stream's locale via std::use_facet().
//6The facet object's formatting service put() is called. Let us see what arguments it takes. Here is the function's interface:

iter_type put

(iter_type

(a)

 

,ios_base&

(b)

 

,char_type

(c)

 

,const tm*

(d)

 

,char)

(e)

The types iter_type and char_type stand for the types that were provided as template arguments when the facet class was instantiated. In this case, they are std::ostreambuf_iterator<> and charT, where charT and traits are the respective streams template arguments. Here is the actual call: nextpos = fac.put(os,os,os.fill(),&date,'x'); Now let's see what the arguments mean:

a.

The first parameter is supposed to be an output iterator. We provide an iterator to the stream's underlying stream buffer. The reference os to the output stream is converted to an output iterator, because output stream buffer iterators have a constructor taking an output stream, that is, basic_ostream<>&.

b.

The second parameter is of type ios_base&, which is one of the stream base classes. The class ios_base contains data for format control (see the section on iostreams for details). The facet object uses this formatting information. We provide the output stream's ios_base part here, using the automatic cast from a reference to an output stream, to a reference to its base class.

c.

The third parameter is the fill character. It is used when the output has to be adjusted and blank characters have to be filled in. We provide the stream's fill character, which one can get by calling the stream's fill() function.

d.

The fourth parameter is a pointer to a time structure std::tm defined in <ctime>.

e.

The fifth parameter is a format character as in the C function std::strftime(); the x stands for the locale's appropriate date representation.

The value returned is an output iterator that points to the position immediately after the last inserted character.


Previous fileTop of DocumentContentsIndex pageNext file