mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			727 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			HTML
		
	
	
	
			
		
		
	
	
			727 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			HTML
		
	
	
	
| <html>
 | |
|   <head>
 | |
|     <title>Libstdc++-porting-howto</title>
 | |
|     <meta content="DocBook XSL Stylesheets V1.16" name="generator">
 | |
|   </head>
 | |
|   <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
 | |
|     <div class="article" id="libstdporting">
 | |
|       <div class="titlepage">
 | |
|         <h1 class="title">
 | |
|           <a name="libstdporting">Libstdc++-porting-howto</a>
 | |
|         </h1>
 | |
|         <h3 class="author">Felix Natter</h3>
 | |
|         <p>
 | |
| 		This document can be distributed under the FDL
 | |
| 		(<a href="http://www.gnu.org">www.gnu.org</a>)
 | |
| 	  </p>
 | |
|         <p class="pubdate">what kind of a date ? I don't drink !</p>
 | |
|         <div class="revhistory">
 | |
|           <table width="100%" border="1">
 | |
|             <tr>
 | |
|               <th colspan="3" valign="top" align="left"><b>Revision History</b></th>
 | |
|             </tr>
 | |
|             <tr>
 | |
|               <td align="left">Revision 0.5</td><td align="left">Thu Jun  1 13:06:50 2000</td><td align="left">fnatter</td>
 | |
|             </tr>
 | |
|             <tr>
 | |
|               <td colspan="3" align="left">First docbook-version.</td>
 | |
|             </tr>
 | |
|             <tr>
 | |
|               <td align="left">Revision 0.8</td><td align="left">Sun Jul 30 20:28:40 2000</td><td align="left">fnatter</td>
 | |
|             </tr>
 | |
|             <tr>
 | |
|               <td colspan="3" align="left">First released version using docbook-xml
 | |
| 		  + second upload to libstdc++-page.
 | |
| 		</td>
 | |
|             </tr>
 | |
|             <tr>
 | |
|               <td align="left">Revision 0.9</td><td align="left">Wed Sep  6 02:59:32 2000</td><td align="left">fnatter</td>
 | |
|             </tr>
 | |
|             <tr>
 | |
|               <td colspan="3" align="left">5 new sections.</td>
 | |
|             </tr>
 | |
|           </table>
 | |
|         </div>
 | |
|         <div class="abstract">
 | |
|           <p>
 | |
|             <a name="N2688"></a><b>Abstract</b>
 | |
|           </p>
 | |
|           <p>
 | |
| 		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.
 | |
| 	  </p>
 | |
|         </div>
 | |
|         <hr>
 | |
|       </div>
 | |
|       <div class="toc">
 | |
|         <p>
 | |
|           <b>Table of Contents</b>
 | |
|         </p>
 | |
|         <dl>
 | |
|           <dt>1. <a href="#sec-nsstd">Namespace std::</a>
 | |
|           </dt>
 | |
|           <dd>
 | |
|             <dl>
 | |
|               <dt>1.1.1. <a href="#sec-gtkmm-hack">Using <i>namespace
 | |
| 		composition</i> if the project uses a separate
 | |
| 		namespace</a>
 | |
|               </dt>
 | |
|               <dt>1.1.2. <a href="#sec-emptyns">Defining an empty namespace std</a>
 | |
|               </dt>
 | |
|               <dt>1.1.3. <a href="#sec-avoidfqn">Avoid to use fully qualified names
 | |
| 	  (i.e. std::string)</a>
 | |
|               </dt>
 | |
|               <dt>1.1.4. <a href="#sec-osprojects">How some open-source-projects deal
 | |
| 	  with this</a>
 | |
|               </dt>
 | |
|             </dl>
 | |
|           </dd>
 | |
|           <dt>2. <a href="#sec-nocreate">there is no ios::nocreate/ios::noreplace
 | |
| 	  in ISO 14882</a>
 | |
|           </dt>
 | |
|           <dt>3. <a href="#sec-stream::attach"><b>stream::attach(int
 | |
| 	  fd)</b> is not in the standard any more</a>
 | |
|           </dt>
 | |
