This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[v3, libstdcxx_so_7] Reorganize basic_string


Hi,

the below is a first stab at reorganizing basic_string for the next
ABI/API version: in a nutshell, the idea is providing flexibility,
a base class encoding the low level memory allocation bits. For now,
I have simply adapted the traditional reference counted policy, but
should be easy adding a different one optimized for short strings
(already prototyped succesfully last week, actually) or another simply
disabling reference-counting (useful for some MT applications), and
whatelse. The reference counted policy itself, probably should be
tweaked a bit, in order to fix two or three long standing bugs, very
difficult to fix cleanly in the present monolithic framework.

Future developments may also lead to a stand alone version of this
code, which could be delivered together with 4.0.x as an extension.
I'm open to any proposal, about this!

First, however, safe, unrestricted development is in order in the
separate v7-branch and benchmarking, debugging, etc. Contributions
are solicited, of course, as usual: in particular the various
insert/replace, etc., shared among the various policies, should be
cleaned up and consolidated. Also, the interfaces between the base
class and basic_string proper are in flux.

Regtested x86/x86_64/ia64-linux, I will commit soon to v7-branch
only, of course.

Last but not least, special thanks to Nathan Myers, my basic_string
master, and Jan Beulich.

Paolo.

////////////////////
2005-02-18  Paolo Carlini  <pcarlini@suse.de>

	* acinclude.m4 ([GLIBCXX_ENABLE_STRING]): New, allows to
	configure at build time the memory allocation policy.
	* configure.ac: Use it.
	* config/linker-map.gnu: Add symbols.
	* config/string/rc_string_base.h: New.
	* include/Makefile.am: Add new headers.
	(host_headers_extra): Add c++string.h.
	* include/bits/basic_string.h: Remove the low level memory
	allocation bits, now configurable: basic_string derives 
	from ___glibcxx_base_string, included via c++string.h.
	* include/bits/basic_string.tcc: Likewise use facilities
	provided by the base class.
	* include/ext/rc_string.h: New, __rc_string encapsulates
	a reference-counted memory allocation policy, very similar
	to the traditional one; derives from __string_utility.
	* include/ext/string_util.h: New, class __string_utility
	provides static utility function for moving and copying
	chars.
	* src/rc_string-inst.cc: New, __rc_string instantiations.
	* src/wrc_string-inst.cc: Likewise.
	* src/Makefile.am: Add.
	* src/string-inst.cc: Tweak consistently.
	* Makefile.in: Regenerate
	* configure: Likewise.
	* include/Makefile.in: Likewise.
	* libmath/Makefile.in: Likewise.
	* libsupc++/Makefile.in: Likewise.
	* po/Makefile.in: Likewise.
	* src/Makefile.in: Likewise.
	* testsuite/Makefile.in: Likewise.
diff -prN libstdc++-v3-orig/Makefile.in libstdc++-v3/Makefile.in
*** libstdc++-v3-orig/Makefile.in	Tue Feb  1 17:02:39 2005
--- libstdc++-v3/Makefile.in	Fri Feb 18 11:18:21 2005
*************** SECTION_FLAGS = @SECTION_FLAGS@
*** 185,190 ****
--- 185,192 ----
  SECTION_LDFLAGS = @SECTION_LDFLAGS@
  SET_MAKE = @SET_MAKE@
  SHELL = @SHELL@
+ STRING_H = @STRING_H@
+ STRING_NAME = @STRING_NAME@
  STRIP = @STRIP@
  SYMVER_MAP = @SYMVER_MAP@
  TOPLEVEL_INCLUDES = @TOPLEVEL_INCLUDES@
diff -prN libstdc++-v3-orig/acinclude.m4 libstdc++-v3/acinclude.m4
*** libstdc++-v3-orig/acinclude.m4	Sun Jan 30 11:25:30 2005
--- libstdc++-v3/acinclude.m4	Fri Feb 18 11:16:30 2005
*************** AC_DEFUN([GLIBCXX_ENABLE_ALLOCATOR], [
*** 1365,1370 ****
--- 1365,1423 ----
  
  
  dnl
+ dnl Check for which std::basic_string base class to use.  The choice is
+ dnl mapped from a subdirectory of include/ext.
+ dnl
+ dnl Default is rc_string.
+ dnl
+ AC_DEFUN([GLIBCXX_ENABLE_STRING], [
+   AC_MSG_CHECKING([for std::basic_string base class to use])
+   GLIBCXX_ENABLE(libstdcxx-string,auto,[=KIND],
+     [use KIND for target std::basic_string base],
+     [permit rc|yes|no|auto])
+ 
+   # If they didn't use this option switch, or if they specified --enable
+   # with no specific model, we'll have to look for one.  If they
+   # specified --disable (???), do likewise.
+   if test $enable_libstdcxx_string = no ||
+      test $enable_libstdcxx_string = yes;
+   then
+      enable_libstdcxx_string=auto
+   fi
+ 
+   # Either a known package, or "auto". Auto implies the default choice
+   # for a particular platform.
+   enable_libstdcxx_string_flag=$enable_libstdcxx_string
+ 
+   # Probe for host-specific support if no specific model is specified.
+   # Default to "new".
+   if test $enable_libstdcxx_string_flag = auto; then
+     case ${target_os} in
+       linux* | gnu* | kfreebsd*-gnu | knetbsd*-gnu)
+         enable_libstdcxx_string_flag=rc
+         ;;
+       *)
+         enable_libstdcxx_string_flag=rc
+         ;;
+     esac
+   fi
+   AC_MSG_RESULT($enable_libstdcxx_string_flag)
+   
+ 
+   # Set configure bits for specified locale package
+   case ${enable_libstdcxx_string_flag} in
+     rc)
+       STRING_H=config/string/rc_string_base.h
+       STRING_NAME=__gnu_cxx::__rc_string
+       ;;
+   esac
+ 
+   AC_SUBST(STRING_H)
+   AC_SUBST(STRING_NAME)
+ ])
+ 
+ 
+ dnl
  dnl Check for whether the Boost-derived checks should be turned on.
  dnl
  dnl --enable-concept-checks turns them on.
diff -prN libstdc++-v3-orig/config/linker-map.gnu libstdc++-v3/config/linker-map.gnu
*** libstdc++-v3-orig/config/linker-map.gnu	Wed Feb 16 11:39:53 2005
--- libstdc++-v3/config/linker-map.gnu	Fri Feb 18 16:01:48 2005
***************
*** 1,6 ****
  ## Linker script for GNU ld 2.13.91+ only.
  ##
! ## Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
  ##
  ## This file is part of the libstdc++ version 3 distribution.
  ##
--- 1,6 ----
  ## Linker script for GNU ld 2.13.91+ only.
  ##
! ## Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
  ##
  ## This file is part of the libstdc++ version 3 distribution.
  ##
*************** GLIBCXX_3.6 {
*** 291,297 ****
      _ZN9__gnu_cxx9free_list12_S_bfl_mutexE;
      _ZN9__gnu_cxx9free_list6_M_getE*;
      _ZN9__gnu_cxx9free_list8_M_clearEv;
! 	
    # DO NOT DELETE THIS LINE.  Port-specific symbols, if any, will be here.
  
    local:
--- 291,306 ----
      _ZN9__gnu_cxx9free_list12_S_bfl_mutexE;
      _ZN9__gnu_cxx9free_list6_M_getE*;
      _ZN9__gnu_cxx9free_list8_M_clearEv;
! 
!     # Added in libstdcxx_so_7-branch   
!     _ZN9__gnu_cxx11__rc_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE*;
!     _ZNK9__gnu_cxx11__rc_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE*;
!     _ZZN9__gnu_cxx11__rc_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE*;
!     
!     _ZZN9__gnu_cxx20__common_pool_policyINS_6__poolELb1EE11_S_get_poolEvE7_S_pool;
!     _ZZN9__gnu_cxx20__common_pool_policyINS_6__poolELb1EE18_S_initialize_onceEvE6__init;
!     _ZGVZN9__gnu_cxx20__common_pool_policyINS_6__poolELb1EE11_S_get_poolEvE7_S_pool;
! 
    # DO NOT DELETE THIS LINE.  Port-specific symbols, if any, will be here.
  
    local:
diff -prN libstdc++-v3-orig/config/string/rc_string_base.h libstdc++-v3/config/string/rc_string_base.h
*** libstdc++-v3-orig/config/string/rc_string_base.h	Thu Jan  1 01:00:00 1970
--- libstdc++-v3/config/string/rc_string_base.h	Fri Feb 18 11:06:11 2005
***************
*** 0 ****
--- 1,37 ----
+ // Base to std::basic_string -*- C++ -*-
+ 
+ // Copyright (C) 2005 Free Software Foundation, Inc.
+ //
+ // This file is part of the GNU ISO C++ Library.  This library is free
+ // software; you can redistribute it and/or modify it under the
+ // terms of the GNU General Public License as published by the
+ // Free Software Foundation; either version 2, or (at your option)
+ // any later version.
+ 
+ // This library is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ // GNU General Public License for more details.
+ 
+ // You should have received a copy of the GNU General Public License along
+ // with this library; see the file COPYING.  If not, write to the Free
+ // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ // USA.
+ 
+ // As a special exception, you may use this file as part of a free software
+ // library without restriction.  Specifically, if other files instantiate
+ // templates or use macros or inline functions from this file, or you compile
+ // this file and link it with other files to produce an executable, this
+ // file does not by itself cause the resulting executable to be covered by
+ // the GNU General Public License.  This exception does not however
+ // invalidate any other reasons why the executable file might be covered by
+ // the GNU General Public License.
+ 
+ #ifndef _CXX_STRING_H
+ #define _CXX_STRING_H 1
+ 
+ // Define rc_string as the base class to std::basic_string.
+ #include <ext/rc_string.h>
+ #define ___glibcxx_base_string  __gnu_cxx::__rc_string
+ 
+ #endif
diff -prN libstdc++-v3-orig/configure libstdc++-v3/configure
*** libstdc++-v3-orig/configure	Tue Feb  1 17:02:48 2005
--- libstdc++-v3/configure	Fri Feb 18 11:17:49 2005
*************** ac_includes_default="\
*** 309,315 ****
  # include <unistd.h>
  #endif"
  
! ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS libtool_VERSION multi_basedir build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar glibcxx_builddir glibcxx_srcdir toplevel_srcdir CC ac_ct_CC EXEEXT OBJEXT CXX ac_ct_CXX CFLAGS CXXFLAGS LN_S AS ac_ct_AS AR ac_ct_AR RANLIB ac_ct_RANLIB MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT LIBTOOL CXXCPP CPPFLAGS enable_shared enable_static GLIBCXX_HOSTED_TRUE GLIBCXX_HOSTED_FALSE GLIBCXX_BUILD_PCH_TRUE GLIBCXX_BUILD_PCH_FALSE glibcxx_PCHFLAGS CSTDIO_H BASIC_FILE_H BASIC_FILE_CC CPP EGREP check_msgfmt glibcxx_MOFILES glibcxx_POFILES glibcxx_localedir USE_NLS CLOCALE_H CMESSAGES_H CCODECVT_CC CCOLLATE_CC CCTYPE_CC CMESSAGES_CC CMONEY_CC CNUMERIC_CC CTIME_H CTIME_CC CLOCALE_CC CLOCALE_INTERNAL_H ALLOCATOR_H ALLOCATOR_NAME C_INCLUDE_DIR GLIBCXX_C_HEADERS_C_TRUE GLIBCXX_C_HEADERS_C_FALSE GLIBCXX_C_HEADERS_C_STD_TRUE GLIBCXX_C_HEADERS_C_STD_FALSE GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE glibcxx_thread_h DEBUG_FLAGS GLIBCXX_BUILD_DEBUG_TRUE GLIBCXX_BUILD_DEBUG_FALSE EXTRA_CXX_FLAGS WERROR SECTION_FLAGS SECTION_LDFLAGS OPT_LDFLAGS LIBMATHOBJS LIBICONV SYMVER_MAP port_specific_symbol_files GLIBCXX_BUILD_VERSIONED_SHLIB_TRUE GLIBCXX_BUILD_VERSIONED_SHLIB_FALSE baseline_dir GLIBCXX_TEST_WCHAR_T_TRUE GLIBCXX_TEST_WCHAR_T_FALSE GLIBCXX_TEST_THREAD_TRUE GLIBCXX_TEST_THREAD_FALSE GLIBCXX_TEST_ABI_TRUE GLIBCXX_TEST_ABI_FALSE ATOMICITY_SRCDIR ATOMIC_WORD_SRCDIR ABI_TWEAKS_SRCDIR OS_INC_SRCDIR glibcxx_prefixdir gxx_include_dir glibcxx_toolexecdir glibcxx_toolexeclibdir GLIBCXX_INCLUDES TOPLEVEL_INCLUDES OPTIMIZE_CXXFLAGS WARN_FLAGS LIBSUPCXX_PICFLAGS LIBOBJS LTLIBOBJS'
  ac_subst_files=''
  
  # Initialize some variables set by options.
--- 309,315 ----
  # include <unistd.h>
  #endif"
  
! ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS libtool_VERSION multi_basedir build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar glibcxx_builddir glibcxx_srcdir toplevel_srcdir CC ac_ct_CC EXEEXT OBJEXT CXX ac_ct_CXX CFLAGS CXXFLAGS LN_S AS ac_ct_AS AR ac_ct_AR RANLIB ac_ct_RANLIB MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT LIBTOOL CXXCPP CPPFLAGS enable_shared enable_static GLIBCXX_HOSTED_TRUE GLIBCXX_HOSTED_FALSE GLIBCXX_BUILD_PCH_TRUE GLIBCXX_BUILD_PCH_FALSE glibcxx_PCHFLAGS CSTDIO_H BASIC_FILE_H BASIC_FILE_CC CPP EGREP check_msgfmt glibcxx_MOFILES glibcxx_POFILES glibcxx_localedir USE_NLS CLOCALE_H CMESSAGES_H CCODECVT_CC CCOLLATE_CC CCTYPE_CC CMESSAGES_CC CMONEY_CC CNUMERIC_CC CTIME_H CTIME_CC CLOCALE_CC CLOCALE_INTERNAL_H ALLOCATOR_H ALLOCATOR_NAME STRING_H STRING_NAME C_INCLUDE_DIR GLIBCXX_C_HEADERS_C_TRUE GLIBCXX_C_HEADERS_C_FALSE GLIBCXX_C_HEADERS_C_STD_TRUE GLIBCXX_C_HEADERS_C_STD_FALSE GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE glibcxx_thread_h DEBUG_FLAGS GLIBCXX_BUILD_DEBUG_TRUE GLIBCXX_BUILD_DEBUG_FALSE EXTRA_CXX_FLAGS WERROR SECTION_FLAGS SECTION_LDFLAGS OPT_LDFLAGS LIBMATHOBJS LIBICONV SYMVER_MAP port_specific_symbol_files GLIBCXX_BUILD_VERSIONED_SHLIB_TRUE GLIBCXX_BUILD_VERSIONED_SHLIB_FALSE baseline_dir GLIBCXX_TEST_WCHAR_T_TRUE GLIBCXX_TEST_WCHAR_T_FALSE GLIBCXX_TEST_THREAD_TRUE GLIBCXX_TEST_THREAD_FALSE GLIBCXX_TEST_ABI_TRUE GLIBCXX_TEST_ABI_FALSE ATOMICITY_SRCDIR ATOMIC_WORD_SRCDIR ABI_TWEAKS_SRCDIR OS_INC_SRCDIR glibcxx_prefixdir gxx_include_dir glibcxx_toolexecdir glibcxx_toolexeclibdir GLIBCXX_INCLUDES TOPLEVEL_INCLUDES OPTIMIZE_CXXFLAGS WARN_FLAGS LIBSUPCXX_PICFLAGS LIBOBJS LTLIBOBJS'
  ac_subst_files=''
  
  # Initialize some variables set by options.
*************** Optional Features:
*** 867,872 ****
--- 867,875 ----
    --enable-libstdcxx-allocator=KIND
                            use KIND for target std::allocator base
                            [default=auto]
+   --enable-libstdcxx-string=KIND
+                           use KIND for target std::basic_string base
+                           [default=auto]
    --enable-cheaders=KIND  construct "C" headers for g++
                            [default=$c_model]
    --enable-c-mbchar       enable multibyte (wide) characters
*************** test x"$pic_mode" = xno && libtool_flags
*** 4390,4396 ****
  case $host in
  *-*-irix6*)
    # Find out which ABI we are using.
!   echo '#line 4393 "configure"' > conftest.$ac_ext
    if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
    (eval $ac_compile) 2>&5
    ac_status=$?
--- 4393,4399 ----
  case $host in
  *-*-irix6*)
    # Find out which ABI we are using.
!   echo '#line 4396 "configure"' > conftest.$ac_ext
    if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
    (eval $ac_compile) 2>&5
    ac_status=$?
*************** fi;
*** 5011,5017 ****
      #
      # Fake what AC_TRY_COMPILE does.  XXX Look at redoing this new-style.
      cat > conftest.$ac_ext << EOF
! #line 5014 "configure"
  struct S { ~S(); };
  void bar();
  void foo()
--- 5014,5020 ----
      #
      # Fake what AC_TRY_COMPILE does.  XXX Look at redoing this new-style.
      cat > conftest.$ac_ext << EOF
