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

// Copyright (C) 2001-2023 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

#pragma GCC system_header

#include <bits/requires_hosted.h> // GNU extensions are currently omitted

#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 <ext/alloc_traits.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)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  namespace __detail
  {
    enum { _S_max_rope_depth = 45 };
    enum _Tag {_S_leaf, _S_concat, _S_substringfn, _S_function};
  } // namespace __detail

  // 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, std::allocator<_Tp>)
    { std::_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()(std::size_t __start_pos, std::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.

// Ignore warnings about std::iterator.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

  template<class _Sequence, std::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];
      std::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);
      }
      
      // Non-const "copy" modifies the parameter - yuck
      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) { }
      
      // Non-const "copy" modifies the parameter - yuck
      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;
      }

#if __cplusplus >= 201103L
      sequence_buffer(sequence_buffer&& __x) : sequence_buffer(__x) { }
      sequence_buffer& operator=(sequence_buffer&& __x) { return *this = __x; }
#endif

      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, std::size_t __len)
      {
	if (__len + _M_buf_count <= _Buf_sz)
	  {
	    std::size_t __i = _M_buf_count;
	    for (std::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, std::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; }
    };
#pragma GCC diagnostic pop
  
  // 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, std::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 = std::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,
	      std::ptrdiff_t __n);

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

  template<class _CharT, class _Alloc>
    _Rope_const_iterator<_CharT, _Alloc>
    operator+(std::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>
    std::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, std::ptrdiff_t __n);

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

  template<class _CharT, class _Alloc>
    _Rope_iterator<_CharT, _Alloc>
    operator+(std::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>
    std::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.

// Ignore warnings about std::binary_function.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
  // 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; }
    };
#pragma GCC diagnostic pop

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

  // 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 std::size_t _RC_t;
    
    // The data member _M_ref_count
    _RC_t _M_ref_count;

    // Constructor
#ifdef __GTHREAD_MUTEX_INIT
    __gthread_mutex_t _M_ref_count_lock = __GTHREAD_MUTEX_INIT;
#else
    __gthread_mutex_t _M_ref_count_lock;
#endif

    _Refcount_Base(_RC_t __n) : _M_ref_count(__n)
    {
#ifndef __GTHREAD_MUTEX_INIT
#ifdef __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
#endif
    }

#ifndef __GTHREAD_MUTEX_INIT
    ~_Refcount_Base()
    { __gthread_mutex_destroy(&_M_ref_count_lock); }
#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);
      _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 std::size_t size_type;
      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_type __size, const allocator_type&)
      : _M_size(__size) { }

      size_type _M_size;