|           <dt>4. <a href="#sec-headers">The new headers</a>
 | |
|           </dt>
 | |
|           <dd>
 | |
|             <dl>
 | |
|               <dt>4.4.1. <a href="#sec-cheaders">New headers replacing C-headers</a>
 | |
|               </dt>
 | |
|               <dt>4.4.2. <a href="#sec-fstream-header">
 | |
| 		<tt><fstream></tt> does
 | |
| 		not define <b>std::cout</b>,
 | |
| 		<b>std::cin</b> etc.</a>
 | |
|               </dt>
 | |
|             </dl>
 | |
|           </dd>
 | |
|           <dt>5. <a href="#sec-iterators">Iterators</a>
 | |
|           </dt>
 | |
|           <dt>6. <a href="#sec-macros">
 | |
| 	  Libc-macros (i.e. <b>isspace</b> from
 | |
| 	  <tt><cctype></tt>)</a>
 | |
|           </dt>
 | |
|           <dt>7. <a href="#sec-stream-state">
 | |
| 	  State of streams
 | |
| 	</a>
 | |
|           </dt>
 | |
|           <dt>8. <a href="#sec-vector-at">vector::at is missing (i.e. gcc 2.95.2)</a>
 | |
|           </dt>
 | |
|           <dt>9. <a href="#sec-eof">Using std::char_traits<char>::eof()</a>
 | |
|           </dt>
 | |
|           <dt>10. <a href="#sec-string-clear">Using string::clear()/string::erase()</a>
 | |
|           </dt>
 | |
|           <dt>11. <a href="#sec-stringstream">Using stringstream's</a>
 | |
|           </dt>
 | |
|           <dt>12. <a href="#sec-about">About...</a>
 | |
|           </dt>
 | |
|         </dl>
 | |
|       </div>
 | |
|       <p>
 | |
| 	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".
 | |
|   </p>
 | |
|       <div class="section" id="sec-nsstd">
 | |
|         <h2 class="title" style="clear: all">
 | |
|           <a name="sec-nsstd"><b>1. Namespace std::</b></a>
 | |
|         </h2>
 | |
|         <p>
 | |
| 	  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:
 | |
| 	  <div class="itemizedlist">
 | |
|             <ul>
 | |
|               <li>
 | |
|                 <a name="N2712"></a>
 | |
|                 <p>wrap your code in <b>namespace std {
 | |
| 			  ... }</b> => This is not an option because only symbols
 | |
| 			from the standard c++-library are defined in namespace std::.
 | |
| 		  </p>
 | |
|               </li>
 | |
|               <li>
 | |
|                 <a name="N2721"></a>
 | |
|                 <p>put a kind of
 | |
| 			<i>using-declaration</i> in your source (either
 | |
| 			<b>using namespace std;</b> or i.e. <b>using
 | |
| 			  std::string;</b>) => works well for source-files, but
 | |
| 			cannot be used in header-files.
 | |
| 		  </p>
 | |
|               </li>
 | |
|               <li>
 | |
|                 <a name="N2736"></a>
 | |
|                 <p>use a <i>fully qualified name</i> for
 | |
| 			each libstdc++-symbol (i.e. <b>std::string</b>,
 | |
| 			<b>std::cout</b>) => can always be used
 | |
| 		  </p>
 | |
|               </li>
 | |
|             </ul>
 | |
|           </div>
 | |
| 	</p>
 | |
|         <p>
 | |
| 	  Because there are many compilers which still use an implementation
 | |
| 	  that does not have the standard C++-library in namespace
 | |
| 	  <b>std::</b>, some care is required to support these as
 | |
| 	  well.
 | |
| 	</p>
 | |
|         <p>
 | |
| 	  Namespace back-portability-issues are generally not a problem with
 | |
| 	  g++, because versions of g++ that do not have libstdc++ in
 | |
| 	  <b>std::</b> use <b>-fno-honor-std</b>
 | |
| 	  (ignore <b>std::</b>, <b>:: = std::</b>) by
 | |
| 	  default. That is, the responsibility for enabling or disabling
 | |
| 	  <b>std::</b> is on the user; the maintainer does not have
 | |