! #line 5017 "configure"
  struct S { ~S(); };
  void bar();
  void foo()
*************** echo "${ECHO_T}$enable_libstdcxx_allocat
*** 6324,6329 ****
--- 6327,6391 ----
  
  
  
+   echo "$as_me:$LINENO: checking for std::basic_string base class to use" >&5
+ echo $ECHO_N "checking for std::basic_string base class to use... $ECHO_C" >&6
+    # Check whether --enable-libstdcxx-string or --disable-libstdcxx-string was given.
+ if test "${enable_libstdcxx_string+set}" = set; then
+   enableval="$enable_libstdcxx_string"
+ 
+       case "$enableval" in
+        rc|yes|no|auto) ;;
+        *) { { echo "$as_me:$LINENO: error: Unknown argument to enable/disable libstdcxx-string" >&5
+ echo "$as_me: error: Unknown argument to enable/disable libstdcxx-string" >&2;}
+    { (exit 1); exit 1; }; } ;;
+                           esac
+ 
+ else
+   enable_libstdcxx_string=auto
+ fi;
+ 
+ 
+   # If they didn't use this option switch, or if they specified --enable
+   # with no specific model, we'll have to look for one.  If they
+   # specified --disable (???), do likewise.
+   if test $enable_libstdcxx_string = no ||
+      test $enable_libstdcxx_string = yes;
+   then
+      enable_libstdcxx_string=auto
+   fi
+ 
+   # Either a known package, or "auto". Auto implies the default choice
+   # for a particular platform.
+   enable_libstdcxx_string_flag=$enable_libstdcxx_string
+ 
+   # Probe for host-specific support if no specific model is specified.
+   # Default to "new".
+   if test $enable_libstdcxx_string_flag = auto; then
+     case ${target_os} in
+       linux* | gnu* | kfreebsd*-gnu | knetbsd*-gnu)
+         enable_libstdcxx_string_flag=rc
+         ;;
+       *)
+         enable_libstdcxx_string_flag=rc
+         ;;
+     esac
+   fi
+   echo "$as_me:$LINENO: result: $enable_libstdcxx_string_flag" >&5
+ echo "${ECHO_T}$enable_libstdcxx_string_flag" >&6
+ 
+ 
+   # Set configure bits for specified locale package
+   case ${enable_libstdcxx_string_flag} in
+     rc)
+       STRING_H=config/string/rc_string_base.h
+       STRING_NAME=__gnu_cxx::__rc_string
+       ;;
+   esac
+ 
+ 
+ 
+ 
+ 
     # Check whether --enable-cheaders or --disable-cheaders was given.
  if test "${enable_cheaders+set}" = set; then
    enableval="$enable_cheaders"
*************** s,@CLOCALE_CC@,$CLOCALE_CC,;t t
*** 100207,100212 ****
--- 100269,100276 ----
  s,@CLOCALE_INTERNAL_H@,$CLOCALE_INTERNAL_H,;t t
  s,@ALLOCATOR_H@,$ALLOCATOR_H,;t t
  s,@ALLOCATOR_NAME@,$ALLOCATOR_NAME,;t t
+ s,@STRING_H@,$STRING_H,;t t
+ s,@STRING_NAME@,$STRING_NAME,;t t
  s,@C_INCLUDE_DIR@,$C_INCLUDE_DIR,;t t
  s,@GLIBCXX_C_HEADERS_C_TRUE@,$GLIBCXX_C_HEADERS_C_TRUE,;t t
  s,@GLIBCXX_C_HEADERS_C_FALSE@,$GLIBCXX_C_HEADERS_C_FALSE,;t t
diff -prN libstdc++-v3-orig/configure.ac libstdc++-v3/configure.ac
*** libstdc++-v3-orig/configure.ac	Sun Jan  9 20:11:02 2005
--- libstdc++-v3/configure.ac	Fri Feb 18 11:14:10 2005
*************** GLIBCXX_ENABLE_PCH($is_hosted)
*** 85,90 ****
--- 85,91 ----
  GLIBCXX_ENABLE_CSTDIO
  GLIBCXX_ENABLE_CLOCALE
  GLIBCXX_ENABLE_ALLOCATOR
+ GLIBCXX_ENABLE_STRING
  GLIBCXX_ENABLE_CHEADERS($c_model)  dnl c_model from configure.host
  GLIBCXX_ENABLE_C_MBCHAR([yes])
  GLIBCXX_ENABLE_C99([yes])
diff -prN libstdc++-v3-orig/include/Makefile.am libstdc++-v3/include/Makefile.am
*** libstdc++-v3-orig/include/Makefile.am	Tue Feb  1 17:06:41 2005
--- libstdc++-v3/include/Makefile.am	Fri Feb 18 11:08:52 2005
*************** ext_headers = \
*** 219,224 ****
--- 219,226 ----
  	${ext_srcdir}/pod_char_traits.h \
  	${ext_srcdir}/pool_allocator.h \
  	${ext_srcdir}/rb_tree \
+ 	${ext_srcdir}/rc_string.h \
+ 	${ext_srcdir}/string_util.h \
  	${ext_srcdir}/rope \
  	${ext_srcdir}/ropeimpl.h \
  	${ext_srcdir}/slist \
*************** host_headers_extra = \
*** 363,368 ****
--- 365,371 ----
  	${host_builddir}/basic_file.h \
  	${host_builddir}/c++config.h \
  	${host_builddir}/c++allocator.h \
+ 	${host_builddir}/c++string.h \
  	${host_builddir}/c++io.h \
  	${host_builddir}/c++locale.h \
  	${host_builddir}/messages_members.h \
*************** stamp-host: ${host_headers} ${host_heade
*** 503,508 ****
--- 506,512 ----
  	  $(LN_S) ${host_headers} . || true ;\
  	  $(LN_S) ${glibcxx_srcdir}/$(BASIC_FILE_H) basic_file.h || true ;\
  	  $(LN_S) ${glibcxx_srcdir}/$(ALLOCATOR_H) c++allocator.h || true ;\
+ 	  $(LN_S) ${glibcxx_srcdir}/$(STRING_H) c++string.h || true ;\
  	  $(LN_S) ${glibcxx_srcdir}/$(CSTDIO_H) c++io.h || true ;\
  	  $(LN_S) ${glibcxx_srcdir}/$(CLOCALE_H) c++locale.h || true ;\
  	  $(LN_S) ${glibcxx_srcdir}/$(CLOCALE_INTERNAL_H) . || true ;\
diff -prN libstdc++-v3-orig/include/Makefile.in libstdc++-v3/include/Makefile.in
*** libstdc++-v3-orig/include/Makefile.in	Tue Feb  1 17:06:44 2005
--- libstdc++-v3/include/Makefile.in	Fri Feb 18 11:18:20 2005
*************** SECTION_FLAGS = @SECTION_FLAGS@
*** 152,157 ****
--- 152,159 ----
  SECTION_LDFLAGS = @SECTION_LDFLAGS@
  SET_MAKE = @SET_MAKE@
  SHELL = @SHELL@
+ STRING_H = @STRING_H@
+ STRING_NAME = @STRING_NAME@
  STRIP = @STRIP@
  SYMVER_MAP = @SYMVER_MAP@
  TOPLEVEL_INCLUDES = @TOPLEVEL_INCLUDES@
*************** ext_headers = \
*** 435,440 ****
--- 437,444 ----
  	${ext_srcdir}/pod_char_traits.h \
  	${ext_srcdir}/pool_allocator.h \
  	${ext_srcdir}/rb_tree \
+ 	${ext_srcdir}/rc_string.h \
+ 	${ext_srcdir}/string_util.h \
  	${ext_srcdir}/rope \
  	${ext_srcdir}/ropeimpl.h \
  	${ext_srcdir}/slist \
*************** host_headers_extra = \
*** 577,582 ****
--- 581,587 ----
  	${host_builddir}/basic_file.h \
  	${host_builddir}/c++config.h \
  	${host_builddir}/c++allocator.h \
+ 	${host_builddir}/c++string.h \
  	${host_builddir}/c++io.h \
  	${host_builddir}/c++locale.h \
  	${host_builddir}/messages_members.h \
*************** stamp-host: ${host_headers} ${host_heade
*** 882,887 ****
--- 887,893 ----
  	  $(LN_S) ${host_headers} . || true ;\
  	  $(LN_S) ${glibcxx_srcdir}/$(BASIC_FILE_H) basic_file.h || true ;\
  	  $(LN_S) ${glibcxx_srcdir}/$(ALLOCATOR_H) c++allocator.h || true ;\
+ 	  $(LN_S) ${glibcxx_srcdir}/$(STRING_H) c++string.h || true ;\
  	  $(LN_S) ${glibcxx_srcdir}/$(CSTDIO_H) c++io.h || true ;\
  	  $(LN_S) ${glibcxx_srcdir}/$(CLOCALE_H) c++locale.h || true ;\
  	  $(LN_S) ${glibcxx_srcdir}/$(CLOCALE_INTERNAL_H) . || true ;\
diff -prN libstdc++-v3-orig/include/bits/basic_string.h libstdc++-v3/include/bits/basic_string.h
*** libstdc++-v3-orig/include/bits/basic_string.h	Tue Feb  1 17:06:50 2005
--- libstdc++-v3/include/bits/basic_string.h	Fri Feb 18 16:17:19 2005
***************
*** 42,48 ****
  
  #pragma GCC system_header
  
! #include <bits/atomicity.h>
  #include <debug/debug.h>
  
  namespace std
--- 42,50 ----
  
  #pragma GCC system_header
  
! // Define the base class to std::basic_string.
! #include <bits/c++string.h>
! 
  #include <debug/debug.h>
  
  namespace std
*************** namespace std
*** 59,113 ****
     *  <a href="tables.html#67">sequence</a>.  Of the
     *  <a href="tables.html#68">optional sequence requirements</a>, only
     *  @c push_back, @c at, and array access are supported.
!    *
!    *  @doctodo
!    *
!    *
!    *  @if maint
!    *  Documentation?  What's that?
!    *  Nathan Myers <ncm@cantrip.org>.
!    *
!    *  A string looks like this:
!    *
!    *  @code
!    *                                        [_Rep]
!    *                                        _M_length
!    *   [basic_string<char_type>]            _M_capacity
!    *   _M_dataplus                          _M_refcount
!    *   _M_p ---------------->               unnamed array of char_type
!    *  @endcode
!    *
!    *  Where the _M_p points to the first character in the string, and
!    *  you cast it to a pointer-to-_Rep and subtract 1 to get a
!    *  pointer to the header.
!    *
!    *  This approach has the enormous advantage that a string object
!    *  requires only one allocation.  All the ugliness is confined
!    *  within a single pair of inline functions, which each compile to
!    *  a single "add" instruction: _Rep::_M_data(), and
!    *  string::_M_rep(); and the allocation function which gets a
!    *  block of raw bytes and with room enough and constructs a _Rep
!    *  object at the front.
!    *
!    *  The reason you want _M_data pointing to the character array and
!    *  not the _Rep is so that the debugger can see the string
!    *  contents. (Probably we should add a non-inline member to get
!    *  the _Rep for the debugger to use, so users can check the actual
!    *  string length.)
!    *
!    *  Note that the _Rep object is a POD so that you can have a
!    *  static "empty string" _Rep object already "constructed" before
!    *  static constructors have run.  The reference-count encoding is
!    *  chosen so that a 0 indicates one reference, so you never try to
!    *  destroy the empty-string _Rep object.
!    *
!    *  All but the last paragraph is considered pretty conventional
!    *  for a C++ string implementation.
!    *  @endif
!   */
    // 21.3  Template class basic_string
    template<typename _CharT, typename _Traits, typename _Alloc>
      class basic_string
      {
        // Types:
      public:
--- 61,72 ----
     *  <a href="tables.html#67">sequence</a>.  Of the
     *  <a href="tables.html#68">optional sequence requirements</a>, only
     *  @c push_back, @c at, and array access are supported.
!    */
! 
    // 21.3  Template class basic_string
    template<typename _CharT, typename _Traits, typename _Alloc>
      class basic_string
+     : private ___glibcxx_base_string<_CharT, _Traits, _Alloc>
      {
        // Types:
      public:
*************** namespace std
*** 126,259 ****
        typedef std::reverse_iterator<const_iterator>	const_reverse_iterator;
        typedef std::reverse_iterator<iterator>		    reverse_iterator;
  
!     private:
!       // _Rep: string representation
!       //   Invariants:
!       //   1. String really contains _M_length + 1 characters: due to 21.3.4
!       //      must be kept null-terminated.
!       //   2. _M_capacity >= _M_length
!       //      Allocated memory is always (_M_capacity + 1) * sizeof(_CharT).
!       //   3. _M_refcount has three states:
!       //      -1: leaked, one reference, no ref-copies allowed, non-const.
!       //       0: one reference, non-const.
!       //     n>0: n + 1 references, operations require a lock, const.
!       //   4. All fields==0 is an empty string, given the extra storage
!       //      beyond-the-end for a null terminator; thus, the shared
!       //      empty string representation needs no constructor.
! 
!       struct _Rep_base
!       {
! 	size_type		_M_length;
! 	size_type		_M_capacity;
! 	_Atomic_word		_M_refcount;
!       };
! 
!       struct _Rep : _Rep_base
!       {
! 	// Types:
! 	typedef typename _Alloc::template rebind<char>::other _Raw_bytes_alloc;
! 
! 	// (Public) Data members:
! 
! 	// The maximum number of individual char_type elements of an
! 	// individual string is determined by _S_max_size. This is the
! 	// value that will be returned by max_size().  (Whereas npos
! 	// is the maximum number of bytes the allocator can allocate.)
! 	// If one was to divvy up the theoretical largest size string,
! 	// with a terminating character and m _CharT elements, it'd
! 	// look like this:
! 	// npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT)
! 	// Solving for m:
! 	// m = ((npos - sizeof(_Rep))/sizeof(CharT)) - 1
! 	// In addition, this implementation quarters this amount.
! 	static const size_type	_S_max_size;
! 	static const _CharT	_S_terminal;
! 
! 	// The following storage is init'd to 0 by the linker, resulting
!         // (carefully) in an empty string with one reference.
!         static size_type _S_empty_rep_storage[];
! 
!         static _Rep&
!         _S_empty_rep()
!         { return *reinterpret_cast<_Rep*>(&_S_empty_rep_storage); }
! 
!         bool
! 	_M_is_leaked() const
!         { return this->_M_refcount < 0; }
! 
!         bool
! 	_M_is_shared() const
!         { return this->_M_refcount > 0; }
! 
!         void
! 	_M_set_leaked()
!         { this->_M_refcount = -1; }
! 
!         void
! 	_M_set_sharable()
!         { this->_M_refcount = 0; }
! 
! 	void
! 	_M_set_length_and_sharable(size_type __n)
! 	{ 
! 	  this->_M_set_sharable();  // One reference.
! 	  this->_M_length = __n;
! 	  this->_M_refdata()[__n] = _S_terminal; // grrr. (per 21.3.4)
! 	  // You cannot leave those LWG people alone for a second.
! 	}
! 
! 	_CharT*
! 	_M_refdata() throw()
! 	{ return reinterpret_cast<_CharT*>(this + 1); }
! 
! 	_CharT*
! 	_M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2)
! 	{
! 	  return (!_M_is_leaked() && __alloc1 == __alloc2)
! 	          ? _M_refcopy() : _M_clone(__alloc1);
! 	}
! 
! 	// Create & Destroy
! 	static _Rep*
! 	_S_create(size_type, size_type, const _Alloc&);
! 
! 	void
! 	_M_dispose(const _Alloc& __a)
! 	{
! #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
! 	  if (__builtin_expect(this != &_S_empty_rep(), false))
! #endif
! 	    if (__gnu_cxx::__exchange_and_add(&this->_M_refcount, -1) <= 0)
! 	      _M_destroy(__a);
! 	}  // XXX MT
! 
! 	void
! 	_M_destroy(const _Alloc&) throw();
! 
! 	_CharT*
! 	_M_refcopy() throw()
! 	{
! #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
! 	  if (__builtin_expect(this != &_S_empty_rep(), false))
! #endif
!             __gnu_cxx::__atomic_add(&this->_M_refcount, 1);
! 	  return _M_refdata();
! 	}  // XXX MT
! 
! 	_CharT*
! 	_M_clone(const _Alloc&, size_type __res = 0);
!       };
! 
!       // Use empty-base optimization: http://www.cantrip.org/emptyopt.html
!       struct _Alloc_hider : _Alloc
!       {
! 	_Alloc_hider(_CharT* __dat, const _Alloc& __a)
! 	: _Alloc(__a), _M_p(__dat) { }
  
- 	_CharT* _M_p; // The actual data.
-       };
- 
-     public:
        // Data Members (public):
        // NB: This is an unsigned type, and thus represents the maximum
        // size that the allocator can hold.
--- 85,93 ----
        typedef std::reverse_iterator<const_iterator>	const_reverse_iterator;
        typedef std::reverse_iterator<iterator>		    reverse_iterator;
  
!       typedef typename ___glibcxx_base_string<_CharT, _Traits, _Alloc>
!                                                             __string_base;
  
        // Data Members (public):
        // NB: This is an unsigned type, and thus represents the maximum
        // size that the allocator can hold.
*************** namespace std
*** 261,298 ****
        static const size_type	npos = static_cast<size_type>(-1);
  
      private:
-       // Data Members (private):
-       mutable _Alloc_hider	_M_dataplus;
- 
-       _CharT*
-       _M_data() const
-       { return  _M_dataplus._M_p; }
- 
-       _CharT*
-       _M_data(_CharT* __p)
-       { return (_M_dataplus._M_p = __p); }
- 
-       _Rep*
-       _M_rep() const
-       { return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); }
- 
-       // For the internal use we have functions similar to `begin'/`end'
-       // but they do not call _M_leak.
-       iterator
-       _M_ibegin() const
-       { return iterator(_M_data()); }
- 
-       iterator
-       _M_iend() const
-       { return iterator(_M_data() + this->size()); }
- 
-       void
-       _M_leak()    // for use in begin() & non-const op[]
-       {
- 	if (!_M_rep()->_M_is_leaked())
- 	  _M_leak_hard();
-       }
- 
        size_type
        _M_check(size_type __pos, const char* __s) const
        {
--- 95,100 ----
*************** namespace std
*** 320,393 ****
        bool
        _M_disjunct(const _CharT* __s) const
        {
! 	return (less<const _CharT*>()(__s, _M_data())
! 		|| less<const _CharT*>()(_M_data() + this->size(), __s));
!       }
! 
!       // When __n = 1 way faster than the general multichar
!       // traits_type::copy/move/assign.
!       static void
!       _M_copy(_CharT* __d, const _CharT* __s, size_type __n)
!       {
! 	if (__n == 1)
! 	  traits_type::assign(*__d, *__s);
! 	else
! 	  traits_type::copy(__d, __s, __n);
        }
  
!       static void
!       _M_move(_CharT* __d, const _CharT* __s, size_type __n)
!       {
! 	if (__n == 1)
! 	  traits_type::assign(*__d, *__s);
! 	else
! 	  traits_type::move(__d, __s, __n);	  
!       }
! 
!       static void
!       _M_assign(_CharT* __d, size_type __n, _CharT __c)
!       {
! 	if (__n == 1)
! 	  traits_type::assign(*__d, __c);
! 	else
! 	  traits_type::assign(__d, __n, __c);	  
!       }
! 
!       // _S_copy_chars is a separate template to permit specialization
!       // to optimize for the common case of pointers as iterators.
!       template<class _Iterator>
!         static void
!         _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2)
!         {
! 	  for (; __k1 != __k2; ++__k1, ++__p)
! 	    traits_type::assign(*__p, *__k1); // These types are off.
! 	}
! 
!       static void
!       _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2)
!       { _S_copy_chars(__p, __k1.base(), __k2.base()); }
! 
!       static void
!       _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2)
!       { _S_copy_chars(__p, __k1.base(), __k2.base()); }
! 
!       static void
!       _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2)
!       { _M_copy(__p, __k1, __k2 - __k1); }
! 
!       static void
!       _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2)
!       { _M_copy(__p, __k1, __k2 - __k1); }
! 
!       void
!       _M_mutate(size_type __pos, size_type __len1, size_type __len2);
! 
!       void
!       _M_leak_hard();
  