# define __ROPE_DEFINE_ALLOC(_Tp, __name) \
        typedef typename \
          __alloc_traits<_Alloc>::template rebind<_Tp>::other __name##Alloc; \
        static _Tp* __name##_allocate(size_type __n) \
          { return __name##Alloc().allocate(__n); } \
        static void __name##_deallocate(_Tp *__p, size_type __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;
#ifdef __GTHREAD_MUTEX_INIT
      __gthread_mutex_t _M_c_string_lock = __GTHREAD_MUTEX_INIT;
#else
      __gthread_mutex_t _M_c_string_lock;
#endif
                        /* 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;
      typedef std::size_t size_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_type __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
      { }
#else
      { __GTHREAD_MUTEX_INIT_FUNCTION (&_M_c_string_lock); }
      ~_Rope_RopeRep()
      { __gthread_mutex_destroy (&_M_c_string_lock); }
#endif
#ifdef __GC
      void
      _M_incr () { }
#endif
      static void
      _S_free_string(__GC_CONST _CharT*, size_type __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>
    {
      typedef std::size_t size_type;
    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_type
      _S_rounded_up_size(size_type __n)
      {
        size_type __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_type(_S_alloc_granularity) - 1)
		&~ (size_type(_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_type __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();
	
	this->__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, std::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>
    {
      typedef std::size_t size_type;
    public:
      // XXX this whole class should be rewritten.
      _Rope_RopeRep<_CharT,_Alloc>* _M_base;      // not 0
      size_type _M_start;

      virtual void
      operator()(size_type __start_pos, size_type __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_type __s,
                          size_type __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); }
#if __cpp_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;
      std::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, std::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, std::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>;
      std::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.
  
// Ignore warnings about std::iterator
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
  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 };
      std::size_t _M_current_pos;
      _RopeRep* _M_root;     // The whole rope.
      std::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, std::size_t __pos)
      : _M_current_pos(__pos), _M_root(__root), _M_buf_ptr(0) { }

      void _M_incr(std::size_t __n);
      void _M_decr(std::size_t __n);
    public:
      std::size_t
      index() const
      { return _M_current_pos; }
    
      _Rope_iterator_base(const _Rope_iterator_base& __x)
      {
        if (0 != __x._M_buf_ptr && __x._M_buf_start != __x._M_tmp_buf)
	  *this = __x;
	else
	  {
            _M_current_pos = __x._M_current_pos;
            _M_root = __x._M_root;
            _M_buf_ptr = 0;
	  }
      }
    };
#pragma GCC diagnostic pop

  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, std::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, std::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 && __x._M_buf_start != __x._M_tmp_buf)
	  *(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)
	  this->_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+=(std::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-=(std::ptrdiff_t __n)
      {
        if (__n >= 0)
	  this->_M_decr(__n);
	else
	  this->_M_incr(-__n);
	return *this;
      }

      _Rope_const_iterator
      operator++(int)
      {
	std::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)
      {
	std::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,
		  std::ptrdiff_t __n);

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

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

      reference
      operator[](std::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 std::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, std::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()))
	  this->_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, std::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 && __x._M_buf_start != __x._M_tmp_buf)
	  {
            _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+=(std::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-=(std::ptrdiff_t __n)
      {
        if (__n >= 0)
	  this->_M_decr(__n);
	else
	  this->_M_incr(-__n);
	return *this;
      }

      _Rope_iterator
      operator++(int)
      {
	std::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)
      {
	std::size_t __old_pos = this->_M_current_pos;
        this->_M_decr(1);
        return _Rope_iterator<_CharT,_Alloc>(_M_root_rope, __old_pos);
      }

      reference
      operator[](std::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 std::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,
		  std::ptrdiff_t __n);

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

      template<class _CharT2, class _Alloc2>
        friend _Rope_iterator<_CharT2, _Alloc2>
        operator+(std::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_traits<_Alloc>::template rebind<_Tp>::other __name##Alloc; \
        static _Tp* __name##_allocate(std::size_t __n) \
          { return __name##Alloc().allocate(__n); } \
        static void __name##_deallocate(_Tp *__p, std::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 std::ptrdiff_t difference_type;
      typedef std::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_type __begin, size_type __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_type __start, size_type __endp1);

      static _RopeRep* _S_concat_char_iter(_RopeRep* __r,
					   const _CharT* __iter,
					   size_type __slen,
					   allocator_type& __a);
      // Concatenate rope and char ptr, copying __iter.
      // Should really take an arbitrary iterator.
      // Result is counted in refcount.
      static _RopeRep* _S_destr_concat_char_iter(_RopeRep* __r,
						 const _CharT* __iter,
						 size_type __slen,
						 allocator_type& __a)
	// 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, __a); }
#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_type __begin, size_type __end,
		      _Rope_char_consumer<_CharT>& __c) const
      { _S_apply_to_pieces(__c, this->_M_tree_ptr, __begin, __end); }

   protected:

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

      static size_type
      _S_allocated_capacity(size_type __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_type __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_type __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_type __s,
			   size_type __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_type __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_type __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_type __slen);
      // A version that potentially clobbers __r if __r->_M_ref_count == 1.
#endif

    private:
      
      static size_type _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_type __start, size_type __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:
      _GLIBCXX_NODISCARD 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_type __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));
	
	__alloc_traits<allocator_type>::construct(_M_get_allocator(),
						  __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_type __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_type __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, _M_get_allocator());
      }

      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)
      {
	allocator_type __a = _M_get_allocator();
	_RopeRep* __old = this->_M_tree_ptr;
	this->_M_tree_ptr
	  = _S_destr_concat_char_iter(this->_M_tree_ptr, &__x, 1, __a);
	_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_type __size = size();
	size_type __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_type __n)
      {
	allocator_type __a = _M_get_allocator();
	_RopeRep* __result =
	  _S_destr_concat_char_iter(this->_M_tree_ptr, __iter, __n, __a);
	_S_unref(this->_M_tree_ptr);
	this->_M_tree_ptr = __result;
	return *this;
      }

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

      rope&
      append(const _CharT* __s, const _CharT* __e)
      {
	allocator_type __a = _M_get_allocator();
	_RopeRep* __result =
	  _S_destr_concat_char_iter(this->_M_tree_ptr, __s, __e - __s, __a);
	_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)
      {
	allocator_type __a = _M_get_allocator();
	_RopeRep* __result =
	  _S_destr_concat_char_iter(this->_M_tree_ptr, &__c, 1, __a);
	_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_type __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_type __pos1,
	      size_type __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_type __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_type __p, size_type __n, _CharT __c)
      {
	rope<_CharT,_Alloc> __r(__n,__c);
	insert(__p, __r);
      }
      
      void
      insert(size_type __p, const _CharT* __i, size_type __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,
							     _M_get_allocator()));
	// _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_type __p, const _CharT* __c_string)
      {	insert(__p, __c_string, _S_char_ptr_len(__c_string)); }

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

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

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

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

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

      // (position, length) versions of replace operations:
      
      void
      replace(size_type __p, size_type __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_type __p, size_type __n,
	      const _CharT* __i, size_type __i_len)
      {
	rope __r(__i, __i_len);
	replace(__p, __n, __r);
      }

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

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

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

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

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

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

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

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

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

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

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

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

      iterator
      insert(const iterator& __p, size_type __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_type __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_type __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_type __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_type __p_index = __p.index();
	erase(__p_index, __q.index() - __p_index);
	return iterator(this, __p_index);
      }

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

      rope
      substr(size_type __start, size_type __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_type __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_type __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 std::ptrdiff_t
    operator-(const _Rope_const_iterator<_CharT, _Alloc>& __x,
	      const _Rope_const_iterator<_CharT, _Alloc>& __y)
    {
      return (std::ptrdiff_t)__x._M_current_pos
	- (std::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,
	      std::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,
	      std::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+(std::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 std::ptrdiff_t
    operator-(const _Rope_iterator<_CharT, _Alloc>& __x,
	      const _Rope_iterator<_CharT, _Alloc>& __y)
    { return ((std::ptrdiff_t)__x._M_current_pos
	      - (std::ptrdiff_t)__y._M_current_pos); }

  template <class _CharT, class _Alloc>
    inline _Rope_iterator<_CharT, _Alloc>
    operator-(const _Rope_iterator<_CharT, _Alloc>& __x,
	      std::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, std::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+(std::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;
      std::size_t __rlen = rope_type::_S_char_ptr_len(__right);
      _Alloc __a = __left.get_allocator();
      return rope_type(rope_type::_S_concat_char_iter(__left._M_tree_ptr,
						      __right, __rlen, __a));
    }

  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;
      _Alloc __a = __left.get_allocator();
      return rope_type(rope_type::_S_concat_char_iter(__left._M_tree_ptr,
						      &__right, 1, __a));
    }

  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, std::size_t __i)
  { return __c.mutable_reference_at(__i); }

  inline wrope::reference
  __mutable_reference_at(wrope& __c, std::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)
{ 
_GLIBCXX_BEGIN_NAMESPACE_VERSION

namespace tr1
{
  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;
      }
    };
} // namespace tr1

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std

# include <ext/ropeimpl.h>

#endif