| 	  to care about it. This probably applies to some other compilers as
 | |
| 	  well.
 | |
| 	</p>
 | |
|         <p>
 | |
| 	  The following sections list some possible solutions to support compilers
 | |
| 	  that cannot ignore std::.
 | |
| 	</p>
 | |
|         <div class="section" id="sec-gtkmm-hack">
 | |
|           <h3 class="title">
 | |
|             <a name="sec-gtkmm-hack"><b>1.1.1. Using <i>namespace
 | |
| 		composition</i> if the project uses a separate
 | |
| 		namespace</b></a>
 | |
|           </h3>
 | |
|           <p>
 | |
| 		<a href="http://gtkmm.sourceforge.net">Gtk--</a> defines
 | |
| 		most of its classes in namespace Gtk::. Thus, it was possible to
 | |
| 		adapt Gtk-- to namespace std:: by using a C++-feature called
 | |
| 		<i>namespace composition</i>. This is what happens if
 | |
| 		you put a <i>using</i>-declaration into a
 | |
| 		namespace-definition: the imported symbol(s) gets imported into the
 | |
| 		currently active namespace(s). For example:
 | |
| 		<pre class="programlisting">
 | |
| 		  namespace Gtk {
 | |
| 		  using std::string;
 | |
| 		  class Window { ... }
 | |
| 		  }
 | |
| 		</pre>
 | |
| 		In this example, <b>std::string</b> gets imported into
 | |
| 		namespace Gtk::.  The result is that you don't have to use
 | |
| 		<b>std::string</b> in this header, but still
 | |
| 		<b>std::string</b> does not get imported into
 | |
| 		user-space (the global namespace ::) unless the user does
 | |
| 		<b>using namespace Gtk;</b> (which is not recommended
 | |
| 		practice for Gtk--, so it is not a problem).  Additionally, the
 | |
| 		<b>using</b>-declarations are wrapped in macros that
 | |
| 		are set based on autoconf-tests to either "" or i.e. <b>using
 | |
| 		  std::string;</b> (depending on whether the system has
 | |
| 		libstdc++ in <b>std::</b> or not).  (ideas from
 | |
| 		<tt><<a href="mailto:llewelly@dbritsch.dsl.xmission.com">llewelly@dbritsch.dsl.xmission.com</a>></tt>, Karl Nelson
 | |
| 		<tt><<a href="mailto:kenelson@ece.ucdavis.edu">kenelson@ece.ucdavis.edu</a>></tt>)
 | |
| 	  </p>
 | |
|         </div>
 | |
|         <div class="section" id="sec-emptyns">
 | |
|           <h3 class="title">
 | |
|             <a name="sec-emptyns"><b>1.1.2. Defining an empty namespace std</b></a>
 | |
|           </h3>
 | |
|           <p>
 | |
| 		By defining an (empty) namespace <b>std::</b> before
 | |
| 		using it, you avoid getting errors on systems where no part of the
 | |
| 		library is in namespace std:
 | |
| 		<pre class="programlisting">
 | |
| 		  namespace std { }
 | |
| 		  using namespace std;
 | |
| 		</pre>
 | |
| 	  </p>
 | |
|         </div>
 | |
|         <div class="section" id="sec-avoidfqn">
 | |
|           <h3 class="title">
 | |
|             <a name="sec-avoidfqn"><b>1.1.3. Avoid to use fully qualified names
 | |
| 	  (i.e. std::string)</b></a>
 | |
|           </h3>
 | |
|           <p>
 | |
| 		If some compilers complain about <b>using
 | |
| 		  std::string;</b>, and if the "hack" for gtk-- mentioned above
 | |
| 		does not work, then it might be a good idea to define a macro
 | |
| 		NS_STD, which is defined to either "" or "std"
 | |
| 		based on an autoconf-test. Then you should be able to use
 | |
| 		<b>NS_STD::string</b>, which will evaluate to
 | |
| 		<b>::string</b> ("string in the global namespace") on
 | |
| 		systems that do not put string in std::.  (This is untested)
 | |
| 	  </p>
 | |
|         </div>
 | |
|         <div class="section" id="sec-osprojects">
 | |