!       static _Rep&
!       _S_empty_rep()
!       { return _Rep::_S_empty_rep(); }
  
      public:
        // Construct/copy/destroy:
--- 122,140 ----
        bool
        _M_disjunct(const _CharT* __s) const
        {
! 	return (less<const _CharT*>()(__s, this->_M_data())
! 		|| less<const _CharT*>()(this->_M_data() + this->size(), __s));
        }
  
!       // For the internal use we have functions similar to `begin'/`end'
!       // but they do not call _M_leak.
!       iterator
!       _M_ibegin() const
!       { return iterator(this->_M_data()); }
  
!       iterator
!       _M_iend() const
!       { return iterator(this->_M_data() + this->_M_rep()->_M_length); }
  
      public:
        // Construct/copy/destroy:
*************** namespace std
*** 397,417 ****
        /**
         *  @brief  Default constructor creates an empty string.
         */
!       inline
!       basic_string();
! 
        /**
         *  @brief  Construct an empty string using allocator a.
         */
        explicit
!       basic_string(const _Alloc& __a);
  
        // NB: per LWG issue 42, semantics different from IS:
        /**
         *  @brief  Construct string with copy of value of @a str.
         *  @param  str  Source string.
         */
!       basic_string(const basic_string& __str);
        /**
         *  @brief  Construct string as copy of a substring.
         *  @param  str  Source string.
--- 144,169 ----
        /**
         *  @brief  Default constructor creates an empty string.
         */
!       basic_string()
!       : __string_base() { }
!       
        /**
         *  @brief  Construct an empty string using allocator a.
         */
        explicit
!       basic_string(const _Alloc& __a)
!       : __string_base(__a) { }
  
        // NB: per LWG issue 42, semantics different from IS:
        /**
         *  @brief  Construct string with copy of value of @a str.
         *  @param  str  Source string.
         */
!       basic_string(const basic_string& __str)
!       : __string_base(__str._M_grab(_Alloc(__str.get_allocator()),
! 				    __str.get_allocator()),
! 		      __str.get_allocator()) { }
! 
        /**
         *  @brief  Construct string as copy of a substring.
         *  @param  str  Source string.
*************** namespace std
*** 419,425 ****
         *  @param  n  Number of characters to copy (default remainder).
         */
        basic_string(const basic_string& __str, size_type __pos,
! 		   size_type __n = npos);
        /**
         *  @brief  Construct string as copy of a substring.
         *  @param  str  Source string.
--- 171,182 ----
         *  @param  n  Number of characters to copy (default remainder).
         */
        basic_string(const basic_string& __str, size_type __pos,
! 		   size_type __n = npos)
!       : __string_base(__str._M_data()
! 		      + __str._M_check(__pos, "basic_string::basic_string"),
! 		      __str._M_data() + __str._M_limit(__pos, __n)
! 		      + __pos, _Alloc()) { }
! 
        /**
         *  @brief  Construct string as copy of a substring.
         *  @param  str  Source string.
*************** namespace std
*** 428,434 ****
         *  @param  a  Allocator to use.
         */
        basic_string(const basic_string& __str, size_type __pos,
! 		   size_type __n, const _Alloc& __a);
  
        /**
         *  @brief  Construct string initialized by a character array.
--- 185,195 ----
         *  @param  a  Allocator to use.
         */
        basic_string(const basic_string& __str, size_type __pos,
! 		   size_type __n, const _Alloc& __a)
!       : __string_base(__str._M_data()
! 		      + __str._M_check(__pos, "basic_string::basic_string"),
! 		      __str._M_data() + __str._M_limit(__pos, __n)
! 		      + __pos, __a) { }
  
        /**
         *  @brief  Construct string initialized by a character array.
*************** namespace std
*** 440,459 ****
         *  meaning.
         */
        basic_string(const _CharT* __s, size_type __n,
! 		   const _Alloc& __a = _Alloc());
        /**
         *  @brief  Construct string as copy of a C string.
         *  @param  s  Source C string.
         *  @param  a  Allocator to use (default is default allocator).
         */
!       basic_string(const _CharT* __s, const _Alloc& __a = _Alloc());
        /**
         *  @brief  Construct string as multiple characters.
         *  @param  n  Number of characters.
         *  @param  c  Character to use.
         *  @param  a  Allocator to use (default is default allocator).
         */
!       basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc());
  
        /**
         *  @brief  Construct string as copy of a range.
--- 201,226 ----
         *  meaning.
         */
        basic_string(const _CharT* __s, size_type __n,
! 		   const _Alloc& __a = _Alloc())
!       : __string_base(__s, __s + __n, __a) { }
! 
        /**
         *  @brief  Construct string as copy of a C string.
         *  @param  s  Source C string.
         *  @param  a  Allocator to use (default is default allocator).
         */
!       basic_string(const _CharT* __s, const _Alloc& __a = _Alloc())
!       : __string_base(__s, __s ? __s + traits_type::length(__s) :
! 		      __s + npos, __a) { }
! 
        /**
         *  @brief  Construct string as multiple characters.
         *  @param  n  Number of characters.
         *  @param  c  Character to use.
         *  @param  a  Allocator to use (default is default allocator).
         */
!       basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc())
!       : __string_base(__n, __c, __a) { }
  
        /**
         *  @brief  Construct string as copy of a range.
*************** namespace std
*** 463,475 ****
         */
        template<class _InputIterator>
          basic_string(_InputIterator __beg, _InputIterator __end,
! 		     const _Alloc& __a = _Alloc());
  
        /**
         *  @brief  Destroy the string instance.
         */
!       ~basic_string()
!       { _M_rep()->_M_dispose(this->get_allocator()); }
  
        /**
         *  @brief  Assign the value of @a str to this string.
--- 230,242 ----
         */
        template<class _InputIterator>
          basic_string(_InputIterator __beg, _InputIterator __end,
! 		     const _Alloc& __a = _Alloc())
! 	: __string_base(__beg, __end, __a) { }
  
        /**
         *  @brief  Destroy the string instance.
         */
!       ~basic_string() { }	
  
        /**
         *  @brief  Assign the value of @a str to this string.
*************** namespace std
*** 509,516 ****
        iterator
        begin()
        {
! 	_M_leak();
! 	return iterator(_M_data());
        }
  
        /**
--- 276,283 ----
        iterator
        begin()
        {
! 	this->_M_leak();
! 	return iterator(this->_M_data());
        }
  
        /**
*************** namespace std
*** 519,525 ****
         */
        const_iterator
        begin() const
!       { return const_iterator(_M_data()); }
  
        /**
         *  Returns a read/write iterator that points one past the last
--- 286,292 ----
         */
        const_iterator
        begin() const
!       { return const_iterator(this->_M_data()); }
  
        /**
         *  Returns a read/write iterator that points one past the last
*************** namespace std
*** 528,535 ****
        iterator
        end()
        {
! 	_M_leak();
! 	return iterator(_M_data() + this->size());
        }
  
        /**
--- 295,302 ----
        iterator
        end()
        {
! 	this->_M_leak();
! 	return iterator(this->_M_data() + this->size());
        }
  
        /**
*************** namespace std
*** 538,544 ****
         */
        const_iterator
        end() const
!       { return const_iterator(_M_data() + this->size()); }
  
        /**
         *  Returns a read/write reverse iterator that points to the last
--- 305,311 ----
         */
        const_iterator
        end() const
!       { return const_iterator(this->_M_data() + this->size()); }
  
        /**
         *  Returns a read/write reverse iterator that points to the last
*************** namespace std
*** 582,599 ****
        ///  null-termination.
        size_type
        size() const
!       { return _M_rep()->_M_length; }
  
        ///  Returns the number of characters in the string, not including any
        ///  null-termination.
        size_type
        length() const
!       { return _M_rep()->_M_length; }
  
        /// Returns the size() of the largest possible %string.
        size_type
        max_size() const
!       { return _Rep::_S_max_size; }
  
        /**
         *  @brief  Resizes the %string to the specified number of characters.
--- 349,366 ----
        ///  null-termination.
        size_type
        size() const
!       { return this->_M_rep()->_M_length; }
  
        ///  Returns the number of characters in the string, not including any
        ///  null-termination.
        size_type
        length() const
!       { return this->_M_rep()->_M_length; }
  
        /// Returns the size() of the largest possible %string.
        size_type
        max_size() const
!       { return __string_base::_S_max_size; }
  
        /**
         *  @brief  Resizes the %string to the specified number of characters.
*************** namespace std
*** 628,634 ****
         */
        size_type
        capacity() const
!       { return _M_rep()->_M_capacity; }
  
        /**
         *  @brief  Attempt to preallocate enough memory for specified number of
--- 395,401 ----
         */
        size_type
        capacity() const
!       { return this->_M_rep()->_M_capacity; }
  
        /**
         *  @brief  Attempt to preallocate enough memory for specified number of
*************** namespace std
*** 655,661 ****
         */
        void
        clear()
!       { _M_mutate(0, this->size(), 0); }
  
        /**
         *  Returns true if the %string is empty.  Equivalent to *this == "".
--- 422,428 ----
         */
        void
        clear()
!       { this->_M_mutate(0, this->size(), 0); }
  
        /**
         *  Returns true if the %string is empty.  Equivalent to *this == "".
*************** namespace std
*** 678,685 ****
        const_reference
        operator[] (size_type __pos) const
        {
! 	_GLIBCXX_DEBUG_ASSERT(__pos <= size());
! 	return _M_data()[__pos];
        }
  
        /**
--- 445,452 ----
        const_reference
        operator[] (size_type __pos) const
        {
! 	_GLIBCXX_DEBUG_ASSERT(__pos <= this->size());
! 	return this->_M_data()[__pos];
        }
  
        /**
*************** namespace std
*** 695,703 ****
        reference
        operator[](size_type __pos)
        {
! 	_GLIBCXX_DEBUG_ASSERT(__pos < size());
! 	_M_leak();
! 	return _M_data()[__pos];
        }
  
        /**
--- 462,470 ----
        reference
        operator[](size_type __pos)
        {
! 	_GLIBCXX_DEBUG_ASSERT(__pos < this->size());
! 	this->_M_leak();
! 	return this->_M_data()[__pos];
        }
  
        /**
*************** namespace std
*** 715,721 ****
        {
  	if (__n >= this->size())
  	  __throw_out_of_range(__N("basic_string::at"));
! 	return _M_data()[__n];
        }
  
        /**
--- 482,488 ----
        {
  	if (__n >= this->size())
  	  __throw_out_of_range(__N("basic_string::at"));
! 	return this->_M_data()[__n];
        }
  
        /**
*************** namespace std
*** 732,741 ****
        reference
        at(size_type __n)
        {
! 	if (__n >= size())
  	  __throw_out_of_range(__N("basic_string::at"));
! 	_M_leak();
! 	return _M_data()[__n];
        }
  
        // Modifiers:
--- 499,508 ----
        reference
        at(size_type __n)
        {
! 	if (__n >= this->size())
  	  __throw_out_of_range(__N("basic_string::at"));
! 	this->_M_leak();
! 	return this->_M_data()[__n];
        }
  
        // Modifiers:
*************** namespace std
*** 845,854 ****
        push_back(_CharT __c)
        { 
  	const size_type __len = 1 + this->size();
! 	if (__len > this->capacity() || _M_rep()->_M_is_shared())
  	  this->reserve(__len);
! 	traits_type::assign(_M_data()[this->size()], __c);
! 	_M_rep()->_M_set_length_and_sharable(__len);
        }
  
        /**
--- 612,621 ----
        push_back(_CharT __c)
        { 
  	const size_type __len = 1 + this->size();
! 	if (__len > this->capacity() || this->_M_rep()->_M_is_shared())
  	  this->reserve(__len);
! 	traits_type::assign(this->_M_data()[this->size()], __c);
! 	this->_M_rep()->_M_set_length(__len);
        }
  
        /**
*************** namespace std
*** 1084,1091 ****
  	_GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend());
  	const size_type __pos = __p - _M_ibegin();
  	_M_replace_aux(__pos, size_type(0), size_type(1), __c);
! 	_M_rep()->_M_set_leaked();
! 	return this->_M_ibegin() + __pos;
        }
  
        /**
--- 851,858 ----
  	_GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend());
  	const size_type __pos = __p - _M_ibegin();
  	_M_replace_aux(__pos, size_type(0), size_type(1), __c);
! 	this->_M_rep()->_M_set_leaked();
! 	return _M_ibegin() + __pos;
        }
  
        /**
*************** namespace std
*** 1105,1112 ****
        basic_string&
        erase(size_type __pos = 0, size_type __n = npos)
        { 
! 	_M_mutate(_M_check(__pos, "basic_string::erase"),
! 		  _M_limit(__pos, __n), size_type(0));
  	return *this;
        }
  
--- 872,879 ----
        basic_string&
        erase(size_type __pos = 0, size_type __n = npos)
        { 
! 	this->_M_mutate(_M_check(__pos, "basic_string::erase"),
! 			_M_limit(__pos, __n), size_type(0));
  	return *this;
        }
  
*************** namespace std
*** 1124,1131 ****
  	_GLIBCXX_DEBUG_PEDASSERT(__position >= _M_ibegin()
  				 && __position < _M_iend());
  	const size_type __pos = __position - _M_ibegin();
! 	_M_mutate(__pos, size_type(1), size_type(0));
! 	_M_rep()->_M_set_leaked();
  	return _M_ibegin() + __pos;
        }
  
--- 891,898 ----
  	_GLIBCXX_DEBUG_PEDASSERT(__position >= _M_ibegin()
  				 && __position < _M_iend());
  	const size_type __pos = __position - _M_ibegin();
! 	this->_M_mutate(__pos, size_type(1), size_type(0));
! 	this->_M_rep()->_M_set_leaked();
  	return _M_ibegin() + __pos;
        }
  
*************** namespace std
*** 1144,1151 ****
  	_GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last
  				 && __last <= _M_iend());
          const size_type __pos = __first - _M_ibegin();
! 	_M_mutate(__pos, __last - __first, size_type(0));
! 	_M_rep()->_M_set_leaked();
  	return _M_ibegin() + __pos;
        }
  
--- 911,918 ----
  	_GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last
  				 && __last <= _M_iend());
          const size_type __pos = __first - _M_ibegin();
! 	this->_M_mutate(__pos, __last - __first, size_type(0));
! 	this->_M_rep()->_M_set_leaked();
  	return _M_ibegin() + __pos;
        }
  
*************** namespace std
*** 1414,1420 ****
  	basic_string&
  	_M_replace_dispatch(iterator __i1, iterator __i2, _Integer __n,
  			    _Integer __val, __true_type)
!         { return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __val); }
  
        template<class _InputIterator>
  	basic_string&
--- 1181,1188 ----
  	basic_string&
  	_M_replace_dispatch(iterator __i1, iterator __i2, _Integer __n,
  			    _Integer __val, __true_type)
!         { return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1,
! 				__n, __val); }
  
        template<class _InputIterator>
  	basic_string&
*************** namespace std
*** 1429,1476 ****
        _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s,
  		      size_type __n2);
  
-       // _S_construct_aux is used to implement the 21.3.1 para 15 which
-       // requires special behaviour if _InIter is an integral type
-       template<class _InIterator>
-         static _CharT*
-         _S_construct_aux(_InIterator __beg, _InIterator __end,
- 			 const _Alloc& __a, __false_type)
- 	{
-           typedef typename iterator_traits<_InIterator>::iterator_category _Tag;
-           return _S_construct(__beg, __end, __a, _Tag());
- 	}
- 
-       template<class _InIterator>
-         static _CharT*
-         _S_construct_aux(_InIterator __beg, _InIterator __end,
- 			 const _Alloc& __a, __true_type)
- 	{ return _S_construct(static_cast<size_type>(__beg),
- 			      static_cast<value_type>(__end), __a); }
- 
-       template<class _InIterator>
-         static _CharT*
-         _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a)
- 	{
- 	  typedef typename std::__is_integer<_InIterator>::__type _Integral;
- 	  return _S_construct_aux(__beg, __end, __a, _Integral());
-         }
- 
-       // For Input Iterators, used in istreambuf_iterators, etc.
-       template<class _InIterator>
-         static _CharT*
-          _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a,
- 		      input_iterator_tag);
- 
-       // For forward_iterators up to random_access_iterators, used for
-       // string::iterator, _CharT*, etc.
-       template<class _FwdIterator>
-         static _CharT*
-         _S_construct(_FwdIterator __beg, _FwdIterator __end, const _Alloc& __a,
- 		     forward_iterator_tag);
- 
-       static _CharT*
-       _S_construct(size_type __req, _CharT __c, const _Alloc& __a);
- 
      public:
  
        /**
--- 1197,1202 ----
*************** namespace std
*** 1506,1512 ****
        */
        const _CharT*
        c_str() const
