// SGI's rope class -*- C++ -*-

// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
// 2012 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 3, 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.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/*
 * Copyright (c) 1997
 * Silicon Graphics Computer Systems, Inc.
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.  Silicon Graphics makes no
 * representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 */

/** @file ext/rope
 *  This file is a GNU extension to the Standard C++ Library (possibly
 *  containing extensions from the HP/SGI STL subset). 
 */

#ifndef _ROPE
#define _ROPE 1

#include <algorithm>
#include <iosfwd>
#include <bits/stl_construct.h>
#include <bits/stl_uninitialized.h>
#include <bits/stl_function.h>
#include <bits/stl_numeric.h>
#include <bits/allocator.h>
#include <bits/gthr.h>
#include <tr1/functional>

# ifdef __GC
#   define __GC_CONST const
# else
#   define __GC_CONST   // constant except for deallocation
# endif

#include <ext/memory> // For uninitialized_copy_n

namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
  namespace __detail
  {
    enum { _S_max_rope_depth = 45 };
    enum _Tag {_S_leaf, _S_concat, _S_substringfn, _S_function};
  } // namespace __detail

  using std::size_t;
  using std::ptrdiff_t;
  using std::allocator;
  using std::_Destroy;

_GLIBCXX_BEGIN_NAMESPACE_VERSION

  // See libstdc++/36832.
  template<typename _ForwardIterator, typename _Allocator>
    void
    _Destroy_const(_ForwardIterator __first,
		   _ForwardIterator __last, _Allocator __alloc)
    {
      for (; __first != __last; ++__first)
	__alloc.destroy(&*__first);
    }

  template<typename _ForwardIterator, typename _Tp>
    inline void
    _Destroy_const(_ForwardIterator __first,
		   _ForwardIterator __last, allocator<_Tp>)
    { _Destroy(__first, __last); }

  // The _S_eos function is used for those functions that
  // convert to/from C-like strings to detect the end of the string.
  
  // The end-of-C-string character.
  // This is what the draft standard says it should be.
  template <class _CharT>
    inline _CharT
    _S_eos(_CharT*)
    { return _CharT(); }

  // Test for basic character types.
  // For basic character types leaves having a trailing eos.
  template <class _CharT>
    inline bool
    _S_is_basic_char_type(_CharT*)
    { return false; }
  
  template <class _CharT>
    inline bool
    _S_is_one_byte_char_type(_CharT*)
    { return false; }

  inline bool
  _S_is_basic_char_type(char*)
  { return true; }
  
  inline bool
  _S_is_one_byte_char_type(char*)
  { return true; }
  
  inline bool
  _S_is_basic_char_type(wchar_t*)
  { return true; }

  // Store an eos iff _CharT is a basic character type.
  // Do not reference _S_eos if it isn't.
  template <class _CharT>
    inline void
    _S_cond_store_eos(_CharT&) { }

  inline void
  _S_cond_store_eos(char& __c)
  { __c = 0; }

  inline void
  _S_cond_store_eos(wchar_t& __c)
  { __c = 0; }

  // char_producers are logically functions that generate a section of
  // a string.  These can be converted to ropes.  The resulting rope
  // invokes the char_producer on demand.  This allows, for example,
  // files to be viewed as ropes without reading the entire file.
  template <class _CharT>
    class char_producer
    {
    public:
      virtual ~char_producer() { };

      virtual void
      operator()(size_t __start_pos, size_t __len,
		 _CharT* __buffer) = 0;
      // Buffer should really be an arbitrary output iterator.
      // That way we could flatten directly into an ostream, etc.
      // This is thoroughly impossible, since iterator types don't
      // have runtime descriptions.
    };

  // Sequence buffers:
  //
  // Sequence must provide an append operation that appends an
  // array to the sequence.  Sequence buffers are useful only if
  // appending an entire array is cheaper than appending element by element.
  // This is true for many string representations.
  // This should  perhaps inherit from ostream<sequence::value_type>
  // and be implemented correspondingly, so that they can be used
  // for formatted.  For the sake of portability, we don't do this yet.
  //
  // For now, sequence buffers behave as output iterators.  But they also
  // behave a little like basic_ostringstream<sequence::value_type> and a
  // little like containers.

  template<class _Sequence, size_t _Buf_sz = 100>
    class sequence_buffer
    : public std::iterator<std::output_iterator_tag, void, void, void, void>
    {
    public:
      typedef typename _Sequence::value_type value_type;
    protected:
      _Sequence* _M_prefix;
      value_type _M_buffer[_Buf_sz];
      size_t     _M_buf_count;
    public:

      void
      flush()
      {
	_M_prefix->append(_M_buffer, _M_buffer + _M_buf_count);
	_M_buf_count = 0;
      }
      
      ~sequence_buffer()
      { flush(); }
      
      sequence_buffer()
      : _M_prefix(0), _M_buf_count(0) { }

      sequence_buffer(const sequence_buffer& __x)
      {
	_M_prefix = __x._M_prefix;
	_M_buf_count = __x._M_buf_count;
	std::copy(__x._M_buffer, __x._M_buffer + __x._M_buf_count, _M_buffer);
      }
      
      sequence_buffer(sequence_buffer& __x)
      {
	__x.flush();
	_M_prefix = __x._M_prefix;
	_M_buf_count = 0;
      }
      
      sequence_buffer(_Sequence& __s)
      : _M_prefix(&__s), _M_buf_count(0) { }
      
      sequence_buffer&
      operator=(sequence_buffer& __x)
      {
	__x.flush();
	_M_prefix = __x._M_prefix;
	_M_buf_count = 0;
	return *this;
      }

      sequence_buffer&
      operator=(const sequence_buffer& __x)
      {
	_M_prefix = __x._M_prefix;
	_M_buf_count = __x._M_buf_count;
	std::copy(__x._M_buffer, __x._M_buffer + __x._M_buf_count, _M_buffer);
	return *this;
      }
      
      void
      push_back(value_type __x)
      {
	if (_M_buf_count < _Buf_sz)
	  {
	    _M_buffer[_M_buf_count] = __x;
	    ++_M_buf_count;
	  }
	else
	  {
	    flush();
	    _M_buffer[0] = __x;
	    _M_buf_count = 1;
	  }
      }
      
      void
      append(value_type* __s, size_t __len)
      {
	if (__len + _M_buf_count <= _Buf_sz)
	  {
	    size_t __i = _M_buf_count;
	    for (size_t __j = 0; __j < __len; __i++, __j++)
	      _M_buffer[__i] = __s[__j];
	    _M_buf_count += __len;
	  }
	else if (0 == _M_buf_count)
	  _M_prefix->append(__s, __s + __len);
	else
	  {
	    flush();
	    append(__s, __len);
	  }
      }

      sequence_buffer&
      write(value_type* __s, size_t __len)
      {
	append(__s, __len);
	return *this;
      }
      
      sequence_buffer&
      put(value_type __x)
      {
	push_back(__x);
	return *this;
      }
      
      sequence_buffer&
      operator=(const value_type& __rhs)
      {
	push_back(__rhs);
	return *this;
      }
      
      sequence_buffer&
      operator*()
      { return *this; }
      
      sequence_buffer&
      operator++()
      { return *this; }
      
      sequence_buffer
      operator++(int)
      { return *this; }
    };
  
  // The following should be treated as private, at least for now.
  template<class _CharT>
    class _Rope_char_consumer
    {
    public:
      // If we had member templates, these should not be virtual.
      // For now we need to use run-time parametrization where
      // compile-time would do.  Hence this should all be private
      // for now.
      // The symmetry with char_producer is accidental and temporary.
      virtual ~_Rope_char_consumer() { };
  
      virtual bool
      operator()(const _CharT* __buffer, size_t __len) = 0;
    };
  
  // First a lot of forward declarations.  The standard seems to require
  // much stricter "declaration before use" than many of the implementations
  // that preceded it.
  template<class _CharT, class _Alloc = allocator<_CharT> >
    class rope;
  
  template<class _CharT, class _Alloc>
    struct _Rope_RopeConcatenation;

  template<class _CharT, class _Alloc>
    struct _Rope_RopeLeaf;
  
  template<class _CharT, class _Alloc>
    struct _Rope_RopeFunction;
  
  template<class _CharT, class _Alloc>
    struct _Rope_RopeSubstring;
  
  template<class _CharT, class _Alloc>
    class _Rope_iterator;
  
  template<class _CharT, class _Alloc>
    class _Rope_const_iterator;
  
  template<class _CharT, class _Alloc>
    class _Rope_char_ref_proxy;
  
  template<class _CharT, class _Alloc>
    class _Rope_char_ptr_proxy;

  template<class _CharT, class _Alloc>
    bool
    operator==(const _Rope_char_ptr_proxy<_CharT, _Alloc>& __x,
	       const _Rope_char_ptr_proxy<_CharT, _Alloc>& __y);

  template<class _CharT, class _Alloc>
    _Rope_const_iterator<_CharT, _Alloc>
    operator-(const _Rope_const_iterator<_CharT, _Alloc>& __x,
	      ptrdiff_t __n);

  template<class _CharT, class _Alloc>
    _Rope_const_iterator<_CharT, _Alloc>
    operator+(const _Rope_const_iterator<_CharT, _Alloc>& __x,
	      ptrdiff_t __n);

  template<class _CharT, class _Alloc>
    _Rope_const_iterator<_CharT, _Alloc>
    operator+(ptrdiff_t __n,
	      const _Rope_const_iterator<_CharT, _Alloc>& __x);

  template<class _CharT, class _Alloc>
    bool
    operator==(const _Rope_const_iterator<_CharT, _Alloc>& __x,
	       const _Rope_const_iterator<_CharT, _Alloc>& __y);

  template<class _CharT, class _Alloc>
    bool
    operator<(const _Rope_const_iterator<_CharT, _Alloc>& __x,
	      const _Rope_const_iterator<_CharT, _Alloc>& __y);
  
  template<class _CharT, class _Alloc>
    ptrdiff_t
    operator-(const _Rope_const_iterator<_CharT, _Alloc>& __x,
	      const _Rope_const_iterator<_CharT, _Alloc>& __y);

  template<class _CharT, class _Alloc>
    _Rope_iterator<_CharT, _Alloc>
    operator-(const _Rope_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n);

  template<class _CharT, class _Alloc>
    _Rope_iterator<_CharT, _Alloc>
    operator+(const _Rope_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n);

  template<class _CharT, class _Alloc>
    _Rope_iterator<_CharT, _Alloc>
    operator+(ptrdiff_t __n, const _Rope_iterator<_CharT, _Alloc>& __x);

  template<class _CharT, class _Alloc>
    bool
    operator==(const _Rope_iterator<_CharT, _Alloc>& __x,
	       const _Rope_iterator<_CharT, _Alloc>& __y);

  template<class _CharT, class _Alloc>
    bool
    operator<(const _Rope_iterator<_CharT, _Alloc>& __x,
	      const _Rope_iterator<_CharT, _Alloc>& __y);

  template<class _CharT, class _Alloc>
    ptrdiff_t
    operator-(const _Rope_iterator<_CharT, _Alloc>& __x,
	      const _Rope_iterator<_CharT, _Alloc>& __y);

  template<class _CharT, class _Alloc>
    rope<_CharT, _Alloc>
    operator+(const rope<_CharT, _Alloc>& __left,
	      const rope<_CharT, _Alloc>& __right);

  template<class _CharT, class _Alloc>
    rope<_CharT, _Alloc>
    operator+(const rope<_CharT, _Alloc>& __left, const _CharT* __right);

  template<class _CharT, class _Alloc>
    rope<_CharT, _Alloc>
    operator+(const rope<_CharT, _Alloc>& __left, _CharT __right);

  // Some helpers, so we can use power on ropes.
  // See below for why this isn't local to the implementation.
  
  // This uses a nonstandard refcount convention.
  // The result has refcount 0.
  template<class _CharT, class _Alloc>
    struct _Rope_Concat_fn
    : public std::binary_function<rope<_CharT, _Alloc>, rope<_CharT, _Alloc>,
				  rope<_CharT, _Alloc> >
    {
      rope<_CharT, _Alloc>
      operator()(const rope<_CharT, _Alloc>& __x,
		 const rope<_CharT, _Alloc>& __y)
      { return __x + __y; }
    };

  template <class _CharT, class _Alloc>
    inline rope<_CharT, _Alloc>
    identity_element(_Rope_Concat_fn<_CharT, _Alloc>)
    { return rope<_CharT, _Alloc>(); }

  static inline void
  __copy_gthr_mutex(__gthread_mutex_t& __to, const __gthread_mutex_t& __from)
  {
#if defined __GXX_EXPERIMENTAL_CXX0X__ \
  && defined _GLIBCXX_GTHREADS_NO_COPY_ASSIGN_IN_CXX11
    __builtin_memcpy(&__to, &__from, sizeof(__to));
#else
    __to = __from;
#endif
  }

  // Class _Refcount_Base provides a type, _RC_t, a data member,
  // _M_ref_count, and member functions _M_incr and _M_decr, which perform
  // atomic preincrement/predecrement.  The constructor initializes
  // _M_ref_count.
  struct _Refcount_Base
  {
    // The type _RC_t
    typedef size_t _RC_t;
    
    // The data member _M_ref_count
    volatile _RC_t _M_ref_count;

    // Constructor
    __gthread_mutex_t _M_ref_count_lock;

    _Refcount_Base(_RC_t __n) : _M_ref_count(__n), _M_ref_count_lock()
    {
#ifdef __GTHREAD_MUTEX_INIT
      __gthread_mutex_t __tmp = __GTHREAD_MUTEX_INIT;
      __copy_gthr_mutex(_M_ref_count_lock, __tmp);
#elif defined(__GTHREAD_MUTEX_INIT_FUNCTION)
      __GTHREAD_MUTEX_INIT_FUNCTION (&_M_ref_count_lock);
#else
#error __GTHREAD_MUTEX_INIT or __GTHREAD_MUTEX_INIT_FUNCTION should be defined by gthr.h abstraction layer, report problem to libstdc++@gcc.gnu.org.
#endif
    }

    void
    _M_incr()
    {
      __gthread_mutex_lock(&_M_ref_count_lock);
      ++_M_ref_count;
      __gthread_mutex_unlock(&_M_ref_count_lock);
    }

    _RC_t
    _M_decr()
    {
      __gthread_mutex_lock(&_M_ref_count_lock);
      volatile _RC_t __tmp = --_M_ref_count;
      __gthread_mutex_unlock(&_M_ref_count_lock);
      return __tmp;
    }
  };

  //
  // What follows should really be local to rope.  Unfortunately,
  // that doesn't work, since it makes it impossible to define generic
  // equality on rope iterators.  According to the draft standard, the
  // template parameters for such an equality operator cannot be inferred
  // from the occurrence of a member class as a parameter.
  // (SGI compilers in fact allow this, but the __result wouldn't be
  // portable.)
  // Similarly, some of the static member functions are member functions
  // only to avoid polluting the global namespace, and to circumvent
  // restrictions on type inference for template functions.
  //

  //
  // The internal data structure for representing a rope.  This is
  // private to the implementation.  A rope is really just a pointer
  // to one of these.
  //
  // A few basic functions for manipulating this data structure
  // are members of _RopeRep.  Most of the more complex algorithms
  // are implemented as rope members.
  //
  // Some of the static member functions of _RopeRep have identically
  // named functions in rope that simply invoke the _RopeRep versions.