|           <h3 class="title">
 | |
|             <a name="sec-osprojects"><b>1.1.4. How some open-source-projects deal
 | |
| 	  with this</b></a>
 | |
|           </h3>
 | |
|           <p>
 | |
| 		This information was gathered around May 2000. It may not be correct
 | |
| 		by the time you read this.
 | |
| 	  </p>
 | |
|           <div class="table">
 | |
|             <p>
 | |
|               <a name="N2901"></a><b>Table 1. Namespace std:: in Open-Source programs</b>
 | |
|             </p>
 | |
|             <table border="1">
 | |
|               <colgroup>
 | |
|                 <col>
 | |
|                 <col>
 | |
|               </colgroup>
 | |
|               <tbody>
 | |
|                 <tr>
 | |
|                   <td><a href="http://www.clanlib.org">clanlib</a></td><td>usual</td>
 | |
|                 </tr>
 | |
|                 <tr>
 | |
|                   <td><a href="http://pingus.seul.org">pingus</a></td><td>usual</td>
 | |
|                 </tr>
 | |
|                 <tr>
 | |
|                   <td><a href="http://www.mozilla.org">mozilla</a></td><td>usual</td>
 | |
|                 </tr>
 | |
|                 <tr>
 | |
|                   <td><a href="http://www.mnemonic.org">mnemonic</a></td><td>none</td>
 | |
|                 </tr>
 | |
|                 <tr>
 | |
|                   <td><a href="http://libsigc.sourceforge.net">
 | |
| 				  libsigc++</a></td><td>conservative-impl</td>
 | |
|                 </tr>
 | |
|               </tbody>
 | |
|             </table>
 | |
|           </div>
 | |
|           <div class="table">
 | |
|             <p>
 | |
|               <a name="N2978"></a><b>Table 2. Notations for categories</b>
 | |
|             </p>
 | |
|             <table border="1">
 | |
|               <colgroup>
 | |
|                 <col>
 | |
|                 <col>
 | |
|               </colgroup>
 | |
|               <tbody>
 | |
|                 <tr>
 | |
|                   <td>usual</td><td>mostly fully qualified names and some
 | |
| 				using-declarations (but not in headers)</td>
 | |
|                 </tr>
 | |
|                 <tr>
 | |
|                   <td>none</td><td>no namespace std at all</td>
 | |
|                 </tr>
 | |
|                 <tr>
 | |
|                   <td>conservative-impl</td><td>wrap all
 | |
| 				namespace-handling in macros to support compilers without
 | |
| 				namespace-support (no libstdc++ used in headers)</td>
 | |
|                 </tr>
 | |
|               </tbody>
 | |
|             </table>
 | |
|           </div>
 | |
|           <p>
 | |
| 		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 <a href="#"></a>).
 | |
| 	  </p>
 | |
|         </div>
 | |
|       </div>
 | |
|       <div class="section" id="sec-nocreate">
 | |
|         <h2 class="title" style="clear: all">
 | |
|           <a name="sec-nocreate"><b>2. there is no ios::nocreate/ios::noreplace
 | |
| 	  in ISO 14882</b></a>
 | |
|         </h2>
 | |
|         <p>
 | |
| 	  I have seen <b>ios::nocreate</b> being used for input-streams,
 | |
| 	  most probably because the authors thought it would be more correct
 | |
| 	  to specify nocreate "explicitly".  So you can simply leave it out
 | |
| 	  for input-streams.
 | |
| 	</p>
 | |
|         <p>
 | |
| 	  For output streams, "nocreate" is probably the default, unless you
 | |
| 	  specify <b>std::ios::trunc</b> ? 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 <b>app</b>,
 | |
| 	  <b>ate</b> and <b>trunc</b> (except for
 | |
| 	  <b>app</b> ?).
 | |
| 	</p>
 | |
|       </div>
 | |
|       <div class="section" id="sec-stream::attach">
 | |
|         <h2 class="title" style="clear: all">
 | |
|           <a name="sec-stream::attach"><b>3. <b>stream::attach(int
 | |
| 	  fd)</b> is not in the standard any more</b></a>
 | |
