_detail::_S_function:
	case __detail::_S_substringfn:
	  {
	    size_t __len = _S_iterator_buf_len;
	    size_t __buf_start_pos = __leaf_pos;
	    size_t __leaf_end = __leaf_pos + __leaf->_M_size;
	    char_producer<_CharT>* __fn = ((_Rope_RopeFunction<_CharT,
					    _Alloc>*)__leaf)->_M_fn;
	    if (__buf_start_pos + __len <= __pos)
	      {
		__buf_start_pos = __pos - __len / 4;
		if (__buf_start_pos + __len > __leaf_end)
		  __buf_start_pos = __leaf_end - __len;
	      }
	    if (__buf_start_pos + __len > __leaf_end)
	      __len = __leaf_end - __buf_start_pos;
	    (*__fn)(__buf_start_pos - __leaf_pos, __len, __x._M_tmp_buf);
	    __x._M_buf_ptr = __x._M_tmp_buf + (__pos - __buf_start_pos);
	    __x._M_buf_start = __x._M_tmp_buf;
	    __x._M_buf_end = __x._M_tmp_buf + __len;
	  }
	  break;
	default:
	  break;
	}
    }

  // Set path and buffer inside a rope iterator.  We assume that
  // pos and root are already set.
  template <class _CharT, class _Alloc>
    void
    _Rope_iterator_base<_CharT, _Alloc>::
    _S_setcache(_Rope_iterator_base<_CharT, _Alloc>& __x)
    {
      const _RopeRep* __path[int(__detail::_S_max_rope_depth) + 1];
      const _RopeRep* __curr_rope;
      int __curr_depth = -1;  /* index into path    */
      size_t __curr_start_pos = 0;
      size_t __pos = __x._M_current_pos;
      unsigned char __dirns = 0; // Bit vector marking right turns in the path

      if (__pos >= __x._M_root->_M_size)
	{
	  __x._M_buf_ptr = 0;
	  return;
	}
      __curr_rope = __x._M_root;
      if (0 != __curr_rope->_M_c_string)
	{
	  /* Treat the root as a leaf. */
	  __x._M_buf_start = __curr_rope->_M_c_string;
	  __x._M_buf_end = __curr_rope->_M_c_string + __curr_rope->_M_size;
	  __x._M_buf_ptr = __curr_rope->_M_c_string + __pos;
	  __x._M_path_end[0] = __curr_rope;
	  __x._M_leaf_index = 0;
	  __x._M_leaf_pos = 0;
	  return;
	}
      for(;;)
	{
	  ++__curr_depth;
	  __path[__curr_depth] = __curr_rope;
	  switch(__curr_rope->_M_tag)
	    {
	    case __detail::_S_leaf:
	    case __detail::_S_function:
	 