From 89cd2243635c023c56704c124e2eb0502c9d3333 Mon Sep 17 00:00:00 2001 From: Felix Natter Date: Thu, 12 Jul 2001 00:02:34 +0000 Subject: [PATCH] porting-howto.xml: Initial checkin of master copy. 2001-07-11 Felix Natter * docs/html/17_intro/porting-howto.xml: Initial checkin of master copy. * docs/html/17_intro/porting-howto.html: check in v0.9.3 From-SVN: r43953 --- libstdc++-v3/ChangeLog | 6 + .../docs/html/17_intro/porting-howto.html | 284 +++---- .../docs/html/17_intro/porting-howto.xml | 758 ++++++++++++++++++ 3 files changed, 892 insertions(+), 156 deletions(-) create mode 100644 libstdc++-v3/docs/html/17_intro/porting-howto.xml diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 15e0bc64372..26c246d441f 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,9 @@ +2001-07-11 Felix Natter + + * docs/html/17_intro/porting-howto.xml: Initial checkin of + master copy. + * docs/html/17_intro/porting-howto.html: check in v0.9.3 + 2001-07-11 Phil Edwards * docs/doxygen/run_doxygen: Don't keep output from previous run. diff --git a/libstdc++-v3/docs/html/17_intro/porting-howto.html b/libstdc++-v3/docs/html/17_intro/porting-howto.html index cb1160fbdad..582d4a6cdf2 100644 --- a/libstdc++-v3/docs/html/17_intro/porting-howto.html +++ b/libstdc++-v3/docs/html/17_intro/porting-howto.html @@ -1,20 +1,20 @@ - + Libstdc++-porting-howto -
+

-Libstdc++-porting-howto

+Libstdc++-porting-howto

Felix Natter

Legal Notice

- This document can be distributed under the FDL - (www.gnu.org) + This document can be distributed under the FDL + (www.gnu.org)

Tue Jun 5 20:07:49 2001

@@ -32,8 +32,8 @@ fnatter First released version using docbook-xml - + second upload to libstdc++-page. - + + second upload to libstdc++-page. + Revision 0.9 Wed Sep 6 02:59:32 2000 @@ -46,21 +46,37 @@ fnatter added information about why file-descriptors are not in the - standard + standard Revision 0.9.2 Tue Jun 5 20:07:49 2001 fnatter - a fix, added hint on increased portability of C-shadow-headers, - added autoconf-test HAVE_CONTAINER_AT - + a fix, added hint on increased portability of C-shadow-headers, + added autoconf-test HAVE_CONTAINER_AT + + +Revision 0.9.3 +Fri Jun 29 16:15:56 2001 +fnatter + + + 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 +

- -Abstract +Abstract