|         </h2>
 | |
|         <p>
 | |
| 	  When using libstdc++-v3, you can use
 | |
| 	  <div id="N3082" class="funcsynopsis">
 | |
|             <p>
 | |
|             </p>
 | |
|             <a name="N3082"></a>
 | |
|             <pre class="funcsynopsisinfo">
 | |
| 		  #include <fstream>
 | |
| 		</pre>
 | |
|             <p>
 | |
|               <code><code class="funcdef">int <b class="fsfunc">basic_filebuf</b></code>(<var class="pdparam">__fd</var>, <var class="pdparam">__name</var>, <var class="pdparam">__mode</var>);<br>int <var class="pdparam">__fd</var>;<br>const char* <var class="pdparam">__name</var>;<br>ios_base::openmode <var class="pdparam">__mode</var>;</code>
 | |
|             </p>
 | |
|             <p>
 | |
|             </p>
 | |
|           </div>
 | |
| 	  For a portable solution (if there is one), you need to implement a
 | |
| 	  subclass of <b>streambuf</b> which opens a file given a
 | |
| 	  descriptor, and then pass an instance of this to the
 | |
| 	  stream-constructor (from the Josuttis-book).
 | |
| 	</p>
 | |
|       </div>
 | |
|       <div class="section" id="sec-headers">
 | |
|         <h2 class="title" style="clear: all">
 | |
|           <a name="sec-headers"><b>4. The new headers</b></a>
 | |
|         </h2>
 | |
|         <p>
 | |
| 	  All new headers can be seen in this <a href="../../testsuite/17_intro/headers.cc">source-code</a>.
 | |
| 	</p>
 | |
|         <p>
 | |
| 	  I think it is a problem for libstdc++-v3 to add links or wrappers
 | |
| 	  for the old headers, because the implementation has changed, and
 | |
| 	  the header name-changes indicate this. It might be preferable to
 | |
| 	  use the new headers and tell users of old compilers that they
 | |
| 	  should create links (which is what they will have to do sometime
 | |
| 	  anyway).
 | |
| 	</p>
 | |
|         <div class="section" id="sec-cheaders">
 | |
|           <h3 class="title">
 | |
|             <a name="sec-cheaders"><b>4.4.1. New headers replacing C-headers</b></a>
 | |
|           </h3>
 | |
|           <p>
 | |
| 		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, ommiting the extension
 | |
| 		(.h). For example, instead of using <tt><math.h></tt>, you should use <tt><cmath></tt>. The standard
 | |
| 		specifies that if you include the C-style header (<tt><math.h></tt> in this case), the symbols
 | |
| 		will be available both in the global namespace and in namespace
 | |
| 		<b>std::</b> (libstdc++-v3, version 2.90.8 currently
 | |
| 		puts them in <b>std::</b> only) On the other hand, if
 | |
| 		you include only the new header (i.e. <tt><pcmath></tt>), the symbols will only be
 | |
| 		defined in namespace <b>std::</b> (and macros will be
 | |
| 		converted to inline-functions).
 | |
| 	  </p>
 | |
|           <p>
 | |
| 		For more information on this, and for information on how the GNU
 | |
| 		C++ implementation reuses ("shadows") the C library-functions, have
 | |
| 		a look at <a href="http://www.cantrip.org/cheaders.html">
 | |
| 		  www.cantrip.org</a>.
 | |
| 	  </p>
 | |
|         </div>
 | |
|         <div class="section" id="sec-fstream-header">
 | |
|           <h3 class="title">
 | |
|             <a name="sec-fstream-header"><b>4.4.2. 
 | |
| 		<tt><fstream></tt> does
 | |
| 		not define <b>std::cout</b>,
 | |
| 		<b>std::cin</b> etc.</b></a>
 | |
|           </h3>
 | |
|           <p>
 | |
| 		In previous versions of the standard, <tt><fstream.h></tt>, <tt><ostream.h></tt> and <tt><istream.h></tt> used to define
 | |
| 		<b>cout</b>, <b>cin</b> and so on. Because
 | |
| 		of the templatized iostreams in libstdc++-v3, you need to include
 | |
