<class _CharT, class _Traits>
  // Here _CharT is both the stream and rope character type.
    class _Rope_insert_char_consumer
    : public _Rope_char_consumer<_CharT>
    {
    private:
      typedef basic_ostream<_CharT,_Traits> _Insert_ostream;
      _Insert_ostream& _M_o;
    public:
      _Rope_insert_char_consumer(_Insert_ostream& __writer)
	: _M_o(__writer) {};
      ~_Rope_insert_char_consumer() { };
      // Caller is presumed to own the ostream
      bool operator() (const _CharT* __leaf, size_t __n);
      // Returns true to continue traversal.
    };

  template<class _CharT, class _Traits>
    bool
    _Rope_insert_char_consumer<_CharT, _Traits>::
    operator()(const _CharT* __leaf, size_t __n)
    {
      size_t __i;
      //  We assume that formatting is set up correctly for each element.
      for (__i = 0; __i < __n; __i++)
	_M_o.put(__leaf[__i]);
      return true;
    }

  template <class _CharT, class _Alloc>
    bool
    rope<_CharT, _Alloc>::
    _S_apply_to_pieces(_Rope_char_consumer<_CharT>& __c,
		       const _RopeRep* __r, size_t __begin, size_t __end)
    {
      if (0 == __r)
	return true;
      switch(__r->_M_tag)
	{
	case __detail::_S_concat:
	  {
	    _RopeConcatenation* __conc = (_RopeConcatenation*)__r;
	    _RopeRep* __left =  __conc->_M_left;
	    size_t __left_len = __left->_M_size;
	    if (__begin < __left_len)
	      {
		size_t __left_end = std::min(__left_len, __end);
		if (!_S_apply_to_pieces(__c, __left, __begin, __left_end))
		  return false;
	      }
	    if (__end > __left_len)
	      {
		_RopeRep* __right =  __conc->_M_right;
		size_t __right_start = std::max(__left_len, __begin);
		if (!_S_apply_to_pieces(__c, __right,
					__right_start - __left_len,
					__end - __left_len))
		  return false;
	      }
	  }
	  return true;
	case __detail::_S_leaf:
	  {
	    _RopeLeaf* __l = (_RopeLeaf*)__r;
	    return __c(__l->_M_data + __begin, __end - __begin);
	  }
	case __detail::_S_function:
	case __detail::_S_substringfn:
	    {
	      _RopeFunction* __f = (_RopeFunction*)