Some notes on porting applications from libstdc++-2.90 (or earlier @@ -93,8 +109,7 @@

2. there is no ios::nocreate/ios::noreplace in ISO 14882
-
3. -stream::attach(int +
3. stream::attach(int fd) is not in the standard any more
4. The new headers @@ -114,9 +129,7 @@ Libc-macros (i.e. isspace from <cctype>)
-
7. - State of streams - +
7. State of streams
8. vector::at is missing (i.e. gcc 2.95.x)
@@ -124,9 +137,11 @@
10. Using string::clear()/string::erase()
-
11. Using stringstream's +
11. GNU Extensions ostream::form and istream::scan +
+
12. Using stringstreams
-
12. About... +
13. About...
@@ -137,10 +152,8 @@ libstdc++-implementations".

- -

- -1. Namespace std:: +

+1. Namespace std::

The latest C++-standard (ISO-14882) requires that the standard @@ -149,19 +162,19 @@ things:

  • -wrap your code in namespace std { +wrap your code in namespace std { ... } => This is not an option because only symbols from the standard c++-library are defined in namespace std::.

  • -put a kind of +put a kind of using-declaration in your source (either using namespace std; or i.e. using std::string;) => works well for source-files, but cannot be used in header-files.

  • -use a fully qualified name for +use a fully qualified name for each libstdc++-symbol (i.e. std::string, std::cout) => can always be used

  • @@ -188,10 +201,8 @@ that cannot ignore std::.

    - -

    - -1.1.1. Using namespace +

    +1.1.1. Using namespace composition if the project uses a separate namespace

    @@ -213,7 +224,7 @@ namespace Gtk::. The result is that you don't have to use std::string in this header, but still std::string does not get imported into - user-space (the global namespace ::) unless the user does + the global namespace (::) unless the user does using namespace Gtk; (which is not recommended practice for Gtk--, so it is not a problem). Additionally, the using-declarations are wrapped in macros that @@ -225,10 +236,8 @@

    - -

    - -1.1.2. Defining an empty namespace std +

    +1.1.2. Defining an empty namespace std

    By defining an (empty) namespace std:: before @@ -241,10 +250,8 @@

    - -

    - -1.1.3. Avoid to use fully qualified names +

    +1.1.3. Avoid to use fully qualified names (i.e. std::string)

    @@ -259,10 +266,8 @@

    - -

    - -1.1.4. How some open-source-projects deal +

    +1.1.4. How some open-source-projects deal with this

    @@ -271,8 +276,7 @@

    - -Table 1. Namespace std:: in Open-Source programs +Table 1. Namespace std:: in Open-Source programs

    @@ -306,8 +310,7 @@

    - -Table 2. Notations for categories +Table 2. Notations for categories

    @@ -334,17 +337,15 @@

    - 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 ). + 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 section on the gtkmm-hack).

    - -

    - -2. there is no ios::nocreate/ios::noreplace +

    +2. there is no ios::nocreate/ios::noreplace in ISO 14882

    @@ -364,11 +365,8 @@

    - -

    - -3. -stream::attach(int +

    +3. stream::attach(int fd) is not in the standard any more

    @@ -379,32 +377,33 @@

    When using libstdc++-v3, you can use -

    +

    - -

    +
     	  #include <fstream>
     	
    -

    -int basic_filebuf -(__fd, __name, __mode);
    int __fd;
    const char* __name;
    ios_base::openmode __mode;

    +

    + basic_filebuf<...>::basic_filebuf<...> + + (file, mode, size);
    __c_file_type* file;
    ios_base::open_mode mode;
    int size;

    but the the signature of this constructor has changed often, and - it might change again. + it might change again. For the current state of this, check + the howto for extensions. +

    +

    For a portable solution (among systems which use filedescriptors), you need to implement a subclass of - streambuf (or - basic_streambuf<..>) which opens a file + std::streambuf (or + std::basic_streambuf<..>) which opens a file given a descriptor, and then pass an instance of this to the stream-constructor (from the Josuttis-book).

    - -

    - -4. The new headers +

    +4. The new headers

    All new headers can be seen in this @@ -415,10 +414,8 @@ a warning that you are using deprecated headers.

    - -

    - -4.4.1. New headers replacing C-headers +

    +4.4.1. New headers replacing C-headers

    You should not use the C-headers (except for system-level @@ -448,10 +445,8 @@

    - -

    - -4.4.2. +

    +4.4.2. <fstream> does not define std::cout, std::cin etc. @@ -470,46 +465,43 @@

    - -

    - -5. Iterators +

    +5. Iterators

    The following are not proper uses of iterators, but may be working fixes for existing uses of iterators.

    • -you cannot do +you cannot do ostream::operator<<(iterator) to print the address of the iterator => use operator<< &*iterator instead ?

    • -you cannot clear an iterator's reference +you cannot clear an iterator's reference (iterator = 0) => use iterator = iterator_type(); ?

    • - -if (iterator) won't work any +if (iterator) won't work any more => use if (iterator != iterator_type()) ?

    - -

    - -6. +

    +6. Libc-macros (i.e. isspace from <cctype>)

    - Glibc 2.0.x and 2.1.x define the <ctype.h> -functionality as - macros (isspace, isalpha etc.). Libstdc++-v3 "shadows" these macros - as described in the . + Glibc 2.0.x and 2.1.x define the + <ctype.h> + -functionality as macros (isspace, isalpha etc.). Libstdc++-v3 + "shadows" these macros as described in the section about + c-headers.

    Older implementations of libstdc++ (g++-2 for egcs 1.x and g++-3 @@ -560,15 +552,13 @@ --enable-cshadow-headers is currently broken. As a result, shadow headers are not being searched.... ' + This is now outdated, but gcc 3.0 still does not have fully + compliant "shadow headers".

    - -

    - -7. - State of streams - +

    +7. State of streams

    At least some older implementations don't have @@ -579,31 +569,11 @@

    - -

    - -8. vector::at is missing (i.e. gcc 2.95.x) +

    +8. vector::at is missing (i.e. gcc 2.95.x)

    - You could easily modify the header-files: - prefix/include/g++-3/stl_vector.h: -

    -	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);
    -	}
    -      
    - (and so on for deque and string) - - Of course a better solution is to add an autoconf-test for this: + One solution is to add an autoconf-test for this:
     	AC_MSG_CHECKING(for container::at)
     	AC_TRY_COMPILE(
    @@ -631,10 +601,8 @@
         

    - -

    - -9. Using std::char_traits<char>::eof() +

    +9. Using std::char_traits<char>::eof()

    @@ -647,10 +615,8 @@
         

    - -

    - -10. Using string::clear()/string::erase() +

    +10. Using string::clear()/string::erase()

    There are two functions for deleting the contents of a string: @@ -676,17 +642,24 @@

    - -

    - -11. Using stringstream's +

    +11. GNU Extensions ostream::form and istream::scan +

    +

    + These are not supported any more - use + + stringstreams instead. +

    +

    +
    +

    +12. Using stringstreams

    Libstdc++-v3 provides the new - i/ostringstream-classes, - (<sstream>), but with older - implementations you still have to use i/ostrstream - (<strstream>): + i/ostringstream-classes, (<sstream>), but for compatibility + with older implementations you still have to use + i/ostrstream (<strstream>):

     	#ifdef HAVE_SSTREAM
     	#include <sstream>
    @@ -696,20 +669,20 @@
           
    • - strstream is considered to be + strstream is considered to be deprecated

    • - strstream is limited to + strstream is limited to char

    • - with ostringstream you don't + with ostringstream you don't have to take care of terminating the string or freeing its memory

    • - istringstream can be re-filled + istringstream can be re-filled (clear(); str(input);)

    @@ -766,17 +739,18 @@ void fromString(const string& input, X& any) { #ifdef HAVE_SSTREAM - std::istringstream iss(input); + std::istringstream iss(input); #else - std::istrstream iss(input.c_str()); + std::istrstream iss(input.c_str()); #endif - X temp; - iss >> temp; - if (iss.fail()) - throw runtime_error(..) - any = temp; + X temp; + iss >> temp; + if (iss.fail()) + throw runtime_error(..) + any = temp; } + Another example of using stringstreams is in this howto.

    I have read the Josuttis book on Standard C++, so some information @@ -786,10 +760,8 @@

    - -

    - -12. About... +

    +13. About...

    Please send any experience, additions, corrections or questions to diff --git a/libstdc++-v3/docs/html/17_intro/porting-howto.xml b/libstdc++-v3/docs/html/17_intro/porting-howto.xml new file mode 100644 index 00000000000..f00d047989c --- /dev/null +++ b/libstdc++-v3/docs/html/17_intro/porting-howto.xml @@ -0,0 +1,758 @@ + + + + + + + + + + +

    + + Libstdc++-porting-howto + + Felix + Natter + +
    + fnatter@gmx.net +
    + + + 0.5 + Thu Jun 1 13:06:50 2000 + fnatter + First docbook-version. + + + 0.8 + Sun Jul 30 20:28:40 2000 + fnatter + First released version using docbook-xml + + second upload to libstdc++-page. + + + + 0.9 + Wed Sep 6 02:59:32 2000 + fnatter + 5 new sections. + + + 0.9.1 + Sat Sep 23 14:20:15 2000 + fnatter + added information about why file-descriptors are not in the + standard + + + 0.9.2 + Tue Jun 5 20:07:49 2001 + fnatter + + a fix, added hint on increased portability of C-shadow-headers, + added autoconf-test HAVE_CONTAINER_AT + + + + 0.9.3 + Fri Jun 29 16:15:56 2001 + fnatter + + 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 + + + + Legal Notice + + This document can be distributed under the FDL + (www.gnu.org) + + + + Tue Jun 5 20:07:49 2001 + + + 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. + + +
    + + + 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". + + +
    Namespace std:: + + 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: + + + wrap your code in namespace std { + ... } => This is not an option because only symbols + from the standard c++-library are defined in namespace std::. + + + put a kind of + using-declaration in your source (either + using namespace std; or i.e. using + std::string;) => works well for source-files, but + cannot be used in header-files. + + + use a fully qualified name for + each libstdc++-symbol (i.e. std::string, + std::cout) => can always be used + + + + + + Because there are many compilers which still use an implementation + that does not have the standard C++-library in namespace + std::, some care is required to support these as + well. + + + + Namespace back-portability-issues are generally not a problem with + g++, because versions of g++ that do not have libstdc++ in + std:: use -fno-honor-std + (ignore std::, :: = std::) by + default. That is, the responsibility for enabling or disabling + std:: is on the user; the maintainer does not have + to care about it. This probably applies to some other compilers as + well. + + + The following sections list some possible solutions to support compilers + that cannot ignore std::. + + +
    + Using <emphasis>namespace + composition</emphasis> if the project uses a separate + namespace + + Gtk-- defines + most of its classes in namespace Gtk::. Thus, it was possible to + adapt Gtk-- to namespace std:: by using a C++-feature called + namespace composition. This is what happens if + you put a using-declaration into a + namespace-definition: the imported symbol(s) gets imported into the + currently active namespace(s). For example: + + namespace Gtk { + using std::string; + class Window { ... } + } + + In this example, std::string gets imported into + namespace Gtk::. The result is that you don't have to use + std::string in this header, but still + std::string does not get imported into + the global namespace (::) unless the user does + using namespace Gtk; (which is not recommended + practice for Gtk--, so it is not a problem). Additionally, the + using-declarations are wrapped in macros that + are set based on autoconf-tests to either "" or i.e. using + std::string; (depending on whether the system has + libstdc++ in std:: or not). (ideas from + llewelly@dbritsch.dsl.xmission.com, Karl Nelson + kenelson@ece.ucdavis.edu) + +
    + +
    + Defining an empty namespace std + + By defining an (empty) namespace std:: before + using it, you avoid getting errors on systems where no part of the + library is in namespace std: + + namespace std { } + using namespace std; + + +
    + +
    + Avoid to use fully qualified names + (i.e. std::string) + + If some compilers complain about using + std::string;, 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 + NS_STD::string, which will evaluate to + ::string ("string in the global namespace") on + systems that do not put string in std::. (This is untested) + +
    + +
    + How some open-source-projects deal + with this + + This information was gathered around May 2000. It may not be correct + by the time you read this. + + Namespace std:: in Open-Source programs + + + + clanlib + + usual + + + pingus + + usual + + + mozilla + + usual + + + mnemonic + none + + + + libsigc++ + conservative-impl + + + +
    + + Notations for categories + + + + usual + mostly fully qualified names and some + using-declarations (but not in headers) + + + none no namespace std at all + + + conservative-impl + wrap all + namespace-handling in macros to support compilers without + namespace-support (no libstdc++ used in headers) + + + +
    + + + 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 section on the gtkmm-hack). + +
    +
    + +
    + there is no ios::nocreate/ios::noreplace + in ISO 14882 + + I have seen ios::nocreate 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. + + + For output streams, "nocreate" is probably the default, unless you + specify std::ios::trunc ? 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 app, + ate and trunc (except for + app ?). + +
    + +
    + <command>stream::attach(int + fd)</command> is not in the standard any more + + Phil Edwards pedwards@disaster.jaj.com 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. + + + When using libstdc++-v3, you can use + + + #include <fstream> + + + + basic_filebuf<...>::basic_filebuf<...> + + + __c_file_type* file + ios_base::open_mode mode + int size + + + but the the signature of this constructor has changed often, and + it might change again. For the current state of this, check + the howto for extensions. + + + For a portable solution (among systems which use + filedescriptors), you need to implement a subclass of + std::streambuf (or + std::basic_streambuf<..>) which opens a file + given a descriptor, and then pass an instance of this to the + stream-constructor (from the Josuttis-book). + +
    + +
    + The new headers + + All new headers can be seen in this + source-code. + + + The old C++-headers (iostream.h etc.) are available, but gcc generates + a warning that you are using deprecated headers. + + +
    + New headers replacing C-headers + + 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 + <math.h>, you + should use <cmath>. In some cases this has + the advantage that the C++-header is more standardized than + the C-header (i.e. <ctime> (almost) + corresponds to either <time.h> or <sys/time.h>). + + The standard specifies that if you include the C-style header + (<math.h> in + this case), the symbols will be available both in the global + namespace and in namespace std:: (but + libstdc++ does not yet have fully compliant headers) On the + other hand, if you include only the new header (i.e. <cmath>), the symbols + will only be defined in namespace std:: + (and macros will be converted to inline-functions). + + + 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 + www.cantrip.org. + +
    + +
    + + <filename class="headerfile"><fstream></filename> does + not define <command>std::cout</command>, + <command>std::cin</command> etc. + + In earlier versions of the standard, + <fstream.h>, + <ostream.h> + and <istream.h> + used to define + cout, cin and so on. Because + of the templatized iostreams in libstdc++-v3, you need to include + <iostream> + explicitly to define these. + +
    +
    + +
    + Iterators + + The following are not proper uses of iterators, but may be working + fixes for existing uses of iterators. + + you cannot do + ostream::operator<<(iterator) to + print the address of the iterator => use + operator<< &*iterator instead ? + + + you cannot clear an iterator's reference + (iterator = 0) => use + iterator = iterator_type(); ? + + + if (iterator) won't work any + more => use if (iterator != iterator_type()) + ? + + + +
    + +
    + + Libc-macros (i.e. <command>isspace</command> from + <filename class = "headerfile"><cctype></filename>) + + Glibc 2.0.x and 2.1.x define the + <ctype.h> + -functionality as macros (isspace, isalpha etc.). Libstdc++-v3 + "shadows" these macros as described in the section about + c-headers. + + + 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: + + #include <cctype> + int main() { std::isspace('X'); } + + will result in something like this (unless using g++-v3): + + std:: (__ctype_b[(int) ( ( 'X' ) )] & (unsigned short int) + _ISspace ) ; + + + + 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 ?). + + + 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 <ctype.h> to define functions + instead of macros: + + // This keeps isalnum, et al from being propagated as macros. + #if __linux__ + #define __NO_CTYPE 1 + #endif + + [ now include <ctype.h> ] + + + + Another problem arises if you put a using namespace + std; declaration at the top, and include <ctype.h>. This will result in + ambiguities between the definitions in the global namespace + (<ctype.h>) and the + definitions in namespace std:: + (<cctype>). + + + The solution to this problem was posted to the libstdc++-v3 + mailing-list: + Benjamin Kosnik bkoz@redhat.com writes: + + --enable-cshadow-headers is currently broken. As a result, shadow + headers are not being searched.... + + This is now outdated, but gcc 3.0 still does not have fully + compliant "shadow headers". + +
    + +
    + State of streams + + At least some older implementations don't have + std::ios_base, so you should use + std::ios::badbit, std::ios::failbit + and std::ios::eofbit and + std::ios::goodbit. + +
    + +
    + vector::at is missing (i.e. gcc 2.95.x) + + One solution is to add an autoconf-test for this: + + 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)]) + + If you are using other (non-GNU) compilers it might be a good idea + to check for string::at separately. + +
    + +
    + Using std::char_traits<char>::eof() + + + #ifdef HAVE_CHAR_TRAITS + #define CPP_EOF std::char_traits<char>::eof() + #else + #define CPP_EOF EOF + #endif + + +
    + +
    + Using string::clear()/string::erase() + + There are two functions for deleting the contents of a string: + clear and erase (the latter + returns the string). + + void + clear() { _M_mutate(0, this->size(), 0); } + + + 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()); + } + + The implementation of erase seems to be more + complicated (from libstdc++-v3), but clear is not + implemented in gcc 2.95.x's libstdc++, so you should use + erase (which is probably faster than + operator=(charT*)). + +
    + +
    + GNU Extensions ostream::form and istream::scan + + These are not supported any more - use + + stringstreams instead. + +
    + +
    + Using stringstreams + + Libstdc++-v3 provides the new + i/ostringstream-classes, (<sstream>), but for compatibility + with older implementations you still have to use + i/ostrstream (<strstream>): + + #ifdef HAVE_SSTREAM + #include <sstream> + #else + #include <strstream> + #endif + + + strstream is considered to be + deprecated + + + strstream is limited to + char + + + with ostringstream you don't + have to take care of terminating the string or freeing its + memory + + + istringstream can be re-filled + (clear(); str(input);) + + + + + + You can then use output-stringstreams like this: + + #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 + + + + Input-stringstreams can be used similarly: + + std::string input; + ... + #ifdef HAVE_SSTREAM + std::istringstream iss(input); + #else + std::istrstream iss(input.c_str()); + #endif + int i; + iss >> i; + + One (the only?) restriction is that an istrstream cannot be re-filled: + + std::istringstream iss(numerator); + iss >> m_num; + // this is not possible with istrstream + iss.clear(); + iss.str(denominator); + iss >> m_den; + + If you don't care about speed, you can put these conversions in + a template-function: + + 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; + } + + Another example of using stringstreams is in this howto. + + + 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. + +
    + +
    + About... + + Please send any experience, additions, corrections or questions to + fnatter@gmx.net or for + discussion to the libstdc++-v3-mailing-list. + +
    + +
    + + + + -- 2.30.2