OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libstdc++-v3/] [docs/] [html/] [17_intro/] [porting-howto.xml] - Rev 20

Compare with Previous | Blame | View Log

<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1//EN"
                         "http://www.oasis-open.org/docbook/xml/4.0/docbookx.dtd">

<?xml-stylesheet type="text/xsl" href="docbook-xslt/docbook/html/docbook.xsl"?>

<!--
  This is written using docbook 4.1 xml. HTML is generated using
  the xslt-stylesheets from http://www.nwalsh.com.
 
  xsltproc is an xslt-processor included in libxslt:
  (http://xmlsoft.org/XSLT/ or here:
  ftp://ftp.gnome.org/pub/GNOME/unstable/sources/libxslt/)
  (it requires libxml2: http://xmlsoft.org
        or here: ftp://ftp.gnome.org/pub/GNOME/stable/sources/libxml/)

  You can find the latest version of this document here:
  http://gcc.gnu.org/onlinedocs/libstdc++/17_intro/porting-howto(.html|.xml)
-->
        
<!-- TODO:
o remove //@label: use automatic numbering
o make this work: <link linkend="sec-gtkmm-hack" endterm="sec-gtkmm-hack.title"/>.
o clean up the section-numbering
-->

<article class = "whitepaper" id = "libstdc++-porting-howto" lang = "en">
  <articleinfo>
    <title>Libstdc++-porting-howto</title>
    <author>
      <firstname>Felix</firstname>
      <surname>Natter</surname>
    </author>
    <address>
      <email>fnatter@gmx.net</email>
    </address>
    <revhistory>
      <revision>
        <revnumber>0.5</revnumber>
        <date>Thu Jun  1 13:06:50 2000</date>
        <authorinitials>fnatter</authorinitials>
        <revremark>First docbook-version.</revremark>
      </revision>
      <revision>
        <revnumber>0.8</revnumber>
        <date>Sun Jul 30 20:28:40 2000</date>
        <authorinitials>fnatter</authorinitials>
        <revremark>First released version using docbook-xml
          + second upload to libstdc++-page.
        </revremark>
      </revision>
      <revision>
        <revnumber>0.9</revnumber>
        <date>Wed Sep  6 02:59:32 2000</date>
        <authorinitials>fnatter</authorinitials>
        <revremark>5 new sections.</revremark>
      </revision>
      <revision>
        <revnumber>0.9.1</revnumber>
        <date>Sat Sep 23 14:20:15 2000</date>
        <authorinitials>fnatter</authorinitials>
        <revremark>added information about why file-descriptors are not in the
          standard</revremark>
      </revision>
      <revision>
        <revnumber>0.9.2</revnumber>
        <date>Tue Jun  5 20:07:49 2001</date>
        <authorinitials>fnatter</authorinitials>
        <revremark>
          a fix, added hint on increased portability of C-shadow-headers,
          added autoconf-test HAVE_CONTAINER_AT
        </revremark>
      </revision>
      <revision>
        <revnumber>0.9.3</revnumber>
        <date>Fri Jun 29 16:15:56 2001</date>
        <authorinitials>fnatter</authorinitials>
        <revremark>
          changed signature of nonstandard filebuf-constructor and
          update the section on filebuf::attach to point to ../ext/howto.html,
          added link to ../21/strings/howto.html
          in sec-stringstream, changed &lt;link&gt;-tags to have content
          (so that these links work),
          replace "user-space" by "global namespace"
          add note about gcc 3.0 and shadow-headers                     
          add section about ostream::form and istream::scan
          sec-vector-at: remove hint to modify headers
          fix spelling error in sec-stringstream
        </revremark>
      </revision>
      <revision>
        <revnumber>0.9.4</revnumber>
        <date>Mon Nov  5 17:01:04 2001</date>
        <authorinitials>fnatter</authorinitials>
        <revremark>
          rewrite section 1.1.3 because of gnu.gcc.help-post by
          Juergen Heinzl
        </revremark>
      </revision>
    </revhistory>
    <legalnotice><title>Legal Notice</title>
      <para>
        This document can be distributed under the FDL
        (<ulink url = "http://www.gnu.org">www.gnu.org</ulink>)
      </para>
    </legalnotice>
    
    <pubdate>Tue Jun  5 20:07:49 2001</pubdate>
    <abstract>
      <para>
        Some notes on porting applications from libstdc++-2.90 (or earlier
        versions) to libstdc++-v3. Not speaking in terms of the GNU libstdc++
        implementations, this means porting from earlier versions of the
        C++-Standard to ISO 14882.
      </para>
    </abstract>
  </articleinfo>

  <para>
    In the following, when I say portable, I will refer to "portable among ISO
    14882-implementations". On the other hand, if I say "backportable" or
    "conservative", I am talking about "compiles with older
    libstdc++-implementations".
  </para>

  <section id="sec-nsstd" label="1"><title>Namespace std::</title>
    <para>
      The latest C++-standard (ISO-14882) requires that the standard
      C++-library is defined in namespace std::. Thus, in order to use
      classes from the standard C++-library, you can do one of three
      things:
      <itemizedlist>

        <listitem><para>wrap your code in <command>namespace std {
              ... }</command> =&gt; This is not an option because only symbols
            from the standard c++-library are defined in namespace std::.
          </para></listitem>

        <listitem><para>put a kind of
            <emphasis>using-declaration</emphasis> in your source (either
            <command>using namespace std;</command> or i.e. <command>using
              std::string;</command>) =&gt; works well for source-files, but
            cannot be used in header-files.
          </para></listitem>

        <listitem><para>use a <emphasis>fully qualified name</emphasis> for
            each libstdc++-symbol (i.e. <command>std::string</command>,
            <command>std::cout</command>) =&gt; can always be used
          </para></listitem>
      </itemizedlist>
    </para>

    <para>
      Because there are many compilers which still use an implementation
      that does not have the standard C++-library in namespace
      <command>std::</command>, some care is required to support these as
      well.
    </para>

    <para>
      Namespace back-portability-issues are generally not a problem with
      g++, because versions of g++ that do not have libstdc++ in
      <command>std::</command> use <command>-fno-honor-std</command>
      (ignore <command>std::</command>, <command>:: = std::</command>) by
      default. That is, the responsibility for enabling or disabling
      <command>std::</command> is on the user; the maintainer does not have
      to care about it. This probably applies to some other compilers as
      well.
    </para>
    <para>
      The following sections list some possible solutions to support compilers
      that cannot ignore std::.
    </para>

    <section id = "sec-gtkmm-hack" label = "1.1">
      <title id="sec-gtkmm-hack.title">Using <emphasis>namespace
          composition</emphasis> if the project uses a separate
        namespace</title>
      <para>
        <ulink url = "http://gtkmm.sourceforge.net">Gtk--</ulink> defines
        most of its classes in namespace Gtk::. Thus, it was possible to
        adapt Gtk-- to namespace std:: by using a C++-feature called
        <emphasis>namespace composition</emphasis>. This is what happens if
        you put a <emphasis>using</emphasis>-declaration into a
        namespace-definition: the imported symbol(s) gets imported into the
        currently active namespace(s). For example:
        <programlisting>
          namespace Gtk {
          using std::string;
          class Window { ... }
          }
        </programlisting>
        In this example, <command>std::string</command> gets imported into
        namespace Gtk::.  The result is that you don't have to use
        <command>std::string</command> in this header, but still
        <command>std::string</command> does not get imported into
        the global namespace (::) unless the user does
        <command>using namespace Gtk;</command> (which is not recommended
        practice for Gtk--, so it is not a problem).  Additionally, the
        <command>using</command>-declarations are wrapped in macros that
        are set based on autoconf-tests to either "" or i.e. <command>using
          std::string;</command> (depending on whether the system has
        libstdc++ in <command>std::</command> or not).  (ideas from
        <email>llewelly@dbritsch.dsl.xmission.com</email>, Karl Nelson
        <email>kenelson@ece.ucdavis.edu</email>)
      </para>
    </section>

    <section id = "sec-emptyns" label = "1.2">
      <title id="sec-emptyns.title">Defining an empty namespace std</title>
      <para>
        By defining an (empty) namespace <command>std::</command> before
        using it, you avoid getting errors on systems where no part of the
        library is in namespace std:
        <programlisting>
          namespace std { }
          using namespace std;
        </programlisting>
      </para>
    </section>

    <section id = "sec-avoidfqn" label = "1.3">
      <title id="sec-avoidfqn.title">Avoid to use fully qualified names
        (i.e. std::string)</title>
      <para>
        If some compilers complain about <command>using
          std::string;</command>, and if the "hack" for gtk-- mentioned above
        does not work, then I see two solutions:
        
        <itemizedlist>
          <listitem><para>
              Define <command>std::</command> as a macro if the compiler
              doesn't know about <command>std::</command>.
              <programlisting>
                #ifdef OLD_COMPILER
                #define std
                #endif
              </programlisting>
              (thanks to Juergen Heinzl who posted this solution on
              gnu.gcc.help)
            </para></listitem>
          
          <listitem><para>
              Define a macro <symbol>NS_STD</symbol>, which is defined to
              either "" or "std"
              based on an autoconf-test. Then you should be able to use
              <command>NS_STD::string</command>, which will evaluate to
              <command>::string</command> ("string in the global namespace") on
              systems that do not put string in std::.  (This is untested)
            </para></listitem>
        </itemizedlist>
          
      </para>
    </section>
    
    <section id = "sec-osprojects" label = "1.4">
      <title id="sec-osprojects.title">How some open-source-projects deal
        with this</title>
      <para>
        This information was gathered around May 2000. It may not be correct
        by the time you read this.
      </para>
      <table><title>Namespace std:: in Open-Source programs</title>
        <tgroup cols = "2">
          <tbody>
            <row>
              <entry><ulink url = "http://www.clanlib.org">clanlib</ulink>
              </entry>
              <entry>usual</entry>
            </row>
            <row>
              <entry><ulink url = "http://pingus.seul.org">pingus</ulink>
              </entry>
              <entry>usual</entry>
            </row>
            <row>
              <entry><ulink url = "http://www.mozilla.org">mozilla</ulink>
              </entry>
              <entry>usual</entry>
            </row>
            <row>
              <entry><ulink url = "http://libsigc.sourceforge.net">
                  libsigc++</ulink></entry>
              <entry>conservative-impl</entry>
            </row>
          </tbody>
        </tgroup>
      </table>

      <table><title>Notations for categories</title>
        <tgroup cols = "2">
          <tbody>
            <row>
              <entry>usual</entry>
              <entry>mostly fully qualified names and some
                using-declarations (but not in headers)</entry>
            </row>
            <row>
              <entry>none</entry> <entry>no namespace std at all</entry>
            </row>
            <row>
              <entry>conservative-impl</entry>
              <entry>wrap all
                namespace-handling in macros to support compilers without
                namespace-support (no libstdc++ used in headers)</entry>
            </row>
          </tbody>
        </tgroup>
      </table>

      <para>
        As you can see, this currently lacks an example of a project
        which uses libstdc++-symbols in headers in a back-portable way
        (except for Gtk--: see the <link linkend="sec-gtkmm-hack"
          endterm="sec-gtkmm-hack.title">section on the gtkmm-hack</link>).
      </para>
    </section>          
  </section> <!-- end of namespace-section -->

  <section id = "sec-nocreate" label = "2">
    <title id="sec-nocreate.title">there is no ios::nocreate/ios::noreplace
      in ISO 14882</title>
    <para>
      I have seen <command>ios::nocreate</command> being used for
      input-streams, most probably because the author thought it would be
      more correct to specify nocreate "explicitly".  So you can simply
      leave it out for input-streams.
    </para>
    <para>
      For output streams, "nocreate" is probably the default, unless you
      specify <command>std::ios::trunc</command> ? To be safe, you can open
      the file for reading, check if it has been opened, and then decide
      whether you want to create/replace or not. To my knowledge, even
      older implementations support <command>app</command>,
      <command>ate</command> and <command>trunc</command> (except for
      <command>app</command> ?).
    </para>
  </section>

  <section id = "sec-stream::attach" label = "3">
    <title id="sec-stream::attach.title"><command>stream::attach(int
        fd)</command> is not in the standard any more</title>
    <para>
      Phil Edwards <email>pedwards@disaster.jaj.com</email> writes:
      It was considered and rejected.  Not all environments use file
      descriptors.  Of those that do, not all of them use integers to represent
      them.
    </para>
    <para>
      When using libstdc++-v3, you can use
      <funcsynopsis>
        <funcsynopsisinfo format="linespecific">
          #include &lt;fstream&gt;
        </funcsynopsisinfo>
        <funcprototype>
          <funcdef>
            <function>basic_filebuf&lt;...&gt;::basic_filebuf&lt;...&gt;
            </function>
          </funcdef>
          <paramdef>__c_file_type* <parameter>file</parameter></paramdef>
          <paramdef>ios_base::open_mode <parameter>mode</parameter></paramdef>
          <paramdef>int <parameter>size</parameter></paramdef>
        </funcprototype>
      </funcsynopsis>
      but the the signature of this constructor has changed often, and
      it might change again. For the current state of this, check
      <ulink url="../ext/howto.html">the howto for extensions</ulink>.
    </para>
    <para>
      For a portable solution (among systems which use
      filedescriptors), you need to implement a subclass of
      <command>std::streambuf</command> (or
      <command>std::basic_streambuf&lt;..&gt;</command>) which opens a file
      given a descriptor, and then pass an instance of this to the
      stream-constructor.  For an example of this, refer to
      <ulink url="http://www.josuttis.com/cppcode/fdstream.html">fdstream example</ulink> 
      by Nicolai Josuttis.
    </para>
  </section>
  
  <section id = "sec-headers" label = "4">
    <title id="sec-headers.title">The new headers</title>
    <para>
      All new headers can be seen in this <ulink url="headers_cc.txt">
        source-code</ulink>.
    </para>
    <para>
      The old C++-headers (iostream.h etc.) are available, but gcc generates
      a warning that you are using deprecated headers.
    </para>

    <section id = "sec-cheaders" label = "4.1">
      <title id="sec-cheaders.title">New headers replacing C-headers</title>
      <para>
        You should not use the C-headers (except for system-level
        headers) from C++ programs. Instead, you should use a set of
        headers that are named by prepending 'c' and, as usual,
        omitting the extension (.h). For example, instead of using
        <filename class="headerfile">&lt;math.h&gt;</filename>, you
        should use <filename class =
          "headerfile">&lt;cmath&gt;</filename>. In some cases this has
        the advantage that the C++-header is more standardized than
        the C-header (i.e. <filename
          class="headerfile">&lt;ctime&gt;</filename> (almost)
        corresponds to either <filename class =
          "headerfile">&lt;time.h&gt;</filename> or <filename class =
          "headerfile">&lt;sys/time.h&gt;</filename>).

        The standard specifies that if you include the C-style header
        (<filename class = "headerfile">&lt;math.h&gt;</filename> in
        this case), the symbols will be available both in the global
        namespace and in namespace <command>std::</command> (but
        libstdc++ does not yet have fully compliant headers) On the
        other hand, if you include only the new header (i.e. <filename
          class = "headerfile">&lt;cmath&gt;</filename>), the symbols
        will only be defined in namespace <command>std::</command>
        (and macros will be converted to inline-functions).
      </para>
      <para>
        For more information on this, and for information on how the
        GNU C++ implementation might reuse ("shadow") the C
        library-functions, have a look at <ulink
          url="http://www.cantrip.org/cheaders.html">
          www.cantrip.org</ulink>.
      </para>
    </section>
    
    <section id = "sec-fstream-header" label = "4.2">
      <title id="sec-fstream-header.title">
        <filename class="headerfile">&lt;fstream&gt;</filename> does
        not define <command>std::cout</command>,
        <command>std::cin</command> etc.</title>
      <para>
        In earlier versions of the standard,
        <filename class="headerfile">&lt;fstream.h&gt;</filename>,
        <filename class="headerfile">&lt;ostream.h&gt;</filename>
        and <filename class="headerfile">&lt;istream.h&gt;</filename>
        used to define
        <command>cout</command>, <command>cin</command> and so on. Because
        of the templatized iostreams in libstdc++-v3, you need to include
        <filename class = "headerfile">&lt;iostream&gt;</filename>
        explicitly to define these.
      </para>
    </section>
  </section>

  <section id = "sec-iterators" label = "5">
    <title id="sec-iterators.title">Iterators</title>
    <para>
      The following are not proper uses of iterators, but may be working
      fixes for existing uses of iterators.
      <itemizedlist>
        <listitem><para>you cannot do
            <command>ostream::operator&lt;&lt;(iterator)</command> to
            print the address of the iterator =&gt; use
            <command>operator&lt;&lt; &amp;*iterator</command> instead ?
          </para>
        </listitem>
        <listitem><para>you cannot clear an iterator's reference
            (<command>iterator = 0</command>) =&gt; use
            <command>iterator = iterator_type();</command> ?
          </para>
        </listitem>
        <listitem><para><command>if (iterator)</command> won't work any
            more => use <command>if (iterator != iterator_type())</command>
            ?</para>
        </listitem>
      </itemizedlist>
    </para>
  </section>

  <section id = "sec-macros" label = "6">
    <title id="sec-macros.title">
      Libc-macros (i.e. <command>isspace</command> from
      <filename class = "headerfile">&lt;cctype&gt;</filename>)</title>
    <para>
      Glibc 2.0.x and 2.1.x define the
      <filename class="headerfile">&lt;ctype.h&gt;</filename>
      -functionality as macros (isspace, isalpha etc.). Libstdc++-v3
      "shadows" these macros as described in the <link
        linkend="sec-cheaders" endterm="sec-cheaders.title">section about
        c-headers</link>.
    </para>
    <para>
      Older implementations of libstdc++ (g++-2 for egcs 1.x and g++-3
      for gcc 2.95.x), however, keep these functions as macros, and so it
      is not back-portable to use fully qualified names. For example:
      <programlisting>
        #include &lt;cctype&gt;
        int main() { std::isspace('X'); }
      </programlisting>
      will result in something like this (unless using g++-v3):
      <programlisting>
        std:: (__ctype_b[(int) ( ( 'X' ) )] &amp; (unsigned short int)
        _ISspace )  ;
      </programlisting>
    </para>
    <para>
      One solution I can think of is to test for -v3 using
      autoconf-macros, and define macros for each of the C-functions
      (maybe that is possible with one "wrapper" macro as well ?).
    </para>
    <para>
      Another solution which would fix g++ is to tell the user to modify a
      header-file so that g++-2 (egcs 1.x) and g++-3 (gcc 2.95.x) define a
      macro which tells <filename
        class="headerfile">&lt;ctype.h&gt;</filename> to define functions
      instead of macros:
      <programlisting>
        // This keeps isalnum, et al from being propagated as macros.
        #if __linux__
        #define __NO_CTYPE 1
        #endif

        [ now include &lt;ctype.h&gt; ]
      </programlisting>
    </para>
    <para>
      Another problem arises if you put a <command>using namespace
        std;</command> declaration at the top, and include <filename class
        = "headerfile">&lt;ctype.h&gt;</filename>. This will result in
      ambiguities between the definitions in the global namespace
      (<filename class = "headerfile">&lt;ctype.h&gt;</filename>) and the
      definitions in namespace <command>std::</command>
      (<command>&lt;cctype&gt;</command>).
    </para>
    <para>
      The solution to this problem was posted to the libstdc++-v3
      mailing-list:
      Benjamin Kosnik <email>bkoz@redhat.com</email> writes:
      <quote>
        --enable-cshadow-headers is currently broken. As a result, shadow
        headers are not being searched....
      </quote>
      This is now outdated, but gcc 3.0 still does not have fully
      compliant "shadow headers".
    </para>
  </section>

  <section id="sec-stream-state" label="7">
    <title id="sec-stream-state.title">State of streams</title>
    <para>
      At least some older implementations don't have
      <command>std::ios_base</command>, so you should use
      <command>std::ios::badbit</command>, <command>std::ios::failbit</command>
      and <command>std::ios::eofbit</command> and
      <command>std::ios::goodbit</command>.
    </para>
  </section>

  <section id="sec-vector-at" label="8">
    <title>vector::at is missing (i.e. gcc 2.95.x)</title>
    <para>
      One solution is to add an autoconf-test for this:
      <programlisting>
        AC_MSG_CHECKING(for container::at)
        AC_TRY_COMPILE(
        [
        #include &lt;vector&gt;
        #include &lt;deque&gt;
        #include &lt;string&gt;
        
        using namespace std;
        ],
        [
        deque&lt;int&gt; test_deque(3);
        test_deque.at(2);
        vector&lt;int&gt; test_vector(2);
        test_vector.at(1);
        string test_string("test_string");
        test_string.at(3);
        ],
        [AC_MSG_RESULT(yes)
        AC_DEFINE(HAVE_CONTAINER_AT)],
        [AC_MSG_RESULT(no)])
      </programlisting>
      If you are using other (non-GNU) compilers it might be a good idea
      to check for <command>string::at</command> separately.
    </para>
  </section>

  <section id="sec-eof" label="9">
    <title>Using std::char_traits&lt;char&gt;::eof()</title>
    <para>
      <programlisting>
        #ifdef HAVE_CHAR_TRAITS
        #define CPP_EOF std::char_traits&lt;char&gt;::eof()
        #else
        #define CPP_EOF EOF
        #endif
      </programlisting>
    </para>
  </section>

  <section id="sec-string-clear" label="10">
    <title>Using string::clear()/string::erase()</title>
    <para>
      There are two functions for deleting the contents of a string:
      <command>clear</command> and <command>erase</command> (the latter
      returns the string).
      <programlisting>
        void 
        clear() { _M_mutate(0, this->size(), 0); }
      </programlisting>
      <programlisting>
        basic_string&amp; 
        erase(size_type __pos = 0, size_type __n = npos)
        { 
        return this->replace(_M_check(__pos), _M_fold(__pos, __n),
        _M_data(), _M_data()); 
        }
      </programlisting>
      The implementation of <command>erase</command> seems to be more
      complicated (from libstdc++-v3), but <command>clear</command> is not
      implemented in gcc 2.95.x's libstdc++, so you should use
      <command>erase</command> (which is probably faster than
      <command>operator=(charT*)</command>).
    </para>
  </section>

  <section id="sec-scan-form" label="11">
    <title>GNU Extensions ostream::form and istream::scan</title>
    <para>
      These     are not supported any more - use
      <link     linkend="sec-stringstream" endterm="sec-stringstream.title">
        stringstreams</link> instead.   
    </para>
  </section>

  <section id="sec-stringstream" label="12">
    <title>Using stringstreams</title>
    <para>
      Libstdc++-v3 provides the new
      <command>i/ostringstream</command>-classes, (<filename
        class="headerfile">&lt;sstream&gt;</filename>), but for compatibility
      with older implementations you still have to use
      <command>i/ostrstream</command> (<filename
        class="headerfile">&lt;strstream&gt;</filename>):
      <programlisting>
        #ifdef HAVE_SSTREAM
        #include &lt;sstream&gt;
        #else
        #include &lt;strstream&gt;
        #endif
      </programlisting>
      <itemizedlist>
        <listitem><para> <command>strstream</command> is considered to be
            deprecated
          </para>
        </listitem>
        <listitem><para> <command>strstream</command> is limited to
            <command>char</command>
          </para>
        </listitem>
        <listitem><para> with <command>ostringstream</command> you don't
            have to take care of terminating the string or freeing its
            memory
          </para>
        </listitem>
        <listitem><para> <command>istringstream</command> can be re-filled
            (clear(); str(input);)
          </para>
        </listitem>
      </itemizedlist>
    </para>
    <para>
      You can then use output-stringstreams like this:
      <programlisting>
        #ifdef HAVE_SSTREAM
        std::ostringstream oss;
        #else
        std::ostrstream oss;
        #endif
        oss &lt;&lt; "Name=" &lt;&lt; m_name &lt;&lt; ", number=" &lt;&lt; m_number &lt;&lt; std::endl;
        ...
        #ifndef HAVE_SSTREAM
        oss &lt;&lt; std::ends; // terminate the char*-string
        #endif
        // str() returns char* for ostrstream and a string for ostringstream
        // this also causes ostrstream to think that the buffer's memory
        // is yours
        m_label.set_text(oss.str());
        #ifndef HAVE_SSTREAM
        // let the ostrstream take care of freeing the memory
        oss.freeze(false);
        #endif
      </programlisting>
    </para>
    <para>
      Input-stringstreams can be used similarly:
      <programlisting>
        std::string input;
        ...
        #ifdef HAVE_SSTREAM
        std::istringstream iss(input);
        #else
        std::istrstream iss(input.c_str());
        #endif
        int i;
        iss >> i; 
      </programlisting>
      One (the only?) restriction is that an istrstream cannot be re-filled:
      <programlisting>
        std::istringstream iss(numerator);
        iss >> m_num;
        // this is not possible with istrstream
        iss.clear();
        iss.str(denominator);
        iss >> m_den;
      </programlisting>
      If you don't care about speed, you can put these conversions in
      a template-function:
      <programlisting>
        template &lt;class X&gt;
        void fromString(const string&amp; input, X&amp; any)
        {
        #ifdef HAVE_SSTREAM
        std::istringstream iss(input);
        #else
        std::istrstream iss(input.c_str());
        #endif
        X temp;
        iss >> temp;
        if (iss.fail())
        throw runtime_error(..)
        any = temp;
        }
      </programlisting>
      Another example of using stringstreams is in <ulink
        url="../21_strings/howto.html">this howto</ulink>.
    </para>
    <para>
      I have read the Josuttis book on Standard C++, so some information
      comes from there. Additionally, there is information in
      "info iostream", which covers the old implementation that gcc 2.95.x
      uses.
    </para>
  </section>

  <section id = "sec-about" label="13">
    <title id="sec-about.title">About...</title>
    <para>
      Please send any experience, additions, corrections or questions to
      <ulink url = "mailto:fnatter@gmx.net">fnatter@gmx.net</ulink> or for
      discussion to the libstdc++-v3-mailing-list.
    </para>
  </section>

</article>

  <!-- this is now obsolete, since the nwalsh-stylesheet generates an index
<para>
<itemizedlist>
<listitem><para>
<link linkend = "sec-nsstd" endterm = "sec-nsstd.title"/>
</para></listitem>
<listitem><para>
<link linkend = "sec-nocreate" endterm = "sec-nocreate.title"/>
</para></listitem>
<listitem><para>
<link linkend = "sec-stream::attach"
  endterm = "sec-stream::attach.title"/>
</para></listitem>
<listitem><para>
<link linkend = "sec-headers" endterm = "sec-headers.title"/>
</para></listitem>
<listitem><para>
<link linkend = "sec-iterators" endterm = "sec-iterators.title"/>
</para></listitem>
<listitem><para>
<link linkend = "sec-macros" endterm = "sec-macros.title"/>
</para></listitem>
<listitem><para>
<link linkend = "sec-about" endterm = "sec-about.title"/>
</para></listitem>
</itemizedlist>
</para>
  -->

<!--
Local Variables:
compile-command: "xsltproc -o porting-howto.html docbook-xslt/docbook/html/docbook.xsl porting-howto.xml"
End:
-->

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.