!       { return _M_data(); }
  
        /**
         *  @brief  Return const pointer to contents.
--- 1232,1238 ----
        */
        const _CharT*
        c_str() const
!       { return this->_M_data(); }
  
        /**
         *  @brief  Return const pointer to contents.
*************** namespace std
*** 1516,1529 ****
        */
        const _CharT*
        data() const
!       { return _M_data(); }
  
        /**
         *  @brief  Return copy of allocator used to construct this string.
        */
        allocator_type
        get_allocator() const
!       { return _M_dataplus; }
  
        /**
         *  @brief  Find position of a C substring.
--- 1242,1255 ----
        */
        const _CharT*
        data() const
!       { return this->_M_data(); }
  
        /**
         *  @brief  Return copy of allocator used to construct this string.
        */
        allocator_type
        get_allocator() const
!       { return this->_M_get_allocator(); }
  
        /**
         *  @brief  Find position of a C substring.
*************** namespace std
*** 1895,1902 ****
        */
        basic_string
        substr(size_type __pos = 0, size_type __n = npos) const
!       { return basic_string(*this,
! 			    _M_check(__pos, "basic_string::substr"), __n); }
  
        /**
         *  @brief  Compare to a string.
--- 1621,1628 ----
        */
        basic_string
        substr(size_type __pos = 0, size_type __n = npos) const
!       { return basic_string(*this, _M_check(__pos, "basic_string::substr"),
! 			    __n); }
  
        /**
         *  @brief  Compare to a string.
*************** namespace std
*** 1916,1922 ****
  	const size_type __osize = __str.size();
  	const size_type __len = std::min(__size, __osize);
  
! 	int __r = traits_type::compare(_M_data(), __str.data(), __len);
  	if (!__r)
  	  __r =  __size - __osize;
  	return __r;
--- 1642,1648 ----
  	const size_type __osize = __str.size();
  	const size_type __len = std::min(__size, __osize);
  
! 	int __r = traits_type::compare(this->_M_data(), __str.data(), __len);
  	if (!__r)
  	  __r =  __size - __osize;
  	return __r;
*************** namespace std
*** 2020,2035 ****
        int
        compare(size_type __pos, size_type __n1, const _CharT* __s,
  	      size_type __n2) const;
!   };
! 
!   template<typename _CharT, typename _Traits, typename _Alloc>
!     inline basic_string<_CharT, _Traits, _Alloc>::
!     basic_string()
! #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
!     : _M_dataplus(_S_empty_rep()._M_refdata(), _Alloc()) { }
! #else
!     : _M_dataplus(_S_construct(size_type(), _CharT(), _Alloc()), _Alloc()) { }
! #endif
  
    // operator+
    /**
--- 1746,1752 ----
        int
        compare(size_type __pos, size_type __n1, const _CharT* __s,
  	      size_type __n2) const;
!     };
  
    // operator+
    /**
*************** namespace std
*** 2066,2072 ****
     *  @return  New string with @a lhs followed by @a rhs.
     */
    template<typename _CharT, typename _Traits, typename _Alloc>
!     basic_string<_CharT,_Traits,_Alloc>
      operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs);
  
    /**
--- 1783,1789 ----
     *  @return  New string with @a lhs followed by @a rhs.
     */
    template<typename _CharT, typename _Traits, typename _Alloc>
!     basic_string<_CharT, _Traits, _Alloc>
      operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs);
  
    /**
*************** namespace std
*** 2412,2418 ****
      basic_istream<wchar_t>&
      getline(basic_istream<wchar_t>& __in, basic_string<wchar_t>& __str,
  	    wchar_t __delim);
! #endif  
  } // namespace std
  
  #endif /* _BASIC_STRING_H */
--- 2129,2138 ----
      basic_istream<wchar_t>&
      getline(basic_istream<wchar_t>& __in, basic_string<wchar_t>& __str,
  	    wchar_t __delim);
! #endif
! 
!   // Undefine.
! #undef ___glibcxx_base_string
  } // namespace std
  
  #endif /* _BASIC_STRING_H */
diff -prN libstdc++-v3-orig/include/bits/basic_string.tcc libstdc++-v3/include/bits/basic_string.tcc
*** libstdc++-v3-orig/include/bits/basic_string.tcc	Mon Dec  6 12:12:30 2004
--- libstdc++-v3/include/bits/basic_string.tcc	Fri Feb 18 11:34:57 2005
***************
*** 1,6 ****
  // Components for manipulating sequences of characters -*- C++ -*-
  
! // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
  // Free Software Foundation, Inc.
  //
  // This file is part of the GNU ISO C++ Library.  This library is free
--- 1,6 ----
  // Components for manipulating sequences of characters -*- C++ -*-
  
! // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
  // Free Software Foundation, Inc.
  //
  // This file is part of the GNU ISO C++ Library.  This library is free
***************
*** 47,258 ****
  
  namespace std
  {
-   template<typename _Type>
-     inline bool
-     __is_null_pointer(_Type* __ptr)
-     { return __ptr == 0; }
- 
-   template<typename _Type>
-     inline bool
-     __is_null_pointer(_Type)
-     { return false; }
- 
-   template<typename _CharT, typename _Traits, typename _Alloc>
-     const typename basic_string<_CharT, _Traits, _Alloc>::size_type
-     basic_string<_CharT, _Traits, _Alloc>::
-     _Rep::_S_max_size = (((npos - sizeof(_Rep_base))/sizeof(_CharT)) - 1) / 4;
- 
-   template<typename _CharT, typename _Traits, typename _Alloc>
-     const _CharT
-     basic_string<_CharT, _Traits, _Alloc>::
-     _Rep::_S_terminal = _CharT();
- 
    template<typename _CharT, typename _Traits, typename _Alloc>
      const typename basic_string<_CharT, _Traits, _Alloc>::size_type
      basic_string<_CharT, _Traits, _Alloc>::npos;
  
-   // Linker sets _S_empty_rep_storage to all 0s (one reference, empty string)
-   // at static init time (before static ctors are run).
-   template<typename _CharT, typename _Traits, typename _Alloc>
-     typename basic_string<_CharT, _Traits, _Alloc>::size_type
-     basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_empty_rep_storage[
-     (sizeof(_Rep_base) + sizeof(_CharT) + sizeof(size_type) - 1) /
-       sizeof(size_type)];
- 
-   // NB: This is the special case for Input Iterators, used in
-   // istreambuf_iterators, etc.
-   // Input Iterators have a cost structure very different from
-   // pointers, calling for a different coding style.
-   template<typename _CharT, typename _Traits, typename _Alloc>
-     template<typename _InIterator>
-       _CharT*
-       basic_string<_CharT, _Traits, _Alloc>::
-       _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a,
- 		   input_iterator_tag)
-       {
- #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
- 	if (__beg == __end && __a == _Alloc())
- 	  return _S_empty_rep()._M_refdata();
- #endif
- 	// Avoid reallocation for common case.
- 	_CharT __buf[128];
- 	size_type __len = 0;
- 	while (__beg != __end && __len < sizeof(__buf) / sizeof(_CharT))
- 	  {
- 	    __buf[__len++] = *__beg;
- 	    ++__beg;
- 	  }
- 	_Rep* __r = _Rep::_S_create(__len, size_type(0), __a);
- 	_M_copy(__r->_M_refdata(), __buf, __len);
- 	try
- 	  {
- 	    while (__beg != __end)
- 	      {
- 		if (__len == __r->_M_capacity)
- 		  {
- 		    // Allocate more space.
- 		    _Rep* __another = _Rep::_S_create(__len + 1, __len, __a);
- 		    _M_copy(__another->_M_refdata(), __r->_M_refdata(), __len);
- 		    __r->_M_destroy(__a);
- 		    __r = __another;
- 		  }
- 		__r->_M_refdata()[__len++] = *__beg;
- 		++__beg;
- 	      }
- 	  }
- 	catch(...)
- 	  {
- 	    __r->_M_destroy(__a);
- 	    __throw_exception_again;
- 	  }
- 	__r->_M_set_length_and_sharable(__len);
- 	return __r->_M_refdata();
-       }
- 
-   template<typename _CharT, typename _Traits, typename _Alloc>
-     template <typename _InIterator>
-       _CharT*
-       basic_string<_CharT, _Traits, _Alloc>::
-       _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a,
- 		   forward_iterator_tag)
-       {
- #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
- 	if (__beg == __end && __a == _Alloc())
- 	  return _S_empty_rep()._M_refdata();
- #endif
- 	// NB: Not required, but considered best practice.
- 	if (__builtin_expect(__is_null_pointer(__beg) && __beg != __end, 0))
- 	  __throw_logic_error(__N("basic_string::_S_construct NULL not valid"));
- 
- 	const size_type __dnew = static_cast<size_type>(std::distance(__beg,
- 								      __end));
- 	// Check for out_of_range and length_error exceptions.
- 	_Rep* __r = _Rep::_S_create(__dnew, size_type(0), __a);
- 	try
- 	  { _S_copy_chars(__r->_M_refdata(), __beg, __end); }
- 	catch(...)
- 	  {
- 	    __r->_M_destroy(__a);
- 	    __throw_exception_again;
- 	  }
- 	__r->_M_set_length_and_sharable(__dnew);
- 	return __r->_M_refdata();
-       }
- 
-   template<typename _CharT, typename _Traits, typename _Alloc>
-     _CharT*
-     basic_string<_CharT, _Traits, _Alloc>::
-     _S_construct(size_type __n, _CharT __c, const _Alloc& __a)
-     {
- #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
-       if (__n == 0 && __a == _Alloc())
- 	return _S_empty_rep()._M_refdata();
- #endif
-       // Check for out_of_range and length_error exceptions.
-       _Rep* __r = _Rep::_S_create(__n, size_type(0), __a);
-       if (__n)
- 	_M_assign(__r->_M_refdata(), __n, __c);
- 
-       __r->_M_set_length_and_sharable(__n);
-       return __r->_M_refdata();
-     }
- 
-   template<typename _CharT, typename _Traits, typename _Alloc>
-     basic_string<_CharT, _Traits, _Alloc>::
-     basic_string(const basic_string& __str)
-     : _M_dataplus(__str._M_rep()->_M_grab(_Alloc(__str.get_allocator()),
- 					  __str.get_allocator()),
- 		  __str.get_allocator())
-     { }
- 
-   template<typename _CharT, typename _Traits, typename _Alloc>
-     basic_string<_CharT, _Traits, _Alloc>::
-     basic_string(const _Alloc& __a)
-     : _M_dataplus(_S_construct(size_type(), _CharT(), __a), __a)
-     { }
- 
-   template<typename _CharT, typename _Traits, typename _Alloc>
-     basic_string<_CharT, _Traits, _Alloc>::
-     basic_string(const basic_string& __str, size_type __pos, size_type __n)
-     : _M_dataplus(_S_construct(__str._M_data()
- 			       + __str._M_check(__pos,
- 						"basic_string::basic_string"),
- 			       __str._M_data() + __str._M_limit(__pos, __n)
- 			       + __pos, _Alloc()), _Alloc())
-     { }
- 
-   template<typename _CharT, typename _Traits, typename _Alloc>
-     basic_string<_CharT, _Traits, _Alloc>::
-     basic_string(const basic_string& __str, size_type __pos,
- 		 size_type __n, const _Alloc& __a)
-     : _M_dataplus(_S_construct(__str._M_data()
- 			       + __str._M_check(__pos,
- 						"basic_string::basic_string"),
- 			       __str._M_data() + __str._M_limit(__pos, __n)
- 			       + __pos, __a), __a)
-     { }
- 
-   // TBD: DPG annotate
-   template<typename _CharT, typename _Traits, typename _Alloc>
-     basic_string<_CharT, _Traits, _Alloc>::
-     basic_string(const _CharT* __s, size_type __n, const _Alloc& __a)
-     : _M_dataplus(_S_construct(__s, __s + __n, __a), __a)
-     { }
- 
-   // TBD: DPG annotate
-   template<typename _CharT, typename _Traits, typename _Alloc>
-     basic_string<_CharT, _Traits, _Alloc>::
-     basic_string(const _CharT* __s, const _Alloc& __a)
-     : _M_dataplus(_S_construct(__s, __s ? __s + traits_type::length(__s) :
- 			       __s + npos, __a), __a)
-     { }
- 
-   template<typename _CharT, typename _Traits, typename _Alloc>
-     basic_string<_CharT, _Traits, _Alloc>::
-     basic_string(size_type __n, _CharT __c, const _Alloc& __a)
-     : _M_dataplus(_S_construct(__n, __c, __a), __a)
-     { }
- 
-   // TBD: DPG annotate
-   template<typename _CharT, typename _Traits, typename _Alloc>
-     template<typename _InputIterator>
-     basic_string<_CharT, _Traits, _Alloc>::
-     basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a)
-     : _M_dataplus(_S_construct(__beg, __end, __a), __a)
-     { }
- 
    template<typename _CharT, typename _Traits, typename _Alloc>
      basic_string<_CharT, _Traits, _Alloc>&
      basic_string<_CharT, _Traits, _Alloc>::
      assign(const basic_string& __str)
      {
!       if (_M_rep() != __str._M_rep())
  	{
- 	  // XXX MT
  	  const allocator_type __a = this->get_allocator();
! 	  _CharT* __tmp = __str._M_rep()->_M_grab(__a, __str.get_allocator());
! 	  _M_rep()->_M_dispose(__a);
! 	  _M_data(__tmp);
  	}
        return *this;
      }