| 		<tt><iostream></tt>
 | |
| 		explicitly to define these.
 | |
| 	  </p>
 | |
|         </div>
 | |
|       </div>
 | |
|       <div class="section" id="sec-iterators">
 | |
|         <h2 class="title" style="clear: all">
 | |
|           <a name="sec-iterators"><b>5. Iterators</b></a>
 | |
|         </h2>
 | |
|         <p>
 | |
| 	  The following are not proper uses of iterators, but may be working
 | |
| 	  fixes for existing uses of iterators.
 | |
| 	  <div class="itemizedlist">
 | |
|             <ul>
 | |
|               <li>
 | |
|                 <a name="N3282"></a>
 | |
|                 <p>you cannot do
 | |
| 			<b>ostream::operator<<(iterator)</b> to
 | |
| 			print the address of the iterator => use
 | |
| 			<b>operator<< &*iterator</b> instead ?
 | |
| 		  </p>
 | |
|               </li>
 | |
|               <li>
 | |
|                 <a name="N3303"></a>
 | |
|                 <p>you cannot clear an iterator's reference
 | |
| 			(<b>iterator = 0</b>) => use
 | |
| 			<b>iterator = iterator_type();</b> ?
 | |
| 		  </p>
 | |
|               </li>
 | |
|               <li>
 | |
|                 <a name="N3316"></a>
 | |
|                 <p>
 | |
|                   <b>if (iterator)</b> won't work any
 | |
| 			more => use <b>if (iterator != iterator_type())</b>
 | |
| 			?</p>
 | |
|               </li>
 | |
|             </ul>
 | |
|           </div>
 | |
| 	</p>
 | |
|       </div>
 | |
|       <div class="section" id="sec-macros">
 | |
|         <h2 class="title" style="clear: all">
 | |
|           <a name="sec-macros"><b>6. 
 | |
| 	  Libc-macros (i.e. <b>isspace</b> from
 | |
| 	  <tt><cctype></tt>)</b></a>
 | |
|         </h2>
 | |
|         <p>
 | |
| 	  Glibc 2.0.x and 2.1.x define the <tt><ctype.h></tt> -functionality as
 | |
| 	  macros (isspace, isalpha etc.). Libstdc++-v3 "shadows" these macros
 | |
| 	  as described in the <a href="#"></a>.
 | |
| 	</p>
 | |
|         <p>
 | |
| 	  Older implementations of libstdc++ (g++-2 for egcs 1.x and g++-3
 | |
| 	  for gcc 2.95.2), however, keep these functions as macros, and so it
 | |
| 	  is not back-portable to use fully qualified names. For example:
 | |
| 	  <pre class="programlisting">
 | |
| 		#include <cctype>
 | |
| 		int main() { std::isspace('X'); }
 | |
| 	  </pre>
 | |
| 	  will result in something like this (unless using g++-v3):
 | |
| 	  <pre class="programlisting">
 | |
| 		std:: (__ctype_b[(int) ( ( 'X' ) )] & (unsigned short int)
 | |
| 		_ISspace )  ;
 | |
| 	  </pre>
 | |
| 	  </p>
 | |
|         <p>
 | |
| 	  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 ?).
 | |
| 	</p>
 | |
|         <p>
 | |
| 	  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.2) define a
 | |
| 	  macro which tells <tt><ctype.h></tt> to define functions
 | |
| 	  instead of macros:
 | |
| 	  <pre class="programlisting">
 | |
| 		// This keeps isalnum, et al from being propagated as macros.
 | |
| 		#if __linux__
 | |
| 		#define __NO_CTYPE 1
 | |
| 		#endif
 | |
| 
 | |
| 		[ now include <ctype.h> ]
 | |
| 	  </pre>
 | |
| 	</p>
 | |
|         <p>
 | |
| 	  Another problem arises if you put a <b>using namespace
 | |
| 		std;</b> declaration at the top, and include <tt><ctype.h></tt>. This will result in
 | |
| 		ambiguities between the definitions in the global namespace
 | |
| 		(<tt><ctype.h></tt>) and the
 | |
| 		definitions in namespace <b>std::</b>
 | |
