    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Extensibility - A Reason For Using Streams in C++</title>
        <link>https://members.accu.org/index.php/journals/459</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>


        <h2>Journal Articles</h2>


<div class="xar-mod-head"><span class="xar-mod-title">Overload Journal #41 - Feb 2001 + Programming Topics</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/journals/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c78/">Overload</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c163/">41</a>
                    (7)
<br />

                                            <a href="https://members.accu.org/index.php/journals/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c65/">Programming</a>
                    (877)
<br />

                                            <a href="https://members.accu.org/index.php/journals/c163-65/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/journals/c163+65/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Extensibility - A Reason For Using Streams in C++</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 26 February 2001 16:46:05 +00:00 or Mon, 26 February 2001 16:46:05 +00:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e16" id="d0e16"></a></h2>
</div>
<p>Should C++ streams be preferred as a method of i/o over the
C-style <tt class="literal">&lt;cstdio&gt;</tt> functions? Well,
the short answer is a resounding yes, but many people and in
particular those coming from a C background, are slow to move to
them. In my experience, it is common for people to pick up on STL
(and use it to the point where they could not manage without it)
but they still can not see the advantages of streams.</p>
<p>This article will attempt to show by means of an ongoing
example, the reasons for the resounding yes stated above. First, a
simple example of a C-style output statement will be presented,
followed by the equivalent using C++ streams. In passing, we will
note that the streams library defines how the user can implement
custom streams, and that the run-time polymorphism granted by the
design of streams gives us flexibility not afforded by the
&lt;cstdio&gt; functions. The streams approach will then be
developed to show how the extensibility of streams can be used to
produce code that is simpler and more self-documenting.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e25" id="d0e25"></a>Example and
Discussion</h2>
</div>
<p>Recently on the accu-general mailing list, Hubert Matthews
posted an example very similar to the following [<a href=
"#HM">HM</a>]:</p>
<p>First, C-style code like this:</p>
<pre class="programlisting">
std::sprintf(buf, &quot;%04d/%02d/%02d %02d:%02d\n&quot;, (current_tm.tm_year + 1900),
                  (current_tm.tm_mon + 1), current_tm.tm_mday,
                    current_tm.tm_hour, current_tm.tm_min);
</pre>
<p>Then, the C++ streams equivalent for comparison:</p>
<pre class="programlisting">
os    // os is an instance of std::ostream
  &lt;&lt; setw(4) &lt;&lt; setfill('0') &lt;&lt; (time_value.tm_year + 1900) &lt;&lt; '/'
  &lt;&lt; setw(2) &lt;&lt; setfill('0') &lt;&lt; (time_value.tm_mon + 1) &lt;&lt; '/'
  &lt;&lt; setw(2) &lt;&lt; setfill('0') &lt;&lt; time_value.tm_mday  &lt;&lt; ' '
  &lt;&lt; setw(2) &lt;&lt; setfill('0') &lt;&lt; time_value.tm_hour  &lt;&lt; ':'
  &lt;&lt; setw(2) &lt;&lt; setfill('0') &lt;&lt; time_value.tm_min;