--- 47,65 ----
  
  namespace std
  {
    template<typename _CharT, typename _Traits, typename _Alloc>
      const typename basic_string<_CharT, _Traits, _Alloc>::size_type
      basic_string<_CharT, _Traits, _Alloc>::npos;
  
    template<typename _CharT, typename _Traits, typename _Alloc>
      basic_string<_CharT, _Traits, _Alloc>&
      basic_string<_CharT, _Traits, _Alloc>::
      assign(const basic_string& __str)
      {
!       if (this->_M_rep() != __str._M_rep())
  	{
  	  const allocator_type __a = this->get_allocator();
! 	  this->_M_assign(__str._M_grab(__a, __str.get_allocator()));
  	}
        return *this;
      }
*************** namespace std
*** 264,280 ****
      {
        __glibcxx_requires_string_len(__s, __n);
        _M_check_length(this->size(), __n, "basic_string::assign");
!       if (_M_disjunct(__s) || _M_rep()->_M_is_shared())
  	return _M_replace_safe(size_type(0), this->size(), __s, __n);
        else
  	{
  	  // Work in-place.
! 	  const size_type __pos = __s - _M_data();
  	  if (__pos >= __n)
! 	    _M_copy(_M_data(), __s, __n);
  	  else if (__pos)
! 	    _M_move(_M_data(), __s, __n);
! 	  _M_rep()->_M_set_length_and_sharable(__n);
  	  return *this;
  	}
       }
--- 71,87 ----
      {
        __glibcxx_requires_string_len(__s, __n);
        _M_check_length(this->size(), __n, "basic_string::assign");
!       if (_M_disjunct(__s) || this->_M_rep()->_M_is_shared())
  	return _M_replace_safe(size_type(0), this->size(), __s, __n);
        else
  	{
  	  // Work in-place.
! 	  const size_type __pos = __s - this->_M_data();
  	  if (__pos >= __n)
! 	    this->_S_copy(this->_M_data(), __s, __n);
  	  else if (__pos)
! 	    this->_S_move(this->_M_data(), __s, __n);
! 	  this->_M_rep()->_M_set_length(__n);
  	  return *this;
  	}
       }
*************** namespace std
*** 288,297 ****
  	{
  	  _M_check_length(size_type(0), __n, "basic_string::append");	  
  	  const size_type __len = __n + this->size();
! 	  if (__len > this->capacity() || _M_rep()->_M_is_shared())
  	    this->reserve(__len);
! 	  _M_assign(_M_data() + this->size(), __n, __c);
! 	  _M_rep()->_M_set_length_and_sharable(__len);
  	}
        return *this;
      }
--- 95,104 ----
  	{
  	  _M_check_length(size_type(0), __n, "basic_string::append");	  
  	  const size_type __len = __n + this->size();
! 	  if (__len > this->capacity() || this->_M_rep()->_M_is_shared())
  	    this->reserve(__len);
! 	  this->_S_assign(this->_M_data() + this->size(), __n, __c);
! 	  this->_M_rep()->_M_set_length(__len);
  	}
        return *this;
      }
*************** namespace std
*** 306,324 ****
  	{
  	  _M_check_length(size_type(0), __n, "basic_string::append");
  	  const size_type __len = __n + this->size();
! 	  if (__len > this->capacity() || _M_rep()->_M_is_shared())
  	    {
  	      if (_M_disjunct(__s))
  		this->reserve(__len);
  	      else
  		{
! 		  const size_type __off = __s - _M_data();
  		  this->reserve(__len);
! 		  __s = _M_data() + __off;
  		}
  	    }
! 	  _M_copy(_M_data() + this->size(), __s, __n);
! 	  _M_rep()->_M_set_length_and_sharable(__len);
  	}
        return *this;
      }
--- 113,131 ----
  	{
  	  _M_check_length(size_type(0), __n, "basic_string::append");
  	  const size_type __len = __n + this->size();
! 	  if (__len > this->capacity() || this->_M_rep()->_M_is_shared())
  	    {
  	      if (_M_disjunct(__s))
  		this->reserve(__len);
  	      else
  		{
! 		  const size_type __off = __s - this->_M_data();
  		  this->reserve(__len);
! 		  __s = this->_M_data() + __off;
  		}
  	    }
! 	  this->_S_copy(this->_M_data() + this->size(), __s, __n);
! 	  this->_M_rep()->_M_set_length(__len);
  	}
        return *this;
      }
*************** namespace std
*** 332,341 ****
        if (__size)
  	{
  	  const size_type __len = __size + this->size();
! 	  if (__len > this->capacity() || _M_rep()->_M_is_shared())
  	    this->reserve(__len);
! 	  _M_copy(_M_data() + this->size(), __str._M_data(), __size);
! 	  _M_rep()->_M_set_length_and_sharable(__len);
  	}
        return *this;
      }    
--- 139,149 ----
        if (__size)
  	{
  	  const size_type __len = __size + this->size();
! 	  if (__len > this->capacity() || this->_M_rep()->_M_is_shared())
  	    this->reserve(__len);
! 	  this->_S_copy(this->_M_data() + this->size(), __str._M_data(),
! 			__size);
! 	  this->_M_rep()->_M_set_length(__len);
  	}
        return *this;
      }    
*************** namespace std
*** 350,359 ****
        if (__n)
  	{
  	  const size_type __len = __n + this->size();
! 	  if (__len > this->capacity() || _M_rep()->_M_is_shared())
  	    this->reserve(__len);
! 	  _M_copy(_M_data() + this->size(), __str._M_data() + __pos, __n);
! 	  _M_rep()->_M_set_length_and_sharable(__len);	  
  	}
        return *this;
      }
--- 158,168 ----
        if (__n)
  	{
  	  const size_type __len = __n + this->size();
! 	  if (__len > this->capacity() || this->_M_rep()->_M_is_shared())
  	    this->reserve(__len);
! 	  this->_S_copy(this->_M_data() + this->size(),
! 			__str._M_data() + __pos, __n);
! 	  this->_M_rep()->_M_set_length(__len);	  
  	}
        return *this;
      }
*************** namespace std
*** 366,389 ****
         __glibcxx_requires_string_len(__s, __n);
         _M_check(__pos, "basic_string::insert");
         _M_check_length(size_type(0), __n, "basic_string::insert");
!        if (_M_disjunct(__s) || _M_rep()->_M_is_shared())
           return _M_replace_safe(__pos, size_type(0), __s, __n);
         else
           {
             // Work in-place.
!            const size_type __off = __s - _M_data();
!            _M_mutate(__pos, 0, __n);
!            __s = _M_data() + __off;
!            _CharT* __p = _M_data() + __pos;
             if (__s  + __n <= __p)
!              _M_copy(__p, __s, __n);
             else if (__s >= __p)
!              _M_copy(__p, __s + __n, __n);
             else
               {
  	       const size_type __nleft = __p - __s;
!                _M_copy(__p, __s, __nleft);
!                _M_copy(__p + __nleft, __p + __n, __n - __nleft);
               }
             return *this;
           }
--- 175,198 ----
         __glibcxx_requires_string_len(__s, __n);
         _M_check(__pos, "basic_string::insert");
         _M_check_length(size_type(0), __n, "basic_string::insert");
!        if (_M_disjunct(__s) || this->_M_rep()->_M_is_shared())
           return _M_replace_safe(__pos, size_type(0), __s, __n);
         else
           {
             // Work in-place.
!            const size_type __off = __s - this->_M_data();
!            this->_M_mutate(__pos, 0, __n);
!            __s = this->_M_data() + __off;
!            _CharT* __p = this->_M_data() + __pos;
             if (__s  + __n <= __p)
!              this->_S_copy(__p, __s, __n);
             else if (__s >= __p)
!              this->_S_copy(__p, __s + __n, __n);
             else
               {
  	       const size_type __nleft = __p - __s;
!                this->_S_copy(__p, __s, __nleft);
!                this->_S_copy(__p + __nleft, __p + __n, __n - __nleft);
               }
             return *this;
           }
*************** namespace std
*** 400,415 ****
         __n1 = _M_limit(__pos, __n1);
         _M_check_length(__n1, __n2, "basic_string::replace");
         bool __left;
!        if (_M_disjunct(__s) || _M_rep()->_M_is_shared())
           return _M_replace_safe(__pos, __n1, __s, __n2);
!        else if ((__left = __s + __n2 <= _M_data() + __pos)
! 		|| _M_data() + __pos + __n1 <= __s)
  	 {
  	   // Work in-place: non-overlapping case.
! 	   size_type __off = __s - _M_data();
  	   __left ? __off : (__off += __n2 - __n1);
! 	   _M_mutate(__pos, __n1, __n2);
! 	   _M_copy(_M_data() + __pos, _M_data() + __off, __n2);
  	   return *this;
  	 }
         else
--- 209,225 ----
         __n1 = _M_limit(__pos, __n1);
         _M_check_length(__n1, __n2, "basic_string::replace");
         bool __left;
!        if (_M_disjunct(__s) || this->_M_rep()->_M_is_shared())
           return _M_replace_safe(__pos, __n1, __s, __n2);
!        else if ((__left = __s + __n2 <= this->_M_data() + __pos)
! 		|| this->_M_data() + __pos + __n1 <= __s)
  	 {
  	   // Work in-place: non-overlapping case.
! 	   size_type __off = __s - this->_M_data();
  	   __left ? __off : (__off += __n2 - __n1);
! 	   this->_M_mutate(__pos, __n1, __n2);
! 	   this->_S_copy(this->_M_data() + __pos,
! 			 this->_M_data() + __off, __n2);
  	   return *this;
  	 }
         else
*************** namespace std
*** 422,500 ****
  
    template<typename _CharT, typename _Traits, typename _Alloc>
      void
-     basic_string<_CharT, _Traits, _Alloc>::_Rep::
-     _M_destroy(const _Alloc& __a) throw ()
-     {
- #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
-       if (this == &_S_empty_rep())
- 	return;
- #endif
-       const size_type __size = sizeof(_Rep_base) +
- 	                       (this->_M_capacity + 1) * sizeof(_CharT);
-       _Raw_bytes_alloc(__a).deallocate(reinterpret_cast<char*>(this), __size);
-     }
- 
-   template<typename _CharT, typename _Traits, typename _Alloc>
-     void
-     basic_string<_CharT, _Traits, _Alloc>::
-     _M_leak_hard()
-     {
- #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
-       if (_M_rep() == &_S_empty_rep())
- 	return;
- #endif
-       if (_M_rep()->_M_is_shared())
- 	_M_mutate(0, 0, 0);
-       _M_rep()->_M_set_leaked();
-     }
- 
-   template<typename _CharT, typename _Traits, typename _Alloc>
-     void
-     basic_string<_CharT, _Traits, _Alloc>::
-     _M_mutate(size_type __pos, size_type __len1, size_type __len2)
-     {
-       const size_type __old_size = this->size();
-       const size_type __new_size = __old_size + __len2 - __len1;
-       const size_type __how_much = __old_size - __pos - __len1;
- 
-       if (__new_size > this->capacity() || _M_rep()->_M_is_shared())
- 	{
- 	  // Must reallocate.
- 	  const allocator_type __a = get_allocator();
- 	  _Rep* __r = _Rep::_S_create(__new_size, this->capacity(), __a);
- 
- 	  if (__pos)
- 	    _M_copy(__r->_M_refdata(), _M_data(), __pos);
- 	  if (__how_much)
- 	    _M_copy(__r->_M_refdata() + __pos + __len2,
- 		    _M_data() + __pos + __len1, __how_much);
- 
- 	  _M_rep()->_M_dispose(__a);
- 	  _M_data(__r->_M_refdata());
- 	}
-       else if (__how_much && __len1 != __len2)
- 	{
- 	  // Work in-place.
- 	  _M_move(_M_data() + __pos + __len2,
- 		  _M_data() + __pos + __len1, __how_much);
- 	}
-       _M_rep()->_M_set_length_and_sharable(__new_size);
-     }
- 
-   template<typename _CharT, typename _Traits, typename _Alloc>
-     void
      basic_string<_CharT, _Traits, _Alloc>::
      reserve(size_type __res)
      {
!       if (__res != this->capacity() || _M_rep()->_M_is_shared())
          {
  	  // Make sure we don't shrink below the current size
  	  if (__res < this->size())
  	    __res = this->size();
! 	  const allocator_type __a = get_allocator();
! 	  _CharT* __tmp = _M_rep()->_M_clone(__a, __res - this->size());
! 	  _M_rep()->_M_dispose(__a);
! 	  _M_data(__tmp);
          }
      }
  
--- 232,246 ----
  
    template<typename _CharT, typename _Traits, typename _Alloc>
      void
      basic_string<_CharT, _Traits, _Alloc>::
      reserve(size_type __res)
      {
!       if (__res != this->capacity() || this->_M_rep()->_M_is_shared())
          {
  	  // Make sure we don't shrink below the current size
  	  if (__res < this->size())
  	    __res = this->size();
! 	  this->_M_reserve(__res);
          }
      }
  
*************** namespace std
*** 503,518 ****
      basic_string<_CharT, _Traits, _Alloc>::
      swap(basic_string& __s)
      {
!       if (_M_rep()->_M_is_leaked())
! 	_M_rep()->_M_set_sharable();
        if (__s._M_rep()->_M_is_leaked())
  	__s._M_rep()->_M_set_sharable();
        if (this->get_allocator() == __s.get_allocator())
! 	{
! 	  _CharT* __tmp = _M_data();
! 	  _M_data(__s._M_data());
! 	  __s._M_data(__tmp);
! 	}
        // The code below can usually be optimized away.
        else
  	{
--- 249,260 ----
      basic_string<_CharT, _Traits, _Alloc>::
      swap(basic_string& __s)
      {
!       if (this->_M_rep()->_M_is_leaked())
! 	this->_M_rep()->_M_set_sharable();
        if (__s._M_rep()->_M_is_leaked())
  	__s._M_rep()->_M_set_sharable();
        if (this->get_allocator() == __s.get_allocator())
! 	this->_M_swap(__s._M_data_pointer());
        // The code below can usually be optimized away.
        else
  	{
*************** namespace std
*** 526,617 ****
      }
  
    template<typename _CharT, typename _Traits, typename _Alloc>
-     typename basic_string<_CharT, _Traits, _Alloc>::_Rep*
-     basic_string<_CharT, _Traits, _Alloc>::_Rep::
-     _S_create(size_type __capacity, size_type __old_capacity,
- 	      const _Alloc& __alloc)
-     {
-       // _GLIBCXX_RESOLVE_LIB_DEFECTS
-       // 83.  String::npos vs. string::max_size()
-       if (__capacity > _S_max_size)
- 	__throw_length_error(__N("basic_string::_S_create"));
- 
-       // The standard places no restriction on allocating more memory
-       // than is strictly needed within this layer at the moment or as
-       // requested by an explicit application call to reserve().
- 
-       // Many malloc implementations perform quite poorly when an
-       // application attempts to allocate memory in a stepwise fashion
-       // growing each allocation size by only 1 char.  Additionally,
-       // it makes little sense to allocate less linear memory than the
-       // natural blocking size of the malloc implementation.
-       // Unfortunately, we would need a somewhat low-level calculation
-       // with tuned parameters to get this perfect for any particular
-       // malloc implementation.  Fortunately, generalizations about
-       // common features seen among implementations seems to suffice.
- 
-       // __pagesize need not match the actual VM page size for good
-       // results in practice, thus we pick a common value on the low
-       // side.  __malloc_header_size is an estimate of the amount of
-       // overhead per memory allocation (in practice seen N * sizeof
-       // (void*) where N is 0, 2 or 4).  According to folklore,
-       // picking this value on the high side is better than
-       // low-balling it (especially when this algorithm is used with
-       // malloc implementations that allocate memory blocks rounded up
-       // to a size which is a power of 2).
-       const size_type __pagesize = 4096;
-       const size_type __malloc_header_size = 4 * sizeof(void*);
- 
-       // The below implements an exponential growth policy, necessary to
-       // meet amortized linear time requirements of the library: see
-       // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html.
-       // It's active for allocations requiring an amount of memory above
-       // system pagesize. This is consistent with the requirements of the
-       // standard: http://gcc.gnu.org/ml/libstdc++/2001-07/msg00130.html
-       if (__capacity > __old_capacity && __capacity < 2 * __old_capacity)
- 	__capacity = 2 * __old_capacity;
- 
-       // NB: Need an array of char_type[__capacity], plus a terminating
-       // null char_type() element, plus enough for the _Rep data structure.
-       // Whew. Seemingly so needy, yet so elemental.
-       size_type __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
- 
-       const size_type __adj_size = __size + __malloc_header_size;
-       if (__adj_size > __pagesize && __capacity > __old_capacity)
- 	{
- 	  const size_type __extra = __pagesize - __adj_size % __pagesize;
- 	  __capacity += __extra / sizeof(_CharT);
- 	  // Never allocate a string bigger than _S_max_size.
- 	  if (__capacity > _S_max_size)
- 	    __capacity = _S_max_size;
- 	  __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
- 	}
- 
-       // NB: Might throw, but no worries about a leak, mate: _Rep()
-       // does not throw.
-       void* __place = _Raw_bytes_alloc(__alloc).allocate(__size);
-       _Rep *__p = new (__place) _Rep;
-       __p->_M_capacity = __capacity;
-       return __p;
-     }
- 
-   template<typename _CharT, typename _Traits, typename _Alloc>
-     _CharT*
-     basic_string<_CharT, _Traits, _Alloc>::_Rep::
-     _M_clone(const _Alloc& __alloc, size_type __res)
-     {
-       // Requested capacity of the clone.
-       const size_type __requested_cap = this->_M_length + __res;
-       _Rep* __r = _Rep::_S_create(__requested_cap, this->_M_capacity,
- 				  __alloc);
-       if (this->_M_length)
- 	_M_copy(__r->_M_refdata(), _M_refdata(), this->_M_length);
- 
-       __r->_M_set_length_and_sharable(this->_M_length);
-       return __r->_M_refdata();
-     }
- 
-   template<typename _CharT, typename _Traits, typename _Alloc>
      void
      basic_string<_CharT, _Traits, _Alloc>::
      resize(size_type __n, _CharT __c)
--- 268,273 ----
*************** namespace std
*** 646,654 ****
  		   _CharT __c)
      {
        _M_check_length(__n1, __n2, "basic_string::_M_replace_aux");
!       _M_mutate(__pos1, __n1, __n2);
        if (__n2)
! 	_M_assign(_M_data() + __pos1, __n2, __c);
        return *this;
      }
  
--- 302,310 ----
  		   _CharT __c)
      {
        _M_check_length(__n1, __n2, "basic_string::_M_replace_aux");
!       this->_M_mutate(__pos1, __n1, __n2);
        if (__n2)
! 	this->_S_assign(this->_M_data() + __pos1, __n2, __c);
        return *this;
      }
  
*************** namespace std
*** 658,666 ****
      _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s,
  		    size_type __n2)
      {
!       _M_mutate(__pos1, __n1, __n2);
        if (__n2)
! 	_M_copy(_M_data() + __pos1, __s, __n2);
        return *this;
      }
     