| 		(<b><cctype></b>).
 | |
| 	</p>
 | |
|         <p>
 | |
| 	  The solution to this problem was posted to the libstdc++-v3
 | |
| 	  mailing-list:
 | |
| 	  Benjamin Kosnik <tt><<a href="mailto:bkoz@redhat.com">bkoz@redhat.com</a>></tt> writes:
 | |
| 	  "
 | |
| 		--enable-cshadow-headers is currently broken. As a result, shadow
 | |
| 		headers are not being searched....
 | |
| 	  "
 | |
| 	</p>
 | |
|       </div>
 | |
|       <div class="section" id="sec-stream-state">
 | |
|         <h2 class="title" style="clear: all">
 | |
|           <a name="sec-stream-state"><b>7. 
 | |
| 	  State of streams
 | |
| 	</b></a>
 | |
|         </h2>
 | |
|         <p>
 | |
| 	  At least some older implementations don't have
 | |
| 	  <b>std::ios_base</b>, so you should use
 | |
| 	  <b>std::ios::badbit</b>, <b>std::ios::failbit</b>
 | |
| 	  and <b>std::ios::eofbit</b> and
 | |
| 	  <b>std::ios::goodbit</b>.
 | |
| 	</p>
 | |
|       </div>
 | |
|       <div class="section" id="sec-vector-at">
 | |
|         <h2 class="title" style="clear: all">
 | |
|           <a name="sec-vector-at"><b>8. vector::at is missing (i.e. gcc 2.95.2)</b></a>
 | |
|         </h2>
 | |
|         <p>
 | |
| 	  For my use, I added it to
 | |
| 	  <tt>prefix/include/g++-3/stl_vector.h</tt>:
 | |
| 	  <pre class="programlisting">
 | |
|   reference operator[](size_type __n) { return *(begin() + __n); }
 | |
|   reference at(size_type __n) {
 | |
|     if (begin() + __n >= end())
 | |
|       throw out_of_range("vector::at");
 | |
|     return *(begin() + __n);
 | |
|   }
 | |
|   const_reference operator[](size_type __n) const { return *(begin() + __n); }
 | |
|   const_reference at(size_type __n) const {
 | |
|     if (begin() + __n >= end())
 | |
|       throw out_of_range("vector::at");
 | |
|     return *(begin() + __n);
 | |
|   }
 | |
| 	  </pre>
 | |
| 	</p>
 | |
|       </div>
 | |
|       <div class="section" id="sec-eof">
 | |
|         <h2 class="title" style="clear: all">
 | |
|           <a name="sec-eof"><b>9. Using std::char_traits<char>::eof()</b></a>
 | |
|         </h2>
 | |
|         <p>
 | |
| 	  <pre class="programlisting">
 | |
| 		#ifdef HAVE_CHAR_TRAITS
 | |
| 		#define CPP_EOF std::char_traits<char>::eof()
 | |
| 		#else
 | |
| 		#define CPP_EOF EOF
 | |
| 		#endif
 | |
| 	  </pre>
 | |
| 	</p>
 | |
|       </div>
 | |
|       <div class="section" id="sec-string-clear">
 | |
|         <h2 class="title" style="clear: all">
 | |
|           <a name="sec-string-clear"><b>10. Using string::clear()/string::erase()</b></a>
 | |
|         </h2>
 | |
|         <p>
 | |
| 	  There are two functions for deleting the contents of a string:
 | |
| 	  <b>clear</b> and <b>erase</b> (the latter
 | |
| 	  returns the string).
 | |
| 	  <pre class="programlisting">
 | |
| 		void 
 | |
| 		clear() { _M_mutate(0, this->size(), 0); }
 | |
| 	  </pre>
 | |
| 	  <pre class="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()); 
 | |
|       }
 | |
| 	  </pre>
 | |
| 	  The implementation of <b>erase</b> seems to be more
 | |
| 	  complicated (from libstdc++-v3), but <b>clear</b> is not
 | |
| 	  implemented in gcc 2.95.2's libstdc++, so you should use
 | |
| 	  <b>erase</b> (which is probably faster than
 | |
| 	  <b>operator=(charT*)</b>).
 | |