</pre>
<p>Hubert asked in his posting: &quot;The old <tt class=
"literal">stdio</tt> way seems much more efficient in terms of
readability, typing, run-time speed and space. Are type-safety and
the avoidance of possible buffer overflows (which are extremely
unlikely in this case) worth it?&quot;</p>
<p>The compile time type safety of the latter (C++ streams) version
is certainly a big plus (indeed this is probably the most often
quoted reason for preferring C++ streams over sticking to the
C-style <tt class="literal">&lt;cstdio&gt;</tt> functions).
Further, it should be noted that some of the most likely sources of
error have been transferred from run time to compile time. It is
true that memory allocation and deletion are typically an overhead
with streams. Having said that, input and output typically are not
fast operations, so any such saving in this area should be
considered an optimisation - that is, only carried out when an
unacceptable lack of performance has been measured.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e51" id="d0e51"></a>Run-Time
Polymorphism</h2>
</div>
<p>Moving on, consider how we could change the destination of the
output. The C-style example above uses <tt class=
"function">printf()</tt>, which is actually equivalent to
<tt class="function">fprintf()</tt> with the output directed to
stdout. Therefore, it is not a problem to write code the output
from which can be directed to either to stdout or to some other
file created by the program. Indeed, it is even possible by using
<tt class="function">fprintf()</tt>, to write code in which the
binding of the output destination - be it to a file on disk or to
<tt class="literal">stdout</tt> - is at run-time, because
<tt class="literal">stdout</tt> is actually just a built in
instance of a <tt class="type">FILE</tt> type. However, often it is
desirable for the possible output destinations to include a buffer
in memory, as well as a disk file and <tt class=
"literal">stdout</tt>. Here, the <tt class=
"literal">&lt;cstdio&gt;</tt> functions are more limiting, and in
fact, there is no obvious way to achieve it: the only <tt class=
"literal">&lt;cstdio&gt;</tt> function facilitating this is
<tt class="function">sprintf()</tt>, and using this necessitates
changing the code, whereas streams are interchangeable at run-time.
Certainly, it should be possible to have an instance of a
<tt class="type">FILE</tt> type that binds its destination to a
memory buffer, but no such thing exists in the <tt class=
"literal">&lt;cstdio&gt;</tt> library. Further, it appears that
there is no way for the user to implement it, as this would mean
interacting with the internals of <tt class="type">FILE</tt>, which
means poking around in the implementation details.</p>
<p>The C++ output streams library includes string streams. For
example, <tt class=
"classname">std::basic_ostringstream&lt;&gt;</tt> binds the
destination to a standard library string. Further, the streams
library defines how to implement user-defined streams. As output
streams are all derived from the common base class <tt class=
"classname">std::basic_ostream&lt;&gt;</tt>, so a function of the
form</p>
<pre class="programlisting">
template &lt;typename T&gt; void f(std::basic_ostream&lt;T&gt;&amp; os) { ... }
</pre>
<p>will work for any output stream including those implemented by
the user.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e107" id="d0e107"></a>User-Defined
Extensions</h2>
</div>
<p>Now back to the code shown above which writes an object of type
<tt class="type">tm</tt> to an output stream. What we would prefer
is to write is code like:</p>
<pre class="programlisting">
std::cout &lt;&lt; format_date_time(4, 2, 2, 2, 2, '0') &lt;&lt; time_value;
</pre>
<p>If we can write the code like this, we will have achieved a
great step forward in readability, not particularly because the
code is so much shorter, but because it is self documenting - it
says exactly what it does! This is the starting point of the
development of our own extensions that will make it possible to
write the code this way. The reason for doing this is to present an
example of how such an extension can be developed; although this
involves some work on the part of the developer, the result can be
used over and over again. For the purposes of this article we will,
to keep things simple, take some liberties. We will:</p>
<div class="orderedlist">
<ol type="1">
<li>
<p>Develop for streams of ordinary chars, so we can use things like
<tt class="classname">std::ostream</tt>, ignoring the longer
template forms.</p>
</li>
<li>
<p>Use our own formatting, ignoring the locales in the C++ standard
library.</p>
</li>
<li>
<p>Hardwire delimiters, such as '/' for delimiting days and months,
and ':' for delimiting hours and minutes.</p>
</li>
</ol>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e132" id="d0e132"></a>A Simple
User-Defined Output Operator</h3>
</div>
<p>To start with, let us leave out the formatting, and content
ourselves with being able to write</p>
<pre class="programlisting">
std::cout &lt;&lt; time_value
</pre>
<p>This is easy. We just write our own output operator, placing its
declaration in a header file:</p>
<pre class="programlisting">
// io_time.h
#ifndef IO_TIME_H
#define IO_TIME_H
#include &lt;iosfwd&gt;
namespace io_time {
  std::ostream&amp; operator&lt;&lt;(  std::ostream&amp; os, std::tm const&amp; time_value);
}
#endif // IO_TIME_H
</pre>
<p>and its definition in an implementation file (this is possible
because we are sticking to plain char):</p>
<pre class="programlisting">
// io_time.cpp
namespace io_time {
  std::ostream&amp; operator&lt;&lt;(  std::ostream&amp; os, std::tm const&amp; time_value) {
    os &lt;&lt; (time_value.tm_year + 1900) &lt;&lt; '/'
       &lt;&lt; (time_value.tm_mon + 1) &lt;&lt; '/' &lt;&lt; time_value.tm_mday  &lt;&lt; ' '
       &lt;&lt; time_value.tm_hour &lt;&lt; ':' &lt;&lt; time_value.tm_min;
    return os;
  }
}
</pre>
<p>Now we can write the simplified code (at this point we are still
not concerning ourselves with formatting).</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e149" id="d0e149"></a>A User-Defined
Manipulator - Header File</h3>
</div>
<p>The next step is to provide the formatting mechanism - the
manipulator format_date_time.</p>
<p>The standard library provides manipulators such as <tt class=
"function">setfill()</tt> and <tt class="function">setw()</tt>,
which in the case of these examples alter (respectively) the fill
character and the width of the output field. These are specified as
functions returning objects that are inserted into the stream
causing the stream to be manipulated, and we can follow the same
pattern. We need a header file:</p>
<pre class="programlisting">
// io_time.h
namespace io_time {
// in which we define the formatting object class:
  class date_time_formatter {
  public:
    date_time_formatter( unsigned int in_year_width, unsigned int in_month_width,
                        unsigned int in_day_width,  unsigned int in_hour_width,
                        unsigned int in_minute_width, char in_fill_char);
    date_time_formatter(date_time_formatter const&amp; original);
    void set_ostream_info(std::ostream&amp; os) const;
  private:
    unsigned int const  year_width;
    unsigned int const  month_width;
    unsigned int const  day_width;
    unsigned int const  hour_width;
    unsigned int const  minute_width;
    char const  fill_char;
    date_time_formatter&amp; operator=(date_time_formatter const&amp;);
  };
</pre>
<p>The contents contain no surprises: this class just holds some
formatting information. Note however, the <tt class=
"methodname">set_ostream_info()</tt> member function, which takes
as its parameter, an object of type <tt class=
"classname">std::ostream</tt> - when called it will apply the
format information it contains to this stream. Also, assignment is
disabled - as the mode of usage does not require assignment, this
is (probably) best, to avoid any possibility of complications.</p>
<p>Next we need the actual manipulator function:</p>
<pre class="programlisting">
  date_time_formatter format_date_time( unsigned int year_w, unsigned int month_w,
                           unsigned int day_w,  unsigned int hour_w,
                           unsigned int min_w,  char fill_c) {
    return date_time_formatter( year_w, month_w, day_w, hour_w, min_w, fill_c);
  }
</pre>
<p>an output operator for objects of this class:</p>
<pre class="programlisting">
std::ostream&amp; operator&lt;&lt;(  std::ostream&amp; os, date_time_formatter const&amp; formatter);
</pre>
<p>as before, an output operator which outputs an object of type
tm:</p>
<pre class="programlisting">
std::ostream&amp; operator&lt;&lt;(  std::ostream&amp; os, std::tm const&amp; time_value);
</pre>
<p>and this completes the header file:</p>
<pre class="programlisting">
} // end namespace io_time
</pre></div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e188" id="d0e188"></a>A User-Defined
Manipulator - Implementation File</h3>
</div>
<p>Now to construct the implementation file.</p>
<pre class="programlisting">
// io_time.cpp
#include &quot;io_time.h&quot;
#include &lt;cctype&gt;
</pre>
<p>In doing this we face the problem of where to store the
formatting information from <tt class=
"classname">date_time_formatter</tt>. In the standard library the
base class <tt class="classname">std::ios_base</tt> contains
storage for the state set by the likes of <tt class=
"methodname">setfill()</tt> and <tt class="methodname">setw()</tt>,
but we have no power to extend this.</p>
<p>To accommodate this need, the streams library provides a
mechanism for the developer to provide custom information storage:
here we will be using the <tt class="classname">ios_base</tt>
member functions <tt class="methodname">iword()</tt> and (the
<tt class="literal">static</tt>) <tt class=
"methodname">xalloc()</tt>. The <tt class="methodname">iword()</tt>
member function has return type <tt class="type">long&amp;</tt> and
takes an <tt class="type">int</tt> parameter. This parameter -
which should be obtained from <tt class="methodname">xalloc()</tt>
- identifies a particular user-specified (and zero-initialised)
flag (for further explanation the reader is referred to a standard
library text such as the one by Nicolai Josuttis [<a href=
"#NJ">NJ</a>]).</p>
<p>Next, we need to reserve some flags, and provide some helper
functions that make their use less long-winded. The best place for
all this is in the anonymous namespace. First, the constants naming
the flags:</p>
<pre class="programlisting">
Namespace {
  int const formatted_flag_index   = std::ios_base::xalloc();
  int const year_width_index   = std::ios_base::xalloc();
  int const month_width_index   = std::ios_base::xalloc();
  int const day_width_index       = std::ios_base::xalloc();
  int const hour_width_index   = std::ios_base::xalloc();
  int const minute_width_index     = std::ios_base::xalloc();
  int const fill_char_index       = std::ios_base::xalloc();
</pre>
<p>and then the helpers:</p>
<pre class="programlisting">
bool is_formatted(std::ostream&amp; os) { return (0 != os.iword(formatted_flag_index)); }
  int const year_width(std::ostream&amp; os) { return os.iword(year_width_index); }
  int const month_width(std::ostream&amp; os) { return os.iword(month_width_index); }
  int const day_width(std::ostream&amp; os) { return os.iword(day_width_index); }
  int const hour_width(std::ostream&amp; os) { return os.iword(hour_width_index); }
  int const minute_width(std::ostream&amp; os) { return os.iword(minute_width_index); }
  void set_fill_char(std::ostream&amp; os) { 
    int fill_char = os.iword(fill_char_index);
    if (std::isprint(fill_char)) os.fill(fill_char);
  }
} // end anonymous namespace
</pre>
<p>Note that setting the fill character is delegated to the helper
function <tt class="function">set_fill_char()</tt>: this is to
accommodate the possibility that the user may have set the fill
character to a non-printing character - if this happens, the fill
character is ignored.</p>
<p>Moving on:</p>
<pre class="programlisting">
namespace io_time {
  void date_time_formatter::set_ostream_info(std::ostream&amp; os) const {
    os.iword(year_width_index)   = year_width;
    os.iword(month_width_index)   = month_width;
    os.iword(day_width_index)   = day_width;
    os.iword(hour_width_index)   = hour_width;
    os.iword(minute_width_index)   = minute_width;
    os.iword(fill_char_index)     = fill_char;
    os.iword(formatted_flag_index ) = true;
  }
  std::ostream&amp; operator&lt;&lt;( std::ostream&amp; os, date_time_formatter const&amp; formatter) {
    formatter.set_ostream_info(os);
    return os;
  }
</pre>
<p>Now it can be seen how the manipulation of the stream works and
why <tt class="classname">date_time_formatter</tt> has the member
function <tt class="methodname">set_ostream_info()</tt>: the actual
work is delegated to <tt class="methodname">set_ostream_info()</tt>
- after all it is this object which has the information needed, so
let it pass the information on to where it is needed. All that the
output operator must do now is call this function on the formatter
object, passing the stream object as the argument to the call.</p>
<p>There remains only to define the output operator for tm type
objects, and the constructors for <tt class=
"classname">date_time_formatter</tt> (which will not be listed here
for the sake of simplicity - all they have to do is initialise the
object's state).</p>
<pre class="programlisting">
std::ostream&amp; operator&lt;&lt;( std::ostream&amp; os, std::tm const&amp; time_value) {
    using std::setw;
    if (is_formatted(os)) {
      set_fill_char(os);
      os  &lt;&lt; setw(year_width(os)) &lt;&lt; (time_value.tm_year + 1900) &lt;&lt; '/';
      set_fill_char(os);
      os  &lt;&lt; setw(month_width(os)) &lt;&lt; (time_value.tm_mon + 1) &lt;&lt; '/';
      set_fill_char(os); 
      os  &lt;&lt; setw(day_width(os)) &lt;&lt; time_value.tm_mday  &lt;&lt; ' ';
      set_fill_char(os);
      os  &lt;&lt; setw(hour_width(os)) &lt;&lt; time_value.tm_hour &lt;&lt; ':';
      set_fill_char(os);
      os  &lt;&lt; setw(minute_width(os)) &lt;&lt; time_value.tm_min;
    }
    else {
      os  &lt;&lt; (time_value.tm_year + 1900) &lt;&lt; '/' &lt;&lt; (time_value.tm_mon + 1) &lt;&lt; '/'
          &lt;&lt; time_value.tm_mday  &lt;&lt; ' ' &lt;&lt; time_value.tm_hour &lt;&lt; ':'
          &lt;&lt; time_value.tm_min;
    }
    os.iword(formatted_flag_index ) = false;
    return os;
  }
</pre></div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e273" id="d0e273"></a>Finally</h2>
</div>
<p>That is it - we have arrived! We can now write:</p>
<pre class="programlisting">
std::cout &lt;&lt; format_date_time(4, 2, 2, 2, 2, '0') &lt;&lt; time_value;
</pre>
<p>as we wanted to. Further, we can use the io_time extension
whenever it suits us, so we can keep on writing expressions like
this.</p>
<p>There is much more development which could be done. A couple of
examples are ...</p>
<p>The typing of the parameters to <tt class=
"function">format_date_time()</tt> could be strengthened</p>
<p>Modification could be made to the formatting to use standard
locale information</p>
<p>... but there is only so much which can usefully be fitted into
one article.</p>
<p>The C++ streams library may not be perfect, but it is still very
useful. Hopefully this article has demonstrated where at least some
of that usefulness lies.</p>
<div class="bibliography">
<div class="titlepage">
<h2><a name="d0e295" id="d0e295"></a>References and
Acknowledgements</h2>
</div>
<div class="bibliomixed"><a name="HM" id="HM"></a>
<p class="bibliomixed">[HM] Hubert Matthews posting on the
<span class="bibliomisc"><tt class=
"literal">accu-general</tt></span> email list on the thread &quot;String
streams v. sprintf&quot; on 3/11/2000. <span class=
"bibliomisc"><span class="emphasis"><em>Thanks are due to Hubert
for his help during an email discussion prior to the writing of
this article (I was unaware of the mechanism for adding
user-defined formatting information to streams until Hubert came
across the explanation in [<a href="#NJ">NJ</a>] and pointed me to
it)</em></span></span>.</p>
</div>
<div class="bibliomixed"><a name="NJ" id="NJ"></a>
<p class="bibliomixed">[NJ] Nicolai Josuttis, <span class=
"citetitle"><i class="citetitle">The C++ Standard Library: A
Tutorial and Reference</i></span>, published by Addison-Wesley.</p>
</div>
</div>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