--- 314,322 ----
      _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s,
  		    size_type __n2)
      {
!       this->_M_mutate(__pos1, __n1, __n2);
        if (__n2)
! 	this->_S_copy(this->_M_data() + __pos1, __s, __n2);
        return *this;
      }
     
*************** namespace std
*** 703,709 ****
        __n = _M_limit(__pos, __n);
        __glibcxx_requires_string_len(__s, __n);
        if (__n)
! 	_M_copy(__s, _M_data() + __pos, __n);
        // 21.3.5.7 par 3: do not append null.  (good.)
        return __n;
      }
--- 359,365 ----
        __n = _M_limit(__pos, __n);
        __glibcxx_requires_string_len(__s, __n);
        if (__n)
! 	this->_S_copy(__s, this->_M_data() + __pos, __n);
        // 21.3.5.7 par 3: do not append null.  (good.)
        return __n;
      }
*************** namespace std
*** 718,724 ****
        const size_type __size = this->size();
        if (__pos + __n <= __size)
  	{
! 	  const _CharT* __data = _M_data();
  	  const _CharT* __p = std::search(__data + __pos, __data + __size,
  					  __s, __s + __n, traits_type::eq);
  	  if (__p != __data + __size || __n == 0)
--- 374,380 ----
        const size_type __size = this->size();
        if (__pos + __n <= __size)
  	{
! 	  const _CharT* __data = this->_M_data();
  	  const _CharT* __p = std::search(__data + __pos, __data + __size,
  					  __s, __s + __n, traits_type::eq);
  	  if (__p != __data + __size || __n == 0)
*************** namespace std
*** 736,742 ****
        const size_type __size = this->size();
        if (__pos < __size)
  	{
! 	  const _CharT* __data = _M_data();
  	  const size_type __n = __size - __pos;
  	  const _CharT* __p = traits_type::find(__data + __pos, __n, __c);
  	  if (__p)
--- 392,398 ----
        const size_type __size = this->size();
        if (__pos < __size)
  	{
! 	  const _CharT* __data = this->_M_data();
  	  const size_type __n = __size - __pos;
  	  const _CharT* __p = traits_type::find(__data + __pos, __n, __c);
  	  if (__p)
*************** namespace std
*** 755,761 ****
        if (__n <= __size)
  	{
  	  __pos = std::min(size_type(__size - __n), __pos);
! 	  const _CharT* __data = _M_data();
  	  do
  	    {
  	      if (traits_type::compare(__data + __pos, __s, __n) == 0)
--- 411,417 ----
        if (__n <= __size)
  	{
  	  __pos = std::min(size_type(__size - __n), __pos);
! 	  const _CharT* __data = this->_M_data();
  	  do
  	    {
  	      if (traits_type::compare(__data + __pos, __s, __n) == 0)
*************** namespace std
*** 777,783 ****
  	  if (--__size > __pos)
  	    __size = __pos;
  	  for (++__size; __size-- > 0; )
! 	    if (traits_type::eq(_M_data()[__size], __c))
  	      return __size;
  	}
        return npos;
--- 433,439 ----
  	  if (--__size > __pos)
  	    __size = __pos;
  	  for (++__size; __size-- > 0; )
! 	    if (traits_type::eq(this->_M_data()[__size], __c))
  	      return __size;
  	}
        return npos;
*************** namespace std
*** 791,797 ****
        __glibcxx_requires_string_len(__s, __n);
        for (; __n && __pos < this->size(); ++__pos)
  	{
! 	  const _CharT* __p = traits_type::find(__s, __n, _M_data()[__pos]);
  	  if (__p)
  	    return __pos;
  	}
--- 447,454 ----
        __glibcxx_requires_string_len(__s, __n);
        for (; __n && __pos < this->size(); ++__pos)
  	{
! 	  const _CharT* __p = traits_type::find(__s, __n,
! 						this->_M_data()[__pos]);
  	  if (__p)
  	    return __pos;
  	}
*************** namespace std
*** 811,817 ****
  	    __size = __pos;
  	  do
  	    {
! 	      if (traits_type::find(__s, __n, _M_data()[__size]))
  		return __size;
  	    }
  	  while (__size-- != 0);
--- 468,474 ----
  	    __size = __pos;
  	  do
  	    {
! 	      if (traits_type::find(__s, __n, this->_M_data()[__size]))
  		return __size;
  	    }
  	  while (__size-- != 0);
*************** namespace std
*** 826,832 ****
      {
        __glibcxx_requires_string_len(__s, __n);
        for (; __pos < this->size(); ++__pos)
! 	if (!traits_type::find(__s, __n, _M_data()[__pos]))
  	  return __pos;
        return npos;
      }
--- 483,489 ----
      {
        __glibcxx_requires_string_len(__s, __n);
        for (; __pos < this->size(); ++__pos)
! 	if (!traits_type::find(__s, __n, this->_M_data()[__pos]))
  	  return __pos;
        return npos;
      }
*************** namespace std
*** 837,843 ****
      find_first_not_of(_CharT __c, size_type __pos) const
      {
        for (; __pos < this->size(); ++__pos)
! 	if (!traits_type::eq(_M_data()[__pos], __c))
  	  return __pos;
        return npos;
      }
--- 494,500 ----
      find_first_not_of(_CharT __c, size_type __pos) const
      {
        for (; __pos < this->size(); ++__pos)
! 	if (!traits_type::eq(this->_M_data()[__pos], __c))
  	  return __pos;
        return npos;
      }
*************** namespace std
*** 855,861 ****
  	    __size = __pos;
  	  do
  	    {
! 	      if (!traits_type::find(__s, __n, _M_data()[__size]))
  		return __size;
  	    }
  	  while (__size--);
--- 512,518 ----
  	    __size = __pos;
  	  do
  	    {
! 	      if (!traits_type::find(__s, __n, this->_M_data()[__size]))
  		return __size;
  	    }
  	  while (__size--);
*************** namespace std
*** 875,881 ****
  	    __size = __pos;
  	  do
  	    {
! 	      if (!traits_type::eq(_M_data()[__size], __c))
  		return __size;
  	    }
  	  while (__size--);
--- 532,538 ----
  	    __size = __pos;
  	  do
  	    {
! 	      if (!traits_type::eq(this->_M_data()[__size], __c))
  		return __size;
  	    }
  	  while (__size--);
*************** namespace std
*** 892,898 ****
        __n = _M_limit(__pos, __n);
        const size_type __osize = __str.size();
        const size_type __len = std::min(__n, __osize);
!       int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len);
        if (!__r)
  	__r = __n - __osize;
        return __r;
--- 549,556 ----
        __n = _M_limit(__pos, __n);
        const size_type __osize = __str.size();
        const size_type __len = std::min(__n, __osize);
!       int __r = traits_type::compare(this->_M_data() + __pos,
! 				     __str.data(), __len);
        if (!__r)
  	__r = __n - __osize;
        return __r;
*************** namespace std
*** 909,915 ****
        __n1 = _M_limit(__pos1, __n1);
        __n2 = __str._M_limit(__pos2, __n2);
        const size_type __len = std::min(__n1, __n2);
!       int __r = traits_type::compare(_M_data() + __pos1,
  				     __str.data() + __pos2, __len);
        if (!__r)
  	__r = __n1 - __n2;
--- 567,573 ----
        __n1 = _M_limit(__pos1, __n1);
        __n2 = __str._M_limit(__pos2, __n2);
        const size_type __len = std::min(__n1, __n2);
!       int __r = traits_type::compare(this->_M_data() + __pos1,
  				     __str.data() + __pos2, __len);
        if (!__r)
  	__r = __n1 - __n2;
*************** namespace std
*** 925,931 ****
        const size_type __size = this->size();
        const size_type __osize = traits_type::length(__s);
        const size_type __len = std::min(__size, __osize);
!       int __r = traits_type::compare(_M_data(), __s, __len);
        if (!__r)
  	__r = __size - __osize;
        return __r;
--- 583,589 ----
        const size_type __size = this->size();
        const size_type __osize = traits_type::length(__s);
        const size_type __len = std::min(__size, __osize);
!       int __r = traits_type::compare(this->_M_data(), __s, __len);
        if (!__r)
  	__r = __size - __osize;
        return __r;
*************** namespace std
*** 941,947 ****
        __n1 = _M_limit(__pos, __n1);
        const size_type __osize = traits_type::length(__s);
        const size_type __len = std::min(__n1, __osize);
!       int __r = traits_type::compare(_M_data() + __pos, __s, __len);
        if (!__r)
  	__r = __n1 - __osize;
        return __r;
--- 599,605 ----
        __n1 = _M_limit(__pos, __n1);
        const size_type __osize = traits_type::length(__s);
        const size_type __len = std::min(__n1, __osize);
!       int __r = traits_type::compare(this->_M_data() + __pos, __s, __len);
        if (!__r)
  	__r = __n1 - __osize;
        return __r;
*************** namespace std
*** 957,963 ****
        _M_check(__pos, "basic_string::compare");
        __n1 = _M_limit(__pos, __n1);
        const size_type __len = std::min(__n1, __n2);
!       int __r = traits_type::compare(_M_data() + __pos, __s, __len);
        if (!__r)
  	__r = __n1 - __n2;
        return __r;
--- 615,621 ----
        _M_check(__pos, "basic_string::compare");
        __n1 = _M_limit(__pos, __n1);
        const size_type __len = std::min(__n1, __n2);
!       int __r = traits_type::compare(this->_M_data() + __pos, __s, __len);
        if (!__r)
  	__r = __n1 - __n2;
        return __r;
diff -prN libstdc++-v3-orig/include/ext/rc_string.h libstdc++-v3/include/ext/rc_string.h
*** libstdc++-v3-orig/include/ext/rc_string.h	Thu Jan  1 01:00:00 1970
--- libstdc++-v3/include/ext/rc_string.h	Fri Feb 18 16:03:48 2005
***************
*** 0 ****
--- 1,633 ----
+ // Reference-counted string -*- C++ -*-
+ 
+ // Copyright (C) 2005 Free Software Foundation, Inc.
+ //
+ // This file is part of the GNU ISO C++ Library.  This library is free
+ // software; you can redistribute it and/or modify it under the
+ // terms of the GNU General Public License as published by the
+ // Free Software Foundation; either version 2, or (at your option)
+ // any later version.
+ 
+ // This library is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ // GNU General Public License for more details.
+ 
+ // You should have received a copy of the GNU General Public License along
+ // with this library; see the file COPYING.  If not, write to the Free
+ // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ // USA.
+ 
+ // As a special exception, you may use this file as part of a free software
+ // library without restriction.  Specifically, if other files instantiate
+ // templates or use macros or inline functions from this file, or you compile
+ // this file and link it with other files to produce an executable, this
+ // file does not by itself cause the resulting executable to be covered by
+ // the GNU General Public License.  This exception does not however
+ // invalidate any other reasons why the executable file might be covered by
+ // the GNU General Public License.
+ 
+ /** @file ext/rc_string.h
+  *  This file is a GNU extension to the Standard C++ Library.
+  */
+ 
+ #ifndef _RC_STRING_H
+ #define _RC_STRING_H 1
+ 
+ #include <bits/functexcept.h>
+ #include <bits/atomicity.h>
+ #include <bits/stringfwd.h>
+ #include <cstddef>
+ #include <bits/stl_iterator_base_types.h>
+ #include <bits/stl_iterator.h>
+ #include <bits/cpp_type_traits.h>
+ #include <algorithm>
+ 
+ #include <ext/string_util.h>
+ 
+ namespace __gnu_cxx
+ {
+   /**
+    *  @if maint
+    *  Documentation?  What's that?
+    *  Nathan Myers <ncm@cantrip.org>.
+    *
+    *  A string looks like this:
+    *
+    *  @code
+    *                                        [_Rep]
+    *                                        _M_length
+    *   [basic_string<char_type>]            _M_capacity
+    *   _M_dataplus                          _M_refcount
+    *   _M_p ---------------->               unnamed array of char_type
+    *  @endcode
+    *
+    *  Where the _M_p points to the first character in the string, and
+    *  you cast it to a pointer-to-_Rep and subtract 1 to get a
+    *  pointer to the header.
+    *
+    *  This approach has the enormous advantage that a string object
+    *  requires only one allocation.  All the ugliness is confined
+    *  within a single pair of inline functions, which each compile to
+    *  a single "add" instruction: _Rep::_M_refdata(), and
+    *  __rc_string::_M_rep(); and the allocation function which gets a
+    *  block of raw bytes and with room enough and constructs a _Rep
+    *  object at the front.
+    *
+    *  The reason you want _M_data pointing to the character array and
+    *  not the _Rep is so that the debugger can see the string
+    *  contents. (Probably we should add a non-inline member to get
+    *  the _Rep for the debugger to use, so users can check the actual
+    *  string length.)
+    *
+    *  Note that the _Rep object is a POD so that you can have a
+    *  static "empty string" _Rep object already "constructed" before
+    *  static constructors have run.  The reference-count encoding is
+    *  chosen so that a 0 indicates one reference, so you never try to
+    *  destroy the empty-string _Rep object.
+    *
+    *  All but the last paragraph is considered pretty conventional
+    *  for a C++ string implementation.
+    *  @endif
+   */
+  template<typename _CharT, typename _Traits, typename _Alloc>
+     class __rc_string
+     : public __string_utility<_CharT, _Traits, _Alloc>
+     {
+     public:
+       using __string_utility<_CharT, _Traits, _Alloc>::_S_assign;
+       using __string_utility<_CharT, _Traits, _Alloc>::_S_copy;
+       using __string_utility<_CharT, _Traits, _Alloc>::_S_move;
+ 
+       // Types:
+       typedef _Traits					    traits_type;
+       typedef typename _Traits::char_type		    value_type;
+       typedef _Alloc					    allocator_type;
+       typedef typename _Alloc::size_type		    size_type;
+ 
+       // The maximum number of individual char_type elements of an
+       // individual string is determined by _S_max_size. This is the
+       // value that will be returned by max_size().  (Whereas npos
+       // is the maximum number of bytes the allocator can allocate.)
+       // If one was to divvy up the theoretical largest size string,
+       // with a terminating character and m _CharT elements, it'd
+       // look like this:
+       // npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT)
+       // Solving for m:
+       // m = ((npos - sizeof(_Rep))/sizeof(CharT)) - 1
+       // In addition, this implementation quarters this amount.
+       static const size_type	_S_max_size;
+       static const _CharT	_S_terminal;      
+ 
+     private:
+       // _Rep: string representation
+       //   Invariants:
+       //   1. String really contains _M_length + 1 characters: due to 21.3.4
+       //      must be kept null-terminated.
+       //   2. _M_capacity >= _M_length
+       //      Allocated memory is always (_M_capacity + 1) * sizeof(_CharT).
+       //   3. _M_refcount has three states:
+       //      -1: leaked, one reference, no ref-copies allowed, non-const.
+       //       0: one reference, non-const.
+       //     n>0: n + 1 references, operations require a lock, const.
+       //   4. All fields==0 is an empty string, given the extra storage
+       //      beyond-the-end for a null terminator; thus, the shared
+       //      empty string representation needs no constructor.
+       struct _Rep
+       {
+ 	size_type		_M_length;
+ 	size_type		_M_capacity;
+ 	_Atomic_word		_M_refcount;
+ 
+ 	typedef typename _Alloc::template rebind<char>::other _Raw_bytes_alloc;
+ 
+         bool
+ 	_M_is_leaked() const
+         { return _M_refcount < 0; }
+ 
+         bool
+ 	_M_is_shared() const
+         { return _M_refcount > 0; }
+ 
+         void
+ 	_M_set_leaked()
+         { _M_refcount = -1; }
+ 
+         void
+ 	_M_set_sharable()
+         { _M_refcount = 0; }
+ 
+ 	_CharT*
+ 	_M_refdata()
+ 	{ return reinterpret_cast<_CharT*>(this + 1); }
+ 
+ 	void
+ 	_M_set_length(size_type __n)
+ 	{ 
+ 	  _M_set_sharable();  // One reference.
+ 	  _M_length = __n;
+ 	  _M_refdata()[__n] = _S_terminal; // grrr. (per 21.3.4)
+ 	  // You cannot leave those LWG people alone for a second.
+ 	}
+ 
+ 	// Create & Destroy
+ 	static _Rep*
+ 	_S_create(size_type, size_type, const _Alloc&);
+ 
+ 	void
+ 	_M_destroy(const _Alloc&) throw();
+ 
+ 	_CharT*
+ 	_M_clone(const _Alloc&, size_type __res = 0);
+       };
+ 
+       struct _Rep_empty : _Rep
+       {
+ 	_CharT                  _M_terminal;
+       };
+ 
+       // Use empty-base optimization: http://www.cantrip.org/emptyopt.html
+       struct _Alloc_hider : _Alloc
+       {
+ 	_Alloc_hider(_CharT* __dat, const _Alloc& __a)
+ 	: _Alloc(__a), _M_p(__dat) { }
+ 
+ 	_CharT* _M_p; // The actual data.
+       };
+ 
+       // Data Members (private):
+       mutable _Alloc_hider	_M_dataplus;
+ 
+     public:
+       _CharT*
+       _M_data() const
+       { return _M_dataplus._M_p; }
+ 
+       _CharT**
+       _M_data_pointer() const
+       { return &_M_dataplus._M_p; }
+ 	
+       _Rep*
+       _M_rep() const
+       { return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); }
+ 
+       void
+       _M_dispose(const _Alloc& __a)
+       {
+ #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
+ 	if (__builtin_expect(_M_rep() != &_S_empty_rep(), false))
+ #endif
+ 	  if (__exchange_and_add(&_M_rep()->_M_refcount, -1) <= 0)
+ 	    _M_rep()->_M_destroy(__a);
+       }  // XXX MT
+ 
+       _CharT*
+       _M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2) const
+       {
+ 	return (!_M_rep()->_M_is_leaked() && __alloc1 == __alloc2)
+ 	        ? _M_refcopy() : _M_rep()->_M_clone(__alloc1);
+       }
+ 
+       void
+       _M_leak()    // for use in begin() & non-const op[]
+       {
+ 	if (!_M_rep()->_M_is_leaked())
+ 	  _M_leak_hard();
+       }
+ 
+       __rc_string()
+ #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
+       : _M_dataplus(_S_empty_rep()._M_refdata(), _Alloc()) { }
+ #else
+       : _M_dataplus(_S_construct(size_type(), _CharT(), _Alloc()), _Alloc()) { }
+ #endif
+       __rc_string(const _Alloc& __a);
+ 
+       __rc_string(_CharT* __ptr, const _Alloc& __a);
+ 
+       __rc_string(size_type __n, _CharT __c, const _Alloc& __a);
+ 
+       template<typename _InputIterator>
+         __rc_string(_InputIterator __beg, _InputIterator __end,
+ 		    const _Alloc& __a);
+ 
+       ~__rc_string()
+       { _M_dispose(_M_get_allocator()); }      
+ 
+       allocator_type
+       _M_get_allocator() const
+       { return _M_dataplus; }
+ 
+       void
+       _M_assign(_CharT* __ptr)
+       {
+ 	_M_dispose(_M_get_allocator());
+ 	_M_dataplus._M_p = __ptr;
+       }
+ 
+       void
+       _M_swap(_CharT** __ptr)
+       {
+ 	_CharT* __tmp = _M_data();
+ 	_M_dataplus._M_p = *__ptr;
+ 	*__ptr = __tmp;
+       }
+ 
+       void
+       _M_reserve(size_type __res);
+ 
+       void
+       _M_mutate(size_type __pos, size_type __len1, size_type __len2);
+ 	
+     private:
+       static _Rep_empty&
+       _S_empty_rep()
+       {
+ 	static _Rep_empty _Empty_rep;
+ 	return _Empty_rep;
+       }
+ 
+       _CharT*
+       _M_refcopy() const throw()
+       {
+ #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
+ 	if (__builtin_expect(_M_rep() != &_S_empty_rep(), false))
+ #endif
+ 	  __atomic_add(&_M_rep()->_M_refcount, 1);
+ 	return _M_data();
+       }  // XXX MT
+ 
+       void
+       _M_leak_hard();
+ 
+       // _S_construct_aux is used to implement the 21.3.1 para 15 which
+       // requires special behaviour if _InIter is an integral type
+       template<class _InIterator>
+         static _CharT*
+         _S_construct_aux(_InIterator __beg, _InIterator __end,
+ 			 const _Alloc& __a, __false_type)
+ 	{
+           typedef typename iterator_traits<_InIterator>::iterator_category _Tag;
+           return _S_construct(__beg, __end, __a, _Tag());
+ 	}
+ 
+       template<class _InIterator>
+         static _CharT*
+         _S_construct_aux(_InIterator __beg, _InIterator __end,
+ 			 const _Alloc& __a, __true_type)
+ 	{ return _S_construct(static_cast<size_type>(__beg),
+ 			      static_cast<value_type>(__end), __a); }
+ 
+       template<class _InIterator>
+         static _CharT*
+         _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a)
+ 	{
+ 	  typedef typename std::__is_integer<_InIterator>::__type _Integral;
+ 	  return _S_construct_aux(__beg, __end, __a, _Integral());
+         }
+ 
+       // For Input Iterators, used in istreambuf_iterators, etc.
+       template<class _InIterator>
+         static _CharT*
+          _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a,
+ 		      std::input_iterator_tag);
+       
+       // For forward_iterators up to random_access_iterators, used for
+       // string::iterator, _CharT*, etc.
+       template<class _FwdIterator>
+         static _CharT*
+         _S_construct(_FwdIterator __beg, _FwdIterator __end, const _Alloc& __a,
+ 		     std::forward_iterator_tag);
+ 
+       static _CharT*
+       _S_construct(size_type __req, _CharT __c, const _Alloc& __a);
+     };
+ 
+   template<typename _CharT, typename _Traits, typename _Alloc>
+     const typename __rc_string<_CharT, _Traits, _Alloc>::size_type
+     __rc_string<_CharT, _Traits, _Alloc>::
+     _S_max_size = (((static_cast<size_type>(-1) - sizeof(_Rep))
+ 		    / sizeof(_CharT)) - 1) / 4;
+ 
+   template<typename _CharT, typename _Traits, typename _Alloc>
+     const _CharT
+     __rc_string<_CharT, _Traits, _Alloc>::_S_terminal = _CharT();
+ 
+     template<typename _CharT, typename _Traits, typename _Alloc>
+     typename __rc_string<_CharT, _Traits, _Alloc>::_Rep*
+     __rc_string<_CharT, _Traits, _Alloc>::_Rep::
+     _S_create(size_type __capacity, size_type __old_capacity,
+ 	      const _Alloc& __alloc)
+     {
+       // _GLIBCXX_RESOLVE_LIB_DEFECTS
+       // 83.  String::npos vs. string::max_size()
+       if (__capacity > _S_max_size)
+ 	std::__throw_length_error(__N("__rc_string::_Rep::_S_create"));
+ 
+       // The standard places no restriction on allocating more memory
+       // than is strictly needed within this layer at the moment or as
+       // requested by an explicit application call to reserve().
+ 
+       // Many malloc implementations perform quite poorly when an
+       // application attempts to allocate memory in a stepwise fashion
+       // growing each allocation size by only 1 char.  Additionally,
+       // it makes little sense to allocate less linear memory than the
+       // natural blocking size of the malloc implementation.
+       // Unfortunately, we would need a somewhat low-level calculation
+       // with tuned parameters to get this perfect for any particular
+       // malloc implementation.  Fortunately, generalizations about
+       // common features seen among implementations seems to suffice.
+ 
+       // __pagesize need not match the actual VM page size for good
+       // results in practice, thus we pick a common value on the low
+       // side.  __malloc_header_size is an estimate of the amount of
+       // overhead per memory allocation (in practice seen N * sizeof
+       // (void*) where N is 0, 2 or 4).  According to folklore,
+       // picking this value on the high side is better than
+       // low-balling it (especially when this algorithm is used with
+       // malloc implementations that allocate memory blocks rounded up
+       // to a size which is a power of 2).
+       const size_type __pagesize = 4096;
+       const size_type __malloc_header_size = 4 * sizeof(void*);
+ 
+       // The below implements an exponential growth policy, necessary to
+       // meet amortized linear time requirements of the library: see
+       // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html.
+       // It's active for allocations requiring an amount of memory above
+       // system pagesize. This is consistent with the requirements of the
+       // standard: http://gcc.gnu.org/ml/libstdc++/2001-07/msg00130.html
+       if (__capacity > __old_capacity && __capacity < 2 * __old_capacity)
+ 	__capacity = 2 * __old_capacity;
+ 
+       // NB: Need an array of char_type[__capacity], plus a terminating
+       // null char_type() element, plus enough for the _Rep data structure.
+       // Whew. Seemingly so needy, yet so elemental.
+       size_type __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
+ 
+       const size_type __adj_size = __size + __malloc_header_size;
+       if (__adj_size > __pagesize && __capacity > __old_capacity)
+ 	{
+ 	  const size_type __extra = __pagesize - __adj_size % __pagesize;
+ 	  __capacity += __extra / sizeof(_CharT);
+ 	  // Never allocate a string bigger than _S_max_size.
+ 	  if (__capacity > _S_max_size)
+ 	    __capacity = _S_max_size;
+ 	  __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
+ 	}
+ 
+       // NB: Might throw, but no worries about a leak, mate: _Rep()
+       // does not throw.
+       void* __place = _Raw_bytes_alloc(__alloc).allocate(__size);
+       _Rep *__p = new (__place) _Rep;
+       __p->_M_capacity = __capacity;
+       return __p;
+     }
+ 
+   template<typename _CharT, typename _Traits, typename _Alloc>
+     void
+     __rc_string<_CharT, _Traits, _Alloc>::_Rep::
+     _M_destroy(const _Alloc& __a) throw ()
+     {
+       const size_type __size = sizeof(_Rep) +
+ 	                       (this->_M_capacity + 1) * sizeof(_CharT);
+       _Raw_bytes_alloc(__a).deallocate(reinterpret_cast<char*>(this), __size);
+     }
+ 
+   template<typename _CharT, typename _Traits, typename _Alloc>
+     _CharT*
+     __rc_string<_CharT, _Traits, _Alloc>::_Rep::
+     _M_clone(const _Alloc& __alloc, size_type __res)
+     {
+       // Requested capacity of the clone.
+       const size_type __requested_cap = this->_M_length + __res;
+       _Rep* __r = _Rep::_S_create(__requested_cap, this->_M_capacity,
+ 				  __alloc);
+       if (this->_M_length)
+ 	_S_copy(__r->_M_refdata(), this->_M_refdata(), this->_M_length);
+ 
+       __r->_M_set_length(this->_M_length);
+       return __r->_M_refdata();
+     }
+ 
+   template<typename _CharT, typename _Traits, typename _Alloc>
+     __rc_string<_CharT, _Traits, _Alloc>::
+     __rc_string(const _Alloc& __a)
+     : _M_dataplus(_S_construct(size_type(), _CharT(), __a), __a) { }
+ 
+   template<typename _CharT, typename _Traits, typename _Alloc>
+     __rc_string<_CharT, _Traits, _Alloc>::
+     __rc_string(_CharT* __ptr, const _Alloc& __a)
+     : _M_dataplus(__ptr, __a) { }
+ 
+   template<typename _CharT, typename _Traits, typename _Alloc>
+     __rc_string<_CharT, _Traits, _Alloc>::
+     __rc_string(size_type __n, _CharT __c, const _Alloc& __a)
+     : _M_dataplus(_S_construct(__n, __c, __a), __a)
+     { }
+ 
+   template<typename _CharT, typename _Traits, typename _Alloc>
+     template<typename _InputIterator>
+     __rc_string<_CharT, _Traits, _Alloc>::
+     __rc_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a)
+     : _M_dataplus(_S_construct(__beg, __end, __a), __a)
+     { }
+ 
+   template<typename _CharT, typename _Traits, typename _Alloc>
+     void
+     __rc_string<_CharT, _Traits, _Alloc>::
+     _M_reserve(size_type __res)
+     {
+       const allocator_type __a = _M_get_allocator();
+       _CharT* __tmp = _M_rep()->_M_clone(__a, __res - _M_rep()->_M_length);
+       _M_dispose(__a);
+       _M_dataplus._M_p = __tmp;
+     }
+ 
+   template<typename _CharT, typename _Traits, typename _Alloc>
+     void
+     __rc_string<_CharT, _Traits, _Alloc>::
+     _M_mutate(size_type __pos, size_type __len1, size_type __len2)
+     {
+       const size_type __old_size = _M_rep()->_M_length;
+       const size_type __new_size = __old_size + __len2 - __len1;
+       const size_type __how_much = __old_size - __pos - __len1;
+ 
+       if (__new_size > _M_rep()->_M_capacity || _M_rep()->_M_is_shared())
+ 	{
+ 	  // Must reallocate.
+ 	  const allocator_type __a = _M_dataplus;
+ 	  _Rep* __r = _Rep::_S_create(__new_size, _M_rep()->_M_capacity, __a);
+ 
+ 	  if (__pos)
+ 	    _S_copy(__r->_M_refdata(), _M_data(), __pos);
+ 	  if (__how_much)
+ 	    _S_copy(__r->_M_refdata() + __pos + __len2,
+ 		    _M_data() + __pos + __len1, __how_much);
+ 
+ 	  _M_dispose(__a);
+ 	  _M_dataplus._M_p = __r->_M_refdata();
+ 	}
+       else if (__how_much && __len1 != __len2)
+ 	{
+ 	  // Work in-place.
+ 	  _S_move(_M_data() + __pos + __len2,
+ 		  _M_data() + __pos + __len1, __how_much);
+ 	}
+       _M_rep()->_M_set_length(__new_size);
+     }
+  
+   // NB: This is the special case for Input Iterators, used in
+   // istreambuf_iterators, etc.
+   // Input Iterators have a cost structure very different from
+   // pointers, calling for a different coding style.
+   template<typename _CharT, typename _Traits, typename _Alloc>
+     template<typename _InIterator>
+       _CharT*
+       __rc_string<_CharT, _Traits, _Alloc>::
+       _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a,
+ 		   std::input_iterator_tag)
+       {
+ #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
+ 	if (__beg == __end && __a == _Alloc())
+ 	  return _S_empty_rep()._M_refdata();
+ #endif
+ 	// Avoid reallocation for common case.
+ 	_CharT __buf[128];
+ 	size_type __len = 0;
+ 	while (__beg != __end && __len < sizeof(__buf) / sizeof(_CharT))
+ 	  {
+ 	    __buf[__len++] = *__beg;
+ 	    ++__beg;
+ 	  }
+ 	_Rep* __r = _Rep::_S_create(__len, size_type(0), __a);
+ 	_S_copy(__r->_M_refdata(), __buf, __len);
+ 	try
+ 	  {
+ 	    while (__beg != __end)
+ 	      {
+ 		if (__len == __r->_M_capacity)
+ 		  {
+ 		    // Allocate more space.
+ 		    _Rep* __another = _Rep::_S_create(__len + 1, __len, __a);
+ 		    _S_copy(__another->_M_refdata(), __r->_M_refdata(), __len);
+ 		    __r->_M_destroy(__a);
+ 		    __r = __another;
+ 		  }
+ 		__r->_M_refdata()[__len++] = *__beg;
+ 		++__beg;
+ 	      }
+ 	  }
+ 	catch(...)
+ 	  {
+ 	    __r->_M_destroy(__a);
+ 	    __throw_exception_again;
+ 	  }
+ 	__r->_M_set_length(__len);
+ 	return __r->_M_refdata();
+       }
+ 
+   template<typename _CharT, typename _Traits, typename _Alloc>
+     template <typename _InIterator>
+       _CharT*
+       __rc_string<_CharT, _Traits, _Alloc>::
+       _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a,
+ 		   std::forward_iterator_tag)
+       {
+ #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
+ 	if (__beg == __end && __a == _Alloc())
+ 	  return _S_empty_rep()._M_refdata();
+ #endif
+ 	// NB: Not required, but considered best practice.
+ 	if (__builtin_expect(__is_null_pointer(__beg) && __beg != __end, 0))
+ 	  std::__throw_logic_error(__N("__rc_string::"
+ 				       "_S_construct NULL not valid"));
+ 
+ 	const size_type __dnew = static_cast<size_type>(std::distance(__beg,
+ 								      __end));
+ 	// Check for out_of_range and length_error exceptions.
+ 	_Rep* __r = _Rep::_S_create(__dnew, size_type(0), __a);
+ 	try
+ 	  { _S_copy_chars(__r->_M_refdata(), __beg, __end); }
+ 	catch(...)
+ 	  {
+ 	    __r->_M_destroy(__a);
+ 	    __throw_exception_again;
+ 	  }
+ 	__r->_M_set_length(__dnew);
+ 	return __r->_M_refdata();
+       }
+ 
+   template<typename _CharT, typename _Traits, typename _Alloc>
+     _CharT*
+     __rc_string<_CharT, _Traits, _Alloc>::
+     _S_construct(size_type __n, _CharT __c, const _Alloc& __a)
+     {
+ #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
+       if (__n == 0 && __a == _Alloc())
+ 	return _S_empty_rep()._M_refdata();
+ #endif
+       // Check for out_of_range and length_error exceptions.
+       _Rep* __r = _Rep::_S_create(__n, size_type(0), __a);
+       if (__n)
+ 	_S_assign(__r->_M_refdata(), __n, __c);
+ 
+       __r->_M_set_length(__n);
+       return __r->_M_refdata();
+     }
+ 
+   template<typename _CharT, typename _Traits, typename _Alloc>
+     void
+     __rc_string<_CharT, _Traits, _Alloc>::
+     _M_leak_hard()
+     {
+ #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
+       if (_M_rep() == &_S_empty_rep())
+ 	return;
+ #endif
+       if (_M_rep()->_M_is_shared())
+ 	_M_mutate(0, 0, 0);
+       _M_rep()->_M_set_leaked();
+     }
+ } // namespace __gnu_cxx
+ 
+ #endif /* _RC_STRING_H */
diff -prN libstdc++-v3-orig/include/ext/string_util.h libstdc++-v3/include/ext/string_util.h
*** libstdc++-v3-orig/include/ext/string_util.h	Thu Jan  1 01:00:00 1970
--- libstdc++-v3/include/ext/string_util.h	Thu Feb 17 12:03:25 2005
***************
*** 0 ****
--- 1,123 ----
+ // String utilities -*- C++ -*-
+ 
+ // Copyright (C) 2005 Free Software Foundation, Inc.
+ //
+ // This file is part of the GNU ISO C++ Library.  This library is free
+ // software; you can redistribute it and/or modify it under the
+ // terms of the GNU General Public License as published by the
+ // Free Software Foundation; either version 2, or (at your option)
+ // any later version.
+ 
+ // This library is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ // GNU General Public License for more details.
+ 
+ // You should have received a copy of the GNU General Public License along
+ // with this library; see the file COPYING.  If not, write to the Free
+ // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ // USA.
+ 
+ // As a special exception, you may use this file as part of a free software
+ // library without restriction.  Specifically, if other files instantiate
+ // templates or use macros or inline functions from this file, or you compile
+ // this file and link it with other files to produce an executable, this
+ // file does not by itself cause the resulting executable to be covered by
+ // the GNU General Public License.  This exception does not however
+ // invalidate any other reasons why the executable file might be covered by
+ // the GNU General Public License.
+ 
+ /** @file ext/string_util.h
+  *  This file is a GNU extension to the Standard C++ Library.
+  */
+ 
+ #ifndef _STRING_UTIL_H
+ #define _STRING_UTIL_H 1
+ 
+ namespace __gnu_cxx
+ {
+   template<typename _Type>
+     inline bool
+     __is_null_pointer(_Type* __ptr)
+     { return __ptr == 0; }
+ 
+   template<typename _Type>
+     inline bool
+     __is_null_pointer(_Type)
+     { return false; }
+ 
+   template<typename _CharT, typename _Traits, typename _Alloc>
+     struct __string_utility
+     {
+       typedef _Traits					    traits_type;      
+       typedef typename _Traits::char_type		    value_type;
+       typedef typename _Alloc::size_type		    size_type;
+       typedef typename _Alloc::pointer			    pointer;
+       typedef typename _Alloc::const_pointer		    const_pointer;
+       typedef __gnu_cxx::
+       __normal_iterator<pointer,
+ 			std::basic_string<_CharT, _Traits, _Alloc> >
+         iterator;
+       typedef __gnu_cxx::
+       __normal_iterator<const_pointer,
+ 			std::basic_string<_CharT, _Traits, _Alloc> >
+         const_iterator;
+ 
+       // When __n = 1 way faster than the general multichar
+       // traits_type::copy/move/assign.
+       static void
+       _S_copy(_CharT* __d, const _CharT* __s, size_type __n)
+       {
+ 	if (__n == 1)
+ 	  traits_type::assign(*__d, *__s);
+ 	else
+ 	  traits_type::copy(__d, __s, __n);
+       }
+ 
+       static void
+       _S_move(_CharT* __d, const _CharT* __s, size_type __n)
+       {
+ 	if (__n == 1)
+ 	  traits_type::assign(*__d, *__s);
+ 	else
+ 	  traits_type::move(__d, __s, __n);	  
+       }
+ 
+       static void
+       _S_assign(_CharT* __d, size_type __n, _CharT __c)
+       {
+ 	if (__n == 1)
+ 	  traits_type::assign(*__d, __c);
+ 	else
+ 	  traits_type::assign(__d, __n, __c);	  
+       }
+ 
+       // _S_copy_chars is a separate template to permit specialization
+       // to optimize for the common case of pointers as iterators.
+       template<class _Iterator>
+         static void
+         _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2)
+         {
+ 	  for (; __k1 != __k2; ++__k1, ++__p)
+ 	    traits_type::assign(*__p, *__k1); // These types are off.
+ 	}
+ 
+       static void
+       _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2)
+       { _S_copy_chars(__p, __k1.base(), __k2.base()); }
+ 
+       static void
+       _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2)
+       { _S_copy_chars(__p, __k1.base(), __k2.base()); }
+ 
+       static void
+       _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2)
+       { _S_copy(__p, __k1, __k2 - __k1); }
+ 
+       static void
+       _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2)
+       { _S_copy(__p, __k1, __k2 - __k1); }
+     };
+ } // namespace __gnu_cxx
+ 
+ #endif /* _STRING_UTIL_H */
diff -prN libstdc++-v3-orig/libmath/Makefile.in libstdc++-v3/libmath/Makefile.in
*** libstdc++-v3-orig/libmath/Makefile.in	Tue Feb  1 17:07:28 2005
--- libstdc++-v3/libmath/Makefile.in	Fri Feb 18 11:18:20 2005
*************** SECTION_FLAGS = @SECTION_FLAGS@
*** 171,176 ****
--- 171,178 ----
  SECTION_LDFLAGS = @SECTION_LDFLAGS@
  SET_MAKE = @SET_MAKE@
  SHELL = @SHELL@
