This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ 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]

[Patch] Add __versa_string to mainline/ext


Hi everyone,

the below finally adds to mainline/ext the "modular" string framework:
in this incarnation, as an extension, I'm adding a 4th template argument
(see vstring.h and vstring_fwd.h), thus making easy testing and
comparing the available base classes.

Actually the work proceeded rather smoothly and you will find also the
I/O bits, in a basic version (no performance optimizations for
char/wchar_t exploiting protected members of streambuf).

For now, I'm only adding an handful of instantation testcases, but I'm
fairly confident that the code would also pass a full testsuite (modulo
trivial fixes like typos) because the classes are adapted from v7-branch
without substantive changes besides renamings, reformattings and other
very-very simple things. More testing during the next days, anyway. Then
I'd like to commit the patch and proceed with further improvements.

Paolo.

P.S. I considered creating a specific directory under /ext but seems
overkill for so few files. Also, both comments at the beginning of the
files and the file names themselves should make sufficiently clear the
purpose of each new file.

//////////////
2005-07-xx  Paolo Carlini  <pcarlini@suse.de>

	Add class __versa_string, a versatile "basic_string-type" class:
	an additional, non-standard, template parameter allows to specify
	the preferred base class. Two are provided: __rc_string_base,
	which implements a behavior very similar to our standard string,
	and __sso_string_base, not reference-counted and optimized for
	short strings. 
	* include/ext/rc_string_base.h: New.
	* include/ext/sso_string_base.h: Likewise.
	* include/ext/vstring.h: Likewise.
	* include/ext/vstring.tcc: Likewise.
	* include/ext/vstring_fwd.h: Likewise.
	* include/ext/vstring_util.h: Likewise.
	* include/Makefile.am: Add.
	* include/Makefile.in: Regenerate.
	* testsuite/ext/vstring/explicit_instantiation/1.cc: New.
	* testsuite/ext/vstring/explicit_instantiation/2.cc: Likewise.
	* testsuite/ext/vstring/explicit_instantiation/char/1.cc: Likewise.
	* testsuite/ext/vstring/explicit_instantiation/wchar_t/1.cc: Likewise.
diff -urN libstdc++-v3-orig/include/Makefile.am libstdc++-v3/include/Makefile.am
--- libstdc++-v3-orig/include/Makefile.am	2005-06-27 17:30:25.000000000 +0200
+++ libstdc++-v3/include/Makefile.am	2005-07-03 16:20:00.000000000 +0200
@@ -456,7 +456,13 @@
 	${ext_srcdir}/rope \
 	${ext_srcdir}/ropeimpl.h \
 	${ext_srcdir}/slist \
-	${ext_srcdir}/typelist.h 
+	${ext_srcdir}/typelist.h \
+	${ext_srcdir}/rc_string_base.h \
+	${ext_srcdir}/sso_string_base.h \
+	${ext_srcdir}/vstring.h \
+	${ext_srcdir}/vstring.tcc \
+	${ext_srcdir}/vstring_fwd.h \
+	${ext_srcdir}/vstring_util.h	
 
 
 tr1_srcdir = ${glibcxx_srcdir}/include/tr1
