-<?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 <link>-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> => 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>) => 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>) => 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://www.mnemonic.org">mnemonic</ulink>
- </entry> <entry>none</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 <fstream>
- </funcsynopsisinfo>
- <funcprototype>
- <funcdef>
- <function>basic_filebuf<...>::basic_filebuf<...>
- </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<..></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"><math.h></filename>, you
- should use <filename class =
- "headerfile"><cmath></filename>. In some cases this has
- the advantage that the C++-header is more standardized than
- the C-header (i.e. <filename
- class="headerfile"><ctime></filename> (almost)
- corresponds to either <filename class =
- "headerfile"><time.h></filename> or <filename class =
- "headerfile"><sys/time.h></filename>).
-
- The standard specifies that if you include the C-style header
- (<filename class = "headerfile"><math.h></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"><cmath></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"><fstream></filename> does
- not define <command>std::cout</command>,
- <command>std::cin</command> etc.</title>
- <para>
- In earlier versions of the standard,
- <filename class="headerfile"><fstream.h></filename>,
- <filename class="headerfile"><ostream.h></filename>
- and <filename class="headerfile"><istream.h></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"><iostream></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<<(iterator)</command> to
- print the address of the iterator => use
- <command>operator<< &*iterator</command> instead ?
- </para>
- </listitem>
- <listitem><para>you cannot clear an iterator's reference
- (<command>iterator = 0</command>) => 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"><cctype></filename>)</title>
- <para>
- Glibc 2.0.x and 2.1.x define the
- <filename class="headerfile"><ctype.h></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 <cctype>
- int main() { std::isspace('X'); }
- </programlisting>
- will result in something like this (unless using g++-v3):
- <programlisting>
- std:: (__ctype_b[(int) ( ( 'X' ) )] & (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"><ctype.h></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 <ctype.h> ]
- </programlisting>
- </para>
- <para>
- Another problem arises if you put a <command>using namespace
- std;</command> declaration at the top, and include <filename class
- = "headerfile"><ctype.h></filename>. This will result in
- ambiguities between the definitions in the global namespace
- (<filename class = "headerfile"><ctype.h></filename>) and the
- definitions in namespace <command>std::</command>
- (<command><cctype></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 <vector>
- #include <deque>
- #include <string>
-
- using namespace std;
- ],
- [
- deque<int> test_deque(3);
- test_deque.at(2);
- vector<int> 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<char>::eof()</title>
- <para>
- <programlisting>
- #ifdef HAVE_CHAR_TRAITS
- #define CPP_EOF std::char_traits<char>::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&
- 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"><sstream></filename>), but for compatibility
- with older implementations you still have to use
- <command>i/ostrstream</command> (<filename
- class="headerfile"><strstream></filename>):
- <programlisting>
- #ifdef HAVE_SSTREAM
- #include <sstream>
- #else
- #include <strstream>
- #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 << "Name=" << m_name << ", number=" << m_number << std::endl;
- ...
- #ifndef HAVE_SSTREAM
- oss << 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 <class X>
- void fromString(const string& input, X& 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:
--->