_old_c_string);
      size_t __s = size();
      _CharT* __result = this->_Data_allocate(_S_rounded_up_size(__s));
      _S_flatten(this->_M_tree_ptr, __result);
      __result[__s] = _S_eos((_CharT*)0);
      this->_M_tree_ptr->_M_unref_nonnil();
      this->_M_tree_ptr = _S_new_RopeLeaf(__result, __s,
					  this->_M_get_allocator());
      return(__result);
    }

  // Algorithm specializations.  More should be added.
  
  template<class _Rope_iterator>  // was templated on CharT and Alloc
    void		          // VC++ workaround
    _Rope_rotate(_Rope_iterator __first,
		 _Rope_iterator __middle,
		 _Rope_iterator __last)
    {
      typedef typename _Rope_iterator::value_type _CharT;
      typedef typename _Rope_iterator::_allocator_type _Alloc;
      
      rope<_CharT, _Alloc>& __r(__first.container());
      rope<_CharT, _Alloc> __prefix = __r.substr(0, __first.index());
      rope<_CharT, _Alloc> __suffix =
	__r.substr(__last.index(), __r.size() - __last.index());
      rope<_CharT, _Alloc> __part1 =
	__r.substr(__middle.index(), __last.index() - __middle.index());
      rope<_CharT, _Alloc> __part2 =
	__r.substr(__first.index(), __middle.index() - __first.index());
      __r = __prefix;
      __r += __part1;
      __r += __part2;
      __r += __suffix;
    }

#if !defined(__GNUC__)
  // Appears to confuse g++
  inline void
  rotate(_Rope_iterator<char, __STL_DEFAULT_ALLOCATOR(char)> __first,
	 _Rope_iterator<char, __STL_DEFAULT_ALLOCATOR(char)> __middle,
	 _Rope_iterator<char, __STL_DEFAULT_ALLOCATOR(char)> __last)
  { _Rope_rotate(__first, __middle, __last); }
#endif

# if 0
  // Probably not useful for several reasons:
  // - for SGIs 7.1 compiler and probably some others,
  //   this forces lots of rope<wchar_t, ...> instantiations, creating a
  //   code bloat and compile time problem.  (Fixed in 7.2.)
  // - wchar_t is 4 bytes wide on most UNIX platforms, making it
  //   unattractive for unicode strings.  Unsigned short may be a better
  //   character type.
  inline void
  rotate(_Rope_iterator<wch