diff -urN libstdc++-v3-orig/include/ext/rc_string_base.h libstdc++-v3/include/ext/rc_string_base.h
--- libstdc++-v3-orig/include/ext/rc_string_base.h	1970-01-01 01:00:00.000000000 +0100
+++ libstdc++-v3/include/ext/rc_string_base.h	2005-07-03 16:18:05.000000000 +0200
@@ -0,0 +1,663 @@
+// Reference-counted versatile string base -*- 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_base.h
+ *  This file is a GNU extension to the Standard C++ Library.
+ *  This is an internal header file, included by other library headers.
+ *  You should not attempt to use it directly.
+ */
+
+#ifndef _RC_STRING_BASE_H
+#define _RC_STRING_BASE_H 1
+
+#include <bits/atomicity.h>
+
+namespace __gnu_cxx
+{
+  /**
+   *  @if maint
+   *  Documentation?  What's that?
+   *  Nathan Myers <ncm@cantrip.org>.
+   *
+   *  A string looks like this:
+   *
+   *  @code
+   *                                        [_Rep]
+   *                                        _M_length
+   *   [__rc_string_base<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_base::_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_base
+    : protected __vstring_utility<_CharT, _Traits, _Alloc>
+    {
+    public:
+      typedef _Traits					    traits_type;
+      typedef typename _Traits::char_type		    value_type;
+      typedef _Alloc					    allocator_type;
+
+      typedef typename __vstring_utility<_CharT, _Traits, _Alloc>::
+        _CharT_alloc_type                                   _CharT_alloc_type;
+      typedef typename _CharT_alloc_type::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;
+
+    private:
+      static const _CharT	_S_terminal;
+
+      // _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<size_type>::other _Raw_alloc;
+
+ 	_CharT*
+	_M_refdata()
+	{ return reinterpret_cast<_CharT*>(this + 1); }
+
+	void
+	_M_set_length(size_type __n)
+	{ 
+	  _M_refcount = 0;  // One reference.
+	  _M_length = __n;
+	  // grrr. (per 21.3.4)
+	  // You cannot leave those LWG people alone for a second.
+	  traits_type::assign(_M_refdata()[__n], _S_terminal);
+	}
+
+	// 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 Member (private):
+      mutable _Alloc_hider	_M_dataplus;
+
+      static _Rep_empty&
+      _S_empty_rep()
+      {
+	static _Rep_empty _Empty_rep;
+	return _Empty_rep;
+      }
+
+      _CharT*
+      _M_data(_CharT* __p)
+      { return (_M_dataplus._M_p = __p); }
+
+      _Rep*
+      _M_rep() const
+      { return &((reinterpret_cast<_Rep*>(_M_data()))[-1]); }
+
+      _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
+
+      _CharT*
+      _M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2) const
+      {
+	return (!_M_is_leaked() && __alloc1 == __alloc2)
+	        ? _M_refcopy() : _M_rep()->_M_clone(__alloc1);
+      }
+
+      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
+
+      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);
+
+    public:
+      _CharT*
+      _M_data() const
+      { return _M_dataplus._M_p; }
+
+      size_type
+      _M_length() const
+      { return _M_rep()->_M_length; }
+
+      size_type
+      _M_capacity() const
+      { return _M_rep()->_M_capacity; }
+
+      bool
+      _M_is_shared() const
+      { return _M_rep()->_M_refcount > 0; }
+
+      bool
+      _M_is_leaked() const
+      { return _M_rep()->_M_refcount < 0; }
+
+      void
+      _M_set_sharable()
+      { _M_rep()->_M_refcount = 0; }
+
+      void
+      _M_set_leaked()
+      { _M_rep()->_M_refcount = -1; }
+
+      void
+      _M_set_length(size_type __n)
+      { _M_rep()->_M_set_length(__n); }
+
+      void
+      _M_leak()    // for use in begin() & non-const op[]
+      {
+	if (!_M_is_leaked())
+	  _M_leak_hard();
+      }
+
+      __rc_string_base()
+#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_base(const _Alloc& __a);
+
+      __rc_string_base(const __rc_string_base& __rcs);
+
+      __rc_string_base(size_type __n, _CharT __c, const _Alloc& __a);
+
+      template<typename _InputIterator>
+        __rc_string_base(_InputIterator __beg, _InputIterator __end,
+		    const _Alloc& __a);
+
+      ~__rc_string_base()
+      { _M_dispose(_M_get_allocator()); }      
+
+      allocator_type
+      _M_get_allocator() const
+      { return _M_dataplus; }
+
+      void
+      _M_swap(__rc_string_base& __rcs)
+      {
+	_CharT* __tmp = _M_data();
+	_M_data(__rcs._M_data());
+	__rcs._M_data(__tmp);
+      }
+
+      void
+      _M_assign(const __rc_string_base& __rcs);
+
+      void
+      _M_reserve(size_type __res);
+
+      void
+      _M_mutate(size_type __pos, size_type __len1, size_type __len2);
+    };
+
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    const typename __rc_string_base<_CharT, _Traits, _Alloc>::size_type
+    __rc_string_base<_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_base<_CharT, _Traits, _Alloc>::_S_terminal = _CharT();
+
+    template<typename _CharT, typename _Traits, typename _Alloc>
+    typename __rc_string_base<_CharT, _Traits, _Alloc>::_Rep*
+    __rc_string_base<_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_base::_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,
+      // plus sizeof(size_type) - 1 to upper round to a size multiple
+      // of sizeof(size_type).
+      // Whew. Seemingly so needy, yet so elemental.
+      size_type __size = ((__capacity + 1) * sizeof(_CharT) + sizeof(_Rep)
+			  + sizeof(size_type) - 1);
+
+      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)
+		    + sizeof(size_type) - 1);
+	}
+
+      // NB: Might throw, but no worries about a leak, mate: _Rep()
+      // does not throw.
+      void* __place = _Raw_alloc(__alloc).allocate(__size
+						   / sizeof(size_type));
+      _Rep *__p = new (__place) _Rep;
+      __p->_M_capacity = __capacity;
+      return __p;
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    void
+    __rc_string_base<_CharT, _Traits, _Alloc>::_Rep::
+    _M_destroy(const _Alloc& __a) throw ()
+    {
+      const size_type __size = ((_M_capacity + 1) * sizeof(_CharT)
+				+ sizeof(_Rep) + sizeof(size_type) - 1);
+      _Raw_alloc(__a).deallocate(reinterpret_cast<size_type*>(this),
+				 __size / sizeof(size_type));
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    _CharT*
+    __rc_string_base<_CharT, _Traits, _Alloc>::_Rep::
+    _M_clone(const _Alloc& __alloc, size_type __res)
+    {
+      // Requested capacity of the clone.
+      const size_type __requested_cap = _M_length + __res;
+      _Rep* __r = _Rep::_S_create(__requested_cap, _M_capacity, __alloc);
+
+      if (_M_length)
+	_S_copy(__r->_M_refdata(), _M_refdata(), _M_length);
+
+      __r->_M_set_length(_M_length);
+      return __r->_M_refdata();
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    __rc_string_base<_CharT, _Traits, _Alloc>::
+    __rc_string_base(const _Alloc& __a)
+    : _M_dataplus(_S_construct(size_type(), _CharT(), __a), __a) { }
+
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    __rc_string_base<_CharT, _Traits, _Alloc>::
+    __rc_string_base(const __rc_string_base& __rcs)
+    : _M_dataplus(__rcs._M_grab(_Alloc(__rcs._M_get_allocator()),
+				__rcs._M_get_allocator()),
+		  __rcs._M_get_allocator()) { }
+
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    __rc_string_base<_CharT, _Traits, _Alloc>::
+    __rc_string_base(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_base<_CharT, _Traits, _Alloc>::
+    __rc_string_base(_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_base<_CharT, _Traits, _Alloc>::
+    _M_leak_hard()
+    {
+#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
+      if (_M_rep() == &_S_empty_rep())
+	return;
+#endif
+      if (_M_is_shared())
+	_M_mutate(0, 0, 0);
+      _M_set_leaked();
+    }
+
+  // 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_base<_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_base<_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_p(__beg) && __beg != __end, 0))
+	  std::__throw_logic_error(__N("__rc_string_base::"
+				       "_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_base<_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_base<_CharT, _Traits, _Alloc>::
+    _M_assign(const __rc_string_base& __rcs)
+    {
+      if (_M_rep() != __rcs._M_rep())
+	{
+	  const allocator_type __a = _M_get_allocator();
+	  _CharT* __tmp = __rcs._M_grab(__a, __rcs._M_get_allocator());
+	  _M_dispose(__a);
+	  _M_data(__tmp);
+	}
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    void
+    __rc_string_base<_CharT, _Traits, _Alloc>::
+    _M_reserve(size_type __res)
+    {
+      if (__res != _M_capacity() || _M_is_shared())
+	{
+	  // Make sure we don't shrink below the current size.
+	  if (__res < _M_length())
+	    __res = _M_length();
+	  
+	  const allocator_type __a = _M_get_allocator();
+	  _CharT* __tmp = _M_rep()->_M_clone(__a, __res - _M_length());
+	  _M_dispose(__a);
+	  _M_data(__tmp);
+	}
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    void
+    __rc_string_base<_CharT, _Traits, _Alloc>::
+    _M_mutate(size_type __pos, size_type __len1, size_type __len2)
+    {
+      const size_type __old_size = _M_length();
+      const size_type __new_size = __old_size + __len2 - __len1;
+      const size_type __how_much = __old_size - __pos - __len1;
+      
+      if (__new_size > _M_capacity() || _M_is_shared())
+	{
+	  // Must reallocate.
+	  const allocator_type __a = _M_get_allocator();
+	  _Rep* __r = _Rep::_S_create(__new_size, _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_data(__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);
+    }
+} // namespace __gnu_cxx
+
+#endif /* _RC_STRING_BASE_H */
diff -urN libstdc++-v3-orig/include/ext/sso_string_base.h libstdc++-v3/include/ext/sso_string_base.h
--- libstdc++-v3-orig/include/ext/sso_string_base.h	1970-01-01 01:00:00.000000000 +0100
+++ libstdc++-v3/include/ext/sso_string_base.h	2005-07-03 16:17:38.000000000 +0200
@@ -0,0 +1,582 @@
+// Short-string-optimized versatile string base -*- 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/sso_string_base.h
+ *  This file is a GNU extension to the Standard C++ Library.
+ *  This is an internal header file, included by other library headers.
+ *  You should not attempt to use it directly.
+ */
+
+#ifndef _SSO_STRING_BASE_H
+#define _SSO_STRING_BASE_H 1
+
+namespace __gnu_cxx
+{
+  // N.B. According to 3.9/10 and 9/4, POD types can have user-defined 
+  // constructors: in that case, cannot be member of an union (9.5/1).
+  // See, f.i., class gnu_char_type in the testsuite.
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   bool = std::__is_scalar<_CharT>::__value>
+    struct __sso_string_local
+    {
+      typedef typename __vstring_utility<_CharT, _Traits, _Alloc>::
+        _CharT_alloc_type::size_type                        size_type;
+
+      enum { _S_local_capacity = 15 };
+      
+      union
+      {
+	_CharT               _M_local_data[_S_local_capacity + 1];
+	size_type            _M_allocated_capacity;
+      };
+    };
+
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    struct __sso_string_local<_CharT, _Traits, _Alloc, false>
+    {
+      typedef typename __vstring_utility<_CharT, _Traits, _Alloc>::
+        _CharT_alloc_type::size_type                        size_type;
+
+      enum { _S_local_capacity = 15 };
+
+      _CharT                 _M_local_data[_S_local_capacity + 1];
+      size_type              _M_allocated_capacity;
+    };
+
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    class __sso_string_base
+    : protected __vstring_utility<_CharT, _Traits, _Alloc>,
+      private __sso_string_local<_CharT, _Traits, _Alloc>
+    {
+      typedef __sso_string_local<_CharT, _Traits, _Alloc>   _Base;
+
+    public:
+      typedef _Traits					    traits_type;
+      typedef typename _Traits::char_type		    value_type;
+      typedef _Alloc					    allocator_type;
+
+      typedef typename __vstring_utility<_CharT, _Traits, _Alloc>::
+        _CharT_alloc_type                                   _CharT_alloc_type;
+      typedef typename _CharT_alloc_type::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 = m * sizeof(_CharT) + sizeof(_CharT)
+      // Solving for m:
+      // m = npos / sizeof(CharT) - 1
+      // In addition, this implementation quarters this amount.
+      static const size_type	_S_max_size;
+
+    private:
+      static const _CharT	_S_terminal;
+
+      using _Base::_S_local_capacity;
+      using _Base::_M_local_data;
+      using _Base::_M_allocated_capacity;
+
+      // Create & Destroy
+      _CharT*
+      _M_create(size_type&, size_type);
+      
+      void
+      _M_dispose() throw()
+      {
+	if (!_M_is_local())
+	  _M_destroy(_M_allocated_capacity + 1);
+      }
+
+      void
+      _M_destroy(size_type) throw();
+
+      // Use empty-base optimization: http://www.cantrip.org/emptyopt.html
+      struct _Alloc_hider : _Alloc
+      {
+	_Alloc_hider(const _Alloc& __a, _CharT* __ptr)
+	: _Alloc(__a), _M_p(__ptr) { }
+
+	_CharT* _M_p; // The actual data.
+      };
+
+      // Data Members (private):
+      _Alloc_hider	        _M_dataplus;
+      size_type                 _M_string_length;
+
+      _CharT*
+      _M_data(_CharT* __p)
+      { return (_M_dataplus._M_p = __p); }
+
+      void
+      _M_length(size_type __length)
+      { _M_string_length = __length; }
+
+      void
+      _M_capacity(size_type __capacity)
+      { _M_allocated_capacity = __capacity; }
+
+      bool
+      _M_is_local() const
+      { return _M_data() == _M_local_data; }
+
+      // _M_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>
+        void
+        _M_construct_aux(_InIterator __beg, _InIterator __end, __false_type)
+	{
+          typedef typename iterator_traits<_InIterator>::iterator_category _Tag;
+          _M_construct(__beg, __end, _Tag());
+	}
+
+      template<class _InIterator>
+        void
+        _M_construct_aux(_InIterator __beg, _InIterator __end, __true_type)
+	{ _M_construct(static_cast<size_type>(__beg),
+		       static_cast<value_type>(__end)); }
+
+      template<class _InIterator>
+        void
+        _M_construct(_InIterator __beg, _InIterator __end)
+	{
+	  typedef typename std::__is_integer<_InIterator>::__type _Integral;
+	  _M_construct_aux(__beg, __end, _Integral());
+        }
+
+      // For Input Iterators, used in istreambuf_iterators, etc.
+      template<class _InIterator>
+        void
+        _M_construct(_InIterator __beg, _InIterator __end,
+		     std::input_iterator_tag);
+      
+      // For forward_iterators up to random_access_iterators, used for
+      // string::iterator, _CharT*, etc.
+      template<class _FwdIterator>
+        void
+        _M_construct(_FwdIterator __beg, _FwdIterator __end,
+		     std::forward_iterator_tag);
+
+      void
+      _M_construct(size_type __req, _CharT __c);
+
+    public:
+      _CharT*
+      _M_data() const
+      { return _M_dataplus._M_p; }
+
+      size_type
+      _M_length() const
+      { return _M_string_length; }
+
+      size_type
+      _M_capacity() const
+      {
+	return _M_is_local() ? size_type(_S_local_capacity)
+	                     : _M_allocated_capacity; 
+      }
+
+      bool
+      _M_is_shared() const
+      { return false; }
+
+      bool
+      _M_is_leaked() const
+      { return false; }
+
+      void
+      _M_set_sharable() { }
+
+      void
+      _M_set_leaked() { }
+
+      void
+      _M_set_length(size_type __n)
+      {
+	_M_length(__n);
+	// grrr. (per 21.3.4)
+	// You cannot leave those LWG people alone for a second.
+	traits_type::assign(_M_data()[__n], _S_terminal);
+      }
+
+      void
+      _M_leak() { }
+
+      __sso_string_base()
+      : _M_dataplus(_Alloc(), _M_local_data)
+      { _M_set_length(0); }
+
+      __sso_string_base(const _Alloc& __a);
+
+      __sso_string_base(const __sso_string_base& __rcs);
+
+      __sso_string_base(size_type __n, _CharT __c, const _Alloc& __a);
+
+      template<typename _InputIterator>
+        __sso_string_base(_InputIterator __beg, _InputIterator __end,
+		     const _Alloc& __a);
+
+      ~__sso_string_base()
+      { _M_dispose(); }
+
+      allocator_type
+      _M_get_allocator() const
+      { return _M_dataplus; }
+
+      void
+      _M_swap(__sso_string_base& __rcs);
+
+      void
+      _M_assign(const __sso_string_base& __rcs);
+
+      void
+      _M_reserve(size_type __res);
+
+      void
+      _M_mutate(size_type __pos, size_type __len1, size_type __len2);
+    };
+
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    void
+    __sso_string_base<_CharT, _Traits, _Alloc>::
+    _M_destroy(size_type __size) throw()
+    { _CharT_alloc_type(_M_get_allocator()).deallocate(_M_data(), __size); }
+
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    void
+    __sso_string_base<_CharT, _Traits, _Alloc>::
+    _M_swap(__sso_string_base& __rcs)
+    {
+      const bool __local = _M_is_local();
+      const bool __rcs_local = __rcs._M_is_local();
+      
+      if (__local && __rcs_local)
+	{
+	  _CharT __tmp_data[_S_local_capacity + 1];
+	  const size_type __tmp_length = __rcs._M_length();
+	  _S_copy(__tmp_data, __rcs._M_data(), __rcs._M_length() + 1);
+	  __rcs._M_length(_M_length());
+	  _S_copy(__rcs._M_data(), _M_data(), _M_length() + 1);
+	  _M_length(__tmp_length);
+	  _S_copy(_M_data(), __tmp_data, __tmp_length + 1);
+	}
+      else if (__local && !__rcs_local)
+	{
+	  const size_type __tmp_capacity = __rcs._M_allocated_capacity;
+	  const size_type __tmp_length = __rcs._M_length();
+	  _CharT* __tmp_ptr = __rcs._M_data();
+	  __rcs._M_data(__rcs._M_local_data);
+	  _S_copy(__rcs._M_data(), _M_data(), _M_length() + 1);
+	  __rcs._M_length(_M_length());
+	  _M_data(__tmp_ptr);
+	  _M_length(__tmp_length);
+	  _M_capacity(__tmp_capacity);
+	}
+      else if (!__local && __rcs_local)
+	{
+	  const size_type __tmp_capacity = _M_allocated_capacity;
+	  const size_type __tmp_length = _M_length();
+	  _CharT* __tmp_ptr = _M_data();
+	  _M_data(_M_local_data);
+	  _S_copy(_M_data(), __rcs._M_data(), __rcs._M_length() + 1);
+	  _M_length(__rcs._M_length());
+	  __rcs._M_data(__tmp_ptr);
+	  __rcs._M_length(__tmp_length);
+	  __rcs._M_capacity(__tmp_capacity);
+	}
+      else
+	{
+	  const size_type __tmp_capacity = _M_allocated_capacity;
+	  const size_type __tmp_length = _M_length();
+	  _CharT* __tmp_ptr = _M_data();
+	  _M_data(__rcs._M_data());
+	  _M_length(__rcs._M_length());
+	  _M_capacity(__rcs._M_allocated_capacity);
+	  __rcs._M_data(__tmp_ptr);
+	  __rcs._M_length(__tmp_length);
+	  __rcs._M_capacity(__tmp_capacity);
+	}
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    const typename __sso_string_base<_CharT, _Traits, _Alloc>::size_type
+    __sso_string_base<_CharT, _Traits, _Alloc>::
+    _S_max_size = ((static_cast<size_type>(-1) / sizeof(_CharT)) - 1) / 4;
+
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    const _CharT
+    __sso_string_base<_CharT, _Traits, _Alloc>::_S_terminal = _CharT();
+
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    _CharT*
+    __sso_string_base<_CharT, _Traits, _Alloc>::
+    _M_create(size_type& __capacity, size_type __old_capacity)
+    {
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 83.  String::npos vs. string::max_size()
+      if (__capacity > _S_max_size)
+	std::__throw_length_error(__N("__sso_string_base::_M_create"));
+
+      // 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.
+      return _CharT_alloc_type(_M_get_allocator()).allocate(__capacity + 1);
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    __sso_string_base<_CharT, _Traits, _Alloc>::
+    __sso_string_base(const _Alloc& __a)
+    : _M_dataplus(__a, _M_local_data)
+    { _M_set_length(0); }
+
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    __sso_string_base<_CharT, _Traits, _Alloc>::
+    __sso_string_base(const __sso_string_base& __rcs)
+    : _M_dataplus(__rcs._M_get_allocator(), _M_local_data)
+    { _M_construct(__rcs._M_data(), __rcs._M_data() + __rcs._M_length()); }
+
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    __sso_string_base<_CharT, _Traits, _Alloc>::
+    __sso_string_base(size_type __n, _CharT __c, const _Alloc& __a)
+    : _M_dataplus(__a, _M_local_data)
+    { _M_construct(__n, __c); }
+
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    template<typename _InputIterator>
+    __sso_string_base<_CharT, _Traits, _Alloc>::
+    __sso_string_base(_InputIterator __beg, _InputIterator __end,
+		      const _Alloc& __a)
+    : _M_dataplus(__a, _M_local_data)
+    { _M_construct(__beg, __end); }
+
+  // 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>
+      void
+      __sso_string_base<_CharT, _Traits, _Alloc>::
+      _M_construct(_InIterator __beg, _InIterator __end,
+		   std::input_iterator_tag)
+      {
+	// Avoid reallocation for common case.
+	size_type __len = 0;
+	size_type __capacity = size_type(_S_local_capacity);
+
+	while (__beg != __end && __len < __capacity)
+	  {
+	    _M_data()[__len++] = *__beg;
+	    ++__beg;
+	  }
+	
+	try
+	  {
+	    while (__beg != __end)
+	      {
+		if (__len == __capacity)
+		  {
+		    // Allocate more space.
+		    __capacity = __len + 1;
+		    _CharT* __another = _M_create(__capacity, __len);
+		    _S_copy(__another, _M_data(), __len);
+		    _M_dispose();
+		    _M_data(__another);
+		    _M_capacity(__capacity);
+		  }
+		_M_data()[__len++] = *__beg;
+		++__beg;
+	      }
+	  }
+	catch(...)
+	  {
+	    _M_dispose();
+	    __throw_exception_again;
+	  }
+
+	_M_set_length(__len);
+      }
+
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    template <typename _InIterator>
+      void
+      __sso_string_base<_CharT, _Traits, _Alloc>::
+      _M_construct(_InIterator __beg, _InIterator __end,
+		   std::forward_iterator_tag)
+      {
+	// NB: Not required, but considered best practice.
+	if (__builtin_expect(__is_null_p(__beg) && __beg != __end, 0))
+	  std::__throw_logic_error(__N("__sso_string_base::"
+				       "_M_construct NULL not valid"));
+
+	size_type __dnew = static_cast<size_type>(std::distance(__beg, __end));
+
+	if (__dnew > size_type(_S_local_capacity))
+	  {
+	    _M_data(_M_create(__dnew, size_type(0)));
+	    _M_capacity(__dnew);
+	  }
+
+	// Check for out_of_range and length_error exceptions.
+	try
+	  { _S_copy_chars(_M_data(), __beg, __end); }
+	catch(...)
+	  {
+	    _M_dispose();
+	    __throw_exception_again;
+	  }
+
+	_M_set_length(__dnew);
+      }
+
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    void
+    __sso_string_base<_CharT, _Traits, _Alloc>::
+    _M_construct(size_type __n, _CharT __c)
+    {
+      if (__n > size_type(_S_local_capacity))
+	{
+	  _M_data(_M_create(__n, size_type(0)));
+	  _M_capacity(__n);
+	}
+
+      if (__n)
+	_S_assign(_M_data(), __n, __c);
+
+      _M_set_length(__n);
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    void
+    __sso_string_base<_CharT, _Traits, _Alloc>::
+    _M_assign(const __sso_string_base& __rcs)
+    {
+      if (this != &__rcs)
+	{
+	  size_type __size = __rcs._M_length();
+
+	  _CharT* __tmp = _M_local_data;
+	  if (__size > size_type(_S_local_capacity))
+	    __tmp = _M_create(__size, size_type(0));
+
+	  _M_dispose();
+	  _M_data(__tmp);
+
+	  if (__size)
+	    _S_copy(_M_data(), __rcs._M_data(), __size);
+
+	  if (!_M_is_local())
+	    _M_capacity(__size);
+
+	  _M_set_length(__size);
+	}
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    void
+    __sso_string_base<_CharT, _Traits, _Alloc>::
+    _M_reserve(size_type __res)
+    {
+      const size_type __capacity = _M_capacity();
+      if (__res != __capacity)
+	{
+	  // Make sure we don't shrink below the current size.
+	  if (__res < _M_length())
+	    __res = _M_length();
+
+	  if (__res > __capacity
+	      || __res > size_type(_S_local_capacity))
+	    {
+	      _CharT* __tmp = _M_create(__res, __capacity);
+	      if (_M_length())
+		_S_copy(__tmp, _M_data(), _M_length());
+	      _M_dispose();
+	      _M_data(__tmp);
+	      _M_capacity(__res);
+	    }
+	  else if (!_M_is_local())
+	    {
+	      const size_type __tmp_capacity = _M_allocated_capacity;
+	      if (_M_length())
+		_S_copy(_M_local_data, _M_data(), _M_length());
+	      _M_destroy(__tmp_capacity + 1);
+	      _M_data(_M_local_data);
+	    }	  
+	  
+	  _M_set_length(_M_length());
+	}
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    void
+    __sso_string_base<_CharT, _Traits, _Alloc>::
+    _M_mutate(size_type __pos, size_type __len1, size_type __len2)
+    {
+      const size_type __old_size = _M_length();
+      const size_type __new_size = __old_size + __len2 - __len1;
+      const size_type __how_much = __old_size - __pos - __len1;
+      
+      if (__new_size > _M_capacity())
+	{
+	  // Must reallocate.
+	  size_type __new_capacity = __new_size;
+	  _CharT* __r = _M_create(__new_capacity, _M_capacity());
+
+	  if (__pos)
+	    _S_copy(__r, _M_data(), __pos);
+	  if (__how_much)
+	    _S_copy(__r + __pos + __len2,
+		    _M_data() + __pos + __len1, __how_much);
+
+	  _M_dispose();
+	  _M_data(__r);
+	  _M_capacity(__new_capacity);
+	}
+      else if (__how_much && __len1 != __len2)
+	{
+	  // Work in-place.
+	  _S_move(_M_data() + __pos + __len2,
+		  _M_data() + __pos + __len1, __how_much);
+	}
+
+      _M_set_length(__new_size);
+    }
+} // namespace __gnu_cxx
+
+#endif /* _SSO_STRING_BASE_H */
diff -urN libstdc++-v3-orig/include/ext/vstring.h libstdc++-v3/include/ext/vstring.h
--- libstdc++-v3-orig/include/ext/vstring.h	1970-01-01 01:00:00.000000000 +0100
+++ libstdc++-v3/include/ext/vstring.h	2005-07-03 16:16:01.000000000 +0200
@@ -0,0 +1,2172 @@
+// Versatile 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/vstring.h
+ *  This file is a GNU extension to the Standard C++ Library.
+ */
+
+#ifndef _VSTRING_H
+#define _VSTRING_H 1
+
+#pragma GCC system_header
+
+#include <ext/vstring_util.h>
+#include <ext/rc_string_base.h>
+#include <ext/sso_string_base.h>
+
+namespace __gnu_cxx
+{
+  /**
+   *  @class __versa_string vstring.h
+   *  @brief  Managing sequences of characters and character-like objects.
+   */
+
+  // Template class __versa_string
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    class __versa_string
+    : private _Base<_CharT, _Traits, _Alloc>
+    {
+      typedef _Base<_CharT, _Traits, _Alloc>                __vstring_base;      
+      typedef typename __vstring_base::_CharT_alloc_type    _CharT_alloc_type;
+
+      // Types:
+    public:
+      typedef _Traits					    traits_type;
+      typedef typename _Traits::char_type		    value_type;
+      typedef _Alloc					    allocator_type;
+      typedef typename _CharT_alloc_type::size_type	    size_type;
+      typedef typename _CharT_alloc_type::difference_type   difference_type;
+      typedef typename _CharT_alloc_type::reference	    reference;
+      typedef typename _CharT_alloc_type::const_reference   const_reference;
+      typedef typename _CharT_alloc_type::pointer	    pointer;
+      typedef typename _CharT_alloc_type::const_pointer	    const_pointer;
+      typedef __gnu_cxx::__normal_iterator<pointer, __versa_string>  iterator;
+      typedef __gnu_cxx::__normal_iterator<const_pointer, __versa_string>
+                                                            const_iterator;
+      typedef std::reverse_iterator<const_iterator>	const_reverse_iterator;
+      typedef std::reverse_iterator<iterator>		    reverse_iterator;
+
+      // Data Members (public):
+      // NB: This is an unsigned type, and thus represents the maximum
+      // size that the allocator can hold.
+      ///  Value returned by various member functions when they fail.
+      static const size_type	npos = static_cast<size_type>(-1);
+
+    private:
+      size_type
+      _M_check(size_type __pos, const char* __s) const
+      {
+	if (__pos > this->size())
+	  std::__throw_out_of_range(__N(__s));
+	return __pos;
+      }
+
+      void
+      _M_check_length(size_type __n1, size_type __n2, const char* __s) const
+      {
+	if (this->max_size() - (this->size() - __n1) < __n2)
+	  std::__throw_length_error(__N(__s));
+      }
+
+      // NB: _M_limit doesn't check for a bad __pos value.
+      size_type
+      _M_limit(size_type __pos, size_type __off) const
+      {
+	const bool __testoff =  __off < this->size() - __pos;
+	return __testoff ? __off : this->size() - __pos;
+      }
+
+      // True if _Rep and source do not overlap.
+      bool
+      _M_disjunct(const _CharT* __s) const
+      {
+	return (std::less<const _CharT*>()(__s, this->_M_data())
+		|| std::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_length()); }
+
+    public:
+      // Construct/copy/destroy:
+      // NB: We overload ctors in some cases instead of using default
+      // arguments, per 17.4.4.4 para. 2 item 2.
+
+      /**
+       *  @brief  Default constructor creates an empty string.
+       */
+      __versa_string()
+      : __vstring_base() { }
+      
+      /**
+       *  @brief  Construct an empty string using allocator @a a.
+       */
+      explicit
+      __versa_string(const _Alloc& __a)
+      : __vstring_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.
+       */
+      __versa_string(const __versa_string& __str)
+      : __vstring_base(__str) { }
+
+      /**
+       *  @brief  Construct string as copy of a substring.
+       *  @param  str  Source string.
+       *  @param  pos  Index of first character to copy from.
+       *  @param  n  Number of characters to copy (default remainder).
+       */
+      __versa_string(const __versa_string& __str, size_type __pos,
+		     size_type __n = npos)
+      : __vstring_base(__str._M_data()
+		       + __str._M_check(__pos,
+					"__versa_string::__versa_string"),
+		       __str._M_data() + __str._M_limit(__pos, __n)
+		       + __pos, _Alloc()) { }
+
+      /**
+       *  @brief  Construct string as copy of a substring.
+       *  @param  str  Source string.
+       *  @param  pos  Index of first character to copy from.
+       *  @param  n  Number of characters to copy.
+       *  @param  a  Allocator to use.
+       */
+      __versa_string(const __versa_string& __str, size_type __pos,
+		     size_type __n, const _Alloc& __a)
+      : __vstring_base(__str._M_data()
+		       + __str._M_check(__pos,
+					"__versa_string::__versa_string"),
+		       __str._M_data() + __str._M_limit(__pos, __n)
+		       + __pos, __a) { }
+
+      /**
+       *  @brief  Construct string initialized by a character array.
+       *  @param  s  Source character array.
+       *  @param  n  Number of characters to copy.
+       *  @param  a  Allocator to use (default is default allocator).
+       *
+       *  NB: @a s must have at least @a n characters, '\0' has no special
+       *  meaning.
+       */
+      __versa_string(const _CharT* __s, size_type __n,
+		     const _Alloc& __a = _Alloc())
+      : __vstring_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).
+       */
+      __versa_string(const _CharT* __s, const _Alloc& __a = _Alloc())
+      : __vstring_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).
+       */
+      __versa_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc())
+      : __vstring_base(__n, __c, __a) { }
+
+      /**
+       *  @brief  Construct string as copy of a range.
+       *  @param  beg  Start of range.
+       *  @param  end  End of range.
+       *  @param  a  Allocator to use (default is default allocator).
+       */
+      template<class _InputIterator>
+        __versa_string(_InputIterator __beg, _InputIterator __end,
+		       const _Alloc& __a = _Alloc())
+	: __vstring_base(__beg, __end, __a) { }
+
+      /**
+       *  @brief  Destroy the string instance.
+       */
+      ~__versa_string() { }	
+
+      /**
+       *  @brief  Assign the value of @a str to this string.
+       *  @param  str  Source string.
+       */
+      __versa_string&
+      operator=(const __versa_string& __str) 
+      { return this->assign(__str); }
+
+      /**
+       *  @brief  Copy contents of @a s into this string.
+       *  @param  s  Source null-terminated string.
+       */
+      __versa_string&
+      operator=(const _CharT* __s) 
+      { return this->assign(__s); }
+
+      /**
+       *  @brief  Set value to string of length 1.
+       *  @param  c  Source character.
+       *
+       *  Assigning to a character makes this string length 1 and
+       *  (*this)[0] == @a c.
+       */
+      __versa_string&
+      operator=(_CharT __c) 
+      { 
+	this->assign(1, __c); 
+	return *this;
+      }
+
+      // Iterators:
+      /**
+       *  Returns a read/write iterator that points to the first character in
+       *  the %string.  Unshares the string.
+       */
+      iterator
+      begin()
+      {
+	this->_M_leak();
+	return iterator(this->_M_data());
+      }
+
+      /**
+       *  Returns a read-only (constant) iterator that points to the first
+       *  character in the %string.
+       */
+      const_iterator
+      begin() const
+      { return const_iterator(this->_M_data()); }
+
+      /**
+       *  Returns a read/write iterator that points one past the last
+       *  character in the %string.  Unshares the string.
+       */
+      iterator
+      end()
+      {
+	this->_M_leak();
+	return iterator(this->_M_data() + this->size());
+      }
+
+      /**
+       *  Returns a read-only (constant) iterator that points one past the
+       *  last character in the %string.
+       */
+      const_iterator
+      end() const
+      { return const_iterator(this->_M_data() + this->size()); }
+
+      /**
+       *  Returns a read/write reverse iterator that points to the last
+       *  character in the %string.  Iteration is done in reverse element
+       *  order.  Unshares the string.
+       */
+      reverse_iterator
+      rbegin()
+      { return reverse_iterator(this->end()); }
+
+      /**
+       *  Returns a read-only (constant) reverse iterator that points
+       *  to the last character in the %string.  Iteration is done in
+       *  reverse element order.
+       */
+      const_reverse_iterator
+      rbegin() const
+      { return const_reverse_iterator(this->end()); }
+
+      /**
+       *  Returns a read/write reverse iterator that points to one before the
+       *  first character in the %string.  Iteration is done in reverse
+       *  element order.  Unshares the string.
+       */
+      reverse_iterator
+      rend()
+      { return reverse_iterator(this->begin()); }
+
+      /**
+       *  Returns a read-only (constant) reverse iterator that points
+       *  to one before the first character in the %string.  Iteration
+       *  is done in reverse element order.
+       */
+      const_reverse_iterator
+      rend() const
+      { return const_reverse_iterator(this->begin()); }
+
+    public:
+      // Capacity:
+      ///  Returns the number of characters in the string, not including any
+      ///  null-termination.
+      size_type
+      size() const
+      { return this->_M_length(); }
+
+      ///  Returns the number of characters in the string, not including any
+      ///  null-termination.
+      size_type
+      length() const
+      { return this->_M_length(); }
+
+      /// Returns the size() of the largest possible %string.
+      size_type
+      max_size() const
+      { return __vstring_base::_S_max_size; }
+
+      /**
+       *  @brief  Resizes the %string to the specified number of characters.
+       *  @param  n  Number of characters the %string should contain.
+       *  @param  c  Character to fill any new elements.
+       *
+       *  This function will %resize the %string to the specified
+       *  number of characters.  If the number is smaller than the
+       *  %string's current size the %string is truncated, otherwise
+       *  the %string is extended and new elements are set to @a c.
+       */
+      void
+      resize(size_type __n, _CharT __c);
+
+      /**
+       *  @brief  Resizes the %string to the specified number of characters.
+       *  @param  n  Number of characters the %string should contain.
+       *
+       *  This function will resize the %string to the specified length.  If
+       *  the new size is smaller than the %string's current size the %string
+       *  is truncated, otherwise the %string is extended and new characters
+       *  are default-constructed.  For basic types such as char, this means
+       *  setting them to 0.
+       */
+      void
+      resize(size_type __n)
+      { this->resize(__n, _CharT()); }
+
+      /**
+       *  Returns the total number of characters that the %string can hold
+       *  before needing to allocate more memory.
+       */
+      size_type
+      capacity() const
+      { return this->_M_capacity(); }
+
+      /**
+       *  @brief  Attempt to preallocate enough memory for specified number of
+       *          characters.
+       *  @param  res_arg  Number of characters required.
+       *  @throw  std::length_error  If @a res_arg exceeds @c max_size().
+       *
+       *  This function attempts to reserve enough memory for the
+       *  %string to hold the specified number of characters.  If the
+       *  number requested is more than max_size(), length_error is
+       *  thrown.
+       *
+       *  The advantage of this function is that if optimal code is a
+       *  necessity and the user can determine the string length that will be
+       *  required, the user can reserve the memory in %advance, and thus
+       *  prevent a possible reallocation of memory and copying of %string
+       *  data.
+       */
+      void
+      reserve(size_type __res_arg = 0)
+      {	this->_M_reserve(__res_arg); }
+
+      /**
+       *  Erases the string, making it empty.
+       */
+      void
+      clear()
+      { this->_M_mutate(0, this->size(), 0); }
+
+      /**
+       *  Returns true if the %string is empty.  Equivalent to *this == "".
+       */
+      bool
+      empty() const
+      { return this->size() == 0; }
+
+      // Element access:
+      /**
+       *  @brief  Subscript access to the data contained in the %string.
+       *  @param  pos  The index of the character to access.
+       *  @return  Read-only (constant) reference to the character.
+       *
+       *  This operator allows for easy, array-style, data access.
+       *  Note that data access with this operator is unchecked and
+       *  out_of_range lookups are not defined. (For checked lookups
+       *  see at().)
+       */
+      const_reference
+      operator[] (size_type __pos) const
+      {
+	_GLIBCXX_DEBUG_ASSERT(__pos <= this->size());
+	return this->_M_data()[__pos];
+      }
+
+      /**
+       *  @brief  Subscript access to the data contained in the %string.
+       *  @param  pos  The index of the character to access.
+       *  @return  Read/write reference to the character.
+       *
+       *  This operator allows for easy, array-style, data access.
+       *  Note that data access with this operator is unchecked and
+       *  out_of_range lookups are not defined. (For checked lookups
+       *  see at().)  Unshares the string.
+       */
+      reference
+      operator[](size_type __pos)
+      {
+	_GLIBCXX_DEBUG_ASSERT(__pos < this->size());
+	this->_M_leak();
+	return this->_M_data()[__pos];
+      }
+
+      /**
+       *  @brief  Provides access to the data contained in the %string.
+       *  @param n The index of the character to access.
+       *  @return  Read-only (const) reference to the character.
+       *  @throw  std::out_of_range  If @a n is an invalid index.
+       *
+       *  This function provides for safer data access.  The parameter is
+       *  first checked that it is in the range of the string.  The function
+       *  throws out_of_range if the check fails.
+       */
+      const_reference
+      at(size_type __n) const
+      {
+	if (__n >= this->size())
+	  std::__throw_out_of_range(__N("__versa_string::at"));
+	return this->_M_data()[__n];
+      }
+
+      /**
+       *  @brief  Provides access to the data contained in the %string.
+       *  @param n The index of the character to access.
+       *  @return  Read/write reference to the character.
+       *  @throw  std::out_of_range  If @a n is an invalid index.
+       *
+       *  This function provides for safer data access.  The parameter is
+       *  first checked that it is in the range of the string.  The function
+       *  throws out_of_range if the check fails.  Success results in
+       *  unsharing the string.
+       */
+      reference
+      at(size_type __n)
+      {
+	if (__n >= this->size())
+	  std::__throw_out_of_range(__N("__versa_string::at"));
+	this->_M_leak();
+	return this->_M_data()[__n];
+      }
+
+      // Modifiers:
+      /**
+       *  @brief  Append a string to this string.
+       *  @param str  The string to append.
+       *  @return  Reference to this string.
+       */
+      __versa_string&
+      operator+=(const __versa_string& __str)
+      { return this->append(__str); }
+
+      /**
+       *  @brief  Append a C string.
+       *  @param s  The C string to append.
+       *  @return  Reference to this string.
+       */
+      __versa_string&
+      operator+=(const _CharT* __s)
+      { return this->append(__s); }
+
+      /**
+       *  @brief  Append a character.
+       *  @param c  The character to append.
+       *  @return  Reference to this string.
+       */
+      __versa_string&
+      operator+=(_CharT __c)
+      { 
+	this->push_back(__c);
+	return *this;
+      }
+
+      /**
+       *  @brief  Append a string to this string.
+       *  @param str  The string to append.
+       *  @return  Reference to this string.
+       */
+      __versa_string&
+      append(const __versa_string& __str);
+
+      /**
+       *  @brief  Append a substring.
+       *  @param str  The string to append.
+       *  @param pos  Index of the first character of str to append.
+       *  @param n  The number of characters to append.
+       *  @return  Reference to this string.
+       *  @throw  std::out_of_range if @a pos is not a valid index.
+       *
+       *  This function appends @a n characters from @a str starting at @a pos
+       *  to this string.  If @a n is is larger than the number of available
+       *  characters in @a str, the remainder of @a str is appended.
+       */
+      __versa_string&
+      append(const __versa_string& __str, size_type __pos, size_type __n);
+
+      /**
+       *  @brief  Append a C substring.
+       *  @param s  The C string to append.
+       *  @param n  The number of characters to append.
+       *  @return  Reference to this string.
+       */
+      __versa_string&
+      append(const _CharT* __s, size_type __n);
+
+      /**
+       *  @brief  Append a C string.
+       *  @param s  The C string to append.
+       *  @return  Reference to this string.
+       */
+      __versa_string&
+      append(const _CharT* __s)
+      {
+	__glibcxx_requires_string(__s);
+	return this->append(__s, traits_type::length(__s));
+      }
+
+      /**
+       *  @brief  Append multiple characters.
+       *  @param n  The number of characters to append.
+       *  @param c  The character to use.
+       *  @return  Reference to this string.
+       *
+       *  Appends n copies of c to this string.
+       */
+      __versa_string&
+      append(size_type __n, _CharT __c);
+
+      /**
+       *  @brief  Append a range of characters.
+       *  @param first  Iterator referencing the first character to append.
+       *  @param last  Iterator marking the end of the range.
+       *  @return  Reference to this string.
+       *
+       *  Appends characters in the range [first,last) to this string.
+       */
+      template<class _InputIterator>
+        __versa_string&
+        append(_InputIterator __first, _InputIterator __last)
+        { return this->replace(_M_iend(), _M_iend(), __first, __last); }
+
+      /**
+       *  @brief  Append a single character.
+       *  @param c  Character to append.
+       */
+      void
+      push_back(_CharT __c)
+      { 
+	const size_type __len = 1 + this->size();
+	if (__len > this->capacity() || this->_M_is_shared())
+	  this->reserve(__len);
+	traits_type::assign(this->_M_data()[this->size()], __c);
+	this->_M_set_length(__len);
+      }
+
+      /**
+       *  @brief  Set value to contents of another string.
+       *  @param  str  Source string to use.
+       *  @return  Reference to this string.
+       */
+      __versa_string&
+      assign(const __versa_string& __str)
+      {
+	this->_M_assign(__str);
+	return *this;
+      }
+
+      /**
+       *  @brief  Set value to a substring of a string.
+       *  @param str  The string to use.
+       *  @param pos  Index of the first character of str.
+       *  @param n  Number of characters to use.
+       *  @return  Reference to this string.
+       *  @throw  std::out_of_range if @a pos is not a valid index.
+       *
+       *  This function sets this string to the substring of @a str consisting
+       *  of @a n characters at @a pos.  If @a n is is larger than the number
+       *  of available characters in @a str, the remainder of @a str is used.
+       */
+      __versa_string&
+      assign(const __versa_string& __str, size_type __pos, size_type __n)
+      { return this->assign(__str._M_data()
+			    + __str._M_check(__pos, "__versa_string::assign"),
+			    __str._M_limit(__pos, __n)); }
+
+      /**
+       *  @brief  Set value to a C substring.
+       *  @param s  The C string to use.
+       *  @param n  Number of characters to use.
+       *  @return  Reference to this string.
+       *
+       *  This function sets the value of this string to the first @a n
+       *  characters of @a s.  If @a n is is larger than the number of
+       *  available characters in @a s, the remainder of @a s is used.
+       */
+      __versa_string&
+      assign(const _CharT* __s, size_type __n);
+
+      /**
+       *  @brief  Set value to contents of a C string.
+       *  @param s  The C string to use.
+       *  @return  Reference to this string.
+       *
+       *  This function sets the value of this string to the value of @a s.
+       *  The data is copied, so there is no dependence on @a s once the
+       *  function returns.
+       */
+      __versa_string&
+      assign(const _CharT* __s)
+      {
+	__glibcxx_requires_string(__s);
+	return this->assign(__s, traits_type::length(__s));
+      }
+
+      /**
+       *  @brief  Set value to multiple characters.
+       *  @param n  Length of the resulting string.
+       *  @param c  The character to use.
+       *  @return  Reference to this string.
+       *
+       *  This function sets the value of this string to @a n copies of
+       *  character @a c.
+       */
+      __versa_string&
+      assign(size_type __n, _CharT __c)
+      { return _M_replace_aux(size_type(0), this->size(), __n, __c); }
+
+      /**
+       *  @brief  Set value to a range of characters.
+       *  @param first  Iterator referencing the first character to append.
+       *  @param last  Iterator marking the end of the range.
+       *  @return  Reference to this string.
+       *
+       *  Sets value of string to characters in the range [first,last).
+      */
+      template<class _InputIterator>
+        __versa_string&
+        assign(_InputIterator __first, _InputIterator __last)
+        { return this->replace(_M_ibegin(), _M_iend(), __first, __last); }
+
+      /**
+       *  @brief  Insert multiple characters.
+       *  @param p  Iterator referencing location in string to insert at.
+       *  @param n  Number of characters to insert
+       *  @param c  The character to insert.
+       *  @throw  std::length_error  If new length exceeds @c max_size().
+       *
+       *  Inserts @a n copies of character @a c starting at the position
+       *  referenced by iterator @a p.  If adding characters causes the length
+       *  to exceed max_size(), length_error is thrown.  The value of the
+       *  string doesn't change if an error is thrown.
+      */
+      void
+      insert(iterator __p, size_type __n, _CharT __c)
+      {	this->replace(__p, __p, __n, __c);  }
+
+      /**
+       *  @brief  Insert a range of characters.
+       *  @param p  Iterator referencing location in string to insert at.
+       *  @param beg  Start of range.
+       *  @param end  End of range.
+       *  @throw  std::length_error  If new length exceeds @c max_size().
+       *
+       *  Inserts characters in range [beg,end).  If adding characters causes
+       *  the length to exceed max_size(), length_error is thrown.  The value
+       *  of the string doesn't change if an error is thrown.
+      */
+      template<class _InputIterator>
+        void
+        insert(iterator __p, _InputIterator __beg, _InputIterator __end)
+        { this->replace(__p, __p, __beg, __end); }
+
+      /**
+       *  @brief  Insert value of a string.
+       *  @param pos1  Iterator referencing location in string to insert at.
+       *  @param str  The string to insert.
+       *  @return  Reference to this string.
+       *  @throw  std::length_error  If new length exceeds @c max_size().
+       *
+       *  Inserts value of @a str starting at @a pos1.  If adding characters
+       *  causes the length to exceed max_size(), length_error is thrown.  The
+       *  value of the string doesn't change if an error is thrown.
+      */
+      __versa_string&
+      insert(size_type __pos1, const __versa_string& __str)
+      { return this->insert(__pos1, __str, size_type(0), __str.size()); }
+
+      /**
+       *  @brief  Insert a substring.
+       *  @param pos1  Iterator referencing location in string to insert at.
+       *  @param str  The string to insert.
+       *  @param pos2  Start of characters in str to insert.
+       *  @param n  Number of characters to insert.
+       *  @return  Reference to this string.
+       *  @throw  std::length_error  If new length exceeds @c max_size().
+       *  @throw  std::out_of_range  If @a pos1 > size() or
+       *  @a pos2 > @a str.size().
+       *
+       *  Starting at @a pos1, insert @a n character of @a str beginning with
+       *  @a pos2.  If adding characters causes the length to exceed
+       *  max_size(), length_error is thrown.  If @a pos1 is beyond the end of
+       *  this string or @a pos2 is beyond the end of @a str, out_of_range is
+       *  thrown.  The value of the string doesn't change if an error is
+       *  thrown.
+      */
+      __versa_string&
+      insert(size_type __pos1, const __versa_string& __str,
+	     size_type __pos2, size_type __n)
+      { return this->insert(__pos1, __str._M_data()
+			    + __str._M_check(__pos2, "__versa_string::insert"),
+			    __str._M_limit(__pos2, __n)); }
+
+      /**
+       *  @brief  Insert a C substring.
+       *  @param pos  Iterator referencing location in string to insert at.
+       *  @param s  The C string to insert.
+       *  @param n  The number of characters to insert.
+       *  @return  Reference to this string.
+       *  @throw  std::length_error  If new length exceeds @c max_size().
+       *  @throw  std::out_of_range  If @a pos is beyond the end of this
+       *  string.
+       *
+       *  Inserts the first @a n characters of @a s starting at @a pos.  If
+       *  adding characters causes the length to exceed max_size(),
+       *  length_error is thrown.  If @a pos is beyond end(), out_of_range is
+       *  thrown.  The value of the string doesn't change if an error is
+       *  thrown.
+      */
+      __versa_string&
+      insert(size_type __pos, const _CharT* __s, size_type __n);
+
+      /**
+       *  @brief  Insert a C string.
+       *  @param pos  Iterator referencing location in string to insert at.
+       *  @param s  The C string to insert.
+       *  @return  Reference to this string.
+       *  @throw  std::length_error  If new length exceeds @c max_size().
+       *  @throw  std::out_of_range  If @a pos is beyond the end of this
+       *  string.
+       *
+       *  Inserts the first @a n characters of @a s starting at @a pos.  If
+       *  adding characters causes the length to exceed max_size(),
+       *  length_error is thrown.  If @a pos is beyond end(), out_of_range is
+       *  thrown.  The value of the string doesn't change if an error is
+       *  thrown.
+      */
+      __versa_string&
+      insert(size_type __pos, const _CharT* __s)
+      {
+	__glibcxx_requires_string(__s);
+	return this->insert(__pos, __s, traits_type::length(__s));
+      }
+
+      /**
+       *  @brief  Insert multiple characters.
+       *  @param pos  Index in string to insert at.
+       *  @param n  Number of characters to insert
+       *  @param c  The character to insert.
+       *  @return  Reference to this string.
+       *  @throw  std::length_error  If new length exceeds @c max_size().
+       *  @throw  std::out_of_range  If @a pos is beyond the end of this
+       *  string.
+       *
+       *  Inserts @a n copies of character @a c starting at index @a pos.  If
+       *  adding characters causes the length to exceed max_size(),
+       *  length_error is thrown.  If @a pos > length(), out_of_range is
+       *  thrown.  The value of the string doesn't change if an error is
+       *  thrown.
+      */
+      __versa_string&
+      insert(size_type __pos, size_type __n, _CharT __c)
+      { return _M_replace_aux(_M_check(__pos, "__versa_string::insert"),
+			      size_type(0), __n, __c); }
+
+      /**
+       *  @brief  Insert one character.
+       *  @param p  Iterator referencing position in string to insert at.
+       *  @param c  The character to insert.
+       *  @return  Iterator referencing newly inserted char.
+       *  @throw  std::length_error  If new length exceeds @c max_size().
+       *
+       *  Inserts character @a c at position referenced by @a p.  If adding
+       *  character causes the length to exceed max_size(), length_error is
+       *  thrown.  If @a p is beyond end of string, out_of_range is thrown.
+       *  The value of the string doesn't change if an error is thrown.
+      */
+      iterator
+      insert(iterator __p, _CharT __c)
+      {
+	_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_set_leaked();
+	return _M_ibegin() + __pos;
+      }
+
+      /**
+       *  @brief  Remove characters.
+       *  @param pos  Index of first character to remove (default 0).
+       *  @param n  Number of characters to remove (default remainder).
+       *  @return  Reference to this string.
+       *  @throw  std::out_of_range  If @a pos is beyond the end of this
+       *  string.
+       *
+       *  Removes @a n characters from this string starting at @a pos.  The
+       *  length of the string is reduced by @a n.  If there are < @a n
+       *  characters to remove, the remainder of the string is truncated.  If
+       *  @a p is beyond end of string, out_of_range is thrown.  The value of
+       *  the string doesn't change if an error is thrown.
+      */
+      __versa_string&
+      erase(size_type __pos = 0, size_type __n = npos)
+      { 
+	this->_M_mutate(_M_check(__pos, "__versa_string::erase"),
+			_M_limit(__pos, __n), size_type(0));
+	return *this;
+      }
+
+      /**
+       *  @brief  Remove one character.
+       *  @param position  Iterator referencing the character to remove.
+       *  @return  iterator referencing same location after removal.
+       *
+       *  Removes the character at @a position from this string. The value
+       *  of the string doesn't change if an error is thrown.
+      */
+      iterator
+      erase(iterator __position)
+      {
+	_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_set_leaked();
+	return _M_ibegin() + __pos;
+      }
+
+      /**
+       *  @brief  Remove a range of characters.
+       *  @param first  Iterator referencing the first character to remove.
+       *  @param last  Iterator referencing the end of the range.
+       *  @return  Iterator referencing location of first after removal.
+       *
+       *  Removes the characters in the range [first,last) from this string.
+       *  The value of the string doesn't change if an error is thrown.
+      */
+      iterator
+      erase(iterator __first, iterator __last)
+      {
+	_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_set_leaked();
+	return _M_ibegin() + __pos;
+      }
+
+      /**
+       *  @brief  Replace characters with value from another string.
+       *  @param pos  Index of first character to replace.
+       *  @param n  Number of characters to be replaced.
+       *  @param str  String to insert.
+       *  @return  Reference to this string.
+       *  @throw  std::out_of_range  If @a pos is beyond the end of this
+       *  string.
+       *  @throw  std::length_error  If new length exceeds @c max_size().
+       *
+       *  Removes the characters in the range [pos,pos+n) from this string.
+       *  In place, the value of @a str is inserted.  If @a pos is beyond end
+       *  of string, out_of_range is thrown.  If the length of the result
+       *  exceeds max_size(), length_error is thrown.  The value of the string
+       *  doesn't change if an error is thrown.
+      */
+      __versa_string&
+      replace(size_type __pos, size_type __n, const __versa_string& __str)
+      { return this->replace(__pos, __n, __str._M_data(), __str.size()); }
+
+      /**
+       *  @brief  Replace characters with value from another string.
+       *  @param pos1  Index of first character to replace.
+       *  @param n1  Number of characters to be replaced.
+       *  @param str  String to insert.
+       *  @param pos2  Index of first character of str to use.
+       *  @param n2  Number of characters from str to use.
+       *  @return  Reference to this string.
+       *  @throw  std::out_of_range  If @a pos1 > size() or @a pos2 >
+       *  str.size().
+       *  @throw  std::length_error  If new length exceeds @c max_size().
+       *
+       *  Removes the characters in the range [pos1,pos1 + n) from this
+       *  string.  In place, the value of @a str is inserted.  If @a pos is
+       *  beyond end of string, out_of_range is thrown.  If the length of the
+       *  result exceeds max_size(), length_error is thrown.  The value of the
+       *  string doesn't change if an error is thrown.
+      */
+      __versa_string&
+      replace(size_type __pos1, size_type __n1, const __versa_string& __str,
+	      size_type __pos2, size_type __n2)
+      {
+	return this->replace(__pos1, __n1, __str._M_data()
+			     + __str._M_check(__pos2,
+					      "__versa_string::replace"),
+			     __str._M_limit(__pos2, __n2));
+      }
+
+      /**
+       *  @brief  Replace characters with value of a C substring.
+       *  @param pos  Index of first character to replace.
+       *  @param n1  Number of characters to be replaced.
+       *  @param s  C string to insert.
+       *  @param n2  Number of characters from @a s to use.
+       *  @return  Reference to this string.
+       *  @throw  std::out_of_range  If @a pos1 > size().
+       *  @throw  std::length_error  If new length exceeds @c max_size().
+       *
+       *  Removes the characters in the range [pos,pos + n1) from this string.
+       *  In place, the first @a n2 characters of @a s are inserted, or all
+       *  of @a s if @a n2 is too large.  If @a pos is beyond end of string,
+       *  out_of_range is thrown.  If the length of result exceeds max_size(),
+       *  length_error is thrown.  The value of the string doesn't change if
+       *  an error is thrown.
+      */
+      __versa_string&
+      replace(size_type __pos, size_type __n1, const _CharT* __s,
+	      size_type __n2);
+
+      /**
+       *  @brief  Replace characters with value of a C string.
+       *  @param pos  Index of first character to replace.
+       *  @param n1  Number of characters to be replaced.
+       *  @param s  C string to insert.
+       *  @return  Reference to this string.
+       *  @throw  std::out_of_range  If @a pos > size().
+       *  @throw  std::length_error  If new length exceeds @c max_size().
+       *
+       *  Removes the characters in the range [pos,pos + n1) from this string.
+       *  In place, the first @a n characters of @a s are inserted.  If @a
+       *  pos is beyond end of string, out_of_range is thrown.  If the length
+       *  of result exceeds max_size(), length_error is thrown.  The value of
+       *  the string doesn't change if an error is thrown.
+      */
+      __versa_string&
+      replace(size_type __pos, size_type __n1, const _CharT* __s)
+      {
+	__glibcxx_requires_string(__s);
+	return this->replace(__pos, __n1, __s, traits_type::length(__s));
+      }
+
+      /**
+       *  @brief  Replace characters with multiple characters.
+       *  @param pos  Index of first character to replace.
+       *  @param n1  Number of characters to be replaced.
+       *  @param n2  Number of characters to insert.
+       *  @param c  Character to insert.
+       *  @return  Reference to this string.
+       *  @throw  std::out_of_range  If @a pos > size().
+       *  @throw  std::length_error  If new length exceeds @c max_size().
+       *
+       *  Removes the characters in the range [pos,pos + n1) from this string.
+       *  In place, @a n2 copies of @a c are inserted.  If @a pos is beyond
+       *  end of string, out_of_range is thrown.  If the length of result
+       *  exceeds max_size(), length_error is thrown.  The value of the string
+       *  doesn't change if an error is thrown.
+      */
+      __versa_string&
+      replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
+      { return _M_replace_aux(_M_check(__pos, "__versa_string::replace"),
+			      _M_limit(__pos, __n1), __n2, __c); }
+
+      /**
+       *  @brief  Replace range of characters with string.
+       *  @param i1  Iterator referencing start of range to replace.
+       *  @param i2  Iterator referencing end of range to replace.
+       *  @param str  String value to insert.
+       *  @return  Reference to this string.
+       *  @throw  std::length_error  If new length exceeds @c max_size().
+       *
+       *  Removes the characters in the range [i1,i2).  In place, the value of
+       *  @a str is inserted.  If the length of result exceeds max_size(),
+       *  length_error is thrown.  The value of the string doesn't change if
+       *  an error is thrown.
+      */
+      __versa_string&
+      replace(iterator __i1, iterator __i2, const __versa_string& __str)
+      { return this->replace(__i1, __i2, __str._M_data(), __str.size()); }
+
+      /**
+       *  @brief  Replace range of characters with C substring.
+       *  @param i1  Iterator referencing start of range to replace.
+       *  @param i2  Iterator referencing end of range to replace.
+       *  @param s  C string value to insert.
+       *  @param n  Number of characters from s to insert.
+       *  @return  Reference to this string.
+       *  @throw  std::length_error  If new length exceeds @c max_size().
+       *
+       *  Removes the characters in the range [i1,i2).  In place, the first @a
+       *  n characters of @a s are inserted.  If the length of result exceeds
+       *  max_size(), length_error is thrown.  The value of the string doesn't
+       *  change if an error is thrown.
+      */
+      __versa_string&
+      replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n)
+      {
+	_GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
+				 && __i2 <= _M_iend());
+	return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n);
+      }
+
+      /**
+       *  @brief  Replace range of characters with C string.
+       *  @param i1  Iterator referencing start of range to replace.
+       *  @param i2  Iterator referencing end of range to replace.
+       *  @param s  C string value to insert.
+       *  @return  Reference to this string.
+       *  @throw  std::length_error  If new length exceeds @c max_size().
+       *
+       *  Removes the characters in the range [i1,i2).  In place, the
+       *  characters of @a s are inserted.  If the length of result exceeds
+       *  max_size(), length_error is thrown.  The value of the string doesn't
+       *  change if an error is thrown.
+      */
+      __versa_string&
+      replace(iterator __i1, iterator __i2, const _CharT* __s)
+      {
+	__glibcxx_requires_string(__s);
+	return this->replace(__i1, __i2, __s, traits_type::length(__s));
+      }
+
+      /**
+       *  @brief  Replace range of characters with multiple characters
+       *  @param i1  Iterator referencing start of range to replace.
+       *  @param i2  Iterator referencing end of range to replace.
+       *  @param n  Number of characters to insert.
+       *  @param c  Character to insert.
+       *  @return  Reference to this string.
+       *  @throw  std::length_error  If new length exceeds @c max_size().
+       *
+       *  Removes the characters in the range [i1,i2).  In place, @a n copies
+       *  of @a c are inserted.  If the length of result exceeds max_size(),
+       *  length_error is thrown.  The value of the string doesn't change if
+       *  an error is thrown.
+      */
+      __versa_string&
+      replace(iterator __i1, iterator __i2, size_type __n, _CharT __c)
+      {
+	_GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
+				 && __i2 <= _M_iend());
+	return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __c);
+      }
+
+      /**
+       *  @brief  Replace range of characters with range.
+       *  @param i1  Iterator referencing start of range to replace.
+       *  @param i2  Iterator referencing end of range to replace.
+       *  @param k1  Iterator referencing start of range to insert.
+       *  @param k2  Iterator referencing end of range to insert.
+       *  @return  Reference to this string.
+       *  @throw  std::length_error  If new length exceeds @c max_size().
+       *
+       *  Removes the characters in the range [i1,i2).  In place, characters
+       *  in the range [k1,k2) are inserted.  If the length of result exceeds
+       *  max_size(), length_error is thrown.  The value of the string doesn't
+       *  change if an error is thrown.
+      */
+      template<class _InputIterator>
+        __versa_string&
+        replace(iterator __i1, iterator __i2,
+		_InputIterator __k1, _InputIterator __k2)
+        {
+	  _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
+				   && __i2 <= _M_iend());
+	  __glibcxx_requires_valid_range(__k1, __k2);
+	  typedef typename std::__is_integer<_InputIterator>::__type _Integral;
+	  return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral());
+	}
+
+      // Specializations for the common case of pointer and iterator:
+      // useful to avoid the overhead of temporary buffering in _M_replace.
+      __versa_string&
+      replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2)
+      {
+	_GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
+				 && __i2 <= _M_iend());
+	__glibcxx_requires_valid_range(__k1, __k2);
+	return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
+			     __k1, __k2 - __k1);
+      }
+
+      __versa_string&
+      replace(iterator __i1, iterator __i2,
+	      const _CharT* __k1, const _CharT* __k2)
+      {
+	_GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
+				 && __i2 <= _M_iend());
+	__glibcxx_requires_valid_range(__k1, __k2);
+	return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
+			     __k1, __k2 - __k1);
+      }
+
+      __versa_string&
+      replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2)
+      {
+	_GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
+				 && __i2 <= _M_iend());
+	__glibcxx_requires_valid_range(__k1, __k2);
+	return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
+			     __k1.base(), __k2 - __k1);
+      }
+
+      __versa_string&
+      replace(iterator __i1, iterator __i2,
+	      const_iterator __k1, const_iterator __k2)
+      {
+	_GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
+				 && __i2 <= _M_iend());
+	__glibcxx_requires_valid_range(__k1, __k2);
+	return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
+			     __k1.base(), __k2 - __k1);
+      }
+      
+    private:
+      template<class _Integer>
+	__versa_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>
+	__versa_string&
+	_M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1,
+			    _InputIterator __k2, __false_type);
+
+      __versa_string&
+      _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
+		     _CharT __c);
+
+      __versa_string&
+      _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s,
+		      size_type __n2);
+
+    public:
+
+      /**
+       *  @brief  Copy substring into C string.
+       *  @param s  C string to copy value into.
+       *  @param n  Number of characters to copy.
+       *  @param pos  Index of first character to copy.
+       *  @return  Number of characters actually copied
+       *  @throw  std::out_of_range  If pos > size().
+       *
+       *  Copies up to @a n characters starting at @a pos into the C string @a
+       *  s.  If @a pos is greater than size(), out_of_range is thrown.
+      */
+      size_type
+      copy(_CharT* __s, size_type __n, size_type __pos = 0) const;
+
+      /**
+       *  @brief  Swap contents with another string.
+       *  @param s  String to swap with.
+       *
+       *  Exchanges the contents of this string with that of @a s in constant
+       *  time.
+      */
+      void
+      swap(__versa_string& __s);
+
+      // String operations:
+      /**
+       *  @brief  Return const pointer to null-terminated contents.
+       *
+       *  This is a handle to internal data.  Do not modify or dire things may
+       *  happen.
+      */
+      const _CharT*
+      c_str() const
+      { return this->_M_data(); }
+
+      /**
+       *  @brief  Return const pointer to contents.
+       *
+       *  This is a handle to internal data.  Do not modify or dire things may
+       *  happen.
+      */
+      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.
+       *  @param s  C string to locate.
+       *  @param pos  Index of character to search from.
+       *  @param n  Number of characters from @a s to search for.
+       *  @return  Index of start of first occurrence.
+       *
+       *  Starting from @a pos, searches forward for the first @a n characters
+       *  in @a s within this string.  If found, returns the index where it
+       *  begins.  If not found, returns npos.
+      */
+      size_type
+      find(const _CharT* __s, size_type __pos, size_type __n) const;
+
+      /**
+       *  @brief  Find position of a string.
+       *  @param str  String to locate.
+       *  @param pos  Index of character to search from (default 0).
+       *  @return  Index of start of first occurrence.
+       *
+       *  Starting from @a pos, searches forward for value of @a str within
+       *  this string.  If found, returns the index where it begins.  If not
+       *  found, returns npos.
+      */
+      size_type
+      find(const __versa_string& __str, size_type __pos = 0) const
+      { return this->find(__str.data(), __pos, __str.size()); }
+
+      /**
+       *  @brief  Find position of a C string.
+       *  @param s  C string to locate.
+       *  @param pos  Index of character to search from (default 0).
+       *  @return  Index of start of first occurrence.
+       *
+       *  Starting from @a pos, searches forward for the value of @a s within
+       *  this string.  If found, returns the index where it begins.  If not
+       *  found, returns npos.
+      */
+      size_type
+      find(const _CharT* __s, size_type __pos = 0) const
+      {
+	__glibcxx_requires_string(__s);
+	return this->find(__s, __pos, traits_type::length(__s));
+      }
+
+      /**
+       *  @brief  Find position of a character.
+       *  @param c  Character to locate.
+       *  @param pos  Index of character to search from (default 0).
+       *  @return  Index of first occurrence.
+       *
+       *  Starting from @a pos, searches forward for @a c within this string.
+       *  If found, returns the index where it was found.  If not found,
+       *  returns npos.
+      */
+      size_type
+      find(_CharT __c, size_type __pos = 0) const;
+
+      /**
+       *  @brief  Find last position of a string.
+       *  @param str  String to locate.
+       *  @param pos  Index of character to search back from (default end).
+       *  @return  Index of start of last occurrence.
+       *
+       *  Starting from @a pos, searches backward for value of @a str within
+       *  this string.  If found, returns the index where it begins.  If not
+       *  found, returns npos.
+      */
+      size_type
+      rfind(const __versa_string& __str, size_type __pos = npos) const
+      { return this->rfind(__str.data(), __pos, __str.size()); }
+
+      /**
+       *  @brief  Find last position of a C substring.
+       *  @param s  C string to locate.
+       *  @param pos  Index of character to search back from.
+       *  @param n  Number of characters from s to search for.
+       *  @return  Index of start of last occurrence.
+       *
+       *  Starting from @a pos, searches backward for the first @a n
+       *  characters in @a s within this string.  If found, returns the index
+       *  where it begins.  If not found, returns npos.
+      */
+      size_type
+      rfind(const _CharT* __s, size_type __pos, size_type __n) const;
+
+      /**
+       *  @brief  Find last position of a C string.
+       *  @param s  C string to locate.
+       *  @param pos  Index of character to start search at (default 0).
+       *  @return  Index of start of  last occurrence.
+       *
+       *  Starting from @a pos, searches backward for the value of @a s within
+       *  this string.  If found, returns the index where it begins.  If not
+       *  found, returns npos.
+      */
+      size_type
+      rfind(const _CharT* __s, size_type __pos = npos) const
+      {
+	__glibcxx_requires_string(__s);
+	return this->rfind(__s, __pos, traits_type::length(__s));
+      }
+
+      /**
+       *  @brief  Find last position of a character.
+       *  @param c  Character to locate.
+       *  @param pos  Index of character to search back from (default 0).
+       *  @return  Index of last occurrence.
+       *
+       *  Starting from @a pos, searches backward for @a c within this string.
+       *  If found, returns the index where it was found.  If not found,
+       *  returns npos.
+      */
+      size_type
+      rfind(_CharT __c, size_type __pos = npos) const;
+
+      /**
+       *  @brief  Find position of a character of string.
+       *  @param str  String containing characters to locate.
+       *  @param pos  Index of character to search from (default 0).
+       *  @return  Index of first occurrence.
+       *
+       *  Starting from @a pos, searches forward for one of the characters of
+       *  @a str within this string.  If found, returns the index where it was
+       *  found.  If not found, returns npos.
+      */
+      size_type
+      find_first_of(const __versa_string& __str, size_type __pos = 0) const
+      { return this->find_first_of(__str.data(), __pos, __str.size()); }
+
+      /**
+       *  @brief  Find position of a character of C substring.
+       *  @param s  String containing characters to locate.
+       *  @param pos  Index of character to search from (default 0).
+       *  @param n  Number of characters from s to search for.
+       *  @return  Index of first occurrence.
+       *
+       *  Starting from @a pos, searches forward for one of the first @a n
+       *  characters of @a s within this string.  If found, returns the index
+       *  where it was found.  If not found, returns npos.
+      */
+      size_type
+      find_first_of(const _CharT* __s, size_type __pos, size_type __n) const;
+
+      /**
+       *  @brief  Find position of a character of C string.
+       *  @param s  String containing characters to locate.
+       *  @param pos  Index of character to search from (default 0).
+       *  @return  Index of first occurrence.
+       *
+       *  Starting from @a pos, searches forward for one of the characters of
+       *  @a s within this string.  If found, returns the index where it was
+       *  found.  If not found, returns npos.
+      */
+      size_type
+      find_first_of(const _CharT* __s, size_type __pos = 0) const
+      {
+	__glibcxx_requires_string(__s);
+	return this->find_first_of(__s, __pos, traits_type::length(__s));
+      }
+
+      /**
+       *  @brief  Find position of a character.
+       *  @param c  Character to locate.
+       *  @param pos  Index of character to search from (default 0).
+       *  @return  Index of first occurrence.
+       *
+       *  Starting from @a pos, searches forward for the character @a c within
+       *  this string.  If found, returns the index where it was found.  If
+       *  not found, returns npos.
+       *
+       *  Note: equivalent to find(c, pos).
+      */
+      size_type
+      find_first_of(_CharT __c, size_type __pos = 0) const
+      { return this->find(__c, __pos); }
+
+      /**
+       *  @brief  Find last position of a character of string.
+       *  @param str  String containing characters to locate.
+       *  @param pos  Index of character to search back from (default end).
+       *  @return  Index of last occurrence.
+       *
+       *  Starting from @a pos, searches backward for one of the characters of
+       *  @a str within this string.  If found, returns the index where it was
+       *  found.  If not found, returns npos.
+      */
+      size_type
+      find_last_of(const __versa_string& __str, size_type __pos = npos) const
+      { return this->find_last_of(__str.data(), __pos, __str.size()); }
+
+      /**
+       *  @brief  Find last position of a character of C substring.
+       *  @param s  C string containing characters to locate.
+       *  @param pos  Index of character to search back from (default end).
+       *  @param n  Number of characters from s to search for.
+       *  @return  Index of last occurrence.
+       *
+       *  Starting from @a pos, searches backward for one of the first @a n
+       *  characters of @a s within this string.  If found, returns the index
+       *  where it was found.  If not found, returns npos.
+      */
+      size_type
+      find_last_of(const _CharT* __s, size_type __pos, size_type __n) const;
+
+      /**
+       *  @brief  Find last position of a character of C string.
+       *  @param s  C string containing characters to locate.
+       *  @param pos  Index of character to search back from (default end).
+       *  @return  Index of last occurrence.
+       *
+       *  Starting from @a pos, searches backward for one of the characters of
+       *  @a s within this string.  If found, returns the index where it was
+       *  found.  If not found, returns npos.
+      */
+      size_type
+      find_last_of(const _CharT* __s, size_type __pos = npos) const
+      {
+	__glibcxx_requires_string(__s);
+	return this->find_last_of(__s, __pos, traits_type::length(__s));
+      }
+
+      /**
+       *  @brief  Find last position of a character.
+       *  @param c  Character to locate.
+       *  @param pos  Index of character to search back from (default 0).
+       *  @return  Index of last occurrence.
+       *
+       *  Starting from @a pos, searches backward for @a c within this string.
+       *  If found, returns the index where it was found.  If not found,
+       *  returns npos.
+       *
+       *  Note: equivalent to rfind(c, pos).
+      */
+      size_type
+      find_last_of(_CharT __c, size_type __pos = npos) const
+      { return this->rfind(__c, __pos); }
+
+      /**
+       *  @brief  Find position of a character not in string.
+       *  @param str  String containing characters to avoid.
+       *  @param pos  Index of character to search from (default 0).
+       *  @return  Index of first occurrence.
+       *
+       *  Starting from @a pos, searches forward for a character not contained
+       *  in @a str within this string.  If found, returns the index where it
+       *  was found.  If not found, returns npos.
+      */
+      size_type
+      find_first_not_of(const __versa_string& __str, size_type __pos = 0) const
+      { return this->find_first_not_of(__str.data(), __pos, __str.size()); }
+
+      /**
+       *  @brief  Find position of a character not in C substring.
+       *  @param s  C string containing characters to avoid.
+       *  @param pos  Index of character to search from (default 0).
+       *  @param n  Number of characters from s to consider.
+       *  @return  Index of first occurrence.
+       *
+       *  Starting from @a pos, searches forward for a character not contained
+       *  in the first @a n characters of @a s within this string.  If found,
+       *  returns the index where it was found.  If not found, returns npos.
+      */
+      size_type
+      find_first_not_of(const _CharT* __s, size_type __pos,
+			size_type __n) const;
+
+      /**
+       *  @brief  Find position of a character not in C string.
+       *  @param s  C string containing characters to avoid.
+       *  @param pos  Index of character to search from (default 0).
+       *  @return  Index of first occurrence.
+       *
+       *  Starting from @a pos, searches forward for a character not contained
+       *  in @a s within this string.  If found, returns the index where it
+       *  was found.  If not found, returns npos.
+      */
+      size_type
+      find_first_not_of(const _CharT* __s, size_type __pos = 0) const
+      {
+	__glibcxx_requires_string(__s);
+	return this->find_first_not_of(__s, __pos, traits_type::length(__s));
+      }
+
+      /**
+       *  @brief  Find position of a different character.
+       *  @param c  Character to avoid.
+       *  @param pos  Index of character to search from (default 0).
+       *  @return  Index of first occurrence.
+       *
+       *  Starting from @a pos, searches forward for a character other than @a c
+       *  within this string.  If found, returns the index where it was found.
+       *  If not found, returns npos.
+      */
+      size_type
+      find_first_not_of(_CharT __c, size_type __pos = 0) const;
+
+      /**
+       *  @brief  Find last position of a character not in string.
+       *  @param str  String containing characters to avoid.
+       *  @param pos  Index of character to search from (default 0).
+       *  @return  Index of first occurrence.
+       *
+       *  Starting from @a pos, searches backward for a character not
+       *  contained in @a str within this string.  If found, returns the index
+       *  where it was found.  If not found, returns npos.
+      */
+      size_type
+      find_last_not_of(const __versa_string& __str,
+		       size_type __pos = npos) const
+      { return this->find_last_not_of(__str.data(), __pos, __str.size()); }
+
+      /**
+       *  @brief  Find last position of a character not in C substring.
+       *  @param s  C string containing characters to avoid.
+       *  @param pos  Index of character to search from (default 0).
+       *  @param n  Number of characters from s to consider.
+       *  @return  Index of first occurrence.
+       *
+       *  Starting from @a pos, searches backward for a character not
+       *  contained in the first @a n characters of @a s within this string.
+       *  If found, returns the index where it was found.  If not found,
+       *  returns npos.
+      */
+      size_type
+      find_last_not_of(const _CharT* __s, size_type __pos,
+		       size_type __n) const;
+      /**
+       *  @brief  Find position of a character not in C string.
+       *  @param s  C string containing characters to avoid.
+       *  @param pos  Index of character to search from (default 0).
+       *  @return  Index of first occurrence.
+       *
+       *  Starting from @a pos, searches backward for a character not
+       *  contained in @a s within this string.  If found, returns the index
+       *  where it was found.  If not found, returns npos.
+      */
+      size_type
+      find_last_not_of(const _CharT* __s, size_type __pos = npos) const
+      {
+	__glibcxx_requires_string(__s);
+	return this->find_last_not_of(__s, __pos, traits_type::length(__s));
+      }
+
+      /**
+       *  @brief  Find last position of a different character.
+       *  @param c  Character to avoid.
+       *  @param pos  Index of character to search from (default 0).
+       *  @return  Index of first occurrence.
+       *
+       *  Starting from @a pos, searches backward for a character other than
+       *  @a c within this string.  If found, returns the index where it was
+       *  found.  If not found, returns npos.
+      */
+      size_type
+      find_last_not_of(_CharT __c, size_type __pos = npos) const;
+
+      /**
+       *  @brief  Get a substring.
+       *  @param pos  Index of first character (default 0).
+       *  @param n  Number of characters in substring (default remainder).
+       *  @return  The new string.
+       *  @throw  std::out_of_range  If pos > size().
+       *
+       *  Construct and return a new string using the @a n characters starting
+       *  at @a pos.  If the string is too short, use the remainder of the
+       *  characters.  If @a pos is beyond the end of the string, out_of_range
+       *  is thrown.
+      */
+      __versa_string
+      substr(size_type __pos = 0, size_type __n = npos) const
+      {
+	return __versa_string(*this, _M_check(__pos, "__versa_string::substr"),
+			      __n);
+      }
+
+      /**
+       *  @brief  Compare to a string.
+       *  @param str  String to compare against.
+       *  @return  Integer < 0, 0, or > 0.
+       *
+       *  Returns an integer < 0 if this string is ordered before @a str, 0 if
+       *  their values are equivalent, or > 0 if this string is ordered after
+       *  @a str.  Determines the effective length rlen of the strings to
+       *  compare as the smallest of size() and str.size().  The function
+       *  then compares the two strings by calling traits::compare(data(),
+       *  str.data(),rlen).  If the result of the comparison is nonzero returns
+       *  it, otherwise the shorter one is ordered first.
+      */
+      int
+      compare(const __versa_string& __str) const
+      {
+	const size_type __size = this->size();
+	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;
+      }
+
+      /**
+       *  @brief  Compare substring to a string.
+       *  @param pos  Index of first character of substring.
+       *  @param n  Number of characters in substring.
+       *  @param str  String to compare against.
+       *  @return  Integer < 0, 0, or > 0.
+       *
+       *  Form the substring of this string from the @a n characters starting
+       *  at @a pos.  Returns an integer < 0 if the substring is ordered
+       *  before @a str, 0 if their values are equivalent, or > 0 if the
+       *  substring is ordered after @a str.  Determines the effective length
+       *  rlen of the strings to compare as the smallest of the length of the
+       *  substring and @a str.size().  The function then compares the two
+       *  strings by calling traits::compare(substring.data(),str.data(),rlen).
+       *  If the result of the comparison is nonzero returns it, otherwise the
+       *  shorter one is ordered first.
+      */
+      int
+      compare(size_type __pos, size_type __n,
+	      const __versa_string& __str) const;
+
+      /**
+       *  @brief  Compare substring to a substring.
+       *  @param pos1  Index of first character of substring.
+       *  @param n1  Number of characters in substring.
+       *  @param str  String to compare against.
+       *  @param pos2  Index of first character of substring of str.
+       *  @param n2  Number of characters in substring of str.
+       *  @return  Integer < 0, 0, or > 0.
+       *
+       *  Form the substring of this string from the @a n1 characters starting
+       *  at @a pos1.  Form the substring of @a str from the @a n2 characters
+       *  starting at @a pos2.  Returns an integer < 0 if this substring is
+       *  ordered before the substring of @a str, 0 if their values are
+       *  equivalent, or > 0 if this substring is ordered after the substring
+       *  of @a str.  Determines the effective length rlen of the strings
+       *  to compare as the smallest of the lengths of the substrings.  The
+       *  function then compares the two strings by calling
+       *  traits::compare(substring.data(),str.substr(pos2,n2).data(),rlen).
+       *  If the result of the comparison is nonzero returns it, otherwise the
+       *  shorter one is ordered first.
+      */
+      int
+      compare(size_type __pos1, size_type __n1, const __versa_string& __str,
+	      size_type __pos2, size_type __n2) const;
+
+      /**
+       *  @brief  Compare to a C string.
+       *  @param s  C string to compare against.
+       *  @return  Integer < 0, 0, or > 0.
+       *
+       *  Returns an integer < 0 if this string is ordered before @a s, 0 if
+       *  their values are equivalent, or > 0 if this string is ordered after
+       *  @a s.  Determines the effective length rlen of the strings to
+       *  compare as the smallest of size() and the length of a string
+       *  constructed from @a s.  The function then compares the two strings
+       *  by calling traits::compare(data(),s,rlen).  If the result of the
+       *  comparison is nonzero returns it, otherwise the shorter one is
+       *  ordered first.
+      */
+      int
+      compare(const _CharT* __s) const;
+
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 5 String::compare specification questionable
+      /**
+       *  @brief  Compare substring to a C string.
+       *  @param pos  Index of first character of substring.
+       *  @param n1  Number of characters in substring.
+       *  @param s  C string to compare against.
+       *  @return  Integer < 0, 0, or > 0.
+       *
+       *  Form the substring of this string from the @a n1 characters starting
+       *  at @a pos.  Returns an integer < 0 if the substring is ordered
+       *  before @a s, 0 if their values are equivalent, or > 0 if the
+       *  substring is ordered after @a s.  Determines the effective length
+       *  rlen of the strings to compare as the smallest of the length of the 
+       *  substring and the length of a string constructed from @a s.  The
+       *  function then compares the two string by calling
+       *  traits::compare(substring.data(),s,rlen).  If the result of the
+       *  comparison is nonzero returns it, otherwise the shorter one is
+       *  ordered first.
+      */
+      int
+      compare(size_type __pos, size_type __n1, const _CharT* __s) const;
+
+      /**
+       *  @brief  Compare substring against a character array.
+       *  @param pos1  Index of first character of substring.
+       *  @param n1  Number of characters in substring.
+       *  @param s  character array to compare against.
+       *  @param n2  Number of characters of s.
+       *  @return  Integer < 0, 0, or > 0.
+       *
+       *  Form the substring of this string from the @a n1 characters starting
+       *  at @a pos1.  Form a string from the first @a n2 characters of @a s.
+       *  Returns an integer < 0 if this substring is ordered before the string
+       *  from @a s, 0 if their values are equivalent, or > 0 if this substring
+       *  is ordered after the string from @a s.   Determines the effective
+       *  length rlen of the strings to compare as the smallest of the length
+       *  of the substring and @a n2.  The function then compares the two
+       *  strings by calling traits::compare(substring.data(),s,rlen).  If the
+       *  result of the comparison is nonzero returns it, otherwise the shorter
+       *  one is ordered first.
+       *
+       *  NB: s must have at least n2 characters, '\0' has no special
+       *  meaning.
+      */
+      int
+      compare(size_type __pos, size_type __n1, const _CharT* __s,
+	      size_type __n2) const;
+    };
+
+  // operator+
+  /**
+   *  @brief  Concatenate two strings.
+   *  @param lhs  First string.
+   *  @param rhs  Last string.
+   *  @return  New string with value of @a lhs followed by @a rhs.
+   */
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    __versa_string<_CharT, _Traits, _Alloc, _Base>
+    operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
+	      const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
+    {
+      __versa_string<_CharT, _Traits, _Alloc, _Base> __str(__lhs);
+      __str.append(__rhs);
+      return __str;
+    }
+
+  /**
+   *  @brief  Concatenate C string and string.
+   *  @param lhs  First string.
+   *  @param rhs  Last string.
+   *  @return  New string with value of @a lhs followed by @a rhs.
+   */
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    __versa_string<_CharT, _Traits, _Alloc, _Base>
+    operator+(const _CharT* __lhs,
+	      const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs);
+
+  /**
+   *  @brief  Concatenate character and string.
+   *  @param lhs  First string.
+   *  @param rhs  Last string.
+   *  @return  New string with @a lhs followed by @a rhs.
+   */
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    __versa_string<_CharT, _Traits, _Alloc, _Base>
+    operator+(_CharT __lhs,
+	      const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs);
+
+  /**
+   *  @brief  Concatenate string and C string.
+   *  @param lhs  First string.
+   *  @param rhs  Last string.
+   *  @return  New string with @a lhs followed by @a rhs.
+   */
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    inline __versa_string<_CharT, _Traits, _Alloc, _Base>
+    operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
+	      const _CharT* __rhs)
+    {
+      __versa_string<_CharT, _Traits, _Alloc, _Base> __str(__lhs);
+      __str.append(__rhs);
+      return __str;
+    }
+
+  /**
+   *  @brief  Concatenate string and character.
+   *  @param lhs  First string.
+   *  @param rhs  Last string.
+   *  @return  New string with @a lhs followed by @a rhs.
+   */
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    inline __versa_string<_CharT, _Traits, _Alloc, _Base>
+    operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
+	      _CharT __rhs)
+    {
+      typedef __versa_string<_CharT, _Traits, _Alloc, _Base>
+	                                                __string_type;
+      typedef typename __string_type::size_type		__size_type;
+      __string_type __str(__lhs);
+      __str.append(__size_type(1), __rhs);
+      return __str;
+    }
+
+  // operator ==
+  /**
+   *  @brief  Test equivalence of two strings.
+   *  @param lhs  First string.
+   *  @param rhs  Second string.
+   *  @return  True if @a lhs.compare(@a rhs) == 0.  False otherwise.
+   */
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    inline bool
+    operator==(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
+	       const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
+    { return __lhs.compare(__rhs) == 0; }
+
+  /**
+   *  @brief  Test equivalence of C string and string.
+   *  @param lhs  C string.
+   *  @param rhs  String.
+   *  @return  True if @a rhs.compare(@a lhs) == 0.  False otherwise.
+   */
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    inline bool
+    operator==(const _CharT* __lhs,
+	       const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
+    { return __rhs.compare(__lhs) == 0; }
+
+  /**
+   *  @brief  Test equivalence of string and C string.
+   *  @param lhs  String.
+   *  @param rhs  C string.
+   *  @return  True if @a lhs.compare(@a rhs) == 0.  False otherwise.
+   */
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    inline bool
+    operator==(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
+	       const _CharT* __rhs)
+    { return __lhs.compare(__rhs) == 0; }
+
+  // operator !=
+  /**
+   *  @brief  Test difference of two strings.
+   *  @param lhs  First string.
+   *  @param rhs  Second string.
+   *  @return  True if @a lhs.compare(@a rhs) != 0.  False otherwise.
+   */
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    inline bool
+    operator!=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
+	       const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
+    { return __rhs.compare(__lhs) != 0; }
+
+  /**
+   *  @brief  Test difference of C string and string.
+   *  @param lhs  C string.
+   *  @param rhs  String.
+   *  @return  True if @a rhs.compare(@a lhs) != 0.  False otherwise.
+   */
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    inline bool
+    operator!=(const _CharT* __lhs,
+	       const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
+    { return __rhs.compare(__lhs) != 0; }
+
+  /**
+   *  @brief  Test difference of string and C string.
+   *  @param lhs  String.
+   *  @param rhs  C string.
+   *  @return  True if @a lhs.compare(@a rhs) != 0.  False otherwise.
+   */
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    inline bool
+    operator!=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
+	       const _CharT* __rhs)
+    { return __lhs.compare(__rhs) != 0; }
+
+  // operator <
+  /**
+   *  @brief  Test if string precedes string.
+   *  @param lhs  First string.
+   *  @param rhs  Second string.
+   *  @return  True if @a lhs precedes @a rhs.  False otherwise.
+   */
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    inline bool
+    operator<(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
+	      const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
+    { return __lhs.compare(__rhs) < 0; }
+
+  /**
+   *  @brief  Test if string precedes C string.
+   *  @param lhs  String.
+   *  @param rhs  C string.
+   *  @return  True if @a lhs precedes @a rhs.  False otherwise.
+   */
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    inline bool
+    operator<(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
+	      const _CharT* __rhs)
+    { return __lhs.compare(__rhs) < 0; }
+
+  /**
+   *  @brief  Test if C string precedes string.
+   *  @param lhs  C string.
+   *  @param rhs  String.
+   *  @return  True if @a lhs precedes @a rhs.  False otherwise.
+   */
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    inline bool
+    operator<(const _CharT* __lhs,
+	      const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
+    { return __rhs.compare(__lhs) > 0; }
+
+  // operator >
+  /**
+   *  @brief  Test if string follows string.
+   *  @param lhs  First string.
+   *  @param rhs  Second string.
+   *  @return  True if @a lhs follows @a rhs.  False otherwise.
+   */
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    inline bool
+    operator>(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
+	      const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
+    { return __lhs.compare(__rhs) > 0; }
+
+  /**
+   *  @brief  Test if string follows C string.
+   *  @param lhs  String.
+   *  @param rhs  C string.
+   *  @return  True if @a lhs follows @a rhs.  False otherwise.
+   */
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    inline bool
+    operator>(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
+	      const _CharT* __rhs)
+    { return __lhs.compare(__rhs) > 0; }
+
+  /**
+   *  @brief  Test if C string follows string.
+   *  @param lhs  C string.
+   *  @param rhs  String.
+   *  @return  True if @a lhs follows @a rhs.  False otherwise.
+   */
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    inline bool
+    operator>(const _CharT* __lhs,
+	      const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
+    { return __rhs.compare(__lhs) < 0; }
+
+  // operator <=
+  /**
+   *  @brief  Test if string doesn't follow string.
+   *  @param lhs  First string.
+   *  @param rhs  Second string.
+   *  @return  True if @a lhs doesn't follow @a rhs.  False otherwise.
+   */
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    inline bool
+    operator<=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
+	       const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
+    { return __lhs.compare(__rhs) <= 0; }
+
+  /**
+   *  @brief  Test if string doesn't follow C string.
+   *  @param lhs  String.
+   *  @param rhs  C string.
+   *  @return  True if @a lhs doesn't follow @a rhs.  False otherwise.
+   */
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    inline bool
+    operator<=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
+	       const _CharT* __rhs)
+    { return __lhs.compare(__rhs) <= 0; }
+
+  /**
+   *  @brief  Test if C string doesn't follow string.
+   *  @param lhs  C string.
+   *  @param rhs  String.
+   *  @return  True if @a lhs doesn't follow @a rhs.  False otherwise.
+   */
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    inline bool
+    operator<=(const _CharT* __lhs,
+	       const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
+    { return __rhs.compare(__lhs) >= 0; }
+
+  // operator >=
+  /**
+   *  @brief  Test if string doesn't precede string.
+   *  @param lhs  First string.
+   *  @param rhs  Second string.
+   *  @return  True if @a lhs doesn't precede @a rhs.  False otherwise.
+   */
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    inline bool
+    operator>=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
+	       const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
+    { return __lhs.compare(__rhs) >= 0; }
+
+  /**
+   *  @brief  Test if string doesn't precede C string.
+   *  @param lhs  String.
+   *  @param rhs  C string.
+   *  @return  True if @a lhs doesn't precede @a rhs.  False otherwise.
+   */
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    inline bool
+    operator>=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
+	       const _CharT* __rhs)
+    { return __lhs.compare(__rhs) >= 0; }
+
+  /**
+   *  @brief  Test if C string doesn't precede string.
+   *  @param lhs  C string.
+   *  @param rhs  String.
+   *  @return  True if @a lhs doesn't precede @a rhs.  False otherwise.
+   */
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    inline bool
+    operator>=(const _CharT* __lhs,
+	       const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
+    { return __rhs.compare(__lhs) <= 0; }
+
+  /**
+   *  @brief  Swap contents of two strings.
+   *  @param lhs  First string.
+   *  @param rhs  Second string.
+   *
+   *  Exchanges the contents of @a lhs and @a rhs in constant time.
+   */
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    inline void
+    swap(__versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
+	 __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
+    { __lhs.swap(__rhs); }
+
+  /**
+   *  @brief  Read stream into a string.
+   *  @param is  Input stream.
+   *  @param str  Buffer to store into.
+   *  @return  Reference to the input stream.
+   *
+   *  Stores characters from @a is into @a str until whitespace is found, the
+   *  end of the stream is encountered, or str.max_size() is reached.  If
+   *  is.width() is non-zero, that is the limit on the number of characters
+   *  stored into @a str.  Any previous contents of @a str are erased.
+   */
+  template<typename _CharT, typename _Traits, typename _Alloc,
+           template <typename, typename, typename> class _Base>
+    std::basic_istream<_CharT, _Traits>&
+    operator>>(std::basic_istream<_CharT, _Traits>& __is,
+	       __versa_string<_CharT, _Traits, _Alloc, _Base>& __str);
+
+  /**
+   *  @brief  Write string to a stream.
+   *  @param os  Output stream.
+   *  @param str  String to write out.
+   *  @return  Reference to the output stream.
+   *
+   *  Output characters of @a str into os following the same rules as for
+   *  writing a C string.
+   */
+  template<typename _CharT, typename _Traits, typename _Alloc,
+           template <typename, typename, typename> class _Base>
+    std::basic_ostream<_CharT, _Traits>&
+    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+	       const __versa_string<_CharT, _Traits, _Alloc, _Base>& __str);
+
+  /**
+   *  @brief  Read a line from stream into a string.
+   *  @param is  Input stream.
+   *  @param str  Buffer to store into.
+   *  @param delim  Character marking end of line.
+   *  @return  Reference to the input stream.
+   *
+   *  Stores characters from @a is into @a str until @a delim is found, the
+   *  end of the stream is encountered, or str.max_size() is reached.  If
+   *  is.width() is non-zero, that is the limit on the number of characters
+   *  stored into @a str.  Any previous contents of @a str are erased.  If @a
+   *  delim was encountered, it is extracted but not stored into @a str.
+   */
+  template<typename _CharT, typename _Traits, typename _Alloc,
+           template <typename, typename, typename> class _Base>
+    std::basic_istream<_CharT, _Traits>&
+    getline(std::basic_istream<_CharT, _Traits>& __is,
+	    __versa_string<_CharT, _Traits, _Alloc, _Base>& __str,
+	    _CharT __delim);
+
+  /**
+   *  @brief  Read a line from stream into a string.
+   *  @param is  Input stream.
+   *  @param str  Buffer to store into.
+   *  @return  Reference to the input stream.
+   *
+   *  Stores characters from is into @a str until '\n' is found, the end of
+   *  the stream is encountered, or str.max_size() is reached.  If is.width()
+   *  is non-zero, that is the limit on the number of characters stored into
+   *  @a str.  Any previous contents of @a str are erased.  If end of line was
+   *  encountered, it is extracted but not stored into @a str.
+   */
+  template<typename _CharT, typename _Traits, typename _Alloc,
+           template <typename, typename, typename> class _Base>
+    inline std::basic_istream<_CharT, _Traits>&
+    getline(std::basic_istream<_CharT, _Traits>& __is,
+	    __versa_string<_CharT, _Traits, _Alloc, _Base>& __str)
+    { return getline(__is, __str, __is.widen('\n')); }      
+
+} // namespace __gnu_cxx
+
+#ifndef _GLIBCXX_EXPORT_TEMPLATE
+# include "vstring.tcc" 
+#endif
+
+#endif /* _VSTRING_H */
diff -urN libstdc++-v3-orig/include/ext/vstring.tcc libstdc++-v3/include/ext/vstring.tcc
--- libstdc++-v3-orig/include/ext/vstring.tcc	1970-01-01 01:00:00.000000000 +0100
+++ libstdc++-v3/include/ext/vstring.tcc	2005-07-03 16:15:02.000000000 +0200
@@ -0,0 +1,789 @@
+// Versatile 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/vstring.tcc
+ *  This file is a GNU extension to the Standard C++ Library.
+ *  This is an internal header file, included by other library headers.
+ *  You should not attempt to use it directly.
+ */
+
+#ifndef _VSTRING_TCC
+#define _VSTRING_TCC 1
+
+#pragma GCC system_header
+
+namespace __gnu_cxx
+{
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    const typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
+    __versa_string<_CharT, _Traits, _Alloc, _Base>::npos;
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    __versa_string<_CharT, _Traits, _Alloc, _Base>&
+    __versa_string<_CharT, _Traits, _Alloc, _Base>::
+    assign(const _CharT* __s, size_type __n)
+    {
+      __glibcxx_requires_string_len(__s, __n);
+      _M_check_length(this->size(), __n, "__versa_string::assign");
+      if (_M_disjunct(__s) || this->_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_set_length(__n);
+	  return *this;
+	}
+     }
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    __versa_string<_CharT, _Traits, _Alloc, _Base>&
+    __versa_string<_CharT, _Traits, _Alloc, _Base>::
+    append(size_type __n, _CharT __c)
+    {
+      if (__n)
+	{
+	  _M_check_length(size_type(0), __n, "__versa_string::append");	  
+	  const size_type __len = __n + this->size();
+	  if (__len > this->capacity() || this->_M_is_shared())
+	    this->reserve(__len);
+	  this->_S_assign(this->_M_data() + this->size(), __n, __c);
+	  this->_M_set_length(__len);
+	}
+      return *this;
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    __versa_string<_CharT, _Traits, _Alloc, _Base>&
+    __versa_string<_CharT, _Traits, _Alloc, _Base>::
+    append(const _CharT* __s, size_type __n)
+    {
+      __glibcxx_requires_string_len(__s, __n);
+      if (__n)
+	{
+	  _M_check_length(size_type(0), __n, "__versa_string::append");
+	  const size_type __len = __n + this->size();
+	  if (__len > this->capacity() || this->_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_set_length(__len);
+	}
+      return *this;
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    __versa_string<_CharT, _Traits, _Alloc, _Base>&
+    __versa_string<_CharT, _Traits, _Alloc, _Base>::
+    append(const __versa_string& __str)
+    {
+      const size_type __size = __str.size();
+      if (__size)
+	{
+	  const size_type __len = __size + this->size();
+	  if (__len > this->capacity() || this->_M_is_shared())
+	    this->reserve(__len);
+	  this->_S_copy(this->_M_data() + this->size(), __str._M_data(),
+			__size);
+	  this->_M_set_length(__len);
+	}
+      return *this;
+    }    
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    __versa_string<_CharT, _Traits, _Alloc, _Base>&
+    __versa_string<_CharT, _Traits, _Alloc, _Base>::
+    append(const __versa_string& __str, size_type __pos, size_type __n)
+    {
+      __str._M_check(__pos, "__versa_string::append");
+      __n = __str._M_limit(__pos, __n);
+      if (__n)
+	{
+	  const size_type __len = __n + this->size();
+	  if (__len > this->capacity() || this->_M_is_shared())
+	    this->reserve(__len);
+	  this->_S_copy(this->_M_data() + this->size(),
+			__str._M_data() + __pos, __n);
+	  this->_M_set_length(__len);	  
+	}
+      return *this;
+    }
+
+   template<typename _CharT, typename _Traits, typename _Alloc,
+	    template <typename, typename, typename> class _Base>
+     __versa_string<_CharT, _Traits, _Alloc, _Base>&
+     __versa_string<_CharT, _Traits, _Alloc, _Base>::
+     insert(size_type __pos, const _CharT* __s, size_type __n)
+     {
+       __glibcxx_requires_string_len(__s, __n);
+       _M_check(__pos, "__versa_string::insert");
+       _M_check_length(size_type(0), __n, "__versa_string::insert");
+       if (_M_disjunct(__s) || this->_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;
+         }
+     }
+
+   template<typename _CharT, typename _Traits, typename _Alloc,
+	    template <typename, typename, typename> class _Base>
+     __versa_string<_CharT, _Traits, _Alloc, _Base>&
+     __versa_string<_CharT, _Traits, _Alloc, _Base>::
+     replace(size_type __pos, size_type __n1, const _CharT* __s,
+	     size_type __n2)
+     {
+       __glibcxx_requires_string_len(__s, __n2);
+       _M_check(__pos, "__versa_string::replace");
+       __n1 = _M_limit(__pos, __n1);
+       _M_check_length(__n1, __n2, "__versa_string::replace");
+       bool __left;
+       if (_M_disjunct(__s) || this->_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
+	 {
+	   // Todo: overlapping case.
+	   const __versa_string __tmp(__s, __n2);
+	   return _M_replace_safe(__pos, __n1, __tmp._M_data(), __n2);
+	 }
+     }
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    void
+    __versa_string<_CharT, _Traits, _Alloc, _Base>::
+    swap(__versa_string& __s)
+    {
+      if (this->_M_is_leaked())
+	this->_M_set_sharable();
+      if (__s._M_is_leaked())
+	__s._M_set_sharable();
+      if (this->get_allocator() == __s.get_allocator())
+	this->_M_swap(__s);
+      // The code below can usually be optimized away.
+      else
+	{
+	  const __versa_string __tmp1(_M_ibegin(), _M_iend(),
+				      __s.get_allocator());
+	  const __versa_string __tmp2(__s._M_ibegin(), __s._M_iend(),
+				      this->get_allocator());
+	  *this = __tmp2;
+	  __s = __tmp1;
+	}
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    void
+    __versa_string<_CharT, _Traits, _Alloc, _Base>::
+    resize(size_type __n, _CharT __c)
+    {
+      const size_type __size = this->size();
+      _M_check_length(__size, __n, "__versa_string::resize");
+      if (__size < __n)
+	this->append(__n - __size, __c);
+      else if (__n < __size)
+	this->erase(__n);
+      // else nothing (in particular, avoid calling _M_mutate() unnecessarily.)
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    template<typename _InputIterator>
+      __versa_string<_CharT, _Traits, _Alloc, _Base>&
+      __versa_string<_CharT, _Traits, _Alloc, _Base>::
+      _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1,
+			  _InputIterator __k2, __false_type)
+      {
+	const __versa_string __s(__k1, __k2);
+	const size_type __n1 = __i2 - __i1;
+	_M_check_length(__n1, __s.size(),
+			"__versa_string::_M_replace_dispatch");
+	return _M_replace_safe(__i1 - _M_ibegin(), __n1, __s._M_data(),
+			       __s.size());
+      }
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    __versa_string<_CharT, _Traits, _Alloc, _Base>&
+    __versa_string<_CharT, _Traits, _Alloc, _Base>::
+    _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
+		   _CharT __c)
+    {
+      _M_check_length(__n1, __n2, "__versa_string::_M_replace_aux");
+      this->_M_mutate(__pos1, __n1, __n2);
+      if (__n2)
+	this->_S_assign(this->_M_data() + __pos1, __n2, __c);
+      return *this;
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    __versa_string<_CharT, _Traits, _Alloc, _Base>&
+    __versa_string<_CharT, _Traits, _Alloc, _Base>::
+    _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;
+    }
+   
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    __versa_string<_CharT, _Traits, _Alloc, _Base>
+    operator+(const _CharT* __lhs,
+	      const __versa_string<_CharT, _Traits, _Alloc>& __rhs)
+    {
+      __glibcxx_requires_string(__lhs);
+      typedef __versa_string<_CharT, _Traits, _Alloc> __string_type;
+      typedef typename __string_type::size_type	  __size_type;
+      const __size_type __len = _Traits::length(__lhs);
+      __string_type __str;
+      __str.reserve(__len + __rhs.size());
+      __str.append(__lhs, __len);
+      __str.append(__rhs);
+      return __str;
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    __versa_string<_CharT, _Traits, _Alloc, _Base>
+    operator+(_CharT __lhs,
+	      const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
+    {
+      typedef __versa_string<_CharT, _Traits, _Alloc> __string_type;
+      typedef typename __string_type::size_type	  __size_type;
+      __string_type __str;
+      const __size_type __len = __rhs.size();
+      __str.reserve(__len + 1);
+      __str.append(__size_type(1), __lhs);
+      __str.append(__rhs);
+      return __str;
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
+    __versa_string<_CharT, _Traits, _Alloc, _Base>::
+    copy(_CharT* __s, size_type __n, size_type __pos) const
+    {
+      _M_check(__pos, "__versa_string::copy");
+      __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;
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
+    __versa_string<_CharT, _Traits, _Alloc, _Base>::
+    find(const _CharT* __s, size_type __pos, size_type __n) const
+    {
+      __glibcxx_requires_string_len(__s, __n);
+      size_type __ret = npos;
+      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)
+	    __ret = __p - __data;
+	}
+      return __ret;
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
+    __versa_string<_CharT, _Traits, _Alloc, _Base>::
+    find(_CharT __c, size_type __pos) const
+    {
+      size_type __ret = npos;
+      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)
+	    __ret = __p - __data;
+	}
+      return __ret;
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
+    __versa_string<_CharT, _Traits, _Alloc, _Base>::
+    rfind(const _CharT* __s, size_type __pos, size_type __n) const
+    {
+      __glibcxx_requires_string_len(__s, __n);
+      const size_type __size = this->size();
+      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)
+		return __pos;
+	    }
+	  while (__pos-- > 0);
+	}
+      return npos;
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
+    __versa_string<_CharT, _Traits, _Alloc, _Base>::
+    rfind(_CharT __c, size_type __pos) const
+    {
+      size_type __size = this->size();
+      if (__size)
+	{
+	  if (--__size > __pos)
+	    __size = __pos;
+	  for (++__size; __size-- > 0; )
+	    if (traits_type::eq(this->_M_data()[__size], __c))
+	      return __size;
+	}
+      return npos;
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
+    __versa_string<_CharT, _Traits, _Alloc, _Base>::
+    find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
+    {
+      __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;
+	}
+      return npos;
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
+    __versa_string<_CharT, _Traits, _Alloc, _Base>::
+    find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
+    {
+      __glibcxx_requires_string_len(__s, __n);
+      size_type __size = this->size();
+      if (__size && __n)
+	{
+	  if (--__size > __pos)
+	    __size = __pos;
+	  do
+	    {
+	      if (traits_type::find(__s, __n, this->_M_data()[__size]))
+		return __size;
+	    }
+	  while (__size-- != 0);
+	}
+      return npos;
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
+    __versa_string<_CharT, _Traits, _Alloc, _Base>::
+    find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
+    {
+      __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;
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
+    __versa_string<_CharT, _Traits, _Alloc, _Base>::
+    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;
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
+    __versa_string<_CharT, _Traits, _Alloc, _Base>::
+    find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
+    {
+      __glibcxx_requires_string_len(__s, __n);
+      size_type __size = this->size();
+      if (__size)
+	{
+	  if (--__size > __pos)
+	    __size = __pos;
+	  do
+	    {
+	      if (!traits_type::find(__s, __n, this->_M_data()[__size]))
+		return __size;
+	    }
+	  while (__size--);
+	}
+      return npos;
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
+    __versa_string<_CharT, _Traits, _Alloc, _Base>::
+    find_last_not_of(_CharT __c, size_type __pos) const
+    {
+      size_type __size = this->size();
+      if (__size)
+	{
+	  if (--__size > __pos)
+	    __size = __pos;
+	  do
+	    {
+	      if (!traits_type::eq(this->_M_data()[__size], __c))
+		return __size;
+	    }
+	  while (__size--);
+	}
+      return npos;
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    int
+    __versa_string<_CharT, _Traits, _Alloc, _Base>::
+    compare(size_type __pos, size_type __n, const __versa_string& __str) const
+    {
+      _M_check(__pos, "__versa_string::compare");
+      __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;
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    int
+    __versa_string<_CharT, _Traits, _Alloc, _Base>::
+    compare(size_type __pos1, size_type __n1, const __versa_string& __str,
+	    size_type __pos2, size_type __n2) const
+    {
+      _M_check(__pos1, "__versa_string::compare");
+      __str._M_check(__pos2, "__versa_string::compare");
+      __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;
+      return __r;
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    int
+    __versa_string<_CharT, _Traits, _Alloc, _Base>::
+    compare(const _CharT* __s) const
+    {
+      __glibcxx_requires_string(__s);
+      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;
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    int
+    __versa_string <_CharT, _Traits, _Alloc, _Base>::
+    compare(size_type __pos, size_type __n1, const _CharT* __s) const
+    {
+      __glibcxx_requires_string(__s);
+      _M_check(__pos, "__versa_string::compare");
+      __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;
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+	   template <typename, typename, typename> class _Base>
+    int
+    __versa_string <_CharT, _Traits, _Alloc, _Base>::
+    compare(size_type __pos, size_type __n1, const _CharT* __s,
+	    size_type __n2) const
+    {
+      __glibcxx_requires_string_len(__s, __n2);
+      _M_check(__pos, "__versa_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;
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+           template <typename, typename, typename> class _Base>
+    std::basic_istream<_CharT, _Traits>&
+    operator>>(std::basic_istream<_CharT, _Traits>& __in,
+	       __versa_string<_CharT, _Traits, _Alloc, _Base>& __str)
+    {
+      typedef std::basic_istream<_CharT, _Traits>	__istream_type;
+      typedef typename __istream_type::int_type		__int_type;
+      typedef typename __istream_type::__streambuf_type __streambuf_type;
+      typedef typename __istream_type::__ctype_type	__ctype_type;
+      typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type;
+      typedef typename __string_type::size_type		__size_type;
+
+      __size_type __extracted = 0;
+      std::ios_base::iostate __err =
+	std::ios_base::iostate(std::ios_base::goodbit);
+      typename __istream_type::sentry __cerb(__in, false);
+      if (__cerb)
+	{
+	  try
+	    {
+	      // Avoid reallocation for common case.
+	      __str.erase();
+	      _CharT __buf[128];
+	      __size_type __len = 0;	      
+	      const std::streamsize __w = __in.width();
+	      const __size_type __n = __w > 0 ? static_cast<__size_type>(__w)
+		                              : __str.max_size();
+	      const __ctype_type& __ct =
+		std::use_facet<__ctype_type>(__in.getloc());
+	      const __int_type __eof = _Traits::eof();
+	      __streambuf_type* __sb = __in.rdbuf();
+	      __int_type __c = __sb->sgetc();
+
+	      while (__extracted < __n
+		     && !_Traits::eq_int_type(__c, __eof)
+		     && !__ct.is(std::ctype_base::space,
+				 _Traits::to_char_type(__c)))
+		{
+		  if (__len == sizeof(__buf) / sizeof(_CharT))
+		    {
+		      __str.append(__buf, sizeof(__buf) / sizeof(_CharT));
+		      __len = 0;
+		    }
+		  __buf[__len++] = _Traits::to_char_type(__c);
+		  ++__extracted;
+		  __c = __sb->snextc();
+		}
+	      __str.append(__buf, __len);
+
+	      if (_Traits::eq_int_type(__c, __eof))
+		__err |= std::ios_base::eofbit;
+	      __in.width(0);
+	    }
+	  catch(...)
+	    {
+	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+	      // 91. Description of operator>> and getline() for string<>
+	      // might cause endless loop
+	      __in._M_setstate(std::ios_base::badbit);
+	    }
+	}
+      // 211.  operator>>(istream&, string&) doesn't set failbit
+      if (!__extracted)
+	__err |= std::ios_base::failbit;
+      if (__err)
+	__in.setstate(__err);
+      return __in;
+    }      
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+           template <typename, typename, typename> class _Base>
+    std::basic_ostream<_CharT, _Traits>&
+    operator<<(std::basic_ostream<_CharT, _Traits>& __out,
+	       const __versa_string<_CharT, _Traits, _Alloc, _Base>& __str)
+    {
+      typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
+      typename __ostream_type::sentry __cerb(__out);
+      if (__cerb)
+	{
+	  const std::streamsize __w = __out.width();
+	  std::streamsize __len = static_cast<std::streamsize>(__str.size());
+	  const _CharT* __s = __str.data();
+
+	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+	  // 25. String operator<< uses width() value wrong
+	  if (__w > __len)
+	    {
+	      _CharT* __cs = (static_cast<
+			      _CharT*>(__builtin_alloca(sizeof(_CharT) * __w)));
+	      std::__pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs,
+						  __s, __w, __len, false);
+	      __s = __cs;
+	      __len = __w;
+	    }
+	  __out._M_write(__s, __len);
+	  __out.width(0);
+	}
+      return __out;
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+           template <typename, typename, typename> class _Base>
+    std::basic_istream<_CharT, _Traits>&
+    getline(std::basic_istream<_CharT, _Traits>& __in,
+	    __versa_string<_CharT, _Traits, _Alloc, _Base>& __str,
+	    _CharT __delim)
+    {
+      typedef std::basic_istream<_CharT, _Traits>	__istream_type;
+      typedef typename __istream_type::int_type		__int_type;
+      typedef typename __istream_type::__streambuf_type __streambuf_type;
+      typedef typename __istream_type::__ctype_type	__ctype_type;
+      typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type;
+      typedef typename __string_type::size_type		__size_type;
+
+      __size_type __extracted = 0;
+      const __size_type __n = __str.max_size();
+      std::ios_base::iostate __err =
+	std::ios_base::iostate(std::ios_base::goodbit);
+      typename __istream_type::sentry __cerb(__in, true);
+      if (__cerb)
+	{
+	  try
+	    {
+	      __str.erase();
+	      const __int_type __idelim = _Traits::to_int_type(__delim);
+	      const __int_type __eof = _Traits::eof();
+	      __streambuf_type* __sb = __in.rdbuf();
+	      __int_type __c = __sb->sgetc();
+
+	      while (__extracted < __n
+		     && !_Traits::eq_int_type(__c, __eof)
+		     && !_Traits::eq_int_type(__c, __idelim))
+		{
+		  __str += _Traits::to_char_type(__c);
+		  ++__extracted;
+		  __c = __sb->snextc();
+		}
+
+	      if (_Traits::eq_int_type(__c, __eof))
+		__err |= std::ios_base::eofbit;
+	      else if (_Traits::eq_int_type(__c, __idelim))
+		{
+		  ++__extracted;		  
+		  __sb->sbumpc();
+		}
+	      else
+		__err |= std::ios_base::failbit;
+	    }
+	  catch(...)
+	    {
+	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+	      // 91. Description of operator>> and getline() for string<>
+	      // might cause endless loop
+	      __in._M_setstate(std::ios_base::badbit);
+	    }
+	}
+      if (!__extracted)
+	__err |= std::ios_base::failbit;
+      if (__err)
+	__in.setstate(__err);
+      return __in;
+    }      
+  
+} // namespace __gnu_cxx
+
+#endif // _VSTRING_TCC
diff -urN libstdc++-v3-orig/include/ext/vstring_fwd.h libstdc++-v3/include/ext/vstring_fwd.h
--- libstdc++-v3-orig/include/ext/vstring_fwd.h	1970-01-01 01:00:00.000000000 +0100
+++ libstdc++-v3/include/ext/vstring_fwd.h	2005-07-03 16:14:50.000000000 +0200
@@ -0,0 +1,74 @@
+// Versatile string forward -*- 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/vstring_fwd.h
+ *  This file is a GNU extension to the Standard C++ Library.
+ *  This is an internal header file, included by other library headers.
+ *  You should not attempt to use it directly.
+ */
+
+#ifndef _VSTRING_FWD_H
+#define _VSTRING_FWD_H 1
+
+#pragma GCC system_header
+
+#include <bits/c++config.h>
+#include <bits/char_traits.h>
+#include <memory> 	// For allocator.
+
+namespace __gnu_cxx
+{
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    class __sso_string_base;
+
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    class __rc_string_base;
+
+  template<typename _CharT, typename _Traits = std::char_traits<_CharT>,
+           typename _Alloc = std::allocator<_CharT>,
+	   template
+	   <typename, typename, typename> class _Base = __sso_string_base>
+    class __versa_string;
+
+  typedef __versa_string<char>                              __vstring;
+  typedef __vstring                                         __sso_string;
+  typedef 
+  __versa_string<char, std::char_traits<char>,
+		 std::allocator<char>, __rc_string_base>    __rc_string;
+
+#ifdef _GLIBCXX_USE_WCHAR_T
+  typedef __versa_string<wchar_t>                           __wvstring;
+  typedef __wvstring                                        __wsso_string;
+  typedef
+  __versa_string<wchar_t, std::char_traits<wchar_t>,
+		 std::allocator<wchar_t>, __rc_string_base> __wrc_string;
+#endif  
+} // namespace __gnu_cxx
+
+#endif /* _VSTRING_FWD_H */
diff -urN libstdc++-v3-orig/include/ext/vstring_util.h libstdc++-v3/include/ext/vstring_util.h
--- libstdc++-v3-orig/include/ext/vstring_util.h	1970-01-01 01:00:00.000000000 +0100
+++ libstdc++-v3/include/ext/vstring_util.h	2005-07-03 16:17:17.000000000 +0200
@@ -0,0 +1,162 @@
+// Versatile 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/vstring_util.h
+ *  This file is a GNU extension to the Standard C++ Library.
+ *  This is an internal header file, included by other library headers.
+ *  You should not attempt to use it directly.
+ */
+
+#ifndef _VSTRING_UTIL_H
+#define _VSTRING_UTIL_H 1
+
+#pragma GCC system_header
+
+#include <ext/vstring_fwd.h>
+#include <debug/debug.h>
+#include <bits/stl_function.h>  // For less
+#include <bits/functexcept.h>
+#include <locale>
+#include <algorithm> // For std::distance, srd::search.
+
+namespace __gnu_cxx
+{
+  template<typename _Type>
+    inline bool
+    __is_null_p(_Type* __ptr)
+    { return __ptr == 0; }
+
+  template<typename _Type>
+    inline bool
+    __is_null_p(_Type)
+    { return false; }
+
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    struct __vstring_utility
+    {
+      typedef typename _Alloc::template rebind<_CharT>::other _CharT_alloc_type;
+
+      typedef _Traits					    traits_type;      
+      typedef typename _Traits::char_type		    value_type;
+      typedef typename _CharT_alloc_type::size_type	    size_type;
+      typedef typename _CharT_alloc_type::pointer	    pointer;
+      typedef typename _CharT_alloc_type::const_pointer	    const_pointer;
+
+      // For __sso_string.
+      typedef __gnu_cxx::
+      __normal_iterator<pointer, __gnu_cxx::
+			__versa_string<_CharT, _Traits, _Alloc,
+				       __sso_string_base> >
+        __sso_iterator;
+      typedef __gnu_cxx::
+      __normal_iterator<const_pointer, __gnu_cxx::
+			__versa_string<_CharT, _Traits, _Alloc,
+				       __sso_string_base> >
+        __const_sso_iterator;
+
+      // For __rc_string.
+      typedef __gnu_cxx::
+      __normal_iterator<pointer, __gnu_cxx::
+			__versa_string<_CharT, _Traits, _Alloc,
+				       __rc_string_base> >
+        __rc_iterator;
+      typedef __gnu_cxx::
+      __normal_iterator<const_pointer, __gnu_cxx::
+			__versa_string<_CharT, _Traits, _Alloc,
+				       __rc_string_base> >
+        __const_rc_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, __sso_iterator __k1, __sso_iterator __k2)
+      { _S_copy_chars(__p, __k1.base(), __k2.base()); }
+
+      static void
+      _S_copy_chars(_CharT* __p, __const_sso_iterator __k1,
+		    __const_sso_iterator __k2)
+      { _S_copy_chars(__p, __k1.base(), __k2.base()); }
+
+      static void
+      _S_copy_chars(_CharT* __p, __rc_iterator __k1, __rc_iterator __k2)
+      { _S_copy_chars(__p, __k1.base(), __k2.base()); }
+
+      static void
+      _S_copy_chars(_CharT* __p, __const_rc_iterator __k1,
+		    __const_rc_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 /* _VSTRING_UTIL_H */
diff -urN libstdc++-v3-orig/testsuite/ext/vstring/explicit_instantiation/1.cc libstdc++-v3/testsuite/ext/vstring/explicit_instantiation/1.cc
--- libstdc++-v3-orig/testsuite/ext/vstring/explicit_instantiation/1.cc	1970-01-01 01:00:00.000000000 +0100
+++ libstdc++-v3/testsuite/ext/vstring/explicit_instantiation/1.cc	2005-07-03 17:12:29.000000000 +0200
@@ -0,0 +1,36 @@
+// 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.
+
+// This file tests explicit instantiation of __versa_string
+
+#include <ext/vstring.h>
+
+// { dg-do compile }
+
+// libstdc++/21770
+template class __gnu_cxx::__versa_string<int, std::char_traits<int>,
+					 std::allocator<char> >;
diff -urN libstdc++-v3-orig/testsuite/ext/vstring/explicit_instantiation/2.cc libstdc++-v3/testsuite/ext/vstring/explicit_instantiation/2.cc
--- libstdc++-v3-orig/testsuite/ext/vstring/explicit_instantiation/2.cc	1970-01-01 01:00:00.000000000 +0100
+++ libstdc++-v3/testsuite/ext/vstring/explicit_instantiation/2.cc	2005-07-03 17:12:08.000000000 +0200
@@ -0,0 +1,41 @@
+// 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.
+
+// This file tests explicit instantiation of __versa_string
+
+#include <ext/vstring.h>
+
+// { dg-do compile }
+
+// libstdc++/21770
+template class __gnu_cxx::__versa_string<int, std::char_traits<int>,
+					 std::allocator<char>,
+					 __gnu_cxx::__sso_string_base>;
+
+template class __gnu_cxx::__versa_string<int, std::char_traits<int>,
+					 std::allocator<char>,
+					 __gnu_cxx::__rc_string_base>;
diff -urN libstdc++-v3-orig/testsuite/ext/vstring/explicit_instantiation/char/1.cc libstdc++-v3/testsuite/ext/vstring/explicit_instantiation/char/1.cc
--- libstdc++-v3-orig/testsuite/ext/vstring/explicit_instantiation/char/1.cc	1970-01-01 01:00:00.000000000 +0100
+++ libstdc++-v3/testsuite/ext/vstring/explicit_instantiation/char/1.cc	2005-07-03 17:43:16.000000000 +0200
@@ -0,0 +1,40 @@
+// 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.
+
+// This file tests explicit instantiation of __versa_string
+
+#include <ext/vstring.h>
+
+// { dg-do compile }
+
+template class __gnu_cxx::__versa_string<char, std::char_traits<char>,
+					 std::allocator<char>,
+					 __gnu_cxx::__sso_string_base>;
+
+template class __gnu_cxx::__versa_string<char, std::char_traits<char>,
+					 std::allocator<char>,
+					 __gnu_cxx::__rc_string_base>;
diff -urN libstdc++-v3-orig/testsuite/ext/vstring/explicit_instantiation/wchar_t/1.cc libstdc++-v3/testsuite/ext/vstring/explicit_instantiation/wchar_t/1.cc
--- libstdc++-v3-orig/testsuite/ext/vstring/explicit_instantiation/wchar_t/1.cc	1970-01-01 01:00:00.000000000 +0100
+++ libstdc++-v3/testsuite/ext/vstring/explicit_instantiation/wchar_t/1.cc	2005-07-03 17:44:09.000000000 +0200
@@ -0,0 +1,40 @@
+// 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.
+
+// This file tests explicit instantiation of __versa_string
+
+#include <ext/vstring.h>
+
+// { dg-do compile }
+
+template class __gnu_cxx::__versa_string<wchar_t, std::char_traits<wchar_t>,
+					 std::allocator<wchar_t>,
+					 __gnu_cxx::__sso_string_base>;
+
+template class __gnu_cxx::__versa_string<wchar_t, std::char_traits<wchar_t>,
+					 std::allocator<wchar_t>,
+					 __gnu_cxx::__rc_string_base>;

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