| 	</p>
 | |
|       </div>
 | |
|       <div class="section" id="sec-stringstream">
 | |
|         <h2 class="title" style="clear: all">
 | |
|           <a name="sec-stringstream"><b>11. Using stringstream's</b></a>
 | |
|         </h2>
 | |
|         <p>
 | |
| 	  Libstdc++-v3 includes the new
 | |
| 	  <b>i/ostringstream</b>-classes, (<tt><sstream></tt>), but with older
 | |
| 	  implementations you still have to use <b>i/ostrstream</b>
 | |
| 	  (<tt><strstream></tt>):
 | |
| 	  <pre class="programlisting">
 | |
| 		#ifdef HAVE_SSTREAM
 | |
| 		#include <sstream>
 | |
| 		#else
 | |
| 		#include <strstream>
 | |
| 		#endif
 | |
| 	  </pre>
 | |
| 	  <div class="itemizedlist">
 | |
|             <ul>
 | |
|               <li>
 | |
|                 <a name="N3595"></a>
 | |
|                 <p> <b>strstream</b> is considered to be
 | |
| 			deprecated
 | |
| 		  </p>
 | |
|               </li>
 | |
|               <li>
 | |
|                 <a name="N3603"></a>
 | |
|                 <p> <b>strstream</b> is limited to
 | |
| 			<b>char</b>
 | |
| 		  </p>
 | |
|               </li>
 | |
|               <li>
 | |
|                 <a name="N3614"></a>
 | |
|                 <p> with <b>ostringstream</b> you don't
 | |
| 			have to take care of terminating the string or freeing its
 | |
| 			memory
 | |
| 		  </p>
 | |
|               </li>
 | |
|               <li>
 | |
|                 <a name="N3622"></a>
 | |
|                 <p> <b>istringstream</b> can be re-filled
 | |
| 			(clear(); str(input);)
 | |
| 		  </p>
 | |
|               </li>
 | |
|             </ul>
 | |
|           </div>
 | |
| 	</p>
 | |
|         <p>
 | |
| 	  You can then use output-stringstreams like this:
 | |
| 	  <pre class="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
 | |
| 	  </pre>
 | |
| 	</p>
 | |
|         <p>
 | |
| 	  Input-stringstreams can be used similarly:
 | |
| 	  <pre class="programlisting">
 | |
| 		std::string input;
 | |
| 		...
 | |
| 		#ifdef HAVE_SSTREAM
 | |
| 		std::istringstream iss(input);
 | |
| 		#else
 | |
| 		std::istrstream iss(input.c_str());
 | |
| 		#endif
 | |
| 		int i;
 | |
| 		iss >> i; 
 | |
| 	  </pre>
 | |
| 	  One (the only?) restriction is that an istrstream cannot be re-filled:
 | |
| 	  <pre class="programlisting">
 | |
| 		std::istringstream iss(numerator);
 | |
| 		iss >> m_num;
 | |
| 		// this is not possible with istrstream
 | |
| 		iss.clear();
 | |
| 		iss.str(denominator);
 | |
| 		iss >> m_den;
 | |
| 	  </pre>
 | |
| 	  If you don't care about speed, you can put these conversions in
 | |
| 	  a template-function:
 | |
| 	  <pre class="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;
 | |
| 		}
 | |
| 	  </pre>
 | |
| 	</p>
 | |
|         <p>
 | |
| 	  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.2
 | |
| 	  uses.
 | |
| 	</p>
 | |
|       </div>
 | |
|       <div class="section" id="sec-about">
 | |
|         <h2 class="title" style="clear: all">
 | |
|           <a name="sec-about"><b>12. About...</b></a>
 | |
|         </h2>
 | |
|         <p>
 | |
| 	  Please send any experience, additions, corrections or questions to
 | |
| 	  <a href="mailto:fnatter@gmx.net">fnatter@gmx.net</a> or for
 | |
| 	  discussion to the libstdc++-v3-mailing-list.
 | |
| 	</p>
 | |
|       </div>
 | |
|     </div>
 | |
|   </body>
 | |
| </html>
 |