+ STRING_H = @STRING_H@
+ STRING_NAME = @STRING_NAME@
  STRIP = @STRIP@
  SYMVER_MAP = @SYMVER_MAP@
  TOPLEVEL_INCLUDES = @TOPLEVEL_INCLUDES@
diff -prN libstdc++-v3-orig/libsupc++/Makefile.in libstdc++-v3/libsupc++/Makefile.in
*** libstdc++-v3-orig/libsupc++/Makefile.in	Tue Feb  1 17:07:30 2005
--- libstdc++-v3/libsupc++/Makefile.in	Fri Feb 18 11:18:20 2005
*************** SECTION_FLAGS = @SECTION_FLAGS@
*** 208,213 ****
--- 208,215 ----
  SECTION_LDFLAGS = @SECTION_LDFLAGS@
  SET_MAKE = @SET_MAKE@
  SHELL = @SHELL@
+ STRING_H = @STRING_H@
+ STRING_NAME = @STRING_NAME@
  STRIP = @STRIP@
  SYMVER_MAP = @SYMVER_MAP@
  TOPLEVEL_INCLUDES = @TOPLEVEL_INCLUDES@
diff -prN libstdc++-v3-orig/po/Makefile.in libstdc++-v3/po/Makefile.in
*** libstdc++-v3-orig/po/Makefile.in	Tue Feb  1 17:07:33 2005
--- libstdc++-v3/po/Makefile.in	Fri Feb 18 11:18:21 2005
*************** SECTION_FLAGS = @SECTION_FLAGS@
*** 152,157 ****
--- 152,159 ----
  SECTION_LDFLAGS = @SECTION_LDFLAGS@
  SET_MAKE = @SET_MAKE@
  SHELL = @SHELL@
