    <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  :: A bin Manipulator For IOStreams</title>
        <link>https://members.accu.org/index.php/articles/350</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>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + Overload Journal #55 - Jun 2003</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/articles/">All</a>

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

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

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

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

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

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c192/">55</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-192/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+192/">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;A bin Manipulator For IOStreams</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 02 June 2003 22:57:04 +01:00 or Mon, 02 June 2003 22:57:04 +01:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e19" id="d0e19"></a></h2>
</div>
<p>The standard stream classes support different bases when doing
formatted I/O with integers: there are manipulators <tt class=
"literal">std::oct</tt>, <tt class="literal">std::dec</tt>, and
<tt class="literal">std::hex</tt> for octal, decimal, and
hexadecimal I/O, respectively. There is, however, no manipulator
for writing and reading integers using other bases, although
something like base two seems to be a natural choice, too.</p>
<p>The question is thus what manipulators are and what a
manipulator for formatting integers using base two would look like.
For this discussion, it is sufficient to concentrate on
manipulators without arguments. These are quite simple: A
manipulator without argument is (at least normally) just a function
with a certain signature. For example, <tt class=
"literal">std::hex</tt> looks something like this:</p>
<pre class="programlisting">
namespace std {
  std::ios_base&amp; hex(std::ios_base&amp; ib) {
    ib.setf(std::ios_base::hex,
    std::ios_base::basefield);A bin Manipulator For IOStreams
    return ib;
  }
}
</pre>
<p>This function just clears a bunch of bits (namely those which
are set in <tt class="literal">basefield</tt>) in the formatting
flags and then sets a few of them again (namely those which are set
in <tt class="literal">hex</tt>). The standard's formatting
functions for integers interpret these flags to determine how
integers are to be formatted and act accordingly. However, these
functions only work correctly for the bases decimal, octal, and
hexadecimal (well, at least these are the only bases for which they
are guaranteed to work).</p>
<p>Before going more into the formatting flags let's discuss how
these manipulator functions actually work. The above function is
used to manipulate the stream with an expression like this:</p>
<pre class="programlisting">
std::cout &lt;&lt; std::hex;
</pre>
<p>What happens is actually pretty simple: the shift operator is
overloaded to take arguments with the signature <tt class=
"literal">std::ios_base&amp;(*)(std::ios_base&amp;)</tt> and this
overload just calls the corresponding function, i.e. something like
this (actually, this function is implemented as a template but this
would only obfuscate the issue):</p>
<pre class="programlisting">
std::ostream&amp;
std::ostream::operator&lt;&lt;
   (std::ios_base&amp;(*m)(std::ios_base&amp;)) {
  m(*this);
  return *this;
}
</pre>
<p>That is, if you want to implement a manipulator, you would just
implement a function with the appropriate signature: it takes a
stream (or one of its base classes: <tt class=
"literal">std::ios_base</tt> or <tt class="literal">std::ios</tt>)
as argument and returns this argument again (the argument and
return type have to be identical but there is some choice toward
the argument types you can use). The function would just do the
manipulation on the argument and then return the argument.</p>
<p>To implement a manipulator which modifies all integer output to
become binary is, however, non-trivial because it requires
interfering with how integers are formatted and the standard
routines for this are not prepared to support bases other than 8,
10, and 16. However, it is doable because it is possible to supply
the formatting code for integers by implementing a class derived
from the <tt class="literal">std::num_put</tt> facet which is then
installed (when necessary) by the manipulator.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e71" id="d0e71"></a>Formatting
Integers</h2>
</div>
<p>My guess is that talking about facets is somewhat confusing so
let's walk through this whole thing, although most of the stuff
will not be related to manipulators directly (some additional stuff
on manipulators will, however, come up below).</p>
<p>Facets are a means to adapt certain stuff to local conventions.
For example, in Germany we use &quot;,&quot; as a decimal point and &quot;.&quot; as a
thousands separator while in other (weird) places, &quot;.&quot; is used as a
decimal point and &quot;,&quot; as a thousands separator. To adapt output
(and other stuff) to the conventions the user is used to, the C++
library uses &quot;facets&quot; which are just classes obeying a few
requirements (essentially, each object has to have a public member
of type <tt class="literal">std::locale::id</tt> named <tt class=
"literal">id</tt> and all public functions should be <tt class=
"literal">const</tt>, i.e. the objects should be immutable). There
are several of them but the interesting one here is <tt class=
"literal">num_put:</tt> the facet doing numerical formatting.
Actually, this is not a class but a class template. I will use a
template here because it is less confusing than using the
specialization we will need to install later.</p>
<p>To replace the functions for formatting integers, a class is
derived from <tt class="literal">num_put</tt> and a few functions
are overridden:</p>
<pre class="programlisting">
template &lt;typename cT, typename OutIt&gt;
class bin_num_put: public
std::num_put&lt;cT, OutIt&gt; {
  OutIt do_put(OutIt to,
               std::ios_base&amp; fmt,
               cT fill,
               long v) const;

  OutIt do_put(OutIt to,
               std::ios_base&amp; fmt,
               cT fill,
               unsigned long v) const;
};
</pre>
<p>There are just two functions dealing with integer values, one
for signed and one for unsigned ones. Each function gets an output
iterator as argument to write individual characters to. After
writing the characters the iterator is returned as the result of
the function. The second parameter is a reference to an object
holding formatting information. The third parameter is the
character to be used for padding a value to a specific length. The
last parameter is the value to be formatted.</p>
<p>Since I'm mostly interested in getting the principle right, I
will just stick to a rather simple implementation using a fixed
width of digits. A &quot;real&quot; implementation might want to omit leading
zeros (this isn't really hard to implement either). Effectively,
just one formatting function is needed because formatting of signed
values can be delegated to formatting unsigned values in this case.
The formatting functions will use another facet, <tt class=
"literal">ctype</tt>, to convert the characters <tt class=
"literal">0</tt> and <tt class="literal">1</tt> to values of the
appropriate character type:</p>
<pre class="programlisting">
template &lt;typename cT, typename OutIt&gt;
OutIt
bin_num_put&lt;cT, OutIt&gt;::do_put(OutIt to,
                               std::ios_base&amp; fmt,
                               cT fill,
                               long v) const {
  return do_put(to, fmt, fill,
                static_cast&lt;unsigned long&gt;(v));
}

template &lt;typename cT, typename OutIt&gt;
OutIt
bin_num_put&lt;cT, OutIt&gt;::do_put(OutIt to,
                               std::ios_base&amp; fmt,
                               cT fill,
                               unsigned long v) const {
  char narrow[] = &quot;01&quot;;
  cT wide[2] = { 0 };
  std::use_facet&lt;std::ctype&lt;cT&gt; &gt;(
    fmt.getloc()).widen(begin(narrow),
    end(narrow) - 1,
    begin(wide));
  cT buffer[std::numeric_limits&lt;unsigned long&gt;::digits];
  std::fill(begin(buffer),
  end(buffer),
  wide[0]);
  cT* end = end(buffer);
  for (; v != 0; v /= 2)
    *-end = wide[v % 2];
  return std::copy(begin(buffer),
  end(buffer), to);
}
</pre>
<p>The above code uses the following two auxiliary functions to get
an iterator (in this case actually just a pointer) to the beginning
and the end of a statically sized array:</p>
<pre class="programlisting">
namespace {
  template &lt;typename T,
    int sz&gt; T* begin(T (&amp;a)[sz]){
    return a;
  }

  template &lt;typename T,
            int sz&gt; T* end(T (&amp;a)[sz]) {
    return a + sz;
  }
}
</pre>
<p>If you don't understand these two functions, just don't worry
about them: I'm using them to conveniently get iterators to the
beginning and the end of a statically sized array.</p>
<p>The above code explicitly excludes the last element of the array
<tt class="literal">narrow</tt> (this is what the -1 is good for).
The reason for this is that the array <tt class=
"literal">narrow</tt> has the size three: the null character at the
end of the string is included in the array. That is, the line
initializing <tt class="literal">narrow</tt> is equivalent to this
one:</p>
<pre class="programlisting">
char narrow[] = { '0', '1', 0 };
</pre>
<p>The actual formatting of the binary number is trivial: an array
with sufficient zeros is obtained and it is filled with digits
starting from the end until there are no further digits. This
approach also works for formatting integers for bases other than
two and this will be used below. Once all digits are available, the
array is copied to its destination. The only somewhat tricky part
is getting the appropriate characters representing <tt class=
"literal">0</tt> and <tt class="literal">1</tt> because we don't
really know the character type. This is done by using the facet
<tt class="literal">std::ctype&lt;cT&gt;</tt> which can &quot;widen&quot; a
narrow character to the corresponding character type.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e142" id="d0e142"></a>The
<tt class="literal">bin</tt> Manipulator</h2>
</div>
<p>OK, now that the routines for formatting integers as binary are
implemented, they need to be installed into our stream to have them
used. Before implementing a corresponding manipulator, lets do this
in a small test program. The facets are objects held by a &quot;locale&quot;
and it is necessary to construct a locale object with the default
<tt class="literal">num_put</tt> facet replaced by the new facet.
To provide this, it is necessary to instantiate the bin_num_put
class template with appropriate types, i.e. with <tt class=
"literal">char</tt> as character type and <tt class=
"literal">std::ostreambuf_iterator&lt;char&gt;</tt> as iterator
type: these are the types used when doing numeric formatting using
std::cout. If a wide character stream like <tt class=
"literal">std::wcout</tt> is used, <tt class="literal">char</tt>
has to be replaced by <tt class="literal">wchar_t</tt>, of course.
Once the new locale is constructed from an existing locale and the
<tt class="literal">bin_num_put</tt> class, it is installed into
the corresponding stream using the <tt class="literal">imbue()</tt>
function:</p>
<pre class="programlisting">
int main() {
  typedef std::ostreambuf_iterator&lt;char&gt;
                               iterator;
  std::locale loc =
    std::locale(std::cout.getloc(),
                new bin_num_put&lt;char, iterator&gt;());
  std::cout.imbue(loc);
  std::cout &lt;&lt; 10 &lt;&lt; &quot;\n&quot;;
}
</pre>
<p>We can just put the code installing the binary formatting into a
manipulator using an appropriate template to make it feasible with
all kinds of streams:</p>
<pre class="programlisting">
template &lt;typename cT, typename traits&gt;
std::basic_ios&lt;cT, traits&gt;&amp;
bin(std::basic_ios&lt;cT, traits&gt;&amp; ios) {
  typedef std::ostreambuf_iterator&lt;cT&gt;
                             iterator;
  std::locale loc =
             std::locale(ios.getloc(),
             new bin_num_put&lt;cT, iterator&gt;());
  ios.imbue(loc);
  return ios;
}
</pre>
<p>... and use it in the expected way:</p>
<pre class="programlisting">
std::cout &lt;&lt; bin &lt;&lt; 10 &lt;&lt; &quot;\n&quot;;
</pre>
<p>Well, except that there is no easy way to turn binary formatting
off again! Since we have replaced the formatting routine we can use
the <tt class="literal">std::hex</tt> manipulator as often as we
want: there will be no change at all.</p>
<pre class="programlisting">
std::cout &lt;&lt; bin &lt;&lt; 10 &lt;&lt; std::hex
          &lt;&lt; 10 &lt;&lt; &quot;\n&quot;; // does not work
</pre>
<p>To do something like this, it is necessary to take the value of
formatting flags into account and act correspondingly. Before
supporting use of the standard manipulators it is, however, useful
to adapt the case to cope with arbitrary bases.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e193" id="d0e193"></a>Storing
Formatting Information</h2>
</div>
<p>To do this, the selected base should be stored with the stream
such that it can be used by the formatting function. The obvious
place to store such information is in an <tt class=
"literal">iword()</tt> of the <tt class="literal">fmt</tt> member.
Here are corresponding manipulators which also install the needed
facet only if it is not yet present:</p>
<pre class="programlisting">
static int base_index =
                std::ios_base::xalloc();
template &lt;typename cT, typename traits&gt;
std::basic_ios&lt;cT, traits&gt;&amp;
install_bin(std::basic_ios&lt;cT,traits&gt;&amp; ios,
            int base) {
  ios.iword(base_index) = base;
  typedef std::ostreambuf_iterator&lt;cT&gt;
                                iterator;
  if(!dynamic_cast
      &lt;bin_num_put&lt;cT, iterator&gt; const*&gt;(
        &amp;std::use_facet&lt;std::num_put&lt;cT,
          iterator&gt; &gt;(ios.getloc())))
    ios.imbue(std::locale(ios.getloc(),
    new bin_num_put&lt;cT, iterator&gt;()));
  return ios;
}

template &lt;typename cT, typename traits&gt;
std::basic_ios&lt;cT, traits&gt;&amp;
bin(std::basic_ios&lt;cT, traits&gt;&amp; ios) {
  return install_bin(ios, 2);
}

template &lt;typename cT, typename traits&gt;
std::basic_ios&lt;cT, traits&gt;&amp;
oct(std::basic_ios&lt;cT, traits&gt;&amp; ios) {
  return install_bin(ios, 8);
}

template &lt;typename cT, typename traits&gt;
std::basic_ios&lt;cT, traits&gt;&amp;
dec(std::basic_ios&lt;cT, traits&gt;&amp; ios) {
  return install_bin(ios, 10);
}

template &lt;typename cT, typename traits&gt;
std::basic_ios&lt;cT, traits&gt;&amp;
hex(std::basic_ios&lt;cT, traits&gt;&amp; ios) {
  return install_bin(ios, 16);
}
</pre>
<p>The function <tt class="literal">xalloc()</tt> &quot;allocates&quot; a new
index for formatting information in the stream objects. This index
can be used with the <tt class="literal">iword()</tt> function of
streams: this function returns a reference to an integer. This
integer is associated with the stream. Initially, the value
returned is set to zero but the above code does not take advantage
of this feature. If an integer is not sufficient, a pointer to the
formatting information can be stored using the <tt class=
"literal">pword()</tt> function.</p>
<p>There is a function called by the various manipulators which
sets the corresponding base and checks whether the appropriate
facet is installed. This is done by obtaining the currently
installed facet and testing whether it is an instantiation of
<tt class="literal">bin_num_put</tt>. If it is not, this facet is
installed. What remains to be done is to use the base in the facet,
too. The modified code looks like this:</p>
<pre class="programlisting">
template &lt;typename cT, typename OutIt&gt;
OutIt
bin_num_put&lt;cT, OutIt&gt;::do_put(OutIt to,
                  std::ios_base&amp; fmt,
                  cT fill,
                  unsigned long v) const {
  char narrow[] = &quot;0123456789abcdef&quot;;
  cT wide[16] = { 0 };
  std::use_facet&lt;std::ctype&lt;cT&gt; &gt;(
        fmt.getloc()).widen(begin(narrow),
        end(narrow) - 1, begin(wide));
  cT buffer[std::numeric_limits&lt;unsigned
                          long&gt;::digits];
  std::fill(begin(buffer), end(buffer),
                                wide[0]);
  int base = fmt.iword(base_index);
  for (cT* it = end(buffer)
       ; v != 0
       ; v /= base)
    *-it = wide[v % base];
    return std::copy(begin(buffer),
                     end(buffer),
                     to);
}
</pre>
<p>Now the manipulators can be tested. For example:</p>
<pre class="programlisting">
int main(int ac, char* av[]) {
int val = ac == 1 ? 10
                   : std::atoi(av[1]);
std::cout &lt;&lt; &quot;bin: &quot; &lt;&lt; bin &lt;&lt; val
                              &lt;&lt; &quot;\n&quot;;
std::cout &lt;&lt; &quot;oct: &quot; &lt;&lt; oct &lt;&lt; val
                              &lt;&lt; &quot;\n&quot;;
std::cout &lt;&lt; &quot;dec: &quot; &lt;&lt; dec &lt;&lt; val
                              &lt;&lt; &quot;\n&quot;;
std::cout &lt;&lt; &quot;hex: &quot; &lt;&lt; hex &lt;&lt; val
                              &lt;&lt; &quot;\n&quot;;
}
</pre>
<p>This code is not yet perfect. Actually, several things need to
be handled but these are relatively simple and don't need specific
new knowledge of the standard library. In particular, the following
aspects are not yet addressed but would need handling in a
reasonable implementation:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Negative values conventionally use a minus sign followed by the
absolute value rather than the two's complement. That is, the
function taking a long as argument cannot directly use the
<tt class="literal">unsigned long</tt> version, at least not for
negative decimal values.</p>
</li>
<li>
<p>Although quite usual for binary values, leading zeros are
normally stripped for other bases. To get leading zeros for binary
values while omitting them for other bases, the <tt class=
"literal">width()</tt> currently installed in the stream could be
used.</p>
</li>
<li>
<p>The formatting has to take care of padding, i.e. it has to add
fill characters: if <tt class="literal">width()</tt> is non-zero,
there should be at least that many characters written to the
sequence. Padding is a little bit tricky because there are three
possible places where padding, i.e. copies of the <tt class=
"literal">fill</tt> argument, should go:</p>
<div class="itemizedlist">
<ul type="circle">
<li>
<p>to the left of the value</p>
</li>
<li>
<p>the right of the value</p>
</li>
<li>
<p>between a leading sign and the value or to the left if there is
no sign</p>
</li>
</ul>
</div>
</li>
</ul>
</div>
<p>This is specified by <tt class="literal">fmt.flags()</tt> &amp;
<tt class="literal">std::ios_base::adjustfield()</tt>: the
corresponding values are <tt class="literal">left</tt>, <tt class=
"literal">right</tt>, and <tt class="literal">internal</tt>. In any
case, after the formatting, the <tt class="literal">width()</tt>
should be set to <tt class="literal">0</tt>.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e285" id="d0e285"></a>Arbitrary
Bases</h2>
</div>
<p>Of course, most of the formatting issues could be taken care of
by the base class: the <tt class="literal">do_put()</tt> function
could check whether the base is 2 and if it is not delegate
processing to the base class. On the other hand, the above facet is
capable of formatting integers according to arbitrary bases as long
as the base is bigger than 1 and there are sufficient different
characters configured to represent the digits. A manipulator
setting an arbitrary base would, however, require a parameter. The
approach to manipulators with parameters is to just provide a class
with a suitable constructor and a shift operator:</p>
<pre class="programlisting">
struct setbase {
  setbase(int base): mBase(base) {}
  int mBase;
};

template &lt;typename cT, typename traits&gt;
std::basic_ostream&lt;cT, traits&gt;&amp;
operator&lt;&lt; (std::basic_ostream&lt;cT,
                            traits&gt;&amp; os,
            setbase const&amp; sb) {
  install_bin(os, sb.mBase);
  return os;
}
</pre>
<p>This manipulator is obviously used identically to the <tt class=
"literal">std::setw</tt> or <tt class=
"literal">std::setprecision</tt> manipulators:</p>
<pre class="programlisting">
std::cout &lt;&lt; setbase(3) &lt;&lt; 10 &lt;&lt; &quot;\n&quot;;
</pre>
<p>The only problem with this manipulator is that the user can set
bases which are out of the supported range (with the code above [2,
16]).</p>
<p>Now let's get back to supporting the standard manipulators: it
would be useful if the standard manipulators could still be used,
eg. for mixed binary and hexadecimal output:</p>
<pre class="programlisting">
std::cout &lt;&lt; &quot;binary: &quot; &lt;&lt; bin &lt;&lt; i
          &lt;&lt; &quot;\n&quot; &lt;&lt; &quot;hexadecimal: &quot;
          &lt;&lt; std::hex &lt;&lt; i &lt;&lt; &quot;\n&quot;;
</pre>
<p>To do so, the formatting code has to become aware of the use of
<tt class="literal">std::hex</tt>. This can be detected if the
special manipulators clear all bits in the <tt class=
"literal">basefield</tt>: the standard manipulators have to set
some bits because the case where no bits are set is treated
specially for integer input (it is equivalent to the <tt class=
"literal">%i</tt> format specifier of <tt class=
"literal">scanf()</tt>, i.e. the base of the integer read is
determined by the first digits). Thus, the binary formatting code
can be rewritten to take special action if the <tt class=
"literal">basefield</tt> is nonzero. A simple approach is
delegating processing to the base class in this case. This is
achieved by adding these two lines to the start of the <tt class=
"literal">do_put()</tt> function:</p>
<pre class="programlisting">
if(fmt.flags() &amp; std::ios_base::basefield)
  return std::num_put&lt;cT,
        OutIt&gt;::do_put(to, fmt, fill, v);
</pre>
<p>The change to the manipulator is even simpler: it just takes the
following line to clear the bits in the <tt class=
"literal">basefield</tt>:</p>
<pre class="programlisting">
ios.unsetf(std::ios_base::basefield);
</pre>
<p>Of course, the overall semantics of using the base class version
change the behavior to some extent. At least the open issues noted
above are covered. Also, the standard <tt class=
"literal">do_put()</tt> functions take care of thousands separators
(if these are configured for the locale) and some special
formatting like upper and lower case letters for hexadecimal
values.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e345" id="d0e345"></a>Stream
Callbacks</h2>
</div>
<p>As a final round-off to the IOStream manipulator discussion
let's deal with those funny callbacks defined in <tt class=
"literal">std::ios_base</tt>. Streams support registration of
callbacks which are called in case of certain events. The main use
of these callbacks is support for resource management when
associating pointers with streams via the <tt class=
"literal">pword()</tt> function. There are three events defined in
<tt class="literal">std::ios_base</tt>:</p>
<div class="variablelist">
<dl>
<dt><span class="term">erase_event:</span></dt>
<dd>
<p>This event is notified when resources associated with the stream
should be released. This event is called when the stream is
destroyed and prior to copying when <tt class=
"literal">copyfmt()</tt> is called.</p>
</dd>
<dt><span class="term">imbue_event:</span></dt>
<dd>
<p>This event is notified when a new locale is imbue()ed into the
stream. Since we modified the locale to take care of binary
formatting, the code below demonstrates how this event is caught to
modify the new locale, too.</p>
</dd>
<dt><span class="term">copyfmt_event:</span></dt>
<dd>
<p>This event is notified when <tt class="literal">copyfmt()</tt>
is called, after copying all formatting data to the stream. The
intent of this event is to either do a deep copy of objects pointed
to (the stream merely copies the pointers) or maintain a reference
count.</p>
</dd>
</dl>
</div>
<p>Stream callbacks are rather primitive: only functions with the
signature <tt class="literal">void(*)(std::ios_base::event,
std::ios_base&amp;, int)</tt> are supported. The first parameter
identifies the event being notified, the second identifies the
stream object for which the event is notified, and the third
parameter is a user parameter passed when registering an event. The
callback just handles the <tt class="literal">imbue_event</tt> and
imbues a modified locale if the corresponding <tt class=
"literal">num_put</tt> facet is not a modified one (note that it
has to be checked whether the facet is already there to prevent an
infinite recursion):</p>
<pre class="programlisting">
template &lt;typename cT, typename traits&gt;
void
bin_callback(std::ios_base::event ev,
             std::ios_base&amp; ios, int) {
  typedef std::ostreambuf_iterator&lt;cT&gt;
                              iterator;
  if(ev == std::ios_base::imbue_event
     &amp;&amp; !dynamic_cast&lt;bin_num_put&lt;cT,
                    iterator&gt; const*&gt;(
        std::use_facet&lt;std::num_put&lt;cT,
            iterator&gt; &gt;(ios.getloc())))
    ios.imbue(std::locale(ios.getloc(),
      new bin_num_put&lt;cT, iterator&gt;()));
}

template &lt;typename cT, typename traits&gt;
std::basic_ios&lt;cT, traits&gt;&amp;
install_bin(std::basic_ios&lt;cT,
               traits&gt;&amp; ios, int base) {
  typedef std::ostreambuf_iterator&lt;cT&gt;
                               iterator;
  if (!dynamic_cast&lt;bin_num_put&lt;cT,
                      iterator&gt; const*&gt;(
        &amp;std::use_facet&lt;std::num_put&lt;cT,
           iterator&gt; &gt;(ios.getloc()))) {
    ios.imbue(std::locale(ios.getloc(),
       new bin_num_put&lt;cT, iterator&gt;()));
    ios.register_callback(
    bin_callback&lt;cT, traits&gt;, 0);
  }
  ios.iword(base_index) = base;
  return ios;
}
</pre>
<p>The callback is registered when a new locale is installed. Since
this basically inhibits reinstalling the original locale without
using <tt class="literal">copyfmt()</tt> (<tt class=
"literal">copyfmt()</tt> copies the locale without triggering the
<tt class="literal">imbue_event</tt>), it is not necessarily the
best design. On the other hand, it might be a reasonable thing to
do anyway and the best thing I could think of for demonstrating
stream callbacks with this example.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e408" id=
"d0e408"></a>Conclusions</h2>
</div>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Manipulators are just functions with certain possible
signatures. The possible signatures are</p>
<pre class="programlisting">
std::ios_base&amp; (*)(std::ios_base&amp;)

template &lt;typename cT, typename traits&gt;
std::basic_ios&lt;cT, traits&gt;&amp;
  (*)(std::basic_ios&lt;cT, traits&gt;&amp;)

template &lt;typename cT, typename traits&gt;
std::basic_ostream&lt;cT, traits&gt;&amp;
  (*)(std::basic_ostream&lt;cT, traits&gt;&amp;)

template &lt;typename cT, typename traits&gt;
std::basic_istream&lt;cT, traits&gt;&amp;
  (*)(std::basic_istream&lt;cT, traits&gt;&amp;)
</pre></li>
<li>
<p>Manipulators can use the functions <tt class=
"literal">xalloc()</tt>, <tt class="literal">iword()</tt>, and
<tt class="literal">pword()</tt> to associate data with a
stream.</p>
</li>
<li>
<p>Numeric formatting used by the stream classes is done via facets
which can be customized to suit specific needs.</p>
</li>
</ul>
</div>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
