Because there are many compilers which still use an implementation
that does not have the standard C++-library in namespace
@@ -235,7 +234,6 @@
libstdc++ in std:: or not). (ideas from
<llewelly@dbritsch.dsl.xmission.com>, Karl Nelson
<kenelson@ece.ucdavis.edu>)
-
@@ -270,7 +267,7 @@
(thanks to Juergen Heinzl who posted this solution on
gnu.gcc.help)
-
+
Define a macro NS_STD, which is defined to
either "" or "std"
@@ -280,8 +277,6 @@
systems that do not put string in std::. (This is untested)
-
-
@@ -356,7 +351,7 @@
-there is no ios::nocreate/ios::noreplace
+There is no ios::nocreate/ios::noreplace
in ISO 14882
I have seen ios::nocreate being used for
@@ -383,22 +378,8 @@
It was considered and rejected. Not all environments use file
descriptors. Of those that do, not all of them use integers to represent
them.
-
- 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
@@ -409,6 +390,14 @@
fdstream example
by Nicolai Josuttis.
+
+
+ An extension is also available:
+ <ext/stdio_filebuf.h> contains a derived class called
+ __gnu_cxx::stdio_filebuf.
+ This class can be constructed from a C FILE* or a file
+ descriptor, and provides the fd() function.
+
@@ -491,7 +480,6 @@
more => use if (iterator != iterator_type())
?
One solution I can think of is to test for -v3 using
autoconf-macros, and define macros for each of the C-functions
@@ -537,7 +524,6 @@
[ 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
@@ -598,7 +584,6 @@
If you are using other (non-GNU) compilers it might be a good idea
to check for string::at separately.
-
@@ -611,7 +596,6 @@
#define CPP_EOF EOF
#endif
-
@@ -637,7 +621,6 @@
implemented in gcc 2.95.x's libstdc++, so you should use
erase (which is probably faster than
operator=(charT*)).
-
@@ -678,7 +661,6 @@
(clear(); str(input);)
-
You can then use output-stringstreams like this:
@@ -701,7 +683,6 @@
oss.freeze(false);
#endif
-
Input-stringstreams can be used similarly:
@@ -743,7 +724,6 @@
}
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
diff --git a/libstdc++-v3/docs/html/17_intro/porting-howto.xml b/libstdc++-v3/docs/html/17_intro/porting-howto.xml
deleted file mode 100644
index cea9111..0000000
--- a/libstdc++-v3/docs/html/17_intro/porting-howto.xml
+++ /dev/null
@@ -1,785 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- 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
-
-
-
- 0.9.4
- Mon Nov 5 17:01:04 2001
- fnatter
-
- rewrite section 1.1.3 because of gnu.gcc.help-post by
- Juergen Heinzl
-
-
-
- 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 namespace
- composition 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 I see two solutions:
-
-
-
- Define std:: as a macro if the compiler
- doesn't know about std::.
-
- #ifdef OLD_COMPILER
- #define std
- #endif
-
- (thanks to Juergen Heinzl who posted this solution on
- gnu.gcc.help)
-
-
-
- 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.
-
-
Notations for categories
-
-
-
- usual
- mostly fully qualified names and some
- using-declarations (but not in headers)
-
-
- noneno 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 ?).
-
-
-
-
- stream::attach(int
- fd) 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 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. For an example of this, refer to
- fdstream example
- by Nicolai Josuttis.
-
-
-
-
- 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.
-
-
-
-
-
- <fstream> does
- not define std::cout,
- std::cin 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. 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 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.7.4