+ STRING_H = @STRING_H@
+ STRING_NAME = @STRING_NAME@
  STRIP = @STRIP@
  SYMVER_MAP = @SYMVER_MAP@
  TOPLEVEL_INCLUDES = @TOPLEVEL_INCLUDES@
diff -prN libstdc++-v3-orig/src/Makefile.am libstdc++-v3/src/Makefile.am
*** libstdc++-v3-orig/src/Makefile.am	Tue Nov 16 13:15:24 2004
--- libstdc++-v3/src/Makefile.am	Wed Feb 16 12:53:54 2005
***************
*** 1,6 ****
  ## Makefile for the src subdirectory of the GNU C++ Standard library.
  ##
! ## Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
  ## Free Software Foundation, Inc.
  ##
  ## This file is part of the libstdc++ version 3 distribution.
--- 1,6 ----
  ## Makefile for the src subdirectory of the GNU C++ Standard library.
  ##
! ## Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005
  ## Free Software Foundation, Inc.
  ##
  ## This file is part of the libstdc++ version 3 distribution.
*************** sources = \
*** 134,142 ****
--- 134,144 ----
  	sstream-inst.cc \
  	streambuf-inst.cc \
  	streambuf.cc \
+ 	rc_string-inst.cc \
  	string-inst.cc \
  	valarray-inst.cc \
  	wlocale-inst.cc \
+ 	wrc_string-inst.cc \
  	wstring-inst.cc \
  	${host_sources} \
  	${host_sources_extra}
diff -prN libstdc++-v3-orig/src/Makefile.in libstdc++-v3/src/Makefile.in
*** libstdc++-v3-orig/src/Makefile.in	Tue Feb  1 17:07:35 2005
--- libstdc++-v3/src/Makefile.in	Fri Feb 18 11:18:21 2005
*************** am__objects_3 = bitmap_allocator.lo pool
*** 73,80 ****
  	concept-inst.lo fstream-inst.lo ext-inst.lo io-inst.lo \
  	istream-inst.lo istream.lo locale-inst.lo locale-misc-inst.lo \
  	misc-inst.lo ostream-inst.lo sstream-inst.lo streambuf-inst.lo \
! 	streambuf.lo string-inst.lo valarray-inst.lo wlocale-inst.lo \
! 	wstring-inst.lo $(am__objects_1) $(am__objects_2)
  am_libstdc___la_OBJECTS = $(am__objects_3)
  libstdc___la_OBJECTS = $(am_libstdc___la_OBJECTS)
  DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
--- 73,81 ----
  	concept-inst.lo fstream-inst.lo ext-inst.lo io-inst.lo \
  	istream-inst.lo istream.lo locale-inst.lo locale-misc-inst.lo \
  	misc-inst.lo ostream-inst.lo sstream-inst.lo streambuf-inst.lo \
! 	streambuf.lo rc_string-inst.lo string-inst.lo valarray-inst.lo \
! 	wlocale-inst.lo wrc_string-inst.lo wstring-inst.lo \
! 	$(am__objects_1) $(am__objects_2)
  am_libstdc___la_OBJECTS = $(am__objects_3)
  libstdc___la_OBJECTS = $(am_libstdc___la_OBJECTS)
  DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
*************** SECTION_FLAGS = @SECTION_FLAGS@
*** 187,192 ****
--- 188,195 ----
  SECTION_LDFLAGS = @SECTION_LDFLAGS@
  SET_MAKE = @SET_MAKE@
  SHELL = @SHELL@
+ STRING_H = @STRING_H@
+ STRING_NAME = @STRING_NAME@
  STRIP = @STRIP@
  SYMVER_MAP = @SYMVER_MAP@
  TOPLEVEL_INCLUDES = @TOPLEVEL_INCLUDES@
*************** sources = \
*** 343,351 ****
--- 346,356 ----
  	sstream-inst.cc \
  	streambuf-inst.cc \
  	streambuf.cc \
+ 	rc_string-inst.cc \
  	string-inst.cc \
  	valarray-inst.cc \
  	wlocale-inst.cc \
+ 	wrc_string-inst.cc \
  	wstring-inst.cc \
  	${host_sources} \
  	${host_sources_extra}
diff -prN libstdc++-v3-orig/src/rc_string-inst.cc libstdc++-v3/src/rc_string-inst.cc
*** libstdc++-v3-orig/src/rc_string-inst.cc	Thu Jan  1 01:00:00 1970
--- libstdc++-v3/src/rc_string-inst.cc	Thu Feb 17 17:21:32 2005
***************
*** 0 ****
--- 1,75 ----
+ // Components for manipulating sequences of characters -*- C++ -*-
+ 
+ // Copyright (C) 2005 Free Software Foundation, Inc.
+ //
+ // This file is part of the GNU ISO C++ Librarbooly.  This library is free
+ // software; you can redistribute it and/or modify it under the
+ // terms of the GNU General Public License as published by the
+ // Free Software Foundation; either version 2, or (at your option)
+ // any later version.
+ 
+ // This library is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ // GNU General Public License for more details.
+ 
+ // You should have received a copy of the GNU General Public License along
+ // with this library; see the file COPYING.  If not, write to the Free
+ // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ // USA.
+ 
+ // As a special exception, you may use this file as part of a free software
+ // library without restriction.  Specifically, if other files instantiate
+ // templates or use macros or inline functions from this file, or you compile
+ // this file and link it with other files to produce an executable, this
+ // file does not by itself cause the resulting executable to be covered by
+ // the GNU General Public License.  This exception does not however
+ // invalidate any other reasons why the executable file might be covered by
+ // the GNU General Public License.
+ 
+ //
+ // ISO C++ 14882:
+ //
+ 
+ #include <bits/c++config.h>
+ #include <ext/rc_string.h>
+ #include <memory> 	// For allocator.
+ #include <bits/char_traits.h>
+ 
+ // Instantiation configuration.
+ #ifndef C
+ # define C char
+ #endif
+ 
+ namespace __gnu_cxx
+ {
+   using std::allocator;
+ 
+   template class __rc_string<C, std::char_traits<C>, allocator<C> >;
+ 
+   typedef __rc_string<C, std::char_traits<C>, allocator<C> > RS;
+ 
+   template
+     RS::__rc_string(C*, C*, const allocator<C>&);
+ 
+   template
+     RS::__rc_string(const C*, const C*, const allocator<C>&);
+ 
+   template 
+     RS::__rc_string(RS::iterator, RS::iterator, const allocator<C>&);
+ 
+   template 
+     C* 
+     RS::_S_construct(RS::iterator, RS::iterator, 
+ 		     const allocator<C>&, std::forward_iterator_tag);
+ 
+   template
+     C*
+     RS::_S_construct(C*, C*, const allocator<C>&,
+ 		     std::forward_iterator_tag);
+ 
+   template
+     C*
+     RS::_S_construct(const C*, const C*, const allocator<C>&,
+ 		     std::forward_iterator_tag);
+ } // namespace __gnu_cxx
diff -prN libstdc++-v3-orig/src/string-inst.cc libstdc++-v3/src/string-inst.cc
*** libstdc++-v3-orig/src/string-inst.cc	Tue Aug 17 16:48:53 2004
--- libstdc++-v3/src/string-inst.cc	Wed Feb 16 12:53:54 2005
*************** namespace std
*** 63,82 ****
    template 
      S::basic_string(S::iterator, S::iterator, const allocator<C>&);
  
-   template 
-     C* 
-     S::_S_construct(S::iterator, S::iterator, 
- 		    const allocator<C>&, forward_iterator_tag);
- 
-   template
-     C*
-     S::_S_construct(C*, C*, const allocator<C>&, forward_iterator_tag);
- 
-   template
-     C*
-     S::_S_construct(const C*, const C*, const allocator<C>&,
- 		    forward_iterator_tag);
- 
    // Used in str::find.
    template
      const C*
--- 63,68 ----
diff -prN libstdc++-v3-orig/src/wrc_string-inst.cc libstdc++-v3/src/wrc_string-inst.cc
*** libstdc++-v3-orig/src/wrc_string-inst.cc	Thu Jan  1 01:00:00 1970
--- libstdc++-v3/src/wrc_string-inst.cc	Wed Feb 16 12:53:54 2005
***************
*** 0 ****
--- 1,39 ----
+ // Components for manipulating sequences of characters -*- C++ -*-
+ 
+ // Copyright (C) 2005 Free Software Foundation, Inc.
+ //
+ // This file is part of the GNU ISO C++ Librarbooly.  This library is free
+ // software; you can redistribute it and/or modify it under the
+ // terms of the GNU General Public License as published by the
+ // Free Software Foundation; either version 2, or (at your option)
+ // any later version.
+ 
+ // This library is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ // GNU General Public License for more details.
+ 
+ // You should have received a copy of the GNU General Public License along
+ // with this library; see the file COPYING.  If not, write to the Free
+ // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ // USA.
+ 
+ // As a special exception, you may use this file as part of a free software
+ // library without restriction.  Specifically, if other files instantiate
+ // templates or use macros or inline functions from this file, or you compile
+ // this file and link it with other files to produce an executable, this
+ // file does not by itself cause the resulting executable to be covered by
+ // the GNU General Public License.  This exception does not however
+ // invalidate any other reasons why the executable file might be covered by
+ // the GNU General Public License.
+ 
+ //
+ // ISO C++ 14882:
+ //
+ 
+ #include <bits/c++config.h>
+ 
+ #ifdef _GLIBCXX_USE_WCHAR_T
+ #define C wchar_t
+ #include "rc_string-inst.cc"
+ #endif
diff -prN libstdc++-v3-orig/testsuite/Makefile.in libstdc++-v3/testsuite/Makefile.in
*** libstdc++-v3-orig/testsuite/Makefile.in	Wed Feb 16 11:39:59 2005
--- libstdc++-v3/testsuite/Makefile.in	Fri Feb 18 11:18:21 2005
*************** SECTION_FLAGS = @SECTION_FLAGS@
*** 181,186 ****
--- 181,188 ----
  SECTION_LDFLAGS = @SECTION_LDFLAGS@
  SET_MAKE = @SET_MAKE@
  SHELL = @SHELL@
+ STRING_H = @STRING_H@
+ STRING_NAME = @STRING_NAME@
  STRIP = @STRIP@
  SYMVER_MAP = @SYMVER_MAP@
  TOPLEVEL_INCLUDES = @TOPLEVEL_INCLUDES@

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]