diff options
author | kan <kan@FreeBSD.org> | 2003-02-10 05:47:54 +0000 |
---|---|---|
committer | kan <kan@FreeBSD.org> | 2003-02-10 05:47:54 +0000 |
commit | 78fa66448c770aa99b6f69113061eb5d77581627 (patch) | |
tree | 548333fba089bbaa9f6f60f38860213a7f7ccf69 /contrib/libstdc++/include | |
parent | 793833d7a78bb624965885760593495e7079d705 (diff) | |
download | FreeBSD-src-78fa66448c770aa99b6f69113061eb5d77581627.zip FreeBSD-src-78fa66448c770aa99b6f69113061eb5d77581627.tar.gz |
Gcc 3.2.2-release C++ support bits.
Diffstat (limited to 'contrib/libstdc++/include')
-rw-r--r-- | contrib/libstdc++/include/Makefile.am | 32 | ||||
-rw-r--r-- | contrib/libstdc++/include/Makefile.in | 33 | ||||
-rw-r--r-- | contrib/libstdc++/include/backward/alloc.h | 4 | ||||
-rw-r--r-- | contrib/libstdc++/include/bits/c++config | 9 | ||||
-rw-r--r-- | contrib/libstdc++/include/bits/fstream.tcc | 7 | ||||
-rw-r--r-- | contrib/libstdc++/include/bits/locale_facets.h | 65 | ||||
-rw-r--r-- | contrib/libstdc++/include/bits/locale_facets.tcc | 11 | ||||
-rw-r--r-- | contrib/libstdc++/include/bits/localefwd.h | 13 | ||||
-rw-r--r-- | contrib/libstdc++/include/bits/slice_array.h | 3 | ||||
-rw-r--r-- | contrib/libstdc++/include/bits/stl_alloc.h | 1393 | ||||
-rw-r--r-- | contrib/libstdc++/include/bits/stl_bvector.h | 4 | ||||
-rw-r--r-- | contrib/libstdc++/include/bits/stl_vector.h | 4 | ||||
-rw-r--r-- | contrib/libstdc++/include/bits/streambuf.tcc | 12 | ||||
-rw-r--r-- | contrib/libstdc++/include/std/std_fstream.h | 18 | ||||
-rw-r--r-- | contrib/libstdc++/include/std/std_streambuf.h | 13 |
15 files changed, 819 insertions, 802 deletions
diff --git a/contrib/libstdc++/include/Makefile.am b/contrib/libstdc++/include/Makefile.am index cb29b24..5c87bb3 100644 --- a/contrib/libstdc++/include/Makefile.am +++ b/contrib/libstdc++/include/Makefile.am @@ -320,6 +320,7 @@ target_headers_extra = \ ${target_builddir}/c++io.h \ ${target_builddir}/c++locale.h \ ${target_builddir}/messages_members.h \ + ${target_builddir}/time_members.h \ ${target_builddir}/codecvt_specializations.h thread_target_headers = \ @@ -409,6 +410,7 @@ ${target_builddir}/stamp-target: ${target_headers} stamp-${target_alias} @LN_S@ ${glibcpp_srcdir}/@CSTDIO_H@ c++io.h || true ;\ @LN_S@ ${glibcpp_srcdir}/@CLOCALE_H@ c++locale.h || true ;\ @LN_S@ ${glibcpp_srcdir}/@CMESSAGES_H@ messages_members.h || true ;\ + @LN_S@ ${glibcpp_srcdir}/@CTIME_H@ time_members.h || true ;\ @LN_S@ ${glibcpp_srcdir}/@CCODECVT_H@ codecvt_specializations.h || true ;\ echo `date` > stamp-target; \ fi @@ -465,32 +467,32 @@ ${target_builddir}/gthr-default.h: ${toplevel_srcdir}/gcc/${glibcpp_thread_h} \ # the rest are taken from the original source tree. gxx_include_dir = @gxx_include_dir@ install-data-local: - $(mkinstalldirs) ${gxx_include_dir} - $(mkinstalldirs) ${gxx_include_dir}/${bits_builddir} + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir} + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${bits_builddir} for file in ${bits_headers}; do \ - $(INSTALL_DATA) $${file} ${gxx_include_dir}/${bits_builddir}; done - $(mkinstalldirs) ${gxx_include_dir}/${backward_builddir} + $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${bits_builddir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${backward_builddir} for file in ${backward_headers}; do \ - $(INSTALL_DATA) $${file} ${gxx_include_dir}/${backward_builddir}; done - $(mkinstalldirs) ${gxx_include_dir}/${ext_builddir} + $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${backward_builddir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${ext_builddir} for file in ${ext_headers}; do \ - $(INSTALL_DATA) $${file} ${gxx_include_dir}/${ext_builddir}; done - $(mkinstalldirs) ${gxx_include_dir}/${c_base_builddir} + $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${ext_builddir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${c_base_builddir} for file in ${c_base_headers_rename}; do \ - $(INSTALL_DATA) ${c_base_builddir}/$${file} ${gxx_include_dir}; done + $(INSTALL_DATA) ${c_base_builddir}/$${file} $(DESTDIR)${gxx_include_dir}/${c_base_builddir}; done c_base_headers_extra_install='$(c_base_headers_extra)';\ for file in $$c_base_headers_extra_install; do \ - $(INSTALL_DATA) $$file ${gxx_include_dir}/${bits_builddir}; done + $(INSTALL_DATA) $$file $(DESTDIR)${gxx_include_dir}/${bits_builddir}; done c_compatibility_headers_install='$(c_compatibility_headers_extra)';\ for file in $$c_compatibility_headers_install; do \ - $(INSTALL_DATA) $$file ${gxx_include_dir}; done - $(mkinstalldirs) ${gxx_include_dir}/${std_builddir} + $(INSTALL_DATA) $$file $(DESTDIR)${gxx_include_dir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${std_builddir} for file in ${std_headers_rename}; do \ - $(INSTALL_DATA) ${std_builddir}/$${file} ${gxx_include_dir}; done - $(mkinstalldirs) ${gxx_include_dir}/${target_builddir} + $(INSTALL_DATA) ${std_builddir}/$${file} $(DESTDIR)${gxx_include_dir}/${std_builddir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${target_builddir} for file in ${target_headers} ${target_headers_extra} \ ${thread_target_headers}; do \ - $(INSTALL_DATA) $${file} ${gxx_include_dir}/${target_builddir}; done + $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${target_builddir}; done # By adding these files here, automake will remove them for 'make clean' #CLEANFILES = ${allstamps} diff --git a/contrib/libstdc++/include/Makefile.in b/contrib/libstdc++/include/Makefile.in index d50f44c..37a06d4 100644 --- a/contrib/libstdc++/include/Makefile.in +++ b/contrib/libstdc++/include/Makefile.in @@ -76,6 +76,7 @@ CMESSAGES_H = @CMESSAGES_H@ CPP = @CPP@ CPU_LIMITS_INC_SRCDIR = @CPU_LIMITS_INC_SRCDIR@ CSTDIO_H = @CSTDIO_H@ +CTIME_H = @CTIME_H@ CXXCPP = @CXXCPP@ C_INCLUDE_DIR = @C_INCLUDE_DIR@ DEBUG_FLAGS = @DEBUG_FLAGS@ @@ -424,6 +425,7 @@ target_headers_extra = \ ${target_builddir}/c++io.h \ ${target_builddir}/c++locale.h \ ${target_builddir}/messages_members.h \ + ${target_builddir}/time_members.h \ ${target_builddir}/codecvt_specializations.h @@ -630,6 +632,7 @@ ${target_builddir}/stamp-target: ${target_headers} stamp-${target_alias} @LN_S@ ${glibcpp_srcdir}/@CSTDIO_H@ c++io.h || true ;\ @LN_S@ ${glibcpp_srcdir}/@CLOCALE_H@ c++locale.h || true ;\ @LN_S@ ${glibcpp_srcdir}/@CMESSAGES_H@ messages_members.h || true ;\ + @LN_S@ ${glibcpp_srcdir}/@CTIME_H@ time_members.h || true ;\ @LN_S@ ${glibcpp_srcdir}/@CCODECVT_H@ codecvt_specializations.h || true ;\ echo `date` > stamp-target; \ fi @@ -672,32 +675,32 @@ ${target_builddir}/gthr-default.h: ${toplevel_srcdir}/gcc/${glibcpp_thread_h} \ -e 's,^#include "\(.*\)",#include <bits/\1>,g' \ < ${toplevel_srcdir}/gcc/${glibcpp_thread_h} > $@ install-data-local: - $(mkinstalldirs) ${gxx_include_dir} - $(mkinstalldirs) ${gxx_include_dir}/${bits_builddir} + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir} + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${bits_builddir} for file in ${bits_headers}; do \ - $(INSTALL_DATA) $${file} ${gxx_include_dir}/${bits_builddir}; done - $(mkinstalldirs) ${gxx_include_dir}/${backward_builddir} + $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${bits_builddir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${backward_builddir} for file in ${backward_headers}; do \ - $(INSTALL_DATA) $${file} ${gxx_include_dir}/${backward_builddir}; done - $(mkinstalldirs) ${gxx_include_dir}/${ext_builddir} + $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${backward_builddir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${ext_builddir} for file in ${ext_headers}; do \ - $(INSTALL_DATA) $${file} ${gxx_include_dir}/${ext_builddir}; done - $(mkinstalldirs) ${gxx_include_dir}/${c_base_builddir} + $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${ext_builddir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${c_base_builddir} for file in ${c_base_headers_rename}; do \ - $(INSTALL_DATA) ${c_base_builddir}/$${file} ${gxx_include_dir}; done + $(INSTALL_DATA) ${c_base_builddir}/$${file} $(DESTDIR)${gxx_include_dir}/${c_base_builddir}; done c_base_headers_extra_install='$(c_base_headers_extra)';\ for file in $$c_base_headers_extra_install; do \ - $(INSTALL_DATA) $$file ${gxx_include_dir}/${bits_builddir}; done + $(INSTALL_DATA) $$file $(DESTDIR)${gxx_include_dir}/${bits_builddir}; done c_compatibility_headers_install='$(c_compatibility_headers_extra)';\ for file in $$c_compatibility_headers_install; do \ - $(INSTALL_DATA) $$file ${gxx_include_dir}; done - $(mkinstalldirs) ${gxx_include_dir}/${std_builddir} + $(INSTALL_DATA) $$file $(DESTDIR)${gxx_include_dir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${std_builddir} for file in ${std_headers_rename}; do \ - $(INSTALL_DATA) ${std_builddir}/$${file} ${gxx_include_dir}; done - $(mkinstalldirs) ${gxx_include_dir}/${target_builddir} + $(INSTALL_DATA) ${std_builddir}/$${file} $(DESTDIR)${gxx_include_dir}/${std_builddir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${target_builddir} for file in ${target_headers} ${target_headers_extra} \ ${thread_target_headers}; do \ - $(INSTALL_DATA) $${file} ${gxx_include_dir}/${target_builddir}; done + $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${target_builddir}; done # By adding these files here, automake will remove them for 'make clean' #CLEANFILES = ${allstamps} diff --git a/contrib/libstdc++/include/backward/alloc.h b/contrib/libstdc++/include/backward/alloc.h index 4344a1d..9482e4c 100644 --- a/contrib/libstdc++/include/backward/alloc.h +++ b/contrib/libstdc++/include/backward/alloc.h @@ -53,10 +53,6 @@ using std::__debug_alloc; using std::__alloc; using std::__single_client_alloc; using std::allocator; -#ifdef __USE_MALLOC -using std::malloc_alloc; -#else using std::__default_alloc_template; -#endif #endif diff --git a/contrib/libstdc++/include/bits/c++config b/contrib/libstdc++/include/bits/c++config index 4315bae..cda776c 100644 --- a/contrib/libstdc++/include/bits/c++config +++ b/contrib/libstdc++/include/bits/c++config @@ -34,7 +34,7 @@ #include <bits/os_defines.h> // The current version of the C++ library in compressed ISO date format. -#define __GLIBCPP__ 20021119 +#define __GLIBCPP__ 20030205 // This is necessary until GCC supports separate template // compilation. @@ -74,13 +74,8 @@ // so, please report any possible issues to libstdc++@gcc.gnu.org . // Do not define __USE_MALLOC on the command line. Enforce it here: #ifdef __USE_MALLOC -#error __USE_MALLOC should only be defined within \ -libstdc++-v3/include/bits/c++config before full recompilation of the library. +#error __USE_MALLOC should never be defined. Read the release notes. #endif -// Define __USE_MALLOC after this point in the file in order to aid debugging -// or globally change allocation policy. This breaks the ABI, thus -// completely recompile the library. A patch to better support -// changing the global allocator policy would be probably be accepted. // The remainder of the prewritten config is mostly automatic; all the // user hooks are listed above. diff --git a/contrib/libstdc++/include/bits/fstream.tcc b/contrib/libstdc++/include/bits/fstream.tcc index 66cb9a1..0b3bec1 100644 --- a/contrib/libstdc++/include/bits/fstream.tcc +++ b/contrib/libstdc++/include/bits/fstream.tcc @@ -1,6 +1,6 @@ // File based streams -*- C++ -*- -// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -461,10 +461,7 @@ namespace std bool __testbeg = gptr() == eback() && pptr() == pbase(); if (__testbeg && _M_buf_locale != __loc) - { - _M_buf_locale = __loc; - _M_buf_locale_init = true; - } + _M_buf_locale = __loc; // NB this may require the reconversion of previously // converted chars. This in turn may cause the reconstruction diff --git a/contrib/libstdc++/include/bits/locale_facets.h b/contrib/libstdc++/include/bits/locale_facets.h index 660bad3..6e42b3b 100644 --- a/contrib/libstdc++/include/bits/locale_facets.h +++ b/contrib/libstdc++/include/bits/locale_facets.h @@ -1011,22 +1011,10 @@ namespace std public: explicit - __timepunct(size_t __refs = 0) - : locale::facet(__refs) - { - _M_name_timepunct = new char[2]; - strcpy(_M_name_timepunct, "C"); - _M_initialize_timepunct(); - } + __timepunct(size_t __refs = 0); explicit - __timepunct(__c_locale __cloc, const char* __s, size_t __refs = 0) - : locale::facet(__refs) - { - _M_name_timepunct = new char[strlen(__s) + 1]; - strcpy(_M_name_timepunct, __s); - _M_initialize_timepunct(__cloc); - } + __timepunct(__c_locale __cloc, const char* __s, size_t __refs = 0); void _M_put(_CharT* __s, size_t __maxlen, const _CharT* __format, @@ -1123,11 +1111,7 @@ namespace std protected: virtual - ~__timepunct() - { - delete [] _M_name_timepunct; - _S_destroy_c_locale(_M_c_locale_timepunct); - } + ~__timepunct(); // For use at construction time only. void @@ -1169,6 +1153,8 @@ namespace std template<typename _CharT> const _CharT* __timepunct<_CharT>::_S_timezones[14]; + // Include host and configuration specific timepunct functions. + #include <bits/time_members.h> template<typename _CharT, typename _InIter> class time_get : public locale::facet, public time_base @@ -1628,32 +1614,17 @@ namespace std // Underlying "C" library locale information saved from // initialization, needed by messages_byname as well. __c_locale _M_c_locale_messages; -#if 1 - // Only needed if glibc < 2.3 char* _M_name_messages; -#endif public: static locale::id id; explicit - messages(size_t __refs = 0) - : locale::facet(__refs) - { - _M_name_messages = new char[2]; - strcpy(_M_name_messages, "C"); - _M_c_locale_messages = _S_c_locale; - } + messages(size_t __refs = 0); // Non-standard. explicit - messages(__c_locale __cloc, const char* __s, size_t __refs = 0) - : locale::facet(__refs) - { - _M_name_messages = new char[strlen(__s) + 1]; - strcpy(_M_name_messages, __s); - _M_c_locale_messages = _S_clone_c_locale(__cloc); - } + messages(__c_locale __cloc, const char* __s, size_t __refs = 0); catalog open(const basic_string<char>& __s, const locale& __loc) const @@ -1673,11 +1644,7 @@ namespace std protected: virtual - ~messages() - { - delete [] _M_name_messages; - _S_destroy_c_locale(_M_c_locale_messages); - } + ~messages(); virtual catalog do_open(const basic_string<char>&, const locale&) const; @@ -1751,9 +1718,6 @@ namespace std messages<wchar_t>::do_get(catalog, int, int, const wstring&) const; #endif - // Include host and configuration specific messages virtual functions. - #include <bits/messages_members.h> - template<typename _CharT> class messages_byname : public messages<_CharT> { @@ -1762,15 +1726,7 @@ namespace std typedef basic_string<_CharT> string_type; explicit - messages_byname(const char* __s, size_t __refs = 0) - : messages<_CharT>(__refs) - { - delete [] _M_name_messages; - _M_name_messages = new char[strlen(__s) + 1]; - strcpy(_M_name_messages, __s); - _S_destroy_c_locale(_M_c_locale_messages); - _S_create_c_locale(_M_c_locale_messages, __s); - } + messages_byname(const char* __s, size_t __refs = 0); protected: virtual @@ -1778,6 +1734,9 @@ namespace std { } }; + // Include host and configuration specific messages functions. + #include <bits/messages_members.h> + // Subclause convenience interfaces, inlines. // NB: These are inline because, when used in a loop, some compilers diff --git a/contrib/libstdc++/include/bits/locale_facets.tcc b/contrib/libstdc++/include/bits/locale_facets.tcc index ce6f3d7..1bf3d7c 100644 --- a/contrib/libstdc++/include/bits/locale_facets.tcc +++ b/contrib/libstdc++/include/bits/locale_facets.tcc @@ -622,9 +622,14 @@ namespace std _M_convert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod, _ValueT __v) const { - // Note: digits10 is rounded down. We need to add 1 to ensure + // Note: digits10 is rounded down: we need to add 1 to ensure // we get the full available precision. - const int __max_digits = numeric_limits<_ValueT>::digits10 + 1; + // Then, in general, one more 1 needs to be added since, when the + // %{g,G} conversion specifiers are chosen inside _S_format_float, the + // precision field is "the maximum number of significant digits", *not* + // the "number of digits to appear after the decimal point", as happens + // for %{e,E,f,F} (C99, 7.19.6.1,4). + const int __max_digits = numeric_limits<_ValueT>::digits10 + 2; streamsize __prec = __io.precision(); if (__prec > static_cast<streamsize>(__max_digits)) @@ -1628,7 +1633,7 @@ namespace std // Find smallest matching string. size_t __minlen = 10; for (size_t __i2 = 0; __i2 < __nmatches; ++__i2) - __minlen = min(__minlen, + __minlen = min(__minlen, __traits_type::length(__names[__matches[__i2]])); if (__pos < __minlen && __beg != __end) diff --git a/contrib/libstdc++/include/bits/localefwd.h b/contrib/libstdc++/include/bits/localefwd.h index d8d742b..dedc764 100644 --- a/contrib/libstdc++/include/bits/localefwd.h +++ b/contrib/libstdc++/include/bits/localefwd.h @@ -264,7 +264,7 @@ namespace std // The "C" reference locale static _Impl* _S_classic; - // Current global reference locale + // Current global locale static _Impl* _S_global; // Number of standard categories. For C++, these categories are @@ -419,10 +419,13 @@ namespace std _Atomic_word _M_references; protected: - // Contains data from the underlying "C" library for default "C" - // or "POSIX" locale. - static __c_locale _S_c_locale; - + // Contains data from the underlying "C" library for for the + // classic locale. + static __c_locale _S_c_locale; + + // String literal for the name of the classic locale. + static char _S_c_name[2]; + explicit facet(size_t __refs = 0) throw(); diff --git a/contrib/libstdc++/include/bits/slice_array.h b/contrib/libstdc++/include/bits/slice_array.h index c8908f8..cca3e63 100644 --- a/contrib/libstdc++/include/bits/slice_array.h +++ b/contrib/libstdc++/include/bits/slice_array.h @@ -120,7 +120,8 @@ namespace std inline slice_array<_Tp>& slice_array<_Tp>::operator=(const slice_array<_Tp>& __a) { - __valarray_copy(_M_array, _M_sz, _M_stride, __a._M_array, __a._M_stride); + __valarray_copy(__a._M_array, __a._M_sz, __a._M_stride, + _M_array, _M_stride); return *this; } diff --git a/contrib/libstdc++/include/bits/stl_alloc.h b/contrib/libstdc++/include/bits/stl_alloc.h index 7c34000..238986d 100644 --- a/contrib/libstdc++/include/bits/stl_alloc.h +++ b/contrib/libstdc++/include/bits/stl_alloc.h @@ -74,6 +74,10 @@ * into a "standard" one. * @endif * + * @note The @c reallocate member functions have been deprecated for 3.2 + * and will be removed in 3.4. You must define @c _GLIBCPP_DEPRECATED + * to make this visible in 3.2; see c++config.h. + * * The canonical description of these classes is in docs/html/ext/howto.html * or online at http://gcc.gnu.org/onlinedocs/libstdc++/ext/howto.html#3 */ @@ -85,6 +89,8 @@ #include <bits/functexcept.h> // For __throw_bad_alloc #include <bits/stl_threads.h> +#include <bits/atomicity.h> + namespace std { /** @@ -94,19 +100,19 @@ namespace std * reallocate(). * @endif * (See @link Allocators allocators info @endlink for more.) - */ - class __new_alloc + */ + class __new_alloc { public: - static void* + static void* allocate(size_t __n) { return ::operator new(__n); } - - static void + + static void deallocate(void* __p, size_t) { ::operator delete(__p); } }; - + /** * @if maint @@ -117,121 +123,134 @@ namespace std * for caveats). "SGI" style, plus __set_malloc_handler for OOM conditions. * @endif * (See @link Allocators allocators info @endlink for more.) - */ - template <int __inst> - class __malloc_alloc_template + */ + template<int __inst> + class __malloc_alloc_template { private: static void* _S_oom_malloc(size_t); + + // _GLIBCPP_DEPRECATED static void* _S_oom_realloc(void*, size_t); + static void (* __malloc_alloc_oom_handler)(); - + public: - static void* + static void* allocate(size_t __n) { - void* __result = malloc(__n); - if (0 == __result) __result = _S_oom_malloc(__n); - return __result; + void* __result = malloc(__n); + if (__builtin_expect(__result == 0, 0)) + __result = _S_oom_malloc(__n); + return __result; } - static void + static void deallocate(void* __p, size_t /* __n */) { free(__p); } - static void* + // _GLIBCPP_DEPRECATED + static void* reallocate(void* __p, size_t /* old_sz */, size_t __new_sz) { - void* __result = realloc(__p, __new_sz); - if (0 == __result) __result = _S_oom_realloc(__p, __new_sz); - return __result; + void* __result = realloc(__p, __new_sz); + if (__builtin_expect(__result == 0, 0)) + __result = _S_oom_realloc(__p, __new_sz); + return __result; } - + static void (* __set_malloc_handler(void (*__f)()))() { - void (* __old)() = __malloc_alloc_oom_handler; - __malloc_alloc_oom_handler = __f; - return(__old); + void (* __old)() = __malloc_alloc_oom_handler; + __malloc_alloc_oom_handler = __f; + return __old; } }; // malloc_alloc out-of-memory handling - template <int __inst> + template<int __inst> void (* __malloc_alloc_template<__inst>::__malloc_alloc_oom_handler)() = 0; - template <int __inst> + template<int __inst> void* - __malloc_alloc_template<__inst>::_S_oom_malloc(size_t __n) + __malloc_alloc_template<__inst>:: + _S_oom_malloc(size_t __n) { void (* __my_malloc_handler)(); void* __result; - - for (;;) - { - __my_malloc_handler = __malloc_alloc_oom_handler; - if (0 == __my_malloc_handler) - std::__throw_bad_alloc(); - (*__my_malloc_handler)(); - __result = malloc(__n); - if (__result) - return(__result); - } + + for (;;) + { + __my_malloc_handler = __malloc_alloc_oom_handler; + if (__builtin_expect(__my_malloc_handler == 0, 0)) + __throw_bad_alloc(); + (*__my_malloc_handler)(); + __result = malloc(__n); + if (__result) + return __result; + } } - - template <int __inst> - void* - __malloc_alloc_template<__inst>::_S_oom_realloc(void* __p, size_t __n) - { + + // _GLIBCPP_DEPRECATED + template<int __inst> + void* + __malloc_alloc_template<__inst>:: + _S_oom_realloc(void* __p, size_t __n) + { void (* __my_malloc_handler)(); void* __result; - - for (;;) - { - __my_malloc_handler = __malloc_alloc_oom_handler; - if (0 == __my_malloc_handler) - std::__throw_bad_alloc(); - (*__my_malloc_handler)(); - __result = realloc(__p, __n); - if (__result) - return(__result); - } - } + for (;;) + { + __my_malloc_handler = __malloc_alloc_oom_handler; + if (__builtin_expect(__my_malloc_handler == 0, 0)) + __throw_bad_alloc(); + (*__my_malloc_handler)(); + __result = realloc(__p, __n); + if (__result) + return __result; + } + } -// Determines the underlying allocator choice for the node allocator. -#ifdef __USE_MALLOC - typedef __malloc_alloc_template<0> __mem_interface; -#else + // Should not be referenced within the library anymore. typedef __new_alloc __mem_interface; -#endif - /** * @if maint * This is used primarily (only?) in _Alloc_traits and other places to - * help provide the _Alloc_type typedef. + * help provide the _Alloc_type typedef. All it does is forward the + * requests after some minimal checking. * * This is neither "standard"-conforming nor "SGI". The _Alloc parameter * must be "SGI" style. * @endif * (See @link Allocators allocators info @endlink for more.) - */ - template<class _Tp, class _Alloc> - class __simple_alloc - { - public: - static _Tp* allocate(size_t __n) - { return 0 == __n ? 0 : (_Tp*) _Alloc::allocate(__n * sizeof (_Tp)); } - - static _Tp* allocate() - { return (_Tp*) _Alloc::allocate(sizeof (_Tp)); } - - static void deallocate(_Tp* __p, size_t __n) - { if (0 != __n) _Alloc::deallocate(__p, __n * sizeof (_Tp)); } - - static void deallocate(_Tp* __p) - { _Alloc::deallocate(__p, sizeof (_Tp)); } - }; + */ + template<typename _Tp, typename _Alloc> + class __simple_alloc + { + public: + static _Tp* + allocate(size_t __n) + { + _Tp* __ret = 0; + if (__n) + __ret = static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp))); + return __ret; + } + + static _Tp* + allocate() + { return (_Tp*) _Alloc::allocate(sizeof (_Tp)); } + + static void + deallocate(_Tp* __p, size_t __n) + { if (0 != __n) _Alloc::deallocate(__p, __n * sizeof (_Tp)); } + + static void + deallocate(_Tp* __p) + { _Alloc::deallocate(__p, sizeof (_Tp)); } + }; /** @@ -247,273 +266,290 @@ namespace std * This adaptor is "SGI" style. The _Alloc parameter must also be "SGI". * @endif * (See @link Allocators allocators info @endlink for more.) - */ - template <class _Alloc> - class __debug_alloc - { - private: - enum {_S_extra = 8}; // Size of space used to store size. Note that this - // must be large enough to preserve alignment. - - public: - - static void* allocate(size_t __n) - { - char* __result = (char*)_Alloc::allocate(__n + (int) _S_extra); - *(size_t*)__result = __n; - return __result + (int) _S_extra; - } - - static void deallocate(void* __p, size_t __n) + */ + template<typename _Alloc> + class __debug_alloc { - char* __real_p = (char*)__p - (int) _S_extra; - assert(*(size_t*)__real_p == __n); - _Alloc::deallocate(__real_p, __n + (int) _S_extra); - } - - static void* reallocate(void* __p, size_t __old_sz, size_t __new_sz) + private: + // Size of space used to store size. Note that this must be + // large enough to preserve alignment. + enum {_S_extra = 8}; + + public: + static void* + allocate(size_t __n) + { + char* __result = (char*)_Alloc::allocate(__n + (int) _S_extra); + *(size_t*)__result = __n; + return __result + (int) _S_extra; + } + + static void + deallocate(void* __p, size_t __n) + { + char* __real_p = (char*)__p - (int) _S_extra; + assert(*(size_t*)__real_p == __n); + _Alloc::deallocate(__real_p, __n + (int) _S_extra); + } + + // _GLIBCPP_DEPRECATED + static void* + reallocate(void* __p, size_t __old_sz, size_t __new_sz) + { + char* __real_p = (char*)__p - (int) _S_extra; + assert(*(size_t*)__real_p == __old_sz); + char* __result = (char*) _Alloc::reallocate(__real_p, + __old_sz + (int) _S_extra, + __new_sz + (int) _S_extra); + *(size_t*)__result = __new_sz; + return __result + (int) _S_extra; + } + }; + + + /** + * @if maint + * Default node allocator. "SGI" style. Uses various allocators to + * fulfill underlying requests (and makes as few requests as possible + * when in default high-speed pool mode). + * + * Important implementation properties: + * 0. If globally mandated, then allocate objects from __new_alloc + * 1. If the clients request an object of size > _MAX_BYTES, the resulting + * object will be obtained directly from __new_alloc + * 2. In all other cases, we allocate an object of size exactly + * _S_round_up(requested_size). Thus the client has enough size + * information that we can return the object to the proper free list + * without permanently losing part of the object. + * + * The first template parameter specifies whether more than one thread may + * use this allocator. It is safe to allocate an object from one instance + * of a default_alloc and deallocate it with another one. This effectively + * transfers its ownership to the second one. This may have undesirable + * effects on reference locality. + * + * The second parameter is unused and serves only to allow the creation of + * multiple default_alloc instances. Note that containers built on different + * allocator instances have different types, limiting the utility of this + * approach. If you do not wish to share the free lists with the main + * default_alloc instance, instantiate this with a non-zero __inst. + * + * @endif + * (See @link Allocators allocators info @endlink for more.) + */ + template<bool __threads, int __inst> + class __default_alloc_template { - char* __real_p = (char*)__p - (int) _S_extra; - assert(*(size_t*)__real_p == __old_sz); - char* __result = (char*) - _Alloc::reallocate(__real_p, __old_sz + (int) _S_extra, - __new_sz + (int) _S_extra); - *(size_t*)__result = __new_sz; - return __result + (int) _S_extra; - } - }; + private: + enum {_ALIGN = 8}; + enum {_MAX_BYTES = 128}; + enum {_NFREELISTS = _MAX_BYTES / _ALIGN}; + union _Obj + { + union _Obj* _M_free_list_link; + char _M_client_data[1]; // The client sees this. + }; -#ifdef __USE_MALLOC + static _Obj* volatile _S_free_list[_NFREELISTS]; -typedef __mem_interface __alloc; -typedef __mem_interface __single_client_alloc; + // Chunk allocation state. + static char* _S_start_free; + static char* _S_end_free; + static size_t _S_heap_size; -#else + static _STL_mutex_lock _S_node_allocator_lock; + static size_t + _S_round_up(size_t __bytes) + { return (((__bytes) + (size_t) _ALIGN-1) & ~((size_t) _ALIGN - 1)); } -/** - * @if maint - * Default node allocator. "SGI" style. Uses __mem_interface for its - * underlying requests (and makes as few requests as possible). - * **** Currently __mem_interface is always __new_alloc, never __malloc*. - * - * Important implementation properties: - * 1. If the clients request an object of size > _MAX_BYTES, the resulting - * object will be obtained directly from the underlying __mem_interface. - * 2. In all other cases, we allocate an object of size exactly - * _S_round_up(requested_size). Thus the client has enough size - * information that we can return the object to the proper free list - * without permanently losing part of the object. - * - * The first template parameter specifies whether more than one thread may - * use this allocator. It is safe to allocate an object from one instance - * of a default_alloc and deallocate it with another one. This effectively - * transfers its ownership to the second one. This may have undesirable - * effects on reference locality. - * - * The second parameter is unused and serves only to allow the creation of - * multiple default_alloc instances. Note that containers built on different - * allocator instances have different types, limiting the utility of this - * approach. If you do not wish to share the free lists with the main - * default_alloc instance, instantiate this with a non-zero __inst. - * - * @endif - * (See @link Allocators allocators info @endlink for more.) -*/ -template<bool __threads, int __inst> - class __default_alloc_template - { - private: - enum {_ALIGN = 8}; - enum {_MAX_BYTES = 128}; - enum {_NFREELISTS = _MAX_BYTES / _ALIGN}; - - union _Obj - { - union _Obj* _M_free_list_link; - char _M_client_data[1]; // The client sees this. - }; + static size_t + _S_freelist_index(size_t __bytes) + { return (((__bytes) + (size_t)_ALIGN - 1)/(size_t)_ALIGN - 1); } + + // Returns an object of size __n, and optionally adds to size __n + // free list. + static void* + _S_refill(size_t __n); + + // Allocates a chunk for nobjs of size size. nobjs may be reduced + // if it is inconvenient to allocate the requested number. + static char* + _S_chunk_alloc(size_t __size, int& __nobjs); + + // It would be nice to use _STL_auto_lock here. But we need a + // test whether threads are in use. + struct _Lock + { + _Lock() { if (__threads) _S_node_allocator_lock._M_acquire_lock(); } + ~_Lock() { if (__threads) _S_node_allocator_lock._M_release_lock(); } + } __attribute__ ((__unused__)); + friend struct _Lock; + + static _Atomic_word _S_force_new; - static _Obj* volatile _S_free_list[_NFREELISTS]; - - // Chunk allocation state. - static char* _S_start_free; - static char* _S_end_free; - static size_t _S_heap_size; - - static _STL_mutex_lock _S_node_allocator_lock; - - static size_t - _S_round_up(size_t __bytes) - { return (((__bytes) + (size_t) _ALIGN-1) & ~((size_t) _ALIGN - 1)); } - - static size_t - _S_freelist_index(size_t __bytes) - { return (((__bytes) + (size_t)_ALIGN-1)/(size_t)_ALIGN - 1); } - - // Returns an object of size __n, and optionally adds to size __n - // free list. - static void* - _S_refill(size_t __n); - - // Allocates a chunk for nobjs of size size. nobjs may be reduced - // if it is inconvenient to allocate the requested number. - static char* - _S_chunk_alloc(size_t __size, int& __nobjs); - - // It would be nice to use _STL_auto_lock here. But we need a - // test whether threads are in use. - class _Lock - { public: - _Lock() { if (__threads) _S_node_allocator_lock._M_acquire_lock(); } - ~_Lock() { if (__threads) _S_node_allocator_lock._M_release_lock(); } - } __attribute__ ((__unused__)); - friend class _Lock; - - public: - // __n must be > 0 - static void* - allocate(size_t __n) - { - void* __ret = 0; - - if (__n > (size_t) _MAX_BYTES) - __ret = __mem_interface::allocate(__n); - else - { - _Obj* volatile* __my_free_list = _S_free_list - + _S_freelist_index(__n); - // Acquire the lock here with a constructor call. This - // ensures that it is released in exit or during stack - // unwinding. - _Lock __lock_instance; - _Obj* __restrict__ __result = *__my_free_list; - if (__result == 0) - __ret = _S_refill(_S_round_up(__n)); - else - { - *__my_free_list = __result -> _M_free_list_link; - __ret = __result; - } - } - return __ret; - }; + // __n must be > 0 + static void* + allocate(size_t __n) + { + void* __ret = 0; + + // If there is a race through here, assume answer from getenv + // will resolve in same direction. Inspired by techniques + // to efficiently support threading found in basic_string.h. + if (_S_force_new == 0) + { + if (getenv("GLIBCPP_FORCE_NEW")) + __atomic_add(&_S_force_new, 1); + else + __atomic_add(&_S_force_new, -1); + // Trust but verify... + assert(_S_force_new != 0); + } + + if ((__n > (size_t) _MAX_BYTES) || (_S_force_new > 0)) + __ret = __new_alloc::allocate(__n); + else + { + _Obj* volatile* __my_free_list = _S_free_list + + _S_freelist_index(__n); + // Acquire the lock here with a constructor call. This + // ensures that it is released in exit or during stack + // unwinding. + _Lock __lock_instance; + _Obj* __restrict__ __result = *__my_free_list; + if (__builtin_expect(__result == 0, 0)) + __ret = _S_refill(_S_round_up(__n)); + else + { + *__my_free_list = __result -> _M_free_list_link; + __ret = __result; + } + if (__builtin_expect(__ret == 0, 0)) + __throw_bad_alloc(); + } + return __ret; + } - // __p may not be 0 - static void - deallocate(void* __p, size_t __n) - { - if (__n > (size_t) _MAX_BYTES) - __mem_interface::deallocate(__p, __n); - else - { - _Obj* volatile* __my_free_list - = _S_free_list + _S_freelist_index(__n); - _Obj* __q = (_Obj*)__p; - - // Acquire the lock here with a constructor call. This ensures that - // it is released in exit or during stack unwinding. - _Lock __lock_instance; - __q -> _M_free_list_link = *__my_free_list; - *__my_free_list = __q; - } - } - - static void* - reallocate(void* __p, size_t __old_sz, size_t __new_sz); - }; + // __p may not be 0 + static void + deallocate(void* __p, size_t __n) + { + if ((__n > (size_t) _MAX_BYTES) || (_S_force_new > 0)) + __new_alloc::deallocate(__p, __n); + else + { + _Obj* volatile* __my_free_list = _S_free_list + + _S_freelist_index(__n); + _Obj* __q = (_Obj*)__p; + + // Acquire the lock here with a constructor call. This + // ensures that it is released in exit or during stack + // unwinding. + _Lock __lock_instance; + __q -> _M_free_list_link = *__my_free_list; + *__my_free_list = __q; + } + } + + // _GLIBCPP_DEPRECATED + static void* + reallocate(void* __p, size_t __old_sz, size_t __new_sz); + }; + template<bool __threads, int __inst> _Atomic_word + __default_alloc_template<__threads, __inst>::_S_force_new = 0; template<bool __threads, int __inst> - inline bool - operator==(const __default_alloc_template<__threads, __inst>&, - const __default_alloc_template<__threads, __inst>&) + inline bool + operator==(const __default_alloc_template<__threads,__inst>&, + const __default_alloc_template<__threads,__inst>&) { return true; } template<bool __threads, int __inst> - inline bool - operator!=(const __default_alloc_template<__threads, __inst>&, - const __default_alloc_template<__threads, __inst>&) + inline bool + operator!=(const __default_alloc_template<__threads,__inst>&, + const __default_alloc_template<__threads,__inst>&) { return false; } // We allocate memory in large chunks in order to avoid fragmenting the - // malloc heap (or whatever __mem_interface is using) too much. We assume - // that __size is properly aligned. We hold the allocation lock. + // heap too much. We assume that __size is properly aligned. We hold + // the allocation lock. template<bool __threads, int __inst> char* - __default_alloc_template<__threads, __inst>::_S_chunk_alloc(size_t __size, - int& __nobjs) + __default_alloc_template<__threads, __inst>:: + _S_chunk_alloc(size_t __size, int& __nobjs) { char* __result; size_t __total_bytes = __size * __nobjs; size_t __bytes_left = _S_end_free - _S_start_free; - - if (__bytes_left >= __total_bytes) - { - __result = _S_start_free; - _S_start_free += __total_bytes; - return(__result); - } - else if (__bytes_left >= __size) - { - __nobjs = (int)(__bytes_left/__size); - __total_bytes = __size * __nobjs; - __result = _S_start_free; - _S_start_free += __total_bytes; - return(__result); - } - else - { - size_t __bytes_to_get = - 2 * __total_bytes + _S_round_up(_S_heap_size >> 4); - // Try to make use of the left-over piece. - if (__bytes_left > 0) - { - _Obj* volatile* __my_free_list = - _S_free_list + _S_freelist_index(__bytes_left); - - ((_Obj*)_S_start_free) -> _M_free_list_link = *__my_free_list; - *__my_free_list = (_Obj*)_S_start_free; - } - _S_start_free = (char*) __mem_interface::allocate(__bytes_to_get); - if (0 == _S_start_free) - { - size_t __i; - _Obj* volatile* __my_free_list; - _Obj* __p; - // Try to make do with what we have. That can't hurt. We - // do not try smaller requests, since that tends to result - // in disaster on multi-process machines. - __i = __size; - for (; __i <= (size_t) _MAX_BYTES; __i += (size_t) _ALIGN) - { - __my_free_list = _S_free_list + _S_freelist_index(__i); - __p = *__my_free_list; - if (0 != __p) - { - *__my_free_list = __p -> _M_free_list_link; - _S_start_free = (char*)__p; - _S_end_free = _S_start_free + __i; - return(_S_chunk_alloc(__size, __nobjs)); - // Any leftover piece will eventually make it to the - // right free list. - } - } - _S_end_free = 0; // In case of exception. - _S_start_free = (char*)__mem_interface::allocate(__bytes_to_get); - // This should either throw an exception or remedy the situation. - // Thus we assume it succeeded. - } - _S_heap_size += __bytes_to_get; - _S_end_free = _S_start_free + __bytes_to_get; - return(_S_chunk_alloc(__size, __nobjs)); - } + + if (__bytes_left >= __total_bytes) + { + __result = _S_start_free; + _S_start_free += __total_bytes; + return __result ; + } + else if (__bytes_left >= __size) + { + __nobjs = (int)(__bytes_left/__size); + __total_bytes = __size * __nobjs; + __result = _S_start_free; + _S_start_free += __total_bytes; + return __result; + } + else + { + size_t __bytes_to_get = + 2 * __total_bytes + _S_round_up(_S_heap_size >> 4); + // Try to make use of the left-over piece. + if (__bytes_left > 0) + { + _Obj* volatile* __my_free_list = + _S_free_list + _S_freelist_index(__bytes_left); + + ((_Obj*)_S_start_free) -> _M_free_list_link = *__my_free_list; + *__my_free_list = (_Obj*)_S_start_free; + } + _S_start_free = (char*) __new_alloc::allocate(__bytes_to_get); + if (_S_start_free == 0) + { + size_t __i; + _Obj* volatile* __my_free_list; + _Obj* __p; + // Try to make do with what we have. That can't hurt. We + // do not try smaller requests, since that tends to result + // in disaster on multi-process machines. + __i = __size; + for (; __i <= (size_t) _MAX_BYTES; __i += (size_t) _ALIGN) + { + __my_free_list = _S_free_list + _S_freelist_index(__i); + __p = *__my_free_list; + if (__p != 0) + { + *__my_free_list = __p -> _M_free_list_link; + _S_start_free = (char*)__p; + _S_end_free = _S_start_free + __i; + return _S_chunk_alloc(__size, __nobjs); + // Any leftover piece will eventually make it to the + // right free list. + } + } + _S_end_free = 0; // In case of exception. + _S_start_free = (char*)__new_alloc::allocate(__bytes_to_get); + // This should either throw an exception or remedy the situation. + // Thus we assume it succeeded. + } + _S_heap_size += __bytes_to_get; + _S_end_free = _S_start_free + __bytes_to_get; + return _S_chunk_alloc(__size, __nobjs); + } } - - + + // Returns an object of size __n, and optionally adds to "size // __n"'s free list. We assume that __n is properly aligned. We // hold the allocation lock. @@ -528,414 +564,421 @@ template<bool __threads, int __inst> _Obj* __current_obj; _Obj* __next_obj; int __i; - - if (1 == __nobjs) return(__chunk); + + if (1 == __nobjs) + return __chunk; __my_free_list = _S_free_list + _S_freelist_index(__n); - - /* Build free list in chunk */ + + // Build free list in chunk. __result = (_Obj*)__chunk; *__my_free_list = __next_obj = (_Obj*)(__chunk + __n); - for (__i = 1; ; __i++) { - __current_obj = __next_obj; - __next_obj = (_Obj*)((char*)__next_obj + __n); - if (__nobjs - 1 == __i) { - __current_obj -> _M_free_list_link = 0; - break; - } else { - __current_obj -> _M_free_list_link = __next_obj; - } - } - return(__result); + for (__i = 1; ; __i++) + { + __current_obj = __next_obj; + __next_obj = (_Obj*)((char*)__next_obj + __n); + if (__nobjs - 1 == __i) + { + __current_obj -> _M_free_list_link = 0; + break; + } + else + __current_obj -> _M_free_list_link = __next_obj; + } + return __result; } + // _GLIBCPP_DEPRECATED template<bool threads, int inst> void* - __default_alloc_template<threads, inst>::reallocate(void* __p, - size_t __old_sz, - size_t __new_sz) + __default_alloc_template<threads, inst>:: + reallocate(void* __p, size_t __old_sz, size_t __new_sz) { void* __result; size_t __copy_sz; - - if (__old_sz > (size_t) _MAX_BYTES && __new_sz > (size_t) _MAX_BYTES) { + + if (__old_sz > (size_t) _MAX_BYTES && __new_sz > (size_t) _MAX_BYTES) return(realloc(__p, __new_sz)); - } - if (_S_round_up(__old_sz) == _S_round_up(__new_sz)) return(__p); + if (_S_round_up(__old_sz) == _S_round_up(__new_sz)) + return(__p); __result = allocate(__new_sz); __copy_sz = __new_sz > __old_sz? __old_sz : __new_sz; memcpy(__result, __p, __copy_sz); deallocate(__p, __old_sz); - return(__result); + return __result; } - + template<bool __threads, int __inst> - _STL_mutex_lock - __default_alloc_template<__threads, __inst>::_S_node_allocator_lock - __STL_MUTEX_INITIALIZER; - + _STL_mutex_lock + __default_alloc_template<__threads,__inst>::_S_node_allocator_lock + __STL_MUTEX_INITIALIZER; + template<bool __threads, int __inst> - char* __default_alloc_template<__threads, __inst>::_S_start_free = 0; - + char* __default_alloc_template<__threads,__inst>::_S_start_free = 0; + template<bool __threads, int __inst> - char* __default_alloc_template<__threads, __inst>::_S_end_free = 0; - + char* __default_alloc_template<__threads,__inst>::_S_end_free = 0; + template<bool __threads, int __inst> - size_t __default_alloc_template<__threads, __inst>::_S_heap_size = 0; - + size_t __default_alloc_template<__threads,__inst>::_S_heap_size = 0; + template<bool __threads, int __inst> - typename __default_alloc_template<__threads, __inst>::_Obj* volatile - __default_alloc_template<__threads, __inst>::_S_free_list[_NFREELISTS]; - - typedef __default_alloc_template<true, 0> __alloc; - typedef __default_alloc_template<false, 0> __single_client_alloc; + typename __default_alloc_template<__threads,__inst>::_Obj* volatile + __default_alloc_template<__threads,__inst>::_S_free_list[_NFREELISTS]; + typedef __default_alloc_template<true,0> __alloc; + typedef __default_alloc_template<false,0> __single_client_alloc; -#endif /* ! __USE_MALLOC */ + /** + * @brief The "standard" allocator, as per [20.4]. + * + * The private _Alloc is "SGI" style. (See comments at the top + * of stl_alloc.h.) + * + * The underlying allocator behaves as follows. + * - __default_alloc_template is used via two typedefs + * - "__single_client_alloc" typedef does no locking for threads + * - "__alloc" typedef is threadsafe via the locks + * - __new_alloc is used for memory requests + * + * (See @link Allocators allocators info @endlink for more.) + */ + template<typename _Tp> + class allocator + { + typedef __alloc _Alloc; // The underlying allocator. + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + + template<typename _Tp1> + struct rebind + { typedef allocator<_Tp1> other; }; + + allocator() throw() {} + allocator(const allocator&) throw() {} + template<typename _Tp1> + allocator(const allocator<_Tp1>&) throw() {} + ~allocator() throw() {} + + pointer + address(reference __x) const { return &__x; } + + const_pointer + address(const_reference __x) const { return &__x; } + + // NB: __n is permitted to be 0. The C++ standard says nothing + // about what the return value is when __n == 0. + _Tp* + allocate(size_type __n, const void* = 0) + { + _Tp* __ret = 0; + if (__n) + { + if (__n <= this->max_size()) + __ret = static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp))); + else + __throw_bad_alloc(); + } + return __ret; + } -/** - * This is a "standard" allocator, as per [20.4]. The private _Alloc is - * "SGI" style. (See comments at the top of stl_alloc.h.) - * - * The underlying allocator behaves as follows. - * - if __USE_MALLOC then - * - thread safety depends on malloc and is entirely out of our hands - * - __malloc_alloc_template is used for memory requests - * - else (the default) - * - __default_alloc_template is used via two typedefs - * - "__single_client_alloc" typedef does no locking for threads - * - "__alloc" typedef is threadsafe via the locks - * - __new_alloc is used for memory requests - * - * (See @link Allocators allocators info @endlink for more.) -*/ -template <class _Tp> -class allocator -{ - typedef __alloc _Alloc; // The underlying allocator. -public: - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef _Tp* pointer; - typedef const _Tp* const_pointer; - typedef _Tp& reference; - typedef const _Tp& const_reference; - typedef _Tp value_type; - - template <class _Tp1> struct rebind { - typedef allocator<_Tp1> other; - }; + // __p is not permitted to be a null pointer. + void + deallocate(pointer __p, size_type __n) + { _Alloc::deallocate(__p, __n * sizeof(_Tp)); } - allocator() throw() {} - allocator(const allocator&) throw() {} - template <class _Tp1> allocator(const allocator<_Tp1>&) throw() {} - ~allocator() throw() {} - - pointer address(reference __x) const { return &__x; } - const_pointer address(const_reference __x) const { return &__x; } - - // __n is permitted to be 0. The C++ standard says nothing about what - // the return value is when __n == 0. - _Tp* allocate(size_type __n, const void* = 0) { - return __n != 0 ? static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp))) - : 0; - } - - // __p is not permitted to be a null pointer. - void deallocate(pointer __p, size_type __n) - { _Alloc::deallocate(__p, __n * sizeof(_Tp)); } - - size_type max_size() const throw() - { return size_t(-1) / sizeof(_Tp); } - - void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); } - void destroy(pointer __p) { __p->~_Tp(); } -}; - -template<> -class allocator<void> { -public: - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef void* pointer; - typedef const void* const_pointer; - typedef void value_type; - - template <class _Tp1> struct rebind { - typedef allocator<_Tp1> other; - }; -}; + size_type + max_size() const throw() { return size_t(-1) / sizeof(_Tp); } + void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); } + void destroy(pointer __p) { __p->~_Tp(); } + }; -template <class _T1, class _T2> -inline bool operator==(const allocator<_T1>&, const allocator<_T2>&) -{ - return true; -} + template<> + class allocator<void> + { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef void* pointer; + typedef const void* const_pointer; + typedef void value_type; + + template<typename _Tp1> + struct rebind + { typedef allocator<_Tp1> other; }; + }; -template <class _T1, class _T2> -inline bool operator!=(const allocator<_T1>&, const allocator<_T2>&) -{ - return false; -} + template<typename _T1, typename _T2> + inline bool + operator==(const allocator<_T1>&, const allocator<_T2>&) + { return true; } -/** - * @if maint - * Allocator adaptor to turn an "SGI" style allocator (e.g., __alloc, - * __malloc_alloc_template) into a "standard" conforming allocator. Note - * that this adaptor does *not* assume that all objects of the underlying - * alloc class are identical, nor does it assume that all of the underlying - * alloc's member functions are static member functions. Note, also, that - * __allocator<_Tp, __alloc> is essentially the same thing as allocator<_Tp>. - * @endif - * (See @link Allocators allocators info @endlink for more.) -*/ -template <class _Tp, class _Alloc> -struct __allocator -{ - _Alloc __underlying_alloc; - - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef _Tp* pointer; - typedef const _Tp* const_pointer; - typedef _Tp& reference; - typedef const _Tp& const_reference; - typedef _Tp value_type; - - template <class _Tp1> struct rebind { - typedef __allocator<_Tp1, _Alloc> other; - }; + template<typename _T1, typename _T2> + inline bool + operator!=(const allocator<_T1>&, const allocator<_T2>&) + { return false; } - __allocator() throw() {} - __allocator(const __allocator& __a) throw() - : __underlying_alloc(__a.__underlying_alloc) {} - template <class _Tp1> - __allocator(const __allocator<_Tp1, _Alloc>& __a) throw() - : __underlying_alloc(__a.__underlying_alloc) {} - ~__allocator() throw() {} - - pointer address(reference __x) const { return &__x; } - const_pointer address(const_reference __x) const { return &__x; } - - // __n is permitted to be 0. - _Tp* allocate(size_type __n, const void* = 0) { - return __n != 0 - ? static_cast<_Tp*>(__underlying_alloc.allocate(__n * sizeof(_Tp))) - : 0; - } - - // __p is not permitted to be a null pointer. - void deallocate(pointer __p, size_type __n) - { __underlying_alloc.deallocate(__p, __n * sizeof(_Tp)); } - - size_type max_size() const throw() - { return size_t(-1) / sizeof(_Tp); } - - void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); } - void destroy(pointer __p) { __p->~_Tp(); } -}; - -template <class _Alloc> -class __allocator<void, _Alloc> { - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef void* pointer; - typedef const void* const_pointer; - typedef void value_type; - - template <class _Tp1> struct rebind { - typedef __allocator<_Tp1, _Alloc> other; - }; -}; -template <class _Tp, class _Alloc> -inline bool operator==(const __allocator<_Tp, _Alloc>& __a1, - const __allocator<_Tp, _Alloc>& __a2) -{ - return __a1.__underlying_alloc == __a2.__underlying_alloc; -} + /** + * @if maint + * Allocator adaptor to turn an "SGI" style allocator (e.g., + * __alloc, __malloc_alloc_template) into a "standard" conforming + * allocator. Note that this adaptor does *not* assume that all + * objects of the underlying alloc class are identical, nor does it + * assume that all of the underlying alloc's member functions are + * static member functions. Note, also, that __allocator<_Tp, + * __alloc> is essentially the same thing as allocator<_Tp>. + * @endif + * (See @link Allocators allocators info @endlink for more.) + */ + template<typename _Tp, typename _Alloc> + struct __allocator + { + _Alloc __underlying_alloc; + + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + + template<typename _Tp1> + struct rebind + { typedef __allocator<_Tp1, _Alloc> other; }; + + __allocator() throw() {} + __allocator(const __allocator& __a) throw() + : __underlying_alloc(__a.__underlying_alloc) {} + + template<typename _Tp1> + __allocator(const __allocator<_Tp1, _Alloc>& __a) throw() + : __underlying_alloc(__a.__underlying_alloc) {} + + ~__allocator() throw() {} + + pointer + address(reference __x) const { return &__x; } + + const_pointer + address(const_reference __x) const { return &__x; } + + // NB: __n is permitted to be 0. The C++ standard says nothing + // about what the return value is when __n == 0. + _Tp* + allocate(size_type __n, const void* = 0) + { + _Tp* __ret = 0; + if (__n) + __ret = static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp))); + return __ret; + } -template <class _Tp, class _Alloc> -inline bool operator!=(const __allocator<_Tp, _Alloc>& __a1, - const __allocator<_Tp, _Alloc>& __a2) -{ - return __a1.__underlying_alloc != __a2.__underlying_alloc; -} + // __p is not permitted to be a null pointer. + void + deallocate(pointer __p, size_type __n) + { __underlying_alloc.deallocate(__p, __n * sizeof(_Tp)); } + + size_type + max_size() const throw() { return size_t(-1) / sizeof(_Tp); } + + void + construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); } + + void + destroy(pointer __p) { __p->~_Tp(); } + }; + template<typename _Alloc> + struct __allocator<void, _Alloc> + { + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef void* pointer; + typedef const void* const_pointer; + typedef void value_type; + + template<typename _Tp1> + struct rebind + { typedef __allocator<_Tp1, _Alloc> other; }; + }; -//@{ -/** Comparison operators for all of the predifined SGI-style allocators. - * This ensures that __allocator<malloc_alloc> (for example) will work - * correctly. As required, all allocators compare equal. -*/ -template <int inst> -inline bool operator==(const __malloc_alloc_template<inst>&, - const __malloc_alloc_template<inst>&) -{ - return true; -} + template<typename _Tp, typename _Alloc> + inline bool + operator==(const __allocator<_Tp,_Alloc>& __a1, + const __allocator<_Tp,_Alloc>& __a2) + { return __a1.__underlying_alloc == __a2.__underlying_alloc; } + + template<typename _Tp, typename _Alloc> + inline bool + operator!=(const __allocator<_Tp, _Alloc>& __a1, + const __allocator<_Tp, _Alloc>& __a2) + { return __a1.__underlying_alloc != __a2.__underlying_alloc; } + + + //@{ + /** Comparison operators for all of the predifined SGI-style allocators. + * This ensures that __allocator<malloc_alloc> (for example) will work + * correctly. As required, all allocators compare equal. + */ + template<int inst> + inline bool + operator==(const __malloc_alloc_template<inst>&, + const __malloc_alloc_template<inst>&) + { return true; } -template <int __inst> -inline bool operator!=(const __malloc_alloc_template<__inst>&, - const __malloc_alloc_template<__inst>&) -{ - return false; -} + template<int __inst> + inline bool + operator!=(const __malloc_alloc_template<__inst>&, + const __malloc_alloc_template<__inst>&) + { return false; } -template <class _Alloc> -inline bool operator==(const __debug_alloc<_Alloc>&, - const __debug_alloc<_Alloc>&) { - return true; -} + template<typename _Alloc> + inline bool + operator==(const __debug_alloc<_Alloc>&, const __debug_alloc<_Alloc>&) + { return true; } -template <class _Alloc> -inline bool operator!=(const __debug_alloc<_Alloc>&, - const __debug_alloc<_Alloc>&) { - return false; -} -//@} + template<typename _Alloc> + inline bool + operator!=(const __debug_alloc<_Alloc>&, const __debug_alloc<_Alloc>&) + { return false; } + //@} -/** - * @if maint - * Another allocator adaptor: _Alloc_traits. This serves two purposes. - * First, make it possible to write containers that can use either "SGI" - * style allocators or "standard" allocators. Second, provide a mechanism - * so that containers can query whether or not the allocator has distinct - * instances. If not, the container can avoid wasting a word of memory to - * store an empty object. For examples of use, see stl_vector.h, etc, or - * any of the other classes derived from this one. - * - * This adaptor uses partial specialization. The general case of - * _Alloc_traits<_Tp, _Alloc> assumes that _Alloc is a - * standard-conforming allocator, possibly with non-equal instances and - * non-static members. (It still behaves correctly even if _Alloc has - * static member and if all instances are equal. Refinements affect - * performance, not correctness.) - * - * There are always two members: allocator_type, which is a standard- - * conforming allocator type for allocating objects of type _Tp, and - * _S_instanceless, a static const member of type bool. If - * _S_instanceless is true, this means that there is no difference - * between any two instances of type allocator_type. Furthermore, if - * _S_instanceless is true, then _Alloc_traits has one additional - * member: _Alloc_type. This type encapsulates allocation and - * deallocation of objects of type _Tp through a static interface; it - * has two member functions, whose signatures are - * - * - static _Tp* allocate(size_t) - * - static void deallocate(_Tp*, size_t) - * - * The size_t parameters are "standard" style (see top of stl_alloc.h) in - * that they take counts, not sizes. - * - * @endif - * (See @link Allocators allocators info @endlink for more.) -*/ -//@{ -// The fully general version. -template <class _Tp, class _Allocator> -struct _Alloc_traits -{ - static const bool _S_instanceless = false; - typedef typename _Allocator::template rebind<_Tp>::other allocator_type; -}; + /** + * @if maint + * Another allocator adaptor: _Alloc_traits. This serves two purposes. + * First, make it possible to write containers that can use either "SGI" + * style allocators or "standard" allocators. Second, provide a mechanism + * so that containers can query whether or not the allocator has distinct + * instances. If not, the container can avoid wasting a word of memory to + * store an empty object. For examples of use, see stl_vector.h, etc, or + * any of the other classes derived from this one. + * + * This adaptor uses partial specialization. The general case of + * _Alloc_traits<_Tp, _Alloc> assumes that _Alloc is a + * standard-conforming allocator, possibly with non-equal instances and + * non-static members. (It still behaves correctly even if _Alloc has + * static member and if all instances are equal. Refinements affect + * performance, not correctness.) + * + * There are always two members: allocator_type, which is a standard- + * conforming allocator type for allocating objects of type _Tp, and + * _S_instanceless, a static const member of type bool. If + * _S_instanceless is true, this means that there is no difference + * between any two instances of type allocator_type. Furthermore, if + * _S_instanceless is true, then _Alloc_traits has one additional + * member: _Alloc_type. This type encapsulates allocation and + * deallocation of objects of type _Tp through a static interface; it + * has two member functions, whose signatures are + * + * - static _Tp* allocate(size_t) + * - static void deallocate(_Tp*, size_t) + * + * The size_t parameters are "standard" style (see top of stl_alloc.h) in + * that they take counts, not sizes. + * + * @endif + * (See @link Allocators allocators info @endlink for more.) + */ + //@{ + // The fully general version. + template<typename _Tp, typename _Allocator> + struct _Alloc_traits + { + static const bool _S_instanceless = false; + typedef typename _Allocator::template rebind<_Tp>::other allocator_type; + }; -template <class _Tp, class _Allocator> -const bool _Alloc_traits<_Tp, _Allocator>::_S_instanceless; + template<typename _Tp, typename _Allocator> + const bool _Alloc_traits<_Tp, _Allocator>::_S_instanceless; -/// The version for the default allocator. -template <class _Tp, class _Tp1> -struct _Alloc_traits<_Tp, allocator<_Tp1> > -{ - static const bool _S_instanceless = true; - typedef __simple_alloc<_Tp, __alloc> _Alloc_type; - typedef allocator<_Tp> allocator_type; -}; -//@} - -//@{ -/// Versions for the predefined "SGI" style allocators. -template <class _Tp, int __inst> -struct _Alloc_traits<_Tp, __malloc_alloc_template<__inst> > -{ - static const bool _S_instanceless = true; - typedef __simple_alloc<_Tp, __malloc_alloc_template<__inst> > _Alloc_type; - typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type; -}; - -#ifndef __USE_MALLOC -template <class _Tp, bool __threads, int __inst> -struct _Alloc_traits<_Tp, __default_alloc_template<__threads, __inst> > -{ - static const bool _S_instanceless = true; - typedef __simple_alloc<_Tp, __default_alloc_template<__threads, __inst> > - _Alloc_type; - typedef __allocator<_Tp, __default_alloc_template<__threads, __inst> > - allocator_type; -}; -#endif + /// The version for the default allocator. + template<typename _Tp, typename _Tp1> + struct _Alloc_traits<_Tp, allocator<_Tp1> > + { + static const bool _S_instanceless = true; + typedef __simple_alloc<_Tp, __alloc> _Alloc_type; + typedef allocator<_Tp> allocator_type; + }; + //@} -template <class _Tp, class _Alloc> -struct _Alloc_traits<_Tp, __debug_alloc<_Alloc> > -{ - static const bool _S_instanceless = true; - typedef __simple_alloc<_Tp, __debug_alloc<_Alloc> > _Alloc_type; - typedef __allocator<_Tp, __debug_alloc<_Alloc> > allocator_type; -}; -//@} - -//@{ -/// Versions for the __allocator adaptor used with the predefined "SGI" style allocators. -template <class _Tp, class _Tp1, int __inst> -struct _Alloc_traits<_Tp, - __allocator<_Tp1, __malloc_alloc_template<__inst> > > -{ - static const bool _S_instanceless = true; - typedef __simple_alloc<_Tp, __malloc_alloc_template<__inst> > _Alloc_type; - typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type; -}; - -#ifndef __USE_MALLOC -template <class _Tp, class _Tp1, bool __thr, int __inst> -struct _Alloc_traits<_Tp, - __allocator<_Tp1, - __default_alloc_template<__thr, __inst> > > -{ - static const bool _S_instanceless = true; - typedef __simple_alloc<_Tp, __default_alloc_template<__thr,__inst> > - _Alloc_type; - typedef __allocator<_Tp, __default_alloc_template<__thr,__inst> > - allocator_type; -}; -#endif + //@{ + /// Versions for the predefined "SGI" style allocators. + template<typename _Tp, int __inst> + struct _Alloc_traits<_Tp, __malloc_alloc_template<__inst> > + { + static const bool _S_instanceless = true; + typedef __simple_alloc<_Tp, __malloc_alloc_template<__inst> > _Alloc_type; + typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type; + }; -template <class _Tp, class _Tp1, class _Alloc> -struct _Alloc_traits<_Tp, __allocator<_Tp1, __debug_alloc<_Alloc> > > -{ - static const bool _S_instanceless = true; - typedef __simple_alloc<_Tp, __debug_alloc<_Alloc> > _Alloc_type; - typedef __allocator<_Tp, __debug_alloc<_Alloc> > allocator_type; -}; -//@} + template<typename _Tp, bool __threads, int __inst> + struct _Alloc_traits<_Tp, __default_alloc_template<__threads, __inst> > + { + static const bool _S_instanceless = true; + typedef __simple_alloc<_Tp, __default_alloc_template<__threads, __inst> > + _Alloc_type; + typedef __allocator<_Tp, __default_alloc_template<__threads, __inst> > + allocator_type; + }; + + template<typename _Tp, typename _Alloc> + struct _Alloc_traits<_Tp, __debug_alloc<_Alloc> > + { + static const bool _S_instanceless = true; + typedef __simple_alloc<_Tp, __debug_alloc<_Alloc> > _Alloc_type; + typedef __allocator<_Tp, __debug_alloc<_Alloc> > allocator_type; + }; + //@} + + //@{ + /// Versions for the __allocator adaptor used with the predefined + /// "SGI" style allocators. + template<typename _Tp, typename _Tp1, int __inst> + struct _Alloc_traits<_Tp, + __allocator<_Tp1, __malloc_alloc_template<__inst> > > + { + static const bool _S_instanceless = true; + typedef __simple_alloc<_Tp, __malloc_alloc_template<__inst> > _Alloc_type; + typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type; + }; + + template<typename _Tp, typename _Tp1, bool __thr, int __inst> + struct _Alloc_traits<_Tp, __allocator<_Tp1, __default_alloc_template<__thr, __inst> > > + { + static const bool _S_instanceless = true; + typedef __simple_alloc<_Tp, __default_alloc_template<__thr,__inst> > + _Alloc_type; + typedef __allocator<_Tp, __default_alloc_template<__thr,__inst> > + allocator_type; + }; + + template<typename _Tp, typename _Tp1, typename _Alloc> + struct _Alloc_traits<_Tp, __allocator<_Tp1, __debug_alloc<_Alloc> > > + { + static const bool _S_instanceless = true; + typedef __simple_alloc<_Tp, __debug_alloc<_Alloc> > _Alloc_type; + typedef __allocator<_Tp, __debug_alloc<_Alloc> > allocator_type; + }; + //@} // Inhibit implicit instantiations for required instantiations, - // which are defined via explicit instantiations elsewhere. + // which are defined via explicit instantiations elsewhere. // NB: This syntax is a GNU extension. extern template class allocator<char>; extern template class allocator<wchar_t>; -#ifdef __USE_MALLOC - extern template class __malloc_alloc_template<0>; -#else - extern template class __default_alloc_template<true, 0>; -#endif + extern template class __default_alloc_template<true,0>; } // namespace std -#endif /* __GLIBCPP_INTERNAL_ALLOC_H */ - -// Local Variables: -// mode:C++ -// End: +#endif diff --git a/contrib/libstdc++/include/bits/stl_bvector.h b/contrib/libstdc++/include/bits/stl_bvector.h index e48ad7d..ce6df71 100644 --- a/contrib/libstdc++/include/bits/stl_bvector.h +++ b/contrib/libstdc++/include/bits/stl_bvector.h @@ -611,7 +611,9 @@ template <typename _Alloc> } void reserve(size_type __n) { - if (capacity() < __n) { + if (__n > this->max_size()) + __throw_length_error("vector::reserve"); + if (this->capacity() < __n) { _Bit_type * __q = _M_bit_alloc(__n); _M_finish = copy(begin(), end(), iterator(__q, 0)); _M_deallocate(); diff --git a/contrib/libstdc++/include/bits/stl_vector.h b/contrib/libstdc++/include/bits/stl_vector.h index 5e2ea54..ef3b1c2 100644 --- a/contrib/libstdc++/include/bits/stl_vector.h +++ b/contrib/libstdc++/include/bits/stl_vector.h @@ -391,7 +391,9 @@ public: * reallocation of memory and copy of vector data. */ void reserve(size_type __n) { - if (capacity() < __n) { + if (__n > this->max_size()) + __throw_length_error("vector::reserve"); + if (this->capacity() < __n) { const size_type __old_size = size(); pointer __tmp = _M_allocate_and_copy(__n, _M_start, _M_finish); _Destroy(_M_start, _M_finish); diff --git a/contrib/libstdc++/include/bits/streambuf.tcc b/contrib/libstdc++/include/bits/streambuf.tcc index c8084ee..5f57df5 100644 --- a/contrib/libstdc++/include/bits/streambuf.tcc +++ b/contrib/libstdc++/include/bits/streambuf.tcc @@ -69,7 +69,7 @@ namespace std bool __testpos = _M_in_cur && _M_in_beg < _M_in_cur; bool __testne = _M_in_cur && !traits_type::eq(__c, this->gptr()[-1]); if (!__testpos || __testne) - __ret = pbackfail(traits_type::to_int_type(__c)); + __ret = this->pbackfail(traits_type::to_int_type(__c)); else { _M_in_cur_move(-1); @@ -209,7 +209,8 @@ namespace std { while (__testput && __bufsize != -1) { - if (__bufsize != 0 && __sbin->gptr() != NULL) + if (__bufsize != 0 && __sbin->gptr() != NULL + && __sbin->gptr() + __bufsize <= __sbin->egptr()) { __xtrct = __sbout->sputn(__sbin->gptr(), __bufsize); __ret += __xtrct; @@ -219,8 +220,11 @@ namespace std } else { - _CharT __buf[256]; - streamsize __charsread = __sbin->sgetn(__buf, sizeof(__buf)); + size_t __size = + __sbin->_M_buf_size_opt > 0 ? __sbin->_M_buf_size_opt : 1; + _CharT* __buf = + static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __size)); + streamsize __charsread = __sbin->sgetn(__buf, __size); __xtrct = __sbout->sputn(__buf, __charsread); __ret += __xtrct; if (__xtrct != __charsread) diff --git a/contrib/libstdc++/include/std/std_fstream.h b/contrib/libstdc++/include/std/std_fstream.h index c386105..838b99d 100644 --- a/contrib/libstdc++/include/std/std_fstream.h +++ b/contrib/libstdc++/include/std/std_fstream.h @@ -1,6 +1,6 @@ // File based streams -*- C++ -*- -// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -141,10 +141,10 @@ namespace std _M_underflow_common(bool __bump); virtual int_type - underflow() { return _M_underflow_common(false); } + underflow(); virtual int_type - uflow() { return _M_underflow_common(true); } + uflow(); virtual int_type pbackfail(int_type __c = _Traits::eof()); @@ -297,6 +297,18 @@ namespace std basic_filebuf<wchar_t>::_M_underflow_common(bool __bump); #endif + // Generic definitions. + template <typename _CharT, typename _Traits> + basic_filebuf<_CharT, _Traits>::int_type + basic_filebuf<_CharT, _Traits>::underflow() + { return _M_underflow_common(false); } + + template <typename _CharT, typename _Traits> + basic_filebuf<_CharT, _Traits>::int_type + basic_filebuf<_CharT, _Traits>::uflow() + { return _M_underflow_common(true); } + + // 27.8.1.5 Template class basic_ifstream /** * Derivation of general input streams, specific to files. diff --git a/contrib/libstdc++/include/std/std_streambuf.h b/contrib/libstdc++/include/std/std_streambuf.h index 491570e..db36ed3 100644 --- a/contrib/libstdc++/include/std/std_streambuf.h +++ b/contrib/libstdc++/include/std/std_streambuf.h @@ -1,6 +1,6 @@ // Stream buffer classes -*- C++ -*- -// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -243,7 +243,6 @@ namespace std _M_buf_size = 0; _M_buf_size_opt = 0; _M_mode = ios_base::openmode(0); - _M_buf_locale_init = false; } // Locales: @@ -257,12 +256,7 @@ namespace std locale getloc() const - { - if (_M_buf_locale_init) - return _M_buf_locale; - else - return locale(); - } + { return _M_buf_locale; } // Buffer and positioning: __streambuf_type* @@ -351,7 +345,7 @@ namespace std _M_buf_unified(false), _M_in_beg(0), _M_in_cur(0), _M_in_end(0), _M_out_beg(0), _M_out_cur(0), _M_out_end(0), _M_mode(ios_base::openmode(0)), _M_buf_locale(locale()), - _M_buf_locale_init(false), _M_pback_cur_save(0), _M_pback_end_save(0), + _M_pback_cur_save(0), _M_pback_end_save(0), _M_pback_init(false) { } @@ -405,7 +399,6 @@ namespace std virtual void imbue(const locale& __loc) { - _M_buf_locale_init = true; if (_M_buf_locale != __loc) _M_buf_locale = __loc; } |