#define __ROPE_DEFINE_ALLOCS(__a) \
        __ROPE_DEFINE_ALLOC(_CharT,_Data) /* character data */ \
        typedef _Rope_RopeConcatenation<_CharT,__a> __C; \
        __ROPE_DEFINE_ALLOC(__C,_C) \
        typedef _Rope_RopeLeaf<_CharT,__a> __L; \
        __ROPE_DEFINE_ALLOC(__L,_L) \
        typedef _Rope_RopeFunction<_CharT,__a> __F; \
        __ROPE_DEFINE_ALLOC(__F,_F) \
        typedef _Rope_RopeSubstring<_CharT,__a> __S; \
        __ROPE_DEFINE_ALLOC(__S,_S)

  //  Internal rope nodes potentially store a copy of the allocator
  //  instance used to allocate them.  This is mostly redundant.
  //  But the alternative would be to pass allocator instances around
  //  in some form to nearly all internal functions, since any pointer
  //  assignment may result in a zero reference count and thus require
  //  deallocation.

#define __STATIC_IF_SGI_ALLOC  /* not static */

  template <class _CharT, class _Alloc>
    struct _Rope_rep_base
    : public _Alloc
    {
      typedef _Alloc allocator_type;

      allocator_type
      get_allocator() const
      { return *static_cast<const _Alloc*>(this); }

      allocator_type&
      _M_get_allocator()
      { return *static_cast<_Alloc*>(this); }

      const allocator_type&
      _M_get_allocator() const
      { return *static_cast<const _Alloc*>(this); }

      _Rope_rep_base(size_t __size, const allocator_type&)
      : _M_size(__size) { }

      size_t _M_size;

# define __ROPE_DEFINE_ALLOC(_Tp, __name) \
        typedef typename \
          _Alloc::template rebind<_Tp>::other __name##Alloc; \
        static _Tp* __name##_allocate(size_t __n) \
          { return __name##Alloc().allocate(__n); } \
        static void __name##_deallocate(_Tp *__p, size_t __n) \
          { __name##Alloc().deallocate(__p, __n); }
      __ROPE_DEFINE_ALLOCS(_Alloc)
# undef __ROPE_DEFINE_ALLOC
    };

  template<class _CharT, class _Alloc>
    struct _Rope_RopeRep
    : public _Rope_rep_base<_CharT, _Alloc>
# ifndef __GC
	     , _Refcount_Base
# endif
    {
    public:
      __detail::_Tag _M_tag:8;
      bool _M_is_balanced:8;
      unsigned char _M_depth;
      __GC_CONST _CharT* _M_c_string;
      __gthread_mutex_t _M_c_string_lock;
                        /* Flattened version of string, if needed.  */
                        /* typically 0.                             */
                        /* If it's not 0, then the memory is owned  */
                        /* by this node.                            */
                        /* In the case of a leaf, this may point to */
                        /* the same memory as the data field.       */
      typedef typename _Rope_rep_base<_CharT, _Alloc>::allocator_type
        allocator_type;

      using _Rope_rep_base<_CharT, _Alloc>::get_allocator;
      using _Rope_rep_base<_CharT, _Alloc>::_M_get_allocator;

      _Rope_RopeRep(__detail::_Tag __t, int __d, bool __b, size_t __size,
		    const allocator_type& __a)
      : _Rope_rep_base<_CharT, _Alloc>(__size, __a),
#ifndef __GC
	_Refcount_Base(1),
#endif
	_M_tag(__t), _M_is_balanced(__b), _M_depth(__d), _M_c_string(0)
#ifdef __GTHREAD_MUTEX_INIT
    {
      // Do not copy a POSIX/gthr mutex once in use.  However, bits are bits.
      __gthread_mutex_t __tmp = __GTHREAD_MUTEX_INIT;
      __copy_gthr_mutex(_M_c_string_lock, __tmp);
    }
#else
    { __GTHREAD_MUTEX_INIT_FUNCTION (&_M_c_string_lock); }
#endif
#ifdef __GC
      void
      _M_incr () { }
#endif
      static void
      _S_free_string(__GC_CONST _CharT*, size_t __len,
		     allocator_type& __a);
#define __STL_FREE_STRING(__s, __l, __a) _S_free_string(__s, __l, __a);
                        // Deallocate data section of a leaf.
                        // This shouldn't be a member function.
                        // But its hard to do anything else at the
                        // moment, because it's templatized w.r.t.
                        // an allocator.
                        // Does nothing if __GC is defined.
#ifndef __GC
      void _M_free_c_string();
      void _M_free_tree();
      // Deallocate t. Assumes t is not 0.
      void
      _M_unref_nonnil()
      {
	if (0 == _M_decr())
	  _M_free_tree();
      }

      void
      _M_ref_nonnil()
      { _M_incr(); }

      static void
      _S_unref(_Rope_RopeRep* __t)
      {
	if (0 != __t)
	  __t->_M_unref_nonnil();
      }

      static void
      _S_ref(_Rope_RopeRep* __t)
      {
	if (0 != __t)
	  __t->_M_incr();
      }
      
      static void
      _S_free_if_unref(_Rope_RopeRep* __t)
      {
	if (0 != __t && 0 == __t->_M_ref_count)
	  __t->_M_free_tree();
      }
#   else /* __GC */
      void _M_unref_nonnil() { }
      void _M_ref_nonnil() { }
      static void _S_unref(_Rope_RopeRep*) { }
      static void _S_ref(_Rope_RopeRep*) { }
      static void _S_free_if_unref(_Rope_RopeRep*) { }
#   endif
protected:
      _Rope_RopeRep&
      operator=(const _Rope_RopeRep&);

      _Rope_RopeRep(const _Rope_RopeRep&);
    };

  template<class _CharT, class _Alloc>
    struct _Rope_RopeLeaf
    : public _Rope_RopeRep<_CharT, _Alloc>
    {
    public:
      // Apparently needed by VC++
      // The data fields of leaves are allocated with some
      // extra space, to accommodate future growth and for basic
      // character types, to hold a trailing eos character.
      enum { _S_alloc_granularity = 8 };
      
      static size_t
      _S_rounded_up_size(size_t __n)
      {
        size_t __size_with_eos;
	
        if (_S_is_basic_char_type((_CharT*)0))
	  __size_with_eos = __n + 1;
	else
	  __size_with_eos = __n;
#ifdef __GC
	return __size_with_eos;
#else
	// Allow slop for in-place expansion.
	return ((__size_with_eos + size_t(_S_alloc_granularity) - 1)
		&~ (size_t(_S_alloc_granularity) - 1));
#endif
      }
      __GC_CONST _CharT* _M_data; /* Not necessarily 0 terminated. */
                                  /* The allocated size is         */
                                  /* _S_rounded_up_size(size), except */
                                  /* in the GC case, in which it   */
                                  /* doesn't matter.               */
      typedef typename _Rope_rep_base<_CharT,_Alloc>::allocator_type
        allocator_type;

      _Rope_RopeLeaf(__GC_CONST _CharT* __d, size_t __size,
		     const allocator_type& __a)
      : _Rope_RopeRep<_CharT, _Alloc>(__detail::_S_leaf, 0, true,
				      __size, __a), _M_data(__d)
      {
        if (_S_is_basic_char_type((_CharT *)0))
	  {
            // already eos terminated.
            this->_M_c_string = __d;
	  }
      }
      // The constructor assumes that d has been allocated with
      // the proper allocator and the properly padded size.
      // In contrast, the destructor deallocates the data:
#ifndef __GC
      ~_Rope_RopeLeaf() throw()
      {
        if (_M_data != this->_M_c_string)
	  this->_M_free_c_string();
	
        __STL_FREE_STRING(_M_data, this->_M_size, this->_M_get_allocator());
      }
#endif
protected:
      _Rope_RopeLeaf&
      operator=(const _Rope_RopeLeaf&);

      _Rope_RopeLeaf(const _Rope_RopeLeaf&);
    };

  template<class _CharT, class _Alloc>
    struct _Rope_RopeConcatenation
    : public _Rope_RopeRep<_CharT, _Alloc>
    {
    public:
      _Rope_RopeRep<_CharT, _Alloc>* _M_left;
      _Rope_RopeRep<_CharT, _Alloc>* _M_right;

      typedef typename _Rope_rep_base<_CharT, _Alloc>::allocator_type
        allocator_type;

      _Rope_RopeConcatenation(_Rope_RopeRep<_CharT, _Alloc>* __l,
			      _Rope_RopeRep<_CharT, _Alloc>* __r,
			      const allocator_type& __a)
	: _Rope_RopeRep<_CharT, _Alloc>(__detail::_S_concat,
				      std::max(__l->_M_depth,
					       __r->_M_depth) + 1,
				      false,
				      __l->_M_size + __r->_M_size, __a),
        _M_left(__l), _M_right(__r)
      { }
#ifndef __GC
      ~_Rope_RopeConcatenation() throw()
      {
	this->_M_free_c_string();
	_M_left->_M_unref_nonnil();
	_M_right->_M_unref_nonnil();
      }
#endif
protected:
      _Rope_RopeConcatenation&
      operator=(const _Rope_RopeConcatenation&);
      
      _Rope_RopeConcatenation(const _Rope_RopeConcatenation&);
    };

  template<class _CharT, class _Alloc>
    struct _Rope_RopeFunction
    : public _Rope_RopeRep<_CharT, _Alloc>
    {
    public:
      char_producer<_CharT>* _M_fn;
#ifndef __GC
      bool _M_delete_when_done; // Char_producer is owned by the
                                // rope and should be explicitly
                                // deleted when the rope becomes
                                // inaccessible.
#else
      // In the GC case, we either register the rope for
      // finalization, or not.  Thus the field is unnecessary;
      // the information is stored in the collector data structures.
      // We do need a finalization procedure to be invoked by the
      // collector.
      static void
      _S_fn_finalization_proc(void * __tree, void *)
      { delete ((_Rope_RopeFunction *)__tree) -> _M_fn; }
#endif
    typedef typename _Rope_rep_base<_CharT, _Alloc>::allocator_type
      allocator_type;

      _Rope_RopeFunction(char_producer<_CharT>* __f, size_t __size,
                        bool __d, const allocator_type& __a)
      : _Rope_RopeRep<_CharT, _Alloc>(__detail::_S_function, 0, true, __size, __a)
	, _M_fn(__f)
#ifndef __GC
	, _M_delete_when_done(__d)
#endif
      {
#ifdef __GC
	if (__d)
	  {
	    GC_REGISTER_FINALIZER(this, _Rope_RopeFunction::
				  _S_fn_finalization_proc, 0, 0, 0);
	  }
#endif
      }
#ifndef __GC
      ~_Rope_RopeFunction() throw()
      {
	this->_M_free_c_string();
	if (_M_delete_when_done)
	  delete _M_fn;
      }
# endif
    protected:
      _Rope_RopeFunction&
      operator=(const _Rope_RopeFunction&);

      _Rope_RopeFunction(const _Rope_RopeFunction&);
    };
  // Substring results are usually represented using just
  // concatenation nodes.  But in the case of very long flat ropes
  // or ropes with a functional representation that isn't practical.
  // In that case, we represent the __result as a special case of
  // RopeFunction, whose char_producer points back to the rope itself.
  // In all cases except repeated substring operations and
  // deallocation, we treat the __result as a RopeFunction.
  template<class _CharT, class _Alloc>
    struct _Rope_RopeSubstring
    : public _Rope_RopeFunction<_CharT, _Alloc>,
      public char_producer<_CharT>
    {
    public:
      // XXX this whole class should be rewritten.
      _Rope_RopeRep<_CharT,_Alloc>* _M_base;      // not 0
      size_t _M_start;

      virtual void
      operator()(size_t __start_pos, size_t __req_len,
		 _CharT* __buffer)
      {
        switch(_M_base->_M_tag)
	  {
	  case __detail::_S_function:
	  case __detail::_S_substringfn:
	    {
	      char_producer<_CharT>* __fn =
		((_Rope_RopeFunction<_CharT,_Alloc>*)_M_base)->_M_fn;
	      (*__fn)(__start_pos + _M_start, __req_len, __buffer);
	    }
	    break;
	  case __detail::_S_leaf:
	    {
	      __GC_CONST _CharT* __s =
		((_Rope_RopeLeaf<_CharT,_Alloc>*)_M_base)->_M_data;
	      uninitialized_copy_n(__s + __start_pos + _M_start, __req_len,
				   __buffer);
	    }
	    break;
	  default:
	    break;
	  }
      }
      
      typedef typename _Rope_rep_base<_CharT, _Alloc>::allocator_type
        allocator_type;

      _Rope_RopeSubstring(_Rope_RopeRep<_CharT, _Alloc>* __b, size_t __s,
                          size_t __l, const allocator_type& __a)
      : _Rope_RopeFunction<_CharT, _Alloc>(this, __l, false, __a),
        char_producer<_CharT>(), _M_base(__b), _M_start(__s)
      {
#ifndef __GC
	_M_base->_M_ref_nonnil();
#endif
        this->_M_tag = __detail::_S_substringfn;
      }
    virtual ~_Rope_RopeSubstring() throw()
      {
#ifndef __GC
	_M_base->_M_unref_nonnil();
	// _M_free_c_string();  -- done by parent class
#endif
      }
    };

  // Self-destructing pointers to Rope_rep.
  // These are not conventional smart pointers.  Their
  // only purpose in life is to ensure that unref is called
  // on the pointer either at normal exit or if an exception
  // is raised.  It is the caller's responsibility to
  // adjust reference counts when these pointers are initialized
  // or assigned to.  (This convention significantly reduces
  // the number of potentially expensive reference count
  // updates.)
#ifndef __GC
  template<class _CharT, class _Alloc>
    struct _Rope_self_destruct_ptr
    {
      _Rope_RopeRep<_CharT, _Alloc>* _M_ptr;

      ~_Rope_self_destruct_ptr()
      { _Rope_RopeRep<_CharT, _Alloc>::_S_unref(_M_ptr); }
#ifdef __EXCEPTIONS
      _Rope_self_destruct_ptr() : _M_ptr(0) { };
#else
      _Rope_self_destruct_ptr() { };
#endif
      _Rope_self_destruct_ptr(_Rope_RopeRep<_CharT, _Alloc>* __p)
      : _M_ptr(__p) { }
    
      _Rope_RopeRep<_CharT, _Alloc>&
      operator*()
      { return *_M_ptr; }
    
      _Rope_RopeRep<_CharT, _Alloc>*
      operator->()
      { return _M_ptr; }
    
      operator _Rope_RopeRep<_CharT, _Alloc>*()
      { return _M_ptr; }
    
      _Rope_self_destruct_ptr&
      operator=(_Rope_RopeRep<_CharT, _Alloc>* __x)
      { _M_ptr = __x; return *this; }
    };
#endif

  // Dereferencing a nonconst iterator has to return something
  // that behaves almost like a reference.  It's not possible to
  // return an actual reference since assignment requires extra
  // work.  And we would get into the same problems as with the
  // CD2 version of basic_string.
  template<class _CharT, class _Alloc>
    class _Rope_char_ref_proxy
    {
      friend class rope<_CharT, _Alloc>;
      friend class _Rope_iterator<_CharT, _Alloc>;
      friend class _Rope_char_ptr_proxy<_CharT, _Alloc>;
#ifdef __GC
      typedef _Rope_RopeRep<_CharT, _Alloc>* _Self_destruct_ptr;
#else
      typedef _Rope_self_destruct_ptr<_CharT, _Alloc> _Self_destruct_ptr;
#endif
      typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep;
      typedef rope<_CharT, _Alloc> _My_rope;
      size_t _M_pos;
      _CharT _M_current;
      bool _M_current_valid;
      _My_rope* _M_root;     // The whole rope.
    public:
      _Rope_char_ref_proxy(_My_rope* __r, size_t __p)
      :  _M_pos(__p), _M_current(), _M_current_valid(false), _M_root(__r) { }

      _Rope_char_ref_proxy(const _Rope_char_ref_proxy& __x)
      : _M_pos(__x._M_pos), _M_current(__x._M_current), 
	_M_current_valid(false), _M_root(__x._M_root) { }

      // Don't preserve cache if the reference can outlive the
      // expression.  We claim that's not possible without calling
      // a copy constructor or generating reference to a proxy
      // reference.  We declare the latter to have undefined semantics.
      _Rope_char_ref_proxy(_My_rope* __r, size_t __p, _CharT __c)
      : _M_pos(__p), _M_current(__c), _M_current_valid(true), _M_root(__r) { }

      inline operator _CharT () const;

      _Rope_char_ref_proxy&
      operator=(_CharT __c);
    
      _Rope_char_ptr_proxy<_CharT, _Alloc> operator&() const;
      
      _Rope_char_ref_proxy&
      operator=(const _Rope_char_ref_proxy& __c)
      { return operator=((_CharT)__c); }
    };

  template<class _CharT, class __Alloc>
    inline void
    swap(_Rope_char_ref_proxy <_CharT, __Alloc > __a,
	 _Rope_char_ref_proxy <_CharT, __Alloc > __b)
    {
      _CharT __tmp = __a;
      __a = __b;
      __b = __tmp;
    }

  template<class _CharT, class _Alloc>
    class _Rope_char_ptr_proxy
    {
      // XXX this class should be rewritten.
      friend class _Rope_char_ref_proxy<_CharT, _Alloc>;
      size_t _M_pos;
      rope<_CharT,_Alloc>* _M_root;     // The whole rope.
    public:
      _Rope_char_ptr_proxy(const _Rope_char_ref_proxy<_CharT,_Alloc>& __x)
      : _M_pos(__x._M_pos), _M_root(__x._M_root) { }

      _Rope_char_ptr_proxy(const _Rope_char_ptr_proxy& __x)
      : _M_pos(__x._M_pos), _M_root(__x._M_root) { }

      _Rope_char_ptr_proxy() { }
      
      _Rope_char_ptr_proxy(_CharT* __x)
      : _M_root(0), _M_pos(0) { }

      _Rope_char_ptr_proxy&
      operator=(const _Rope_char_ptr_proxy& __x)
      {
        _M_pos = __x._M_pos;
        _M_root = __x._M_root;
        return *this;
      }

      template<class _CharT2, class _Alloc2>
        friend bool
        operator==(const _Rope_char_ptr_proxy<_CharT2, _Alloc2>& __x,
		   const _Rope_char_ptr_proxy<_CharT2, _Alloc2>& __y);

      _Rope_char_ref_proxy<_CharT, _Alloc> operator*() const
      { return _Rope_char_ref_proxy<_CharT, _Alloc>(_M_root, _M_pos); }
    };

  // Rope iterators:
  // Unlike in the C version, we cache only part of the stack
  // for rope iterators, since they must be efficiently copyable.
  // When we run out of cache, we have to reconstruct the iterator
  // value.
  // Pointers from iterators are not included in reference counts.
  // Iterators are assumed to be thread private.  Ropes can
  // be shared.
  
  template<class _CharT, class _Alloc>
    class _Rope_iterator_base
    : public std::iterator<std::random_access_iterator_tag, _CharT>
    {
      friend class rope<_CharT, _Alloc>;
    public:
      typedef _Alloc _allocator_type; // used in _Rope_rotate, VC++ workaround
      typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep;
      // Borland doesn't want this to be protected.
    protected:
      enum { _S_path_cache_len = 4 }; // Must be <= 9.
      enum { _S_iterator_buf_len = 15 };
      size_t _M_current_pos;
      _RopeRep* _M_root;     // The whole rope.
      size_t _M_leaf_pos;    // Starting position for current leaf
      __GC_CONST _CharT* _M_buf_start;
                             // Buffer possibly
                             // containing current char.
      __GC_CONST _CharT* _M_buf_ptr;
                             // Pointer to current char in buffer.
                             // != 0 ==> buffer valid.
      __GC_CONST _CharT* _M_buf_end;
                             // One past __last valid char in buffer.
      // What follows is the path cache.  We go out of our
      // way to make this compact.
      // Path_end contains the bottom section of the path from
      // the root to the current leaf.
      const _RopeRep* _M_path_end[_S_path_cache_len];
      int _M_leaf_index;     // Last valid __pos in path_end;
                             // _M_path_end[0] ... _M_path_end[leaf_index-1]
                             // point to concatenation nodes.
      unsigned char _M_path_directions;
                          // (path_directions >> __i) & 1 is 1
                          // iff we got from _M_path_end[leaf_index - __i - 1]
                          // to _M_path_end[leaf_index - __i] by going to the
                          // __right. Assumes path_cache_len <= 9.
      _CharT _M_tmp_buf[_S_iterator_buf_len];
                        // Short buffer for surrounding chars.
                        // This is useful primarily for
                        // RopeFunctions.  We put the buffer
                        // here to avoid locking in the
                        // multithreaded case.
      // The cached path is generally assumed to be valid
      // only if the buffer is valid.
      static void _S_setbuf(_Rope_iterator_base& __x);
                                        // Set buffer contents given
                                        // path cache.
      static void _S_setcache(_Rope_iterator_base& __x);
                                        // Set buffer contents and
                                        // path cache.
      static void _S_setcache_for_incr(_Rope_iterator_base& __x);
                                        // As above, but assumes path
                                        // cache is valid for previous posn.
      _Rope_iterator_base() { }

      _Rope_iterator_base(_RopeRep* __root, size_t __pos)
      : _M_current_pos(__pos), _M_root(__root), _M_buf_ptr(0) { }

      void _M_incr(size_t __n);
      void _M_decr(size_t __n);
    public:
      size_t
      index() const
      { return _M_current_pos; }
    
      _Rope_iterator_base(const _Rope_iterator_base& __x)
      {
        if (0 != __x._M_buf_ptr)
	  *this = __x;
	else
	  {
            _M_current_pos = __x._M_current_pos;
            _M_root = __x._M_root;
            _M_buf_ptr = 0;
	  }
      }
    };

  template<class _CharT, class _Alloc>
    class _Rope_iterator;

  template<class _CharT, class _Alloc>
    class _Rope_const_iterator
    : public _Rope_iterator_base<_CharT, _Alloc>
    {
      friend class rope<_CharT, _Alloc>;
    protected:
      typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep;
      // The one from the base class may not be directly visible.
      _Rope_const_iterator(const _RopeRep* __root, size_t __pos)
      : _Rope_iterator_base<_CharT, _Alloc>(const_cast<_RopeRep*>(__root),
					    __pos)
                   // Only nonconst iterators modify root ref count
      { }
  public:
      typedef _CharT reference;   // Really a value.  Returning a reference
                                  // Would be a mess, since it would have
                                  // to be included in refcount.
      typedef const _CharT* pointer;

    public:
      _Rope_const_iterator() { };

      _Rope_const_iterator(const _Rope_const_iterator& __x)
      : _Rope_iterator_base<_CharT,_Alloc>(__x) { }

      _Rope_const_iterator(const _Rope_iterator<_CharT,_Alloc>& __x);
    
      _Rope_const_iterator(const rope<_CharT, _Alloc>& __r, size_t __pos)
      : _Rope_iterator_base<_CharT,_Alloc>(__r._M_tree_ptr, __pos) { }

      _Rope_const_iterator&
      operator=(const _Rope_const_iterator& __x)
      {
        if (0 != __x._M_buf_ptr)
	  *(static_cast<_Rope_iterator_base<_CharT, _Alloc>*>(this)) = __x;
	else
	  {
            this->_M_current_pos = __x._M_current_pos;
            this->_M_root = __x._M_root;
            this->_M_buf_ptr = 0;
	  }
        return(*this);
      }

      reference
      operator*()
      {
        if (0 == this->_M_buf_ptr)
	  _S_setcache(*this);
        return *this->_M_buf_ptr;
      }

      // Without this const version, Rope iterators do not meet the
      // requirements of an Input Iterator.
      reference
      operator*() const
      {
	return *const_cast<_Rope_const_iterator&>(*this);
      }

      _Rope_const_iterator&
      operator++()
      {
        __GC_CONST _CharT* __next;
        if (0 != this->_M_buf_ptr
	    && (__next = this->_M_buf_ptr + 1) < this->_M_buf_end)
	  {
            this->_M_buf_ptr = __next;
            ++this->_M_current_pos;
	  }
	else
	  this->_M_incr(1);
	return *this;
      }

      _Rope_const_iterator&
      operator+=(ptrdiff_t __n)
      {
        if (__n >= 0)
	  this->_M_incr(__n);
	else
	  this->_M_decr(-__n);
	return *this;
      }

      _Rope_const_iterator&
      operator--()
      {
        this->_M_decr(1);
        return *this;
      }

      _Rope_const_iterator&
      operator-=(ptrdiff_t __n)
      {
        if (__n >= 0)
	  this->_M_decr(__n);
	else
	  this->_M_incr(-__n);
	return *this;
      }

      _Rope_const_iterator
      operator++(int)
      {
        size_t __old_pos = this->_M_current_pos;
        this->_M_incr(1);
        return _Rope_const_iterator<_CharT,_Alloc>(this->_M_root, __old_pos);
        // This makes a subsequent dereference expensive.
        // Perhaps we should instead copy the iterator
        // if it has a valid cache?
      }

      _Rope_const_iterator
      operator--(int)
      {
        size_t __old_pos = this->_M_current_pos;
        this->_M_decr(1);
        return _Rope_const_iterator<_CharT,_Alloc>(this->_M_root, __old_pos);
      }

      template<class _CharT2, class _Alloc2>
        friend _Rope_const_iterator<_CharT2, _Alloc2>
        operator-(const _Rope_const_iterator<_CharT2, _Alloc2>& __x,
		  ptrdiff_t __n);

      template<class _CharT2, class _Alloc2>
        friend _Rope_const_iterator<_CharT2, _Alloc2>
        operator+(const _Rope_const_iterator<_CharT2, _Alloc2>& __x,
		  ptrdiff_t __n);

      template<class _CharT2, class _Alloc2>
        friend _Rope_const_iterator<_CharT2, _Alloc2>
        operator+(ptrdiff_t __n,
		  const _Rope_const_iterator<_CharT2, _Alloc2>& __x);

      reference
      operator[](size_t __n)
      { return rope<_CharT, _Alloc>::_S_fetch(this->_M_root,
					      this->_M_current_pos + __n); }

      template<class _CharT2, class _Alloc2>
        friend bool
        operator==(const _Rope_const_iterator<_CharT2, _Alloc2>& __x,
		   const _Rope_const_iterator<_CharT2, _Alloc2>& __y);

      template<class _CharT2, class _Alloc2>
        friend bool
        operator<(const _Rope_const_iterator<_CharT2, _Alloc2>& __x,
		  const _Rope_const_iterator<_CharT2, _Alloc2>& __y);

      template<class _CharT2, class _Alloc2>
        friend ptrdiff_t
        operator-(const _Rope_const_iterator<_CharT2, _Alloc2>& __x,
		  const _Rope_const_iterator<_CharT2, _Alloc2>& __y);
    };

  template<class _CharT, class _Alloc>
    class _Rope_iterator
    : public _Rope_iterator_base<_CharT, _Alloc>
    {
      friend class rope<_CharT, _Alloc>;
    protected:
      typedef typename _Rope_iterator_base<_CharT, _Alloc>::_RopeRep _RopeRep;
      rope<_CharT, _Alloc>* _M_root_rope;

      // root is treated as a cached version of this, and is used to
      // detect changes to the underlying rope.

      // Root is included in the reference count.  This is necessary
      // so that we can detect changes reliably.  Unfortunately, it
      // requires careful bookkeeping for the nonGC case.
      _Rope_iterator(rope<_CharT, _Alloc>* __r, size_t __pos)
      : _Rope_iterator_base<_CharT, _Alloc>(__r->_M_tree_ptr, __pos),
        _M_root_rope(__r)
      { _RopeRep::_S_ref(this->_M_root);
        if (!(__r -> empty()))
	  _S_setcache(*this);
      }

      void _M_check();
    public:
      typedef _Rope_char_ref_proxy<_CharT, _Alloc>  reference;
      typedef _Rope_char_ref_proxy<_CharT, _Alloc>* pointer;

      rope<_CharT, _Alloc>&
      container()
      { return *_M_root_rope; }

      _Rope_iterator()
      {
        this->_M_root = 0;  // Needed for reference counting.
      };

      _Rope_iterator(const _Rope_iterator& __x)
      : _Rope_iterator_base<_CharT, _Alloc>(__x)
      {
        _M_root_rope = __x._M_root_rope;
        _RopeRep::_S_ref(this->_M_root);
      }

      _Rope_iterator(rope<_CharT, _Alloc>& __r, size_t __pos);

      ~_Rope_iterator()
      { _RopeRep::_S_unref(this->_M_root); }

      _Rope_iterator&
      operator=(const _Rope_iterator& __x)
      {
        _RopeRep* __old = this->_M_root;
	
        _RopeRep::_S_ref(__x._M_root);
        if (0 != __x._M_buf_ptr)
	  {
            _M_root_rope = __x._M_root_rope;
            *(static_cast<_Rope_iterator_base<_CharT, _Alloc>*>(this)) = __x;
	  }
	else
	  {
	    this->_M_current_pos = __x._M_current_pos;
            this->_M_root = __x._M_root;
            _M_root_rope = __x._M_root_rope;
            this->_M_buf_ptr = 0;
	  }
        _RopeRep::_S_unref(__old);
        return(*this);
      }

      reference
      operator*()
      {
        _M_check();
        if (0 == this->_M_buf_ptr)
	  return _Rope_char_ref_proxy<_CharT, _Alloc>(_M_root_rope,
						      this->_M_current_pos);
	else
	  return _Rope_char_ref_proxy<_CharT, _Alloc>(_M_root_rope,
						      this->_M_current_pos,
						      *this->_M_buf_ptr);
      }

      // See above comment.
      reference
      operator*() const
      {
	return *const_cast<_Rope_iterator&>(*this);
      }

      _Rope_iterator&
      operator++()
      {
        this->_M_incr(1);
        return *this;
      }

      _Rope_iterator&
      operator+=(ptrdiff_t __n)
      {
        if (__n >= 0)
	  this->_M_incr(__n);
	else
	  this->_M_decr(-__n);
	return *this;
      }

      _Rope_iterator&
      operator--()
      {
        this->_M_decr(1);
        return *this;
      }

      _Rope_iterator&
      operator-=(ptrdiff_t __n)
      {
        if (__n >= 0)
	  this->_M_decr(__n);
	else
	  this->_M_incr(-__n);
	return *this;
      }

      _Rope_iterator
      operator++(int)
      {
        size_t __old_pos = this->_M_current_pos;
        this->_M_incr(1);
        return _Rope_iterator<_CharT,_Alloc>(_M_root_rope, __old_pos);
      }

      _Rope_iterator
      operator--(int)
      {
        size_t __old_pos = this->_M_current_pos;
        this->_M_decr(1);
        return _Rope_iterator<_CharT,_Alloc>(_M_root_rope, __old_pos);
      }

      reference
      operator[](ptrdiff_t __n)
      { return _Rope_char_ref_proxy<_CharT, _Alloc>(_M_root_rope,
						    this->_M_current_pos
						    + __n); }

      template<class _CharT2, class _Alloc2>
        friend bool
        operator==(const _Rope_iterator<_CharT2, _Alloc2>& __x,
		   const _Rope_iterator<_CharT2, _Alloc2>& __y);

      template<class _CharT2, class _Alloc2>
        friend bool
        operator<(const _Rope_iterator<_CharT2, _Alloc2>& __x,
		  const _Rope_iterator<_CharT2, _Alloc2>& __y);

      template<class _CharT2, class _Alloc2>
        friend ptrdiff_t
        operator-(const _Rope_iterator<_CharT2, _Alloc2>& __x,
		  const _Rope_iterator<_CharT2, _Alloc2>& __y);

      template<class _CharT2, class _Alloc2>
        friend _Rope_iterator<_CharT2, _Alloc2>
        operator-(const _Rope_iterator<_CharT2, _Alloc2>& __x, ptrdiff_t __n);

      template<class _CharT2, class _Alloc2>
        friend _Rope_iterator<_CharT2, _Alloc2>
        operator+(const _Rope_iterator<_CharT2, _Alloc2>& __x, ptrdiff_t __n);

      template<class _CharT2, class _Alloc2>
        friend _Rope_iterator<_CharT2, _Alloc2>
        operator+(ptrdiff_t __n, const _Rope_iterator<_CharT2, _Alloc2>& __x);
    };


  template <class _CharT, class _Alloc>
    struct _Rope_base
    : public _Alloc
    {
      typedef _Alloc allocator_type;

      allocator_type
      get_allocator() const
      { return *static_cast<const _Alloc*>(this); }

      allocator_type&
      _M_get_allocator()
      { return *static_cast<_Alloc*>(this); }

      const allocator_type&
      _M_get_allocator() const
      { return *static_cast<const _Alloc*>(this); }

      typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep;
      // The one in _Base may not be visible due to template rules.

      _Rope_base(_RopeRep* __t, const allocator_type&)
      : _M_tree_ptr(__t) { }

      _Rope_base(const allocator_type&) { }

      // The only data member of a rope:
      _RopeRep *_M_tree_ptr;

#define __ROPE_DEFINE_ALLOC(_Tp, __name) \
        typedef typename \
          _Alloc::template rebind<_Tp>::other __name##Alloc; \
        static _Tp* __name##_allocate(size_t __n) \
          { return __name##Alloc().allocate(__n); } \
        static void __name##_deallocate(_Tp *__p, size_t __n) \
          { __name##Alloc().deallocate(__p, __n); }
      __ROPE_DEFINE_ALLOCS(_Alloc)
#undef __ROPE_DEFINE_ALLOC

	protected:
      _Rope_base&
      operator=(const _Rope_base&);
      
      _Rope_base(const _Rope_base&);
    };

  /**
   *  This is an SGI extension.
   *  @ingroup SGIextensions
   *  @doctodo
   */
  template <class _CharT, class _Alloc>
    class rope : public _Rope_base<_CharT, _Alloc>
    {
    public:
      typedef _CharT value_type;
      typedef ptrdiff_t difference_type;
      typedef size_t size_type;
      typedef _CharT const_reference;
      typedef const _CharT* const_pointer;
      typedef _Rope_iterator<_CharT, _Alloc> iterator;
      typedef _Rope_const_iterator<_CharT, _Alloc> const_iterator;
      typedef _Rope_char_ref_proxy<_CharT, _Alloc> reference;
      typedef _Rope_char_ptr_proxy<_CharT, _Alloc> pointer;

      friend class _Rope_iterator<_CharT, _Alloc>;
      friend class _Rope_const_iterator<_CharT, _Alloc>;
      friend struct _Rope_RopeRep<_CharT, _Alloc>;
      friend class _Rope_iterator_base<_CharT, _Alloc>;
      friend class _Rope_char_ptr_proxy<_CharT, _Alloc>;
      friend class _Rope_char_ref_proxy<_CharT, _Alloc>;
      friend struct _Rope_RopeSubstring<_CharT, _Alloc>;

    protected:
      typedef _Rope_base<_CharT, _Alloc> _Base;
      typedef typename _Base::allocator_type allocator_type;
      using _Base::_M_tree_ptr;
      using _Base::get_allocator;
      using _Base::_M_get_allocator;      
      typedef __GC_CONST _CharT* _Cstrptr;
      
      static _CharT _S_empty_c_str[1];
      
      static bool
      _S_is0(_CharT __c)
      { return __c == _S_eos((_CharT*)0); }
      
      enum { _S_copy_max = 23 };
                // For strings shorter than _S_copy_max, we copy to
                // concatenate.

      typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep;
      typedef _Rope_RopeConcatenation<_CharT, _Alloc> _RopeConcatenation;
      typedef _Rope_RopeLeaf<_CharT, _Alloc> _RopeLeaf;
      typedef _Rope_RopeFunction<_CharT, _Alloc> _RopeFunction;
      typedef _Rope_RopeSubstring<_CharT, _Alloc> _RopeSubstring;

      // Retrieve a character at the indicated position.
      static _CharT _S_fetch(_RopeRep* __r, size_type __pos);

#ifndef __GC
      // Obtain a pointer to the character at the indicated position.
      // The pointer can be used to change the character.
      // If such a pointer cannot be produced, as is frequently the
      // case, 0 is returned instead.
      // (Returns nonzero only if all nodes in the path have a refcount
      // of 1.)
      static _CharT* _S_fetch_ptr(_RopeRep* __r, size_type __pos);
#endif

      static bool
      _S_apply_to_pieces(// should be template parameter
			 _Rope_char_consumer<_CharT>& __c,
			 const _RopeRep* __r,
			 size_t __begin, size_t __end);
                         // begin and end are assumed to be in range.

#ifndef __GC
      static void
      _S_unref(_RopeRep* __t)
      { _RopeRep::_S_unref(__t); }

      static void
      _S_ref(_RopeRep* __t)
      { _RopeRep::_S_ref(__t); }

#else /* __GC */
      static void _S_unref(_RopeRep*) { }
      static void _S_ref(_RopeRep*) { }
#endif

#ifdef __GC
      typedef _Rope_RopeRep<_CharT, _Alloc>* _Self_destruct_ptr;
#else
      typedef _Rope_self_destruct_ptr<_CharT, _Alloc> _Self_destruct_ptr;
#endif

      // _Result is counted in refcount.
      static _RopeRep* _S_substring(_RopeRep* __base,
                                    size_t __start, size_t __endp1);

      static _RopeRep* _S_concat_char_iter(_RopeRep* __r,
					   const _CharT* __iter, size_t __slen);
      // Concatenate rope and char ptr, copying __s.
      // Should really take an arbitrary iterator.
      // Result is counted in refcount.
      static _RopeRep* _S_destr_concat_char_iter(_RopeRep* __r,
						 const _CharT* __iter,
						 size_t __slen)
	// As above, but one reference to __r is about to be
	// destroyed.  Thus the pieces may be recycled if all
	// relevant reference counts are 1.
#ifdef __GC
	// We can't really do anything since refcounts are unavailable.
      { return _S_concat_char_iter(__r, __iter, __slen); }
#else
      ;
#endif

      static _RopeRep* _S_concat(_RopeRep* __left, _RopeRep* __right);
      // General concatenation on _RopeRep.  _Result
      // has refcount of 1.  Adjusts argument refcounts.

   public:
      void
      apply_to_pieces(size_t __begin, size_t __end,
		      _Rope_char_consumer<_CharT>& __c) const
      { _S_apply_to_pieces(__c, this->_M_tree_ptr, __begin, __end); }

   protected:

      static size_t
      _S_rounded_up_size(size_t __n)
      { return _RopeLeaf::_S_rounded_up_size(__n); }

      static size_t
      _S_allocated_capacity(size_t __n)
      {
	if (_S_is_basic_char_type((_CharT*)0))
	  return _S_rounded_up_size(__n) - 1;
	else
	  return _S_rounded_up_size(__n);
	
      }

      // Allocate and construct a RopeLeaf using the supplied allocator
      // Takes ownership of s instead of copying.
      static _RopeLeaf*
      _S_new_RopeLeaf(__GC_CONST _CharT *__s,
		      size_t __size, allocator_type& __a)
      {
	_RopeLeaf* __space = typename _Base::_LAlloc(__a).allocate(1);
	return new(__space) _RopeLeaf(__s, __size, __a);
      }

      static _RopeConcatenation*
      _S_new_RopeConcatenation(_RopeRep* __left, _RopeRep* __right,
			       allocator_type& __a)
      {
	_RopeConcatenation* __space = typename _Base::_CAlloc(__a).allocate(1);
	return new(__space) _RopeConcatenation(__left, __right, __a);
      }

      static _RopeFunction*
      _S_new_RopeFunction(char_producer<_CharT>* __f,
			  size_t __size, bool __d, allocator_type& __a)
      {
	_RopeFunction* __space = typename _Base::_FAlloc(__a).allocate(1);
	return new(__space) _RopeFunction(__f, __size, __d, __a);
      }

      static _RopeSubstring*
      _S_new_RopeSubstring(_Rope_RopeRep<_CharT,_Alloc>* __b, size_t __s,
			   size_t __l, allocator_type& __a)
      {
	_RopeSubstring* __space = typename _Base::_SAlloc(__a).allocate(1);
	return new(__space) _RopeSubstring(__b, __s, __l, __a);
      }
      
      static _RopeLeaf*
      _S_RopeLeaf_from_unowned_char_ptr(const _CharT *__s,
					size_t __size, allocator_type& __a)
#define __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __size, __a) \
                _S_RopeLeaf_from_unowned_char_ptr(__s, __size, __a)
      {
	if (0 == __size)
	  return 0;
	_CharT* __buf = __a.allocate(_S_rounded_up_size(__size));
	
	__uninitialized_copy_n_a(__s, __size, __buf, __a);
	_S_cond_store_eos(__buf[__size]);
	__try
	  { return _S_new_RopeLeaf(__buf, __size, __a); }
	__catch(...)
	  {
	    _RopeRep::__STL_FREE_STRING(__buf, __size, __a);
	    __throw_exception_again;
	  }
      }

      // Concatenation of nonempty strings.
      // Always builds a concatenation node.
      // Rebalances if the result is too deep.
      // Result has refcount 1.
      // Does not increment left and right ref counts even though
      // they are referenced.
      static _RopeRep*
      _S_tree_concat(_RopeRep* __left, _RopeRep* __right);

      // Concatenation helper functions
      static _RopeLeaf*
      _S_leaf_concat_char_iter(_RopeLeaf* __r,
			       const _CharT* __iter, size_t __slen);
      // Concatenate by copying leaf.
      // should take an arbitrary iterator
      // result has refcount 1.
#ifndef __GC
      static _RopeLeaf*
      _S_destr_leaf_concat_char_iter(_RopeLeaf* __r,
				     const _CharT* __iter, size_t __slen);
      // A version that potentially clobbers __r if __r->_M_ref_count == 1.
#endif

    private:
      
      static size_t _S_char_ptr_len(const _CharT* __s);
      // slightly generalized strlen

      rope(_RopeRep* __t, const allocator_type& __a = allocator_type())
      : _Base(__t, __a) { }


      // Copy __r to the _CharT buffer.
      // Returns __buffer + __r->_M_size.
      // Assumes that buffer is uninitialized.
      static _CharT* _S_flatten(_RopeRep* __r, _CharT* __buffer);

      // Again, with explicit starting position and length.
      // Assumes that buffer is uninitialized.
      static _CharT* _S_flatten(_RopeRep* __r,
				size_t __start, size_t __len,
				_CharT* __buffer);

      static const unsigned long
      _S_min_len[__detail::_S_max_rope_depth + 1];
      
      static bool
      _S_is_balanced(_RopeRep* __r)
      { return (__r->_M_size >= _S_min_len[__r->_M_depth]); }

      static bool
      _S_is_almost_balanced(_RopeRep* __r)
      { return (__r->_M_depth == 0
		|| __r->_M_size >= _S_min_len[__r->_M_depth - 1]); }

      static bool
      _S_is_roughly_balanced(_RopeRep* __r)
      { return (__r->_M_depth <= 1
		|| __r->_M_size >= _S_min_len[__r->_M_depth - 2]); }

      // Assumes the result is not empty.
      static _RopeRep*
      _S_concat_and_set_balanced(_RopeRep* __left, _RopeRep* __right)
      {
	_RopeRep* __result = _S_concat(__left, __right);
	if (_S_is_balanced(__result))
	  __result->_M_is_balanced = true;
	return __result;
      }

      // The basic rebalancing operation.  Logically copies the
      // rope.  The result has refcount of 1.  The client will
      // usually decrement the reference count of __r.
      // The result is within height 2 of balanced by the above
      // definition.
      static _RopeRep* _S_balance(_RopeRep* __r);

      // Add all unbalanced subtrees to the forest of balanced trees.
      // Used only by balance.
      static void _S_add_to_forest(_RopeRep*__r, _RopeRep** __forest);

      // Add __r to forest, assuming __r is already balanced.
      static void _S_add_leaf_to_forest(_RopeRep* __r, _RopeRep** __forest);
      
      // Print to stdout, exposing structure
      static void _S_dump(_RopeRep* __r, int __indent = 0);
      
      // Return -1, 0, or 1 if __x < __y, __x == __y, or __x > __y resp.
      static int _S_compare(const _RopeRep* __x, const _RopeRep* __y);
      
    public:
      bool
      empty() const
      { return 0 == this->_M_tree_ptr; }
      
      // Comparison member function.  This is public only for those
      // clients that need a ternary comparison.  Others
      // should use the comparison operators below.
      int
      compare(const rope& __y) const
      { return _S_compare(this->_M_tree_ptr, __y._M_tree_ptr); }

      rope(const _CharT* __s, const allocator_type& __a = allocator_type())
      : _Base(__a)
      {
	this->_M_tree_ptr =
	  __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, _S_char_ptr_len(__s),
					   _M_get_allocator());
      }

      rope(const _CharT* __s, size_t __len,
	   const allocator_type& __a = allocator_type())
      : _Base(__a)
      {
	this->_M_tree_ptr =
	  __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __len, _M_get_allocator());
      }

      // Should perhaps be templatized with respect to the iterator type
      // and use Sequence_buffer.  (It should perhaps use sequence_buffer
      // even now.)
      rope(const _CharT* __s, const _CharT* __e,
	   const allocator_type& __a = allocator_type())
      : _Base(__a)
      {
	this->_M_tree_ptr =
	  __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __e - __s, _M_get_allocator());
      }

      rope(const const_iterator& __s, const const_iterator& __e,
	   const allocator_type& __a = allocator_type())
      : _Base(_S_substring(__s._M_root, __s._M_current_pos,
			   __e._M_current_pos), __a)
      { }

      rope(const iterator& __s, const iterator& __e,
	   const allocator_type& __a = allocator_type())
      : _Base(_S_substring(__s._M_root, __s._M_current_pos,
			   __e._M_current_pos), __a)
      { }

      rope(_CharT __c, const allocator_type& __a = allocator_type())
      : _Base(__a)
      {
	_CharT* __buf = this->_Data_allocate(_S_rounded_up_size(1));
	
	_M_get_allocator().construct(__buf, __c);
	__try
	  {
	    this->_M_tree_ptr = _S_new_RopeLeaf(__buf, 1,
						_M_get_allocator());
	  }
	__catch(...)
	  {
	    _RopeRep::__STL_FREE_STRING(__buf, 1, _M_get_allocator());
	    __throw_exception_again;
	  }
      }

      rope(size_t __n, _CharT __c,
	   const allocator_type& __a = allocator_type());

      rope(const allocator_type& __a = allocator_type())
      : _Base(0, __a) { }

      // Construct a rope from a function that can compute its members
      rope(char_producer<_CharT> *__fn, size_t __len, bool __delete_fn,
	   const allocator_type& __a = allocator_type())
      : _Base(__a)
      {
	this->_M_tree_ptr = (0 == __len) ?
	  0 : _S_new_RopeFunction(__fn, __len, __delete_fn, __a);
      }

      rope(const rope& __x, const allocator_type& __a = allocator_type())
      : _Base(__x._M_tree_ptr, __a)
      { _S_ref(this->_M_tree_ptr); }

      ~rope() throw()
      { _S_unref(this->_M_tree_ptr); }

      rope&
      operator=(const rope& __x)
      {
	_RopeRep* __old = this->_M_tree_ptr;
	this->_M_tree_ptr = __x._M_tree_ptr;
	_S_ref(this->_M_tree_ptr);
	_S_unref(__old);
	return *this;
      }

      void
      clear()
      {
	_S_unref(this->_M_tree_ptr);
	this->_M_tree_ptr = 0;
      }
      
      void
      push_back(_CharT __x)
      {
	_RopeRep* __old = this->_M_tree_ptr;
	this->_M_tree_ptr
	  = _S_destr_concat_char_iter(this->_M_tree_ptr, &__x, 1);
	_S_unref(__old);
      }

      void
      pop_back()
      {
	_RopeRep* __old = this->_M_tree_ptr;
	this->_M_tree_ptr = _S_substring(this->_M_tree_ptr,
					 0, this->_M_tree_ptr->_M_size - 1);
	_S_unref(__old);
      }

      _CharT
      back() const
      { return _S_fetch(this->_M_tree_ptr, this->_M_tree_ptr->_M_size - 1); }

      void
      push_front(_CharT __x)
      {
	_RopeRep* __old = this->_M_tree_ptr;
	_RopeRep* __left =
	  __STL_ROPE_FROM_UNOWNED_CHAR_PTR(&__x, 1, _M_get_allocator());
	__try
	  {
	    this->_M_tree_ptr = _S_concat(__left, this->_M_tree_ptr);
	    _S_unref(__old);
	    _S_unref(__left);
	  }
	__catch(...)
	  {
	    _S_unref(__left);
	    __throw_exception_again;
	  }
      }

      void
      pop_front()
      {
	_RopeRep* __old = this->_M_tree_ptr;
	this->_M_tree_ptr
	  = _S_substring(this->_M_tree_ptr, 1, this->_M_tree_ptr->_M_size);
	_S_unref(__old);
      }

      _CharT
      front() const
      { return _S_fetch(this->_M_tree_ptr, 0); }

      void
      balance()
      {
	_RopeRep* __old = this->_M_tree_ptr;
	this->_M_tree_ptr = _S_balance(this->_M_tree_ptr);
	_S_unref(__old);
      }

      void
      copy(_CharT* __buffer) const
      {
	_Destroy_const(__buffer, __buffer + size(), _M_get_allocator());
	_S_flatten(this->_M_tree_ptr, __buffer);
      }

      // This is the copy function from the standard, but
      // with the arguments reordered to make it consistent with the
      // rest of the interface.
      // Note that this guaranteed not to compile if the draft standard
      // order is assumed.
      size_type
      copy(size_type __pos, size_type __n, _CharT* __buffer) const
      {
	size_t __size = size();
	size_t __len = (__pos + __n > __size? __size - __pos : __n);

	_Destroy_const(__buffer, __buffer + __len, _M_get_allocator());
	_S_flatten(this->_M_tree_ptr, __pos, __len, __buffer);
	return __len;
      }

      // Print to stdout, exposing structure.  May be useful for
      // performance debugging.
      void
      dump()
      { _S_dump(this->_M_tree_ptr); }
      
      // Convert to 0 terminated string in new allocated memory.
      // Embedded 0s in the input do not terminate the copy.
      const _CharT* c_str() const;

      // As above, but also use the flattened representation as
      // the new rope representation.
      const _CharT* replace_with_c_str();
      
      // Reclaim memory for the c_str generated flattened string.
      // Intentionally undocumented, since it's hard to say when this
      // is safe for multiple threads.
      void
      delete_c_str ()
      {
	if (0 == this->_M_tree_ptr)
	  return;
	if (__detail::_S_leaf == this->_M_tree_ptr->_M_tag &&
	    ((_RopeLeaf*)this->_M_tree_ptr)->_M_data ==
	    this->_M_tree_ptr->_M_c_string)
	  {
	    // Representation shared
	    return;
	  }
#ifndef __GC
	this->_M_tree_ptr->_M_free_c_string();
#endif
	this->_M_tree_ptr->_M_c_string = 0;
      }

      _CharT
      operator[] (size_type __pos) const
      { return _S_fetch(this->_M_tree_ptr, __pos); }

      _CharT
      at(size_type __pos) const
      {
	// if (__pos >= size()) throw out_of_range;  // XXX
	return (*this)[__pos];
      }

      const_iterator
      begin() const
      { return(const_iterator(this->_M_tree_ptr, 0)); }

      // An easy way to get a const iterator from a non-const container.
      const_iterator
      const_begin() const
      { return(const_iterator(this->_M_tree_ptr, 0)); }

      const_iterator
      end() const
      { return(const_iterator(this->_M_tree_ptr, size())); }

      const_iterator
      const_end() const
      { return(const_iterator(this->_M_tree_ptr, size())); }

      size_type
      size() const
      {	return(0 == this->_M_tree_ptr? 0 : this->_M_tree_ptr->_M_size); }
      
      size_type
      length() const
      {	return size(); }

      size_type
      max_size() const
      {
	return _S_min_len[int(__detail::_S_max_rope_depth) - 1] - 1;
	//  Guarantees that the result can be sufficiently
	//  balanced.  Longer ropes will probably still work,
	//  but it's harder to make guarantees.
      }

      typedef std::reverse_iterator<const_iterator> const_reverse_iterator;

      const_reverse_iterator
      rbegin() const
      { return const_reverse_iterator(end()); }

      const_reverse_iterator
      const_rbegin() const
      {	return const_reverse_iterator(end()); }

      const_reverse_iterator
      rend() const
      { return const_reverse_iterator(begin()); }
      
      const_reverse_iterator
      const_rend() const
      {	return const_reverse_iterator(begin()); }

      template<class _CharT2, class _Alloc2>
        friend rope<_CharT2, _Alloc2>
        operator+(const rope<_CharT2, _Alloc2>& __left,
		  const rope<_CharT2, _Alloc2>& __right);

      template<class _CharT2, class _Alloc2>
        friend rope<_CharT2, _Alloc2>
        operator+(const rope<_CharT2, _Alloc2>& __left, const _CharT2* __right);

      template<class _CharT2, class _Alloc2>
        friend rope<_CharT2, _Alloc2>
        operator+(const rope<_CharT2, _Alloc2>& __left, _CharT2 __right);

      // The symmetric cases are intentionally omitted, since they're
      // presumed to be less common, and we don't handle them as well.

      // The following should really be templatized.  The first
      // argument should be an input iterator or forward iterator with
      // value_type _CharT.
      rope&
      append(const _CharT* __iter, size_t __n)
      {
	_RopeRep* __result =
	  _S_destr_concat_char_iter(this->_M_tree_ptr, __iter, __n);
	_S_unref(this->_M_tree_ptr);
	this->_M_tree_ptr = __result;
	return *this;
      }

      rope&
      append(const _CharT* __c_string)
      {
	size_t __len = _S_char_ptr_len(__c_string);
	append(__c_string, __len);
	return(*this);
      }

      rope&
      append(const _CharT* __s, const _CharT* __e)
      {
	_RopeRep* __result =
	  _S_destr_concat_char_iter(this->_M_tree_ptr, __s, __e - __s);
	_S_unref(this->_M_tree_ptr);
	this->_M_tree_ptr = __result;
	return *this;
      }

      rope&
      append(const_iterator __s, const_iterator __e)
      {
	_Self_destruct_ptr __appendee(_S_substring(__s._M_root,
						   __s._M_current_pos,
						   __e._M_current_pos));
	_RopeRep* __result = _S_concat(this->_M_tree_ptr, 
				       (_RopeRep*)__appendee);
	_S_unref(this->_M_tree_ptr);
	this->_M_tree_ptr = __result;
	return *this;
      }

      rope&
      append(_CharT __c)
      {
	_RopeRep* __result =
	  _S_destr_concat_char_iter(this->_M_tree_ptr, &__c, 1);
	_S_unref(this->_M_tree_ptr);
	this->_M_tree_ptr = __result;
	return *this;
      }

      rope&
      append()
      { return append(_CharT()); }  // XXX why?

      rope&
      append(const rope& __y)
      {
	_RopeRep* __result = _S_concat(this->_M_tree_ptr, __y._M_tree_ptr);
	_S_unref(this->_M_tree_ptr);
	this->_M_tree_ptr = __result;
	return *this;
      }

      rope&
      append(size_t __n, _CharT __c)
      {
	rope<_CharT,_Alloc> __last(__n, __c);
	return append(__last);
      }

      void
      swap(rope& __b)
      {
	_RopeRep* __tmp = this->_M_tree_ptr;
	this->_M_tree_ptr = __b._M_tree_ptr;
	__b._M_tree_ptr = __tmp;
      }

    protected:
      // Result is included in refcount.
      static _RopeRep*
      replace(_RopeRep* __old, size_t __pos1,
	      size_t __pos2, _RopeRep* __r)
      {
	if (0 == __old)
	  {
	    _S_ref(__r);
	    return __r;
	  }
	_Self_destruct_ptr __left(_S_substring(__old, 0, __pos1));
	_Self_destruct_ptr __right(_S_substring(__old, __pos2, __old->_M_size));
	_RopeRep* __result;

	if (0 == __r)
	  __result = _S_concat(__left, __right);
	else
	  {
	    _Self_destruct_ptr __left_result(_S_concat(__left, __r));
	    __result = _S_concat(__left_result, __right);
	  }
	return __result;
      }

    public:
      void
      insert(size_t __p, const rope& __r)
      {
	_RopeRep* __result =
	  replace(this->_M_tree_ptr, __p, __p, __r._M_tree_ptr);
	_S_unref(this->_M_tree_ptr);
	this->_M_tree_ptr = __result;
      }

      void
      insert(size_t __p, size_t __n, _CharT __c)
      {
	rope<_CharT,_Alloc> __r(__n,__c);
	insert(__p, __r);
      }
      
      void
      insert(size_t __p, const _CharT* __i, size_t __n)
      {
	_Self_destruct_ptr __left(_S_substring(this->_M_tree_ptr, 0, __p));
	_Self_destruct_ptr __right(_S_substring(this->_M_tree_ptr,
						__p, size()));
	_Self_destruct_ptr __left_result(_S_concat_char_iter(__left, __i, __n));
	// _S_ destr_concat_char_iter should be safe here.
	// But as it stands it's probably not a win, since __left
	// is likely to have additional references.
	_RopeRep* __result = _S_concat(__left_result, __right);
	_S_unref(this->_M_tree_ptr);
	this->_M_tree_ptr = __result;
      }

      void
      insert(size_t __p, const _CharT* __c_string)
      {	insert(__p, __c_string, _S_char_ptr_len(__c_string)); }

      void
      insert(size_t __p, _CharT __c)
      { insert(__p, &__c, 1); }

      void
      insert(size_t __p)
      {
	_CharT __c = _CharT();
	insert(__p, &__c, 1);
      }

      void
      insert(size_t __p, const _CharT* __i, const _CharT* __j)
      {
	rope __r(__i, __j);
	insert(__p, __r);
      }

      void
      insert(size_t __p, const const_iterator& __i,
	     const const_iterator& __j)
      {
	rope __r(__i, __j);
	insert(__p, __r);
      }

      void
      insert(size_t __p, const iterator& __i,
	     const iterator& __j)
      {
	rope __r(__i, __j);
	insert(__p, __r);
      }

      // (position, length) versions of replace operations:
      
      void
      replace(size_t __p, size_t __n, const rope& __r)
      {
	_RopeRep* __result =
	  replace(this->_M_tree_ptr, __p, __p + __n, __r._M_tree_ptr);
	_S_unref(this->_M_tree_ptr);
	this->_M_tree_ptr = __result;
      }

      void
      replace(size_t __p, size_t __n,
	      const _CharT* __i, size_t __i_len)
      {
	rope __r(__i, __i_len);
	replace(__p, __n, __r);
      }

      void
      replace(size_t __p, size_t __n, _CharT __c)
      {
	rope __r(__c);
	replace(__p, __n, __r);
      }

      void
      replace(size_t __p, size_t __n, const _CharT* __c_string)
      {
	rope __r(__c_string);
	replace(__p, __n, __r);
      }
      
      void
      replace(size_t __p, size_t __n,
	      const _CharT* __i, const _CharT* __j)
      {
	rope __r(__i, __j);
	replace(__p, __n, __r);
      }
      
      void
      replace(size_t __p, size_t __n,
	      const const_iterator& __i, const const_iterator& __j)
      {
	rope __r(__i, __j);
	replace(__p, __n, __r);
      }

      void
      replace(size_t __p, size_t __n,
	      const iterator& __i, const iterator& __j)
      {
	rope __r(__i, __j);
	replace(__p, __n, __r);
      }

      // Single character variants:
      void
      replace(size_t __p, _CharT __c)
      {
	iterator __i(this, __p);
	*__i = __c;
      }

      void
      replace(size_t __p, const rope& __r)
      { replace(__p, 1, __r); }

      void
      replace(size_t __p, const _CharT* __i, size_t __i_len)
      { replace(__p, 1, __i, __i_len); }

      void
      replace(size_t __p, const _CharT* __c_string)
      {	replace(__p, 1, __c_string); }

      void
      replace(size_t __p, const _CharT* __i, const _CharT* __j)
      {	replace(__p, 1, __i, __j); }

      void
      replace(size_t __p, const const_iterator& __i,
	      const const_iterator& __j)
      { replace(__p, 1, __i, __j); }

      void
      replace(size_t __p, const iterator& __i,
	      const iterator& __j)
      { replace(__p, 1, __i, __j); }

      // Erase, (position, size) variant.
      void
      erase(size_t __p, size_t __n)
      {
	_RopeRep* __result = replace(this->_M_tree_ptr, __p,
				     __p + __n, 0);
	_S_unref(this->_M_tree_ptr);
	this->_M_tree_ptr = __result;
      }

      // Erase, single character
      void
      erase(size_t __p)
      { erase(__p, __p + 1); }

      // Insert, iterator variants.
      iterator
      insert(const iterator& __p, const rope& __r)
      {
	insert(__p.index(), __r);
	return __p;
      }

      iterator
      insert(const iterator& __p, size_t __n, _CharT __c)
      {
	insert(__p.index(), __n, __c);
	return __p;
      }

      iterator insert(const iterator& __p, _CharT __c)
      {
	insert(__p.index(), __c);
	return __p;
      }
      
      iterator
      insert(const iterator& __p )
      {
	insert(__p.index());
	return __p;
      }
      
      iterator
      insert(const iterator& __p, const _CharT* c_string)
      {
	insert(__p.index(), c_string);
	return __p;
      }
      
      iterator
      insert(const iterator& __p, const _CharT* __i, size_t __n)
      {
	insert(__p.index(), __i, __n);
	return __p;
      }
      
      iterator
      insert(const iterator& __p, const _CharT* __i,
	     const _CharT* __j)
      {
	insert(__p.index(), __i, __j); 
	return __p;
      }
      
      iterator
      insert(const iterator& __p,
	     const const_iterator& __i, const const_iterator& __j)
      {
	insert(__p.index(), __i, __j);
	return __p;
      }
      
      iterator
      insert(const iterator& __p,
	     const iterator& __i, const iterator& __j)
      {
	insert(__p.index(), __i, __j);
	return __p;
      }

      // Replace, range variants.
      void
      replace(const iterator& __p, const iterator& __q, const rope& __r)
      {	replace(__p.index(), __q.index() - __p.index(), __r); }

      void
      replace(const iterator& __p, const iterator& __q, _CharT __c)
      { replace(__p.index(), __q.index() - __p.index(), __c); }
      
      void
      replace(const iterator& __p, const iterator& __q,
	      const _CharT* __c_string)
      { replace(__p.index(), __q.index() - __p.index(), __c_string); }
      
      void
      replace(const iterator& __p, const iterator& __q,
	      const _CharT* __i, size_t __n)
      { replace(__p.index(), __q.index() - __p.index(), __i, __n); }
      
      void
      replace(const iterator& __p, const iterator& __q,
	      const _CharT* __i, const _CharT* __j)
      { replace(__p.index(), __q.index() - __p.index(), __i, __j); }
      
      void
      replace(const iterator& __p, const iterator& __q,
	      const const_iterator& __i, const const_iterator& __j)
      { replace(__p.index(), __q.index() - __p.index(), __i, __j); }
      
      void
      replace(const iterator& __p, const iterator& __q,
	      const iterator& __i, const iterator& __j)
      { replace(__p.index(), __q.index() - __p.index(), __i, __j); }

      // Replace, iterator variants.
      void
      replace(const iterator& __p, const rope& __r)
      { replace(__p.index(), __r); }
      
      void
      replace(const iterator& __p, _CharT __c)
      { replace(__p.index(), __c); }
      
      void
      replace(const iterator& __p, const _CharT* __c_string)
      { replace(__p.index(), __c_string); }
      
      void
      replace(const iterator& __p, const _CharT* __i, size_t __n)
      { replace(__p.index(), __i, __n); }
      
      void
      replace(const iterator& __p, const _CharT* __i, const _CharT* __j)
      { replace(__p.index(), __i, __j); }
      
      void
      replace(const iterator& __p, const_iterator __i, const_iterator __j)
      { replace(__p.index(), __i, __j); }
      
      void
      replace(const iterator& __p, iterator __i, iterator __j)
      { replace(__p.index(), __i, __j); }

      // Iterator and range variants of erase
      iterator
      erase(const iterator& __p, const iterator& __q)
      {
	size_t __p_index = __p.index();
	erase(__p_index, __q.index() - __p_index);
	return iterator(this, __p_index);
      }

      iterator
      erase(const iterator& __p)
      {
	size_t __p_index = __p.index();
	erase(__p_index, 1);
	return iterator(this, __p_index);
      }

      rope
      substr(size_t __start, size_t __len = 1) const
      {
	return rope<_CharT, _Alloc>(_S_substring(this->_M_tree_ptr,
						 __start,
						 __start + __len));
      }

      rope
      substr(iterator __start, iterator __end) const
      {
	return rope<_CharT, _Alloc>(_S_substring(this->_M_tree_ptr,
						 __start.index(),
						 __end.index()));
      }

      rope
      substr(iterator __start) const
      {
	size_t __pos = __start.index();
	return rope<_CharT, _Alloc>(_S_substring(this->_M_tree_ptr,
						 __pos, __pos + 1));
      }

      rope
      substr(const_iterator __start, const_iterator __end) const
      {
	// This might eventually take advantage of the cache in the
	// iterator.
	return rope<_CharT, _Alloc>(_S_substring(this->_M_tree_ptr,
						 __start.index(),
						 __end.index()));
      }

      rope<_CharT, _Alloc>
      substr(const_iterator __start)
      {
	size_t __pos = __start.index();
	return rope<_CharT, _Alloc>(_S_substring(this->_M_tree_ptr,
						 __pos, __pos + 1));
      }

      static const size_type npos;

      size_type find(_CharT __c, size_type __pos = 0) const;

      size_type
      find(const _CharT* __s, size_type __pos = 0) const
      {
	size_type __result_pos;
	const_iterator __result =
	  std::search(const_begin() + __pos, const_end(),
		      __s, __s + _S_char_ptr_len(__s));
	__result_pos = __result.index();
#ifndef __STL_OLD_ROPE_SEMANTICS
	if (__result_pos == size())
	  __result_pos = npos;
#endif
	return __result_pos;
      }

      iterator
      mutable_begin()
      { return(iterator(this, 0)); }
      
      iterator
      mutable_end()
      { return(iterator(this, size())); }

      typedef std::reverse_iterator<iterator> reverse_iterator;
      
      reverse_iterator
      mutable_rbegin()
      { return reverse_iterator(mutable_end()); }

      reverse_iterator
      mutable_rend()
      { return reverse_iterator(mutable_begin()); }

      reference
      mutable_reference_at(size_type __pos)
      { return reference(this, __pos); }

#ifdef __STD_STUFF
      reference
      operator[] (size_type __pos)
      { return _char_ref_proxy(this, __pos); }

      reference
      at(size_type __pos)
      {
	// if (__pos >= size()) throw out_of_range;  // XXX
	return (*this)[__pos];
      }
      
      void resize(size_type __n, _CharT __c) { }
      void resize(size_type __n) { }
      void reserve(size_type __res_arg = 0) { }
      
      size_type
      capacity() const
      { return max_size(); }

      // Stuff below this line is dangerous because it's error prone.
      // I would really like to get rid of it.
      // copy function with funny arg ordering.
      size_type
      copy(_CharT* __buffer, size_type __n,
	   size_type __pos = 0) const
      { return copy(__pos, __n, __buffer); }

      iterator
      end()
      { return mutable_end(); }

      iterator
      begin()
      { return mutable_begin(); }

      reverse_iterator
      rend()
      { return mutable_rend(); }
      
      reverse_iterator
      rbegin()
      { return mutable_rbegin(); }

#else
      const_iterator
      end()
      { return const_end(); }

      const_iterator
      begin()
      { return const_begin(); }

      const_reverse_iterator
      rend()
      { return const_rend(); }

      const_reverse_iterator
      rbegin()
      { return const_rbegin(); }

#endif
    };

  template <class _CharT, class _Alloc>
    const typename rope<_CharT, _Alloc>::size_type
    rope<_CharT, _Alloc>::npos = (size_type)(-1);
  
  template <class _CharT, class _Alloc>
    inline bool operator==(const _Rope_const_iterator<_CharT, _Alloc>& __x,
			   const _Rope_const_iterator<_CharT, _Alloc>& __y)
    { return (__x._M_current_pos == __y._M_current_pos
	      && __x._M_root == __y._M_root); }

  template <class _CharT, class _Alloc>
    inline bool operator<(const _Rope_const_iterator<_CharT, _Alloc>& __x,
			  const _Rope_const_iterator<_CharT, _Alloc>& __y)
    { return (__x._M_current_pos < __y._M_current_pos); }

  template <class _CharT, class _Alloc>
    inline bool operator!=(const _Rope_const_iterator<_CharT, _Alloc>& __x,
			   const _Rope_const_iterator<_CharT, _Alloc>& __y)
    { return !(__x == __y); }

  template <class _CharT, class _Alloc>
    inline bool operator>(const _Rope_const_iterator<_CharT, _Alloc>& __x,
			  const _Rope_const_iterator<_CharT, _Alloc>& __y)
    { return __y < __x; }

  template <class _CharT, class _Alloc>
    inline bool
    operator<=(const _Rope_const_iterator<_CharT, _Alloc>& __x,
	       const _Rope_const_iterator<_CharT, _Alloc>& __y)
    { return !(__y < __x); }

  template <class _CharT, class _Alloc>
    inline bool
    operator>=(const _Rope_const_iterator<_CharT, _Alloc>& __x,
	       const _Rope_const_iterator<_CharT, _Alloc>& __y)
    { return !(__x < __y); }

  template <class _CharT, class _Alloc>
    inline ptrdiff_t
    operator-(const _Rope_const_iterator<_CharT, _Alloc>& __x,
	      const _Rope_const_iterator<_CharT, _Alloc>& __y)
    { return (ptrdiff_t)__x._M_current_pos - (ptrdiff_t)__y._M_current_pos; }

  template <class _CharT, class _Alloc>
    inline _Rope_const_iterator<_CharT, _Alloc>
    operator-(const _Rope_const_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n)
    { return _Rope_const_iterator<_CharT, _Alloc>(__x._M_root,
						  __x._M_current_pos - __n); }

  template <class _CharT, class _Alloc>
    inline _Rope_const_iterator<_CharT, _Alloc>
    operator+(const _Rope_const_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n)
    { return _Rope_const_iterator<_CharT, _Alloc>(__x._M_root,
						  __x._M_current_pos + __n); }

  template <class _CharT, class _Alloc>
    inline _Rope_const_iterator<_CharT, _Alloc>
    operator+(ptrdiff_t __n, const _Rope_const_iterator<_CharT, _Alloc>& __x)
  { return _Rope_const_iterator<_CharT, _Alloc>(__x._M_root,
						__x._M_current_pos + __n); }

  template <class _CharT, class _Alloc>
    inline bool
    operator==(const _Rope_iterator<_CharT, _Alloc>& __x,
	       const _Rope_iterator<_CharT, _Alloc>& __y)
    {return (__x._M_current_pos == __y._M_current_pos
	     && __x._M_root_rope == __y._M_root_rope); }
  
  template <class _CharT, class _Alloc>
    inline bool
    operator<(const _Rope_iterator<_CharT, _Alloc>& __x,
	      const _Rope_iterator<_CharT, _Alloc>& __y)
    { return (__x._M_current_pos < __y._M_current_pos); }

  template <class _CharT, class _Alloc>
    inline bool
    operator!=(const _Rope_iterator<_CharT, _Alloc>& __x,
	       const _Rope_iterator<_CharT, _Alloc>& __y)
    { return !(__x == __y); }

  template <class _CharT, class _Alloc>
    inline bool
    operator>(const _Rope_iterator<_CharT, _Alloc>& __x,
	      const _Rope_iterator<_CharT, _Alloc>& __y)
    { return __y < __x; }

  template <class _CharT, class _Alloc>
    inline bool
    operator<=(const _Rope_iterator<_CharT, _Alloc>& __x,
	       const _Rope_iterator<_CharT, _Alloc>& __y)
    { return !(__y < __x); }

  template <class _CharT, class _Alloc>
    inline bool
    operator>=(const _Rope_iterator<_CharT, _Alloc>& __x,
	       const _Rope_iterator<_CharT, _Alloc>& __y)
    { return !(__x < __y); }

  template <class _CharT, class _Alloc>
    inline ptrdiff_t
    operator-(const _Rope_iterator<_CharT, _Alloc>& __x,
	      const _Rope_iterator<_CharT, _Alloc>& __y)
    { return ((ptrdiff_t)__x._M_current_pos
	      - (ptrdiff_t)__y._M_current_pos); }

  template <class _CharT, class _Alloc>
    inline _Rope_iterator<_CharT, _Alloc>
    operator-(const _Rope_iterator<_CharT, _Alloc>& __x,
	      ptrdiff_t __n)
    { return _Rope_iterator<_CharT, _Alloc>(__x._M_root_rope,
					    __x._M_current_pos - __n); }

  template <class _CharT, class _Alloc>
    inline _Rope_iterator<_CharT, _Alloc>
    operator+(const _Rope_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n)
    { return _Rope_iterator<_CharT, _Alloc>(__x._M_root_rope,
					    __x._M_current_pos + __n); }

  template <class _CharT, class _Alloc>
    inline _Rope_iterator<_CharT, _Alloc>
    operator+(ptrdiff_t __n, const _Rope_iterator<_CharT, _Alloc>& __x)
    { return _Rope_iterator<_CharT, _Alloc>(__x._M_root_rope,
					    __x._M_current_pos + __n); }

  template <class _CharT, class _Alloc>
    inline rope<_CharT, _Alloc>
    operator+(const rope<_CharT, _Alloc>& __left,
	      const rope<_CharT, _Alloc>& __right)
    {
      // Inlining this should make it possible to keep __left and
      // __right in registers.
      typedef rope<_CharT, _Alloc> rope_type;
      return rope_type(rope_type::_S_concat(__left._M_tree_ptr, 
					    __right._M_tree_ptr));
    }

  template <class _CharT, class _Alloc>
    inline rope<_CharT, _Alloc>&
    operator+=(rope<_CharT, _Alloc>& __left,
	       const rope<_CharT, _Alloc>& __right)
    {
      __left.append(__right);
      return __left;
    }

  template <class _CharT, class _Alloc>
    inline rope<_CharT, _Alloc>
    operator+(const rope<_CharT, _Alloc>& __left,
	      const _CharT* __right)
    {
      typedef rope<_CharT, _Alloc> rope_type;
      size_t __rlen = rope_type::_S_char_ptr_len(__right);
      return rope_type(rope_type::_S_concat_char_iter(__left._M_tree_ptr,
						      __right, __rlen));
    }

  template <class _CharT, class _Alloc>
    inline rope<_CharT, _Alloc>&
    operator+=(rope<_CharT, _Alloc>& __left,
	       const _CharT* __right)
    {
      __left.append(__right);
      return __left;
    }

  template <class _CharT, class _Alloc>
    inline rope<_CharT, _Alloc>
    operator+(const rope<_CharT, _Alloc>& __left, _CharT __right)
    {
      typedef rope<_CharT, _Alloc> rope_type;
      return rope_type(rope_type::_S_concat_char_iter(__left._M_tree_ptr,
						      &__right, 1));
    }

  template <class _CharT, class _Alloc>
    inline rope<_CharT, _Alloc>&
    operator+=(rope<_CharT, _Alloc>& __left, _CharT __right)
    {
      __left.append(__right);
      return __left;
    }
  
  template <class _CharT, class _Alloc>
    bool
    operator<(const rope<_CharT, _Alloc>& __left,
	      const rope<_CharT, _Alloc>& __right)
    { return __left.compare(__right) < 0; }

  template <class _CharT, class _Alloc>
    bool
    operator==(const rope<_CharT, _Alloc>& __left,
	       const rope<_CharT, _Alloc>& __right)
    { return __left.compare(__right) == 0; }

  template <class _CharT, class _Alloc>
    inline bool
    operator==(const _Rope_char_ptr_proxy<_CharT, _Alloc>& __x,
	       const _Rope_char_ptr_proxy<_CharT, _Alloc>& __y)
    { return (__x._M_pos == __y._M_pos && __x._M_root == __y._M_root); }

  template <class _CharT, class _Alloc>
    inline bool
    operator!=(const rope<_CharT, _Alloc>& __x,
	       const rope<_CharT, _Alloc>& __y)
    { return !(__x == __y); }

  template <class _CharT, class _Alloc>
    inline bool
    operator>(const rope<_CharT, _Alloc>& __x,
	      const rope<_CharT, _Alloc>& __y)
    { return __y < __x; }

  template <class _CharT, class _Alloc>
    inline bool
    operator<=(const rope<_CharT, _Alloc>& __x,
	       const rope<_CharT, _Alloc>& __y)
    { return !(__y < __x); }

  template <class _CharT, class _Alloc>
    inline bool
    operator>=(const rope<_CharT, _Alloc>& __x,
	       const rope<_CharT, _Alloc>& __y)
    { return !(__x < __y); }

  template <class _CharT, class _Alloc>
    inline bool
    operator!=(const _Rope_char_ptr_proxy<_CharT, _Alloc>& __x,
	       const _Rope_char_ptr_proxy<_CharT, _Alloc>& __y)
    { return !(__x == __y); }

  template<class _CharT, class _Traits, class _Alloc>
    std::basic_ostream<_CharT, _Traits>&
    operator<<(std::basic_ostream<_CharT, _Traits>& __o,
	       const rope<_CharT, _Alloc>& __r);

  typedef rope<char> crope;
  typedef rope<wchar_t> wrope;

  inline crope::reference
  __mutable_reference_at(crope& __c, size_t __i)
  { return __c.mutable_reference_at(__i); }

  inline wrope::reference
  __mutable_reference_at(wrope& __c, size_t __i)
  { return __c.mutable_reference_at(__i); }

  template <class _CharT, class _Alloc>
    inline void
    swap(rope<_CharT, _Alloc>& __x, rope<_CharT, _Alloc>& __y)
    { __x.swap(__y); }

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace


namespace std _GLIBCXX_VISIBILITY(default)
{ 
namespace tr1
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  template<>
    struct hash<__gnu_cxx::crope>
    {
      size_t
      operator()(const __gnu_cxx::crope& __str) const
      {
	size_t __size = __str.size();
	if (0 == __size)
	  return 0;
	return 13 * __str[0] + 5 * __str[__size - 1] + __size;
      }
    };


  template<>
    struct hash<__gnu_cxx::wrope>
    {
      size_t
      operator()(const __gnu_cxx::wrope& __str) const
      {
	size_t __size = __str.size();
	if (0 == __size)
	  return 0;
	return 13 * __str[0] + 5 * __str[__size - 1] + __size;
      }
    };

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace tr1
} // namespace std

# include <ext/ropeimpl.h>

#endif
