<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
        <title>
            Iostream manipulators for convenient extraction and insertion
            of struct tm objects
        </title>
    </head>

    <body>
        <table>
            <tr>
                <td align="left">Doc. no.</td>
                <td align="left">N2071=06-0141</td>
            </tr>
            <tr>
                <td align="left">Date:</td>
                <td align="left">2006-09-09</td>
            </tr>
            <tr>
                <td align="left">Project:</td>
                <td align="left">Programming Language C++</td>
            </tr>
            <tr>
                <td align="left">Reply to:</td>
                <td align="left">
                    <a href="mailto:sebor@roguewave.com">Martin Sebor
                </td>
            </tr>
        </table>
        <hr><!-------------------------------------------------------->
        <h1>
            Iostream manipulators for convenient extraction and insertion
            of struct tm objects
        </h1>
        <!------------------------------------------------------------>
        <h2>
            Index
        </h2>
        <ul>
            <li>
                <a href="#motivation">Motivation</a>
            </li>
            <li>
                <a href="#description">Description</a>
            </li>
            <li>
                <a href="#changes">Proposed Changes</a>
            </li>
            <li>
                <a href="#implementation">Implementation</a>
            </li>
        </ul>
        <!------------------------------------------------------------>
        <h2>
            <a name="motivation">Motivation</a>
        </h2>
        <p>

            The C++  standard library facet class  templates provide a
            robust  interface to  the localization  library,  one that
            lends  itself  well to  being  implemented  and used  with
            efficiency in mind.  The <i>get</i> and <i>put</i> parsing
            and  formatting facets  specifically  are especially  well
            suited to be used as the engine of a higher-level and more
            convenient interfaces such  as iostreams.  However, due to
            the large number and complexity of their arguments and due
            to the  complexities of the error handling involved  they
            are less than ideal for direct use by programs.

        </p>
        <p>

            The  <code>num_get</code> and  <code>num_put</code> facets
            are a  good example  of where this  design works  well and
            does not  pose any  serious problems to  programs.  Nearly
            every C++  program relies on the services  provided by the
            facets  by  virtue  of  making  calls  to  the  arithmetic
            iostream extractor  and inserter operators,  yet only very
            few programs ever need to access these facets directly. In
            fact,  many C++ programmers  are not  even aware  that the
            facets exist.

        </p>
        <p>

            Unfortunately,      the      <code>num_get</code>      and
            <code>num_put</code> facets  mentioned above are  the only
            such  example   in  the  C++   localization  library.   No
            convenient interface  similar to the  arithmetic inserters
            and  extractors exists  to make  it  as easy  to parse  or
            format   time   (or   monetary)  sequences   and   values,
            respectively, as it is  for arithmetic types. C++ programs
            that need  to do  so must code  directly to  the low-level
            interfaces  of  the   time  and  monetary  <i>get</i>  and
            <i>put</i>  facets.   We  believe that  these  interfaces,
            while  powerful, are  cumbersome enough  to use  that they
            deter most C++ programmers  from taking advantage of their
            functionality.

        </p>
        <p>

            Rather   than  dealing   with  the   intricacies   of  the
            <code>time_put</code>  facet,  C++  programmers  typically
            resort   to  using   the  C   standard   library  function
            <code>strftime</code>   which    provides   a   convenient
            interface   familiar   to  anyone   who   has  ever   used
            <code>printf</code>.

        </p>
        <p>

            In POSIX environments, C++  programmers in need of parsing
            time sequences  can make use  of the <code>strftime</code>
            counterpart,  <code>strptime</code>.  In others,  however,
            they  have  no alternative  but  to  turn to  non-portable
            solutions or implement their own.

        </p>
        <!------------------------------------------------------------>
        <h2>
            <a name="description">Description</a>
        </h2>
        <p>

            In  this paper we  propose a  convenient interface  to the
            parsing   and  formatting   facilities  provided   by  the
            <code>time_get</code>  and  <code>time_put</code>  facets,
            one  that we  believe  is nearly  as  easy to  use as  the
            arithmetic   inserters  and   extractors.    The  proposed
            interface   takes  the   form  of   a  pair   of  matching
            manipulators that, when  used with the existing extraction
            and  insertion operators,  provide the  desired simplicity
            and ease  of use.   Note that due  to the wide  variety of
            formats  simply  overloading  the extractor  and  inserter
            operators   on  <code>struct   tm</code>   would  not   be
            practical.

        </p>
        <p>

            Note that the  definition of function <code>f</code> shown
            in  the  <a  href="#changes">Proposed Changes</a>  section
            relies    on     the    extension    proposed     in    <a
            href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2070">N2070=06-0140</a>.
            However, it may be  possible to implement the manipulators
            even  without this  extension, for  example by  relying on
            implementation details.

        </p>
        <p>

            Note: While independent of one another, this proposal
            should be reviewed and considered in conjunction with <a
            href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2072">N2071=06-0140</a>
            &ndash; Iostream manipulators for convenient extraction
            and insertion of monetary values.

        </p>
        <!------------------------------------------------------------>
        <h2>
            <a name="changes">Proposed Changes</a>
        </h2>
        <p>

            Add a new section after lib.std.manip titled Extended
            Manipulators [lib.ext.manip], with the following text:

        </p>
        <blockquote>

            The  header  <code>&lt;iomanip&gt;</code>  also defines  a
            number  of functions  that use  the <i>smanip</i>  type to
            provide  extractors  and  inserters  that  allow  for  the
            extraction and parsing of  time sequences and values,
            respectively.

        </blockquote>
        <blockquote>

            The type designated <i>smanip</i> in each of the following
            function descriptions is implementation-defined and may be
            different for each function.

        </blockquote>
        <blockquote>
            <code>

            template &lt;class charT&gt;
            <i>smanip</i> get_time (struct tm *tmb, const charT *fmt);

            </code>
        </blockquote>
        <blockquote>

            <i>Requires:</i><code>tmb</code>  is valid  pointer  to an
            object of <code>struct  tm</code>, and <code>fmt</code> is
            a  valid pointer  to an  array of  type <code>charT</code>
            with  length of <code>char_traits&lt;charT&gt;(fmt)</code>
            elements.

        </blockquote>
        <blockquote>

            <i>Returns:</i>  An object  <code>s</code>  of unspecified
            type  such  that  if  <code>in</code>  is  an  object  of
            (derived        from)        <code>basic_istream&lt;charT,
            traits&gt;</code>,   the  type   of   <code>tmb</code>  is
            <code>struct tm*</code>  and the type  of <code>fmt</code>
            is <code>const charT*</code>  then the expression <code>in
            &gt;&gt;   get_time(tmb,   fmt)</code>   behaves   as   if
            <code>f(str,   tmb,  fmt)</code>   were   evaluated  where
            <code>f</code> may  be defined similarly  to the following
            (exception handling omitted):

        </blockquote>
        <pre>
        template &lt;class charT, class traits&gt;
        void f (basic_ios&lt;charT, traits&gt;&amp; str, struct tm *tmb, const charT *fmt)
        {
            typedef streambuf_iterator&lt;charT&gt; Iter;
            typedef time_get&lt;charT, Iter&gt;     TimeGet;

            ios_base::iostate err = ios_base::goodbit;
            const TimeGet &amp;tg = use_facet&lt;TimeGet&gt;(strm.getloc ());

            tg.get (Iter (str.rdbuf ()), Iter (), str, err, tmb, fmt, fmt + traits::length (fmt));

            if (ios_base::goodbit != err)
                str.setstate (err);
        }
        </pre>
        <blockquote>

            <i>Note:</i> The type of the <code>in &gt;&gt; s</code>
            expression is             <code>basic_istream&lt;charT,
            traits&gt;&amp;</code> and its value is </code>in</code>.

        </blockquote>
        <blockquote>
            <code>

            template &lt;class charT&gt;
            <i>smanip</i> put_time (const struct tm *tmb, const charT *fmt);

            </code>
        </blockquote>
        <blockquote>

            <i>Returns:</i>  An object  <code>s</code>  of unspecified
            type  such  that  if  <code>out</code>  is  an  object  of
            (derived        from)        <code>basic_ostream&lt;charT,
            traits&gt;</code>,   the  type   of   <code>tmb</code>  is
            <code>struct tmb*</code> and  the type of <code>fmt</code>
            is <code>const charT*</code> then the expression <code>out
            &lt;&lt;   s</code>   behaves   as  if   <code>f(s,   tmb,
            fmt)</code>  were evaluated  where  <code>f</code> may  be
            defined  similarly to  the  following (exception  handling
            omitted):

        </blockquote>

        <pre>
        template &lt;class charT, class traits&gt;
        void f (basic_ios&lt;charT, traits&gt;&amp; str, const struct tm *tmb, const charT *fmt)
        {
            typedef ostreambuf_iterator&lt;charT&gt; Iter;
            typedef time_put&lt;charT, Iter&gt;      TimePut;

            const TimePut &amp;tp = use_facet&lt;TimePut&gt;(str.getloc ());
            const Iter end = tp.put (Iter (str.rdbuf ()), str, str.fill (), tmb, fmt, fmt + traits::length (fmt));

            if (end.failed ())
                str.setstate (ios_base::badbit);
        }
        </pre>
        <blockquote>

            <i>Note:</i> The type of the <code>out &lt;&lt; s</code>
            expression is            <code>basic_ostream&lt;charT,
            traits&gt;&amp;</code> and             its value is
            <code>out</code>.

        </blockquote>
        <!------------------------------------------------------------>
        <h2>
            <a name="implementation">Implementation</a>
        </h2>
        <p>

            A reference implementation  of this extension is available
            for     review      in     the     Open      Source     <a
            href="http://incubator.apache.org/stdcxx/">Apache       C++
            Standard  Library</a>  in  the   form  of  a  complete  <a
            href="http://svn.apache.org/repos/asf/incubator/stdcxx/trunk/examples/manual/time_manip.cpp">example
            program</a>.
        </p>
    </body>
</html>
