class _Alloc>
    void
    _Rope_iterator<_CharT, _Alloc>::
    _M_check()
    {
      if (_M_root_rope->_M_tree_ptr != this->_M_root)
	{
	  // _Rope was modified.  Get things fixed up.
	  _RopeRep::_S_unref(this->_M_root);
	  this->_M_root = _M_root_rope->_M_tree_ptr;
	  _RopeRep::_S_ref(this->_M_root);
	  this->_M_buf_ptr = 0;
	}
    }

  template <class _CharT, class _Alloc>
    inline
    _Rope_const_iterator<_CharT, _Alloc>::
    _Rope_const_iterator(const _Rope_iterator<_CharT, _Alloc>& __x)
    : _Rope_iterator_base<_CharT, _Alloc>(__x)
    { }

  template <class _CharT, class _Alloc>
    inline
    _Rope_iterator<_CharT, _Alloc>::
    _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); }

  template <class _CharT, class _Alloc>
    inline size_t
    rope<_CharT, _Alloc>::
    _S_char_ptr_len(const _CharT* __s)
    {
      const _CharT* __p = __s;
      
      while (!_S_is0(*__p))
	++__p;
      return (__p - __s);
    }


#ifndef __GC

  template <class _CharT, class _Alloc>
    inline void
    _Rope_RopeRep<_CharT, _Alloc>::
    _M_free_c_string()
    {
      _CharT* __cstr = _M_c_string;
      if (0 != __cstr)
	{
	  size_t __size = this->_M_size + 1;
	  _Destroy(__cstr, __cstr + __size, _M_get_allocator());
	  this->_Data_deallocate(__cstr, __size);
	}
    }

  template <class _CharT, class _Alloc>
    inline void
    _Rope_RopeRep<_CharT, _Alloc>::
    _S_free_string(_CharT* __s, size_t __n, allocator_type& __a)
    {
      if (!_S_is_basic_char_type((_CharT*)0))
	_Destroy(__s, __s + __n, __a);
      
      //  This has to be a static member, so this gets a bit messy
      __a.deallocate(__s,
		     _Rope_RopeLeaf<_CharT, _Alloc>::_S_rounded_up_size(__n));
    }

  //  There are several reasons for not doing this with virtual destructors
  //  and a class specific delete operator:
  //  - A class specific delete operator can't easily get access to
  //    allocator insta