1951a39d68df598db08dfced8b4707755864a0492Ying Wang// SGI's rope class implementation -*- C++ -*-
2951a39d68df598db08dfced8b4707755864a0492Ying Wang
3951a39d68df598db08dfced8b4707755864a0492Ying Wang// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4951a39d68df598db08dfced8b4707755864a0492Ying Wang// Free Software Foundation, Inc.
5951a39d68df598db08dfced8b4707755864a0492Ying Wang//
6951a39d68df598db08dfced8b4707755864a0492Ying Wang// This file is part of the GNU ISO C++ Library.  This library is free
7951a39d68df598db08dfced8b4707755864a0492Ying Wang// software; you can redistribute it and/or modify it under the
8951a39d68df598db08dfced8b4707755864a0492Ying Wang// terms of the GNU General Public License as published by the
9951a39d68df598db08dfced8b4707755864a0492Ying Wang// Free Software Foundation; either version 3, or (at your option)
10951a39d68df598db08dfced8b4707755864a0492Ying Wang// any later version.
11951a39d68df598db08dfced8b4707755864a0492Ying Wang
12951a39d68df598db08dfced8b4707755864a0492Ying Wang// This library is distributed in the hope that it will be useful,
13951a39d68df598db08dfced8b4707755864a0492Ying Wang// but WITHOUT ANY WARRANTY; without even the implied warranty of
14951a39d68df598db08dfced8b4707755864a0492Ying Wang// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15951a39d68df598db08dfced8b4707755864a0492Ying Wang// GNU General Public License for more details.
16951a39d68df598db08dfced8b4707755864a0492Ying Wang
17951a39d68df598db08dfced8b4707755864a0492Ying Wang// Under Section 7 of GPL version 3, you are granted additional
18951a39d68df598db08dfced8b4707755864a0492Ying Wang// permissions described in the GCC Runtime Library Exception, version
19951a39d68df598db08dfced8b4707755864a0492Ying Wang// 3.1, as published by the Free Software Foundation.
20951a39d68df598db08dfced8b4707755864a0492Ying Wang
21951a39d68df598db08dfced8b4707755864a0492Ying Wang// You should have received a copy of the GNU General Public License and
22951a39d68df598db08dfced8b4707755864a0492Ying Wang// a copy of the GCC Runtime Library Exception along with this program;
23951a39d68df598db08dfced8b4707755864a0492Ying Wang// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24951a39d68df598db08dfced8b4707755864a0492Ying Wang// <http://www.gnu.org/licenses/>.
25951a39d68df598db08dfced8b4707755864a0492Ying Wang
26951a39d68df598db08dfced8b4707755864a0492Ying Wang/*
27951a39d68df598db08dfced8b4707755864a0492Ying Wang * Copyright (c) 1997
28951a39d68df598db08dfced8b4707755864a0492Ying Wang * Silicon Graphics Computer Systems, Inc.
29951a39d68df598db08dfced8b4707755864a0492Ying Wang *
30951a39d68df598db08dfced8b4707755864a0492Ying Wang * Permission to use, copy, modify, distribute and sell this software
31951a39d68df598db08dfced8b4707755864a0492Ying Wang * and its documentation for any purpose is hereby granted without fee,
32951a39d68df598db08dfced8b4707755864a0492Ying Wang * provided that the above copyright notice appear in all copies and
33951a39d68df598db08dfced8b4707755864a0492Ying Wang * that both that copyright notice and this permission notice appear
34951a39d68df598db08dfced8b4707755864a0492Ying Wang * in supporting documentation.  Silicon Graphics makes no
35951a39d68df598db08dfced8b4707755864a0492Ying Wang * representations about the suitability of this software for any
36951a39d68df598db08dfced8b4707755864a0492Ying Wang * purpose.  It is provided "as is" without express or implied warranty.
37951a39d68df598db08dfced8b4707755864a0492Ying Wang */
38951a39d68df598db08dfced8b4707755864a0492Ying Wang
39951a39d68df598db08dfced8b4707755864a0492Ying Wang/** @file ropeimpl.h
40951a39d68df598db08dfced8b4707755864a0492Ying Wang *  This is an internal header file, included by other library headers.
41951a39d68df598db08dfced8b4707755864a0492Ying Wang *  You should not attempt to use it directly.
42951a39d68df598db08dfced8b4707755864a0492Ying Wang */
43951a39d68df598db08dfced8b4707755864a0492Ying Wang
44951a39d68df598db08dfced8b4707755864a0492Ying Wang#include <cstdio>
45951a39d68df598db08dfced8b4707755864a0492Ying Wang#include <ostream>
46951a39d68df598db08dfced8b4707755864a0492Ying Wang#include <bits/functexcept.h>
47951a39d68df598db08dfced8b4707755864a0492Ying Wang
48951a39d68df598db08dfced8b4707755864a0492Ying Wang#include <ext/algorithm> // For copy_n and lexicographical_compare_3way
49951a39d68df598db08dfced8b4707755864a0492Ying Wang#include <ext/memory> // For uninitialized_copy_n
50951a39d68df598db08dfced8b4707755864a0492Ying Wang#include <ext/numeric> // For power
51951a39d68df598db08dfced8b4707755864a0492Ying Wang
52951a39d68df598db08dfced8b4707755864a0492Ying Wang_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
53951a39d68df598db08dfced8b4707755864a0492Ying Wang
54951a39d68df598db08dfced8b4707755864a0492Ying Wang  using std::size_t;
55951a39d68df598db08dfced8b4707755864a0492Ying Wang  using std::printf;
56951a39d68df598db08dfced8b4707755864a0492Ying Wang  using std::basic_ostream;
57951a39d68df598db08dfced8b4707755864a0492Ying Wang  using std::__throw_length_error;
58951a39d68df598db08dfced8b4707755864a0492Ying Wang  using std::_Destroy;
59951a39d68df598db08dfced8b4707755864a0492Ying Wang  using std::uninitialized_fill_n;
60951a39d68df598db08dfced8b4707755864a0492Ying Wang
61951a39d68df598db08dfced8b4707755864a0492Ying Wang  // Set buf_start, buf_end, and buf_ptr appropriately, filling tmp_buf
62951a39d68df598db08dfced8b4707755864a0492Ying Wang  // if necessary.  Assumes _M_path_end[leaf_index] and leaf_pos are correct.
63951a39d68df598db08dfced8b4707755864a0492Ying Wang  // Results in a valid buf_ptr if the iterator can be legitimately
64951a39d68df598db08dfced8b4707755864a0492Ying Wang  // dereferenced.
65951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
66951a39d68df598db08dfced8b4707755864a0492Ying Wang    void
67951a39d68df598db08dfced8b4707755864a0492Ying Wang    _Rope_iterator_base<_CharT, _Alloc>::
68951a39d68df598db08dfced8b4707755864a0492Ying Wang    _S_setbuf(_Rope_iterator_base<_CharT, _Alloc>& __x)
69951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
70951a39d68df598db08dfced8b4707755864a0492Ying Wang      const _RopeRep* __leaf = __x._M_path_end[__x._M_leaf_index];
71951a39d68df598db08dfced8b4707755864a0492Ying Wang      size_t __leaf_pos = __x._M_leaf_pos;
72951a39d68df598db08dfced8b4707755864a0492Ying Wang      size_t __pos = __x._M_current_pos;
73951a39d68df598db08dfced8b4707755864a0492Ying Wang
74951a39d68df598db08dfced8b4707755864a0492Ying Wang      switch(__leaf->_M_tag)
75951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
76951a39d68df598db08dfced8b4707755864a0492Ying Wang	case __detail::_S_leaf:
77951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __x._M_buf_start = ((_Rope_RopeLeaf<_CharT, _Alloc>*)__leaf)->_M_data;
78951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __x._M_buf_ptr = __x._M_buf_start + (__pos - __leaf_pos);
79951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __x._M_buf_end = __x._M_buf_start + __leaf->_M_size;
80951a39d68df598db08dfced8b4707755864a0492Ying Wang	  break;
81951a39d68df598db08dfced8b4707755864a0492Ying Wang	case __detail::_S_function:
82951a39d68df598db08dfced8b4707755864a0492Ying Wang	case __detail::_S_substringfn:
83951a39d68df598db08dfced8b4707755864a0492Ying Wang	  {
84951a39d68df598db08dfced8b4707755864a0492Ying Wang	    size_t __len = _S_iterator_buf_len;
85951a39d68df598db08dfced8b4707755864a0492Ying Wang	    size_t __buf_start_pos = __leaf_pos;
86951a39d68df598db08dfced8b4707755864a0492Ying Wang	    size_t __leaf_end = __leaf_pos + __leaf->_M_size;
87951a39d68df598db08dfced8b4707755864a0492Ying Wang	    char_producer<_CharT>* __fn = ((_Rope_RopeFunction<_CharT,
88951a39d68df598db08dfced8b4707755864a0492Ying Wang					    _Alloc>*)__leaf)->_M_fn;
89951a39d68df598db08dfced8b4707755864a0492Ying Wang	    if (__buf_start_pos + __len <= __pos)
90951a39d68df598db08dfced8b4707755864a0492Ying Wang	      {
91951a39d68df598db08dfced8b4707755864a0492Ying Wang		__buf_start_pos = __pos - __len / 4;
92951a39d68df598db08dfced8b4707755864a0492Ying Wang		if (__buf_start_pos + __len > __leaf_end)
93951a39d68df598db08dfced8b4707755864a0492Ying Wang		  __buf_start_pos = __leaf_end - __len;
94951a39d68df598db08dfced8b4707755864a0492Ying Wang	      }
95951a39d68df598db08dfced8b4707755864a0492Ying Wang	    if (__buf_start_pos + __len > __leaf_end)
96951a39d68df598db08dfced8b4707755864a0492Ying Wang	      __len = __leaf_end - __buf_start_pos;
97951a39d68df598db08dfced8b4707755864a0492Ying Wang	    (*__fn)(__buf_start_pos - __leaf_pos, __len, __x._M_tmp_buf);
98951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __x._M_buf_ptr = __x._M_tmp_buf + (__pos - __buf_start_pos);
99951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __x._M_buf_start = __x._M_tmp_buf;
100951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __x._M_buf_end = __x._M_tmp_buf + __len;
101951a39d68df598db08dfced8b4707755864a0492Ying Wang	  }
102951a39d68df598db08dfced8b4707755864a0492Ying Wang	  break;
103951a39d68df598db08dfced8b4707755864a0492Ying Wang	default:
104951a39d68df598db08dfced8b4707755864a0492Ying Wang	  break;
105951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
106951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
107951a39d68df598db08dfced8b4707755864a0492Ying Wang
108951a39d68df598db08dfced8b4707755864a0492Ying Wang  // Set path and buffer inside a rope iterator.  We assume that
109951a39d68df598db08dfced8b4707755864a0492Ying Wang  // pos and root are already set.
110951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
111951a39d68df598db08dfced8b4707755864a0492Ying Wang    void
112951a39d68df598db08dfced8b4707755864a0492Ying Wang    _Rope_iterator_base<_CharT, _Alloc>::
113951a39d68df598db08dfced8b4707755864a0492Ying Wang    _S_setcache(_Rope_iterator_base<_CharT, _Alloc>& __x)
114951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
115951a39d68df598db08dfced8b4707755864a0492Ying Wang      const _RopeRep* __path[int(__detail::_S_max_rope_depth) + 1];
116951a39d68df598db08dfced8b4707755864a0492Ying Wang      const _RopeRep* __curr_rope;
117951a39d68df598db08dfced8b4707755864a0492Ying Wang      int __curr_depth = -1;  /* index into path    */
118951a39d68df598db08dfced8b4707755864a0492Ying Wang      size_t __curr_start_pos = 0;
119951a39d68df598db08dfced8b4707755864a0492Ying Wang      size_t __pos = __x._M_current_pos;
120951a39d68df598db08dfced8b4707755864a0492Ying Wang      unsigned char __dirns = 0; // Bit vector marking right turns in the path
121951a39d68df598db08dfced8b4707755864a0492Ying Wang
122951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (__pos >= __x._M_root->_M_size)
123951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
124951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __x._M_buf_ptr = 0;
125951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return;
126951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
127951a39d68df598db08dfced8b4707755864a0492Ying Wang      __curr_rope = __x._M_root;
128951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (0 != __curr_rope->_M_c_string)
129951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
130951a39d68df598db08dfced8b4707755864a0492Ying Wang	  /* Treat the root as a leaf. */
131951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __x._M_buf_start = __curr_rope->_M_c_string;
132951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __x._M_buf_end = __curr_rope->_M_c_string + __curr_rope->_M_size;
133951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __x._M_buf_ptr = __curr_rope->_M_c_string + __pos;
134951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __x._M_path_end[0] = __curr_rope;
135951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __x._M_leaf_index = 0;
136951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __x._M_leaf_pos = 0;
137951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return;
138951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
139951a39d68df598db08dfced8b4707755864a0492Ying Wang      for(;;)
140951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
141951a39d68df598db08dfced8b4707755864a0492Ying Wang	  ++__curr_depth;
142951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __path[__curr_depth] = __curr_rope;
143951a39d68df598db08dfced8b4707755864a0492Ying Wang	  switch(__curr_rope->_M_tag)
144951a39d68df598db08dfced8b4707755864a0492Ying Wang	    {
145951a39d68df598db08dfced8b4707755864a0492Ying Wang	    case __detail::_S_leaf:
146951a39d68df598db08dfced8b4707755864a0492Ying Wang	    case __detail::_S_function:
147951a39d68df598db08dfced8b4707755864a0492Ying Wang	    case __detail::_S_substringfn:
148951a39d68df598db08dfced8b4707755864a0492Ying Wang	      __x._M_leaf_pos = __curr_start_pos;
149951a39d68df598db08dfced8b4707755864a0492Ying Wang	      goto done;
150951a39d68df598db08dfced8b4707755864a0492Ying Wang	    case __detail::_S_concat:
151951a39d68df598db08dfced8b4707755864a0492Ying Wang	      {
152951a39d68df598db08dfced8b4707755864a0492Ying Wang		_Rope_RopeConcatenation<_CharT, _Alloc>* __c =
153951a39d68df598db08dfced8b4707755864a0492Ying Wang		  (_Rope_RopeConcatenation<_CharT, _Alloc>*)__curr_rope;
154951a39d68df598db08dfced8b4707755864a0492Ying Wang		_RopeRep* __left = __c->_M_left;
155951a39d68df598db08dfced8b4707755864a0492Ying Wang		size_t __left_len = __left->_M_size;
156951a39d68df598db08dfced8b4707755864a0492Ying Wang
157951a39d68df598db08dfced8b4707755864a0492Ying Wang		__dirns <<= 1;
158951a39d68df598db08dfced8b4707755864a0492Ying Wang		if (__pos >= __curr_start_pos + __left_len)
159951a39d68df598db08dfced8b4707755864a0492Ying Wang		  {
160951a39d68df598db08dfced8b4707755864a0492Ying Wang		    __dirns |= 1;
161951a39d68df598db08dfced8b4707755864a0492Ying Wang		    __curr_rope = __c->_M_right;
162951a39d68df598db08dfced8b4707755864a0492Ying Wang		    __curr_start_pos += __left_len;
163951a39d68df598db08dfced8b4707755864a0492Ying Wang		  }
164951a39d68df598db08dfced8b4707755864a0492Ying Wang		else
165951a39d68df598db08dfced8b4707755864a0492Ying Wang		  __curr_rope = __left;
166951a39d68df598db08dfced8b4707755864a0492Ying Wang	      }
167951a39d68df598db08dfced8b4707755864a0492Ying Wang	      break;
168951a39d68df598db08dfced8b4707755864a0492Ying Wang	    }
169951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
170951a39d68df598db08dfced8b4707755864a0492Ying Wang    done:
171951a39d68df598db08dfced8b4707755864a0492Ying Wang      // Copy last section of path into _M_path_end.
172951a39d68df598db08dfced8b4707755864a0492Ying Wang      {
173951a39d68df598db08dfced8b4707755864a0492Ying Wang	int __i = -1;
174951a39d68df598db08dfced8b4707755864a0492Ying Wang	int __j = __curr_depth + 1 - int(_S_path_cache_len);
175951a39d68df598db08dfced8b4707755864a0492Ying Wang
176951a39d68df598db08dfced8b4707755864a0492Ying Wang	if (__j < 0) __j = 0;
177951a39d68df598db08dfced8b4707755864a0492Ying Wang	while (__j <= __curr_depth)
178951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __x._M_path_end[++__i] = __path[__j++];
179951a39d68df598db08dfced8b4707755864a0492Ying Wang	__x._M_leaf_index = __i;
180951a39d68df598db08dfced8b4707755864a0492Ying Wang      }
181951a39d68df598db08dfced8b4707755864a0492Ying Wang      __x._M_path_directions = __dirns;
182951a39d68df598db08dfced8b4707755864a0492Ying Wang      _S_setbuf(__x);
183951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
184951a39d68df598db08dfced8b4707755864a0492Ying Wang
185951a39d68df598db08dfced8b4707755864a0492Ying Wang  // Specialized version of the above.  Assumes that
186951a39d68df598db08dfced8b4707755864a0492Ying Wang  // the path cache is valid for the previous position.
187951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
188951a39d68df598db08dfced8b4707755864a0492Ying Wang    void
189951a39d68df598db08dfced8b4707755864a0492Ying Wang    _Rope_iterator_base<_CharT, _Alloc>::
190951a39d68df598db08dfced8b4707755864a0492Ying Wang    _S_setcache_for_incr(_Rope_iterator_base<_CharT, _Alloc>& __x)
191951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
192951a39d68df598db08dfced8b4707755864a0492Ying Wang      int __current_index = __x._M_leaf_index;
193951a39d68df598db08dfced8b4707755864a0492Ying Wang      const _RopeRep* __current_node = __x._M_path_end[__current_index];
194951a39d68df598db08dfced8b4707755864a0492Ying Wang      size_t __len = __current_node->_M_size;
195951a39d68df598db08dfced8b4707755864a0492Ying Wang      size_t __node_start_pos = __x._M_leaf_pos;
196951a39d68df598db08dfced8b4707755864a0492Ying Wang      unsigned char __dirns = __x._M_path_directions;
197951a39d68df598db08dfced8b4707755864a0492Ying Wang      _Rope_RopeConcatenation<_CharT, _Alloc>* __c;
198951a39d68df598db08dfced8b4707755864a0492Ying Wang
199951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (__x._M_current_pos - __node_start_pos < __len)
200951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
201951a39d68df598db08dfced8b4707755864a0492Ying Wang	  /* More stuff in this leaf, we just didn't cache it. */
202951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _S_setbuf(__x);
203951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return;
204951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
205951a39d68df598db08dfced8b4707755864a0492Ying Wang      //  node_start_pos is starting position of last_node.
206951a39d68df598db08dfced8b4707755864a0492Ying Wang      while (--__current_index >= 0)
207951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
208951a39d68df598db08dfced8b4707755864a0492Ying Wang	  if (!(__dirns & 1) /* Path turned left */)
209951a39d68df598db08dfced8b4707755864a0492Ying Wang	    break;
210951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __current_node = __x._M_path_end[__current_index];
211951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __c = (_Rope_RopeConcatenation<_CharT, _Alloc>*)__current_node;
212951a39d68df598db08dfced8b4707755864a0492Ying Wang	  // Otherwise we were in the right child.  Thus we should pop
213951a39d68df598db08dfced8b4707755864a0492Ying Wang	  // the concatenation node.
214951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __node_start_pos -= __c->_M_left->_M_size;
215951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __dirns >>= 1;
216951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
217951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (__current_index < 0)
218951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
219951a39d68df598db08dfced8b4707755864a0492Ying Wang	  // We underflowed the cache. Punt.
220951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _S_setcache(__x);
221951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return;
222951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
223951a39d68df598db08dfced8b4707755864a0492Ying Wang      __current_node = __x._M_path_end[__current_index];
224951a39d68df598db08dfced8b4707755864a0492Ying Wang      __c = (_Rope_RopeConcatenation<_CharT, _Alloc>*)__current_node;
225951a39d68df598db08dfced8b4707755864a0492Ying Wang      // current_node is a concatenation node.  We are positioned on the first
226951a39d68df598db08dfced8b4707755864a0492Ying Wang      // character in its right child.
227951a39d68df598db08dfced8b4707755864a0492Ying Wang      // node_start_pos is starting position of current_node.
228951a39d68df598db08dfced8b4707755864a0492Ying Wang      __node_start_pos += __c->_M_left->_M_size;
229951a39d68df598db08dfced8b4707755864a0492Ying Wang      __current_node = __c->_M_right;
230951a39d68df598db08dfced8b4707755864a0492Ying Wang      __x._M_path_end[++__current_index] = __current_node;
231951a39d68df598db08dfced8b4707755864a0492Ying Wang      __dirns |= 1;
232951a39d68df598db08dfced8b4707755864a0492Ying Wang      while (__detail::_S_concat == __current_node->_M_tag)
233951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
234951a39d68df598db08dfced8b4707755864a0492Ying Wang	  ++__current_index;
235951a39d68df598db08dfced8b4707755864a0492Ying Wang	  if (int(_S_path_cache_len) == __current_index)
236951a39d68df598db08dfced8b4707755864a0492Ying Wang	    {
237951a39d68df598db08dfced8b4707755864a0492Ying Wang	      int __i;
238951a39d68df598db08dfced8b4707755864a0492Ying Wang	      for (__i = 0; __i < int(_S_path_cache_len) - 1; __i++)
239951a39d68df598db08dfced8b4707755864a0492Ying Wang		__x._M_path_end[__i] = __x._M_path_end[__i+1];
240951a39d68df598db08dfced8b4707755864a0492Ying Wang	      --__current_index;
241951a39d68df598db08dfced8b4707755864a0492Ying Wang	    }
242951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __current_node =
243951a39d68df598db08dfced8b4707755864a0492Ying Wang	    ((_Rope_RopeConcatenation<_CharT, _Alloc>*)__current_node)->_M_left;
244951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __x._M_path_end[__current_index] = __current_node;
245951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __dirns <<= 1;
246951a39d68df598db08dfced8b4707755864a0492Ying Wang	  // node_start_pos is unchanged.
247951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
248951a39d68df598db08dfced8b4707755864a0492Ying Wang      __x._M_leaf_index = __current_index;
249951a39d68df598db08dfced8b4707755864a0492Ying Wang      __x._M_leaf_pos = __node_start_pos;
250951a39d68df598db08dfced8b4707755864a0492Ying Wang      __x._M_path_directions = __dirns;
251951a39d68df598db08dfced8b4707755864a0492Ying Wang      _S_setbuf(__x);
252951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
253951a39d68df598db08dfced8b4707755864a0492Ying Wang
254951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
255951a39d68df598db08dfced8b4707755864a0492Ying Wang    void
256951a39d68df598db08dfced8b4707755864a0492Ying Wang    _Rope_iterator_base<_CharT, _Alloc>::
257951a39d68df598db08dfced8b4707755864a0492Ying Wang    _M_incr(size_t __n)
258951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
259951a39d68df598db08dfced8b4707755864a0492Ying Wang      _M_current_pos += __n;
260951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (0 != _M_buf_ptr)
261951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
262951a39d68df598db08dfced8b4707755864a0492Ying Wang	  size_t __chars_left = _M_buf_end - _M_buf_ptr;
263951a39d68df598db08dfced8b4707755864a0492Ying Wang	  if (__chars_left > __n)
264951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _M_buf_ptr += __n;
265951a39d68df598db08dfced8b4707755864a0492Ying Wang	  else if (__chars_left == __n)
266951a39d68df598db08dfced8b4707755864a0492Ying Wang	    {
267951a39d68df598db08dfced8b4707755864a0492Ying Wang	      _M_buf_ptr += __n;
268951a39d68df598db08dfced8b4707755864a0492Ying Wang	      _S_setcache_for_incr(*this);
269951a39d68df598db08dfced8b4707755864a0492Ying Wang	    }
270951a39d68df598db08dfced8b4707755864a0492Ying Wang	  else
271951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _M_buf_ptr = 0;
272951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
273951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
274951a39d68df598db08dfced8b4707755864a0492Ying Wang
275951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
276951a39d68df598db08dfced8b4707755864a0492Ying Wang    void
277951a39d68df598db08dfced8b4707755864a0492Ying Wang    _Rope_iterator_base<_CharT, _Alloc>::
278951a39d68df598db08dfced8b4707755864a0492Ying Wang    _M_decr(size_t __n)
279951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
280951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (0 != _M_buf_ptr)
281951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
282951a39d68df598db08dfced8b4707755864a0492Ying Wang	  size_t __chars_left = _M_buf_ptr - _M_buf_start;
283951a39d68df598db08dfced8b4707755864a0492Ying Wang	  if (__chars_left >= __n)
284951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _M_buf_ptr -= __n;
285951a39d68df598db08dfced8b4707755864a0492Ying Wang	  else
286951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _M_buf_ptr = 0;
287951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
288951a39d68df598db08dfced8b4707755864a0492Ying Wang      _M_current_pos -= __n;
289951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
290951a39d68df598db08dfced8b4707755864a0492Ying Wang
291951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
292951a39d68df598db08dfced8b4707755864a0492Ying Wang    void
293951a39d68df598db08dfced8b4707755864a0492Ying Wang    _Rope_iterator<_CharT, _Alloc>::
294951a39d68df598db08dfced8b4707755864a0492Ying Wang    _M_check()
295951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
296951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (_M_root_rope->_M_tree_ptr != this->_M_root)
297951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
298951a39d68df598db08dfced8b4707755864a0492Ying Wang	  // _Rope was modified.  Get things fixed up.
299951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _RopeRep::_S_unref(this->_M_root);
300951a39d68df598db08dfced8b4707755864a0492Ying Wang	  this->_M_root = _M_root_rope->_M_tree_ptr;
301951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _RopeRep::_S_ref(this->_M_root);
302951a39d68df598db08dfced8b4707755864a0492Ying Wang	  this->_M_buf_ptr = 0;
303951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
304951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
305951a39d68df598db08dfced8b4707755864a0492Ying Wang
306951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
307951a39d68df598db08dfced8b4707755864a0492Ying Wang    inline
308951a39d68df598db08dfced8b4707755864a0492Ying Wang    _Rope_const_iterator<_CharT, _Alloc>::
309951a39d68df598db08dfced8b4707755864a0492Ying Wang    _Rope_const_iterator(const _Rope_iterator<_CharT, _Alloc>& __x)
310951a39d68df598db08dfced8b4707755864a0492Ying Wang    : _Rope_iterator_base<_CharT, _Alloc>(__x)
311951a39d68df598db08dfced8b4707755864a0492Ying Wang    { }
312951a39d68df598db08dfced8b4707755864a0492Ying Wang
313951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
314951a39d68df598db08dfced8b4707755864a0492Ying Wang    inline
315951a39d68df598db08dfced8b4707755864a0492Ying Wang    _Rope_iterator<_CharT, _Alloc>::
316951a39d68df598db08dfced8b4707755864a0492Ying Wang    _Rope_iterator(rope<_CharT, _Alloc>& __r, size_t __pos)
317951a39d68df598db08dfced8b4707755864a0492Ying Wang    : _Rope_iterator_base<_CharT,_Alloc>(__r._M_tree_ptr, __pos),
318951a39d68df598db08dfced8b4707755864a0492Ying Wang      _M_root_rope(&__r)
319951a39d68df598db08dfced8b4707755864a0492Ying Wang    { _RopeRep::_S_ref(this->_M_root); }
320951a39d68df598db08dfced8b4707755864a0492Ying Wang
321951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
322951a39d68df598db08dfced8b4707755864a0492Ying Wang    inline size_t
323951a39d68df598db08dfced8b4707755864a0492Ying Wang    rope<_CharT, _Alloc>::
324951a39d68df598db08dfced8b4707755864a0492Ying Wang    _S_char_ptr_len(const _CharT* __s)
325951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
326951a39d68df598db08dfced8b4707755864a0492Ying Wang      const _CharT* __p = __s;
327951a39d68df598db08dfced8b4707755864a0492Ying Wang
328951a39d68df598db08dfced8b4707755864a0492Ying Wang      while (!_S_is0(*__p))
329951a39d68df598db08dfced8b4707755864a0492Ying Wang	++__p;
330951a39d68df598db08dfced8b4707755864a0492Ying Wang      return (__p - __s);
331951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
332951a39d68df598db08dfced8b4707755864a0492Ying Wang
333951a39d68df598db08dfced8b4707755864a0492Ying Wang
334951a39d68df598db08dfced8b4707755864a0492Ying Wang#ifndef __GC
335951a39d68df598db08dfced8b4707755864a0492Ying Wang
336951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
337951a39d68df598db08dfced8b4707755864a0492Ying Wang    inline void
338951a39d68df598db08dfced8b4707755864a0492Ying Wang    _Rope_RopeRep<_CharT, _Alloc>::
339951a39d68df598db08dfced8b4707755864a0492Ying Wang    _M_free_c_string()
340951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
341951a39d68df598db08dfced8b4707755864a0492Ying Wang      _CharT* __cstr = _M_c_string;
342951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (0 != __cstr)
343951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
344951a39d68df598db08dfced8b4707755864a0492Ying Wang	  size_t __size = this->_M_size + 1;
345951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _Destroy(__cstr, __cstr + __size, _M_get_allocator());
346951a39d68df598db08dfced8b4707755864a0492Ying Wang	  this->_Data_deallocate(__cstr, __size);
347951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
348951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
349951a39d68df598db08dfced8b4707755864a0492Ying Wang
350951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
351951a39d68df598db08dfced8b4707755864a0492Ying Wang    inline void
352951a39d68df598db08dfced8b4707755864a0492Ying Wang    _Rope_RopeRep<_CharT, _Alloc>::
353951a39d68df598db08dfced8b4707755864a0492Ying Wang    _S_free_string(_CharT* __s, size_t __n, allocator_type& __a)
354951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
355951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (!_S_is_basic_char_type((_CharT*)0))
356951a39d68df598db08dfced8b4707755864a0492Ying Wang	_Destroy(__s, __s + __n, __a);
357951a39d68df598db08dfced8b4707755864a0492Ying Wang
358951a39d68df598db08dfced8b4707755864a0492Ying Wang      //  This has to be a static member, so this gets a bit messy
359951a39d68df598db08dfced8b4707755864a0492Ying Wang      __a.deallocate(__s,
360951a39d68df598db08dfced8b4707755864a0492Ying Wang		     _Rope_RopeLeaf<_CharT, _Alloc>::_S_rounded_up_size(__n));
361951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
362951a39d68df598db08dfced8b4707755864a0492Ying Wang
363951a39d68df598db08dfced8b4707755864a0492Ying Wang  //  There are several reasons for not doing this with virtual destructors
364951a39d68df598db08dfced8b4707755864a0492Ying Wang  //  and a class specific delete operator:
365951a39d68df598db08dfced8b4707755864a0492Ying Wang  //  - A class specific delete operator can't easily get access to
366951a39d68df598db08dfced8b4707755864a0492Ying Wang  //    allocator instances if we need them.
367951a39d68df598db08dfced8b4707755864a0492Ying Wang  //  - Any virtual function would need a 4 or byte vtable pointer;
368951a39d68df598db08dfced8b4707755864a0492Ying Wang  //    this only requires a one byte tag per object.
369951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
370951a39d68df598db08dfced8b4707755864a0492Ying Wang    void
371951a39d68df598db08dfced8b4707755864a0492Ying Wang    _Rope_RopeRep<_CharT, _Alloc>::
372951a39d68df598db08dfced8b4707755864a0492Ying Wang    _M_free_tree()
373951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
374951a39d68df598db08dfced8b4707755864a0492Ying Wang      switch(_M_tag)
375951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
376951a39d68df598db08dfced8b4707755864a0492Ying Wang	case __detail::_S_leaf:
377951a39d68df598db08dfced8b4707755864a0492Ying Wang	  {
378951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _Rope_RopeLeaf<_CharT, _Alloc>* __l
379951a39d68df598db08dfced8b4707755864a0492Ying Wang	      = (_Rope_RopeLeaf<_CharT, _Alloc>*)this;
380951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __l->_Rope_RopeLeaf<_CharT, _Alloc>::~_Rope_RopeLeaf();
381951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _L_deallocate(__l, 1);
382951a39d68df598db08dfced8b4707755864a0492Ying Wang	    break;
383951a39d68df598db08dfced8b4707755864a0492Ying Wang	  }
384951a39d68df598db08dfced8b4707755864a0492Ying Wang	case __detail::_S_concat:
385951a39d68df598db08dfced8b4707755864a0492Ying Wang	  {
386951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _Rope_RopeConcatenation<_CharT,_Alloc>* __c
387951a39d68df598db08dfced8b4707755864a0492Ying Wang	      = (_Rope_RopeConcatenation<_CharT, _Alloc>*)this;
388951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __c->_Rope_RopeConcatenation<_CharT, _Alloc>::
389951a39d68df598db08dfced8b4707755864a0492Ying Wang	      ~_Rope_RopeConcatenation();
390951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _C_deallocate(__c, 1);
391951a39d68df598db08dfced8b4707755864a0492Ying Wang	    break;
392951a39d68df598db08dfced8b4707755864a0492Ying Wang	  }
393951a39d68df598db08dfced8b4707755864a0492Ying Wang	case __detail::_S_function:
394951a39d68df598db08dfced8b4707755864a0492Ying Wang	  {
395951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _Rope_RopeFunction<_CharT, _Alloc>* __f
396951a39d68df598db08dfced8b4707755864a0492Ying Wang	      = (_Rope_RopeFunction<_CharT, _Alloc>*)this;
397951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __f->_Rope_RopeFunction<_CharT, _Alloc>::~_Rope_RopeFunction();
398951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _F_deallocate(__f, 1);
399951a39d68df598db08dfced8b4707755864a0492Ying Wang	    break;
400951a39d68df598db08dfced8b4707755864a0492Ying Wang	  }
401951a39d68df598db08dfced8b4707755864a0492Ying Wang	case __detail::_S_substringfn:
402951a39d68df598db08dfced8b4707755864a0492Ying Wang	  {
403951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _Rope_RopeSubstring<_CharT, _Alloc>* __ss =
404951a39d68df598db08dfced8b4707755864a0492Ying Wang	      (_Rope_RopeSubstring<_CharT, _Alloc>*)this;
405951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __ss->_Rope_RopeSubstring<_CharT, _Alloc>::
406951a39d68df598db08dfced8b4707755864a0492Ying Wang	      ~_Rope_RopeSubstring();
407951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _S_deallocate(__ss, 1);
408951a39d68df598db08dfced8b4707755864a0492Ying Wang	    break;
409951a39d68df598db08dfced8b4707755864a0492Ying Wang	  }
410951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
411951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
412951a39d68df598db08dfced8b4707755864a0492Ying Wang#else
413951a39d68df598db08dfced8b4707755864a0492Ying Wang
414951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
415951a39d68df598db08dfced8b4707755864a0492Ying Wang    inline void
416951a39d68df598db08dfced8b4707755864a0492Ying Wang    _Rope_RopeRep<_CharT, _Alloc>::
417951a39d68df598db08dfced8b4707755864a0492Ying Wang    _S_free_string(const _CharT*, size_t, allocator_type)
418951a39d68df598db08dfced8b4707755864a0492Ying Wang    { }
419951a39d68df598db08dfced8b4707755864a0492Ying Wang
420951a39d68df598db08dfced8b4707755864a0492Ying Wang#endif
421951a39d68df598db08dfced8b4707755864a0492Ying Wang
422951a39d68df598db08dfced8b4707755864a0492Ying Wang  // Concatenate a C string onto a leaf rope by copying the rope data.
423951a39d68df598db08dfced8b4707755864a0492Ying Wang  // Used for short ropes.
424951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
425951a39d68df598db08dfced8b4707755864a0492Ying Wang    typename rope<_CharT, _Alloc>::_RopeLeaf*
426951a39d68df598db08dfced8b4707755864a0492Ying Wang    rope<_CharT, _Alloc>::
427951a39d68df598db08dfced8b4707755864a0492Ying Wang    _S_leaf_concat_char_iter(_RopeLeaf* __r, const _CharT* __iter, size_t __len)
428951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
429951a39d68df598db08dfced8b4707755864a0492Ying Wang      size_t __old_len = __r->_M_size;
430951a39d68df598db08dfced8b4707755864a0492Ying Wang      _CharT* __new_data = (_CharT*)
431951a39d68df598db08dfced8b4707755864a0492Ying Wang	_Data_allocate(_S_rounded_up_size(__old_len + __len));
432951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RopeLeaf* __result;
433951a39d68df598db08dfced8b4707755864a0492Ying Wang
434951a39d68df598db08dfced8b4707755864a0492Ying Wang      uninitialized_copy_n(__r->_M_data, __old_len, __new_data);
435951a39d68df598db08dfced8b4707755864a0492Ying Wang      uninitialized_copy_n(__iter, __len, __new_data + __old_len);
436951a39d68df598db08dfced8b4707755864a0492Ying Wang      _S_cond_store_eos(__new_data[__old_len + __len]);
437951a39d68df598db08dfced8b4707755864a0492Ying Wang      __try
438951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
439951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __result = _S_new_RopeLeaf(__new_data, __old_len + __len,
440951a39d68df598db08dfced8b4707755864a0492Ying Wang				     __r->_M_get_allocator());
441951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
442951a39d68df598db08dfced8b4707755864a0492Ying Wang      __catch(...)
443951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
444951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _RopeRep::__STL_FREE_STRING(__new_data, __old_len + __len,
445951a39d68df598db08dfced8b4707755864a0492Ying Wang				      __r->_M_get_allocator());
446951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __throw_exception_again;
447951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
448951a39d68df598db08dfced8b4707755864a0492Ying Wang      return __result;
449951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
450951a39d68df598db08dfced8b4707755864a0492Ying Wang
451951a39d68df598db08dfced8b4707755864a0492Ying Wang#ifndef __GC
452951a39d68df598db08dfced8b4707755864a0492Ying Wang  // As above, but it's OK to clobber original if refcount is 1
453951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
454951a39d68df598db08dfced8b4707755864a0492Ying Wang    typename rope<_CharT,_Alloc>::_RopeLeaf*
455951a39d68df598db08dfced8b4707755864a0492Ying Wang    rope<_CharT, _Alloc>::
456951a39d68df598db08dfced8b4707755864a0492Ying Wang    _S_destr_leaf_concat_char_iter(_RopeLeaf* __r, const _CharT* __iter,
457951a39d68df598db08dfced8b4707755864a0492Ying Wang				   size_t __len)
458951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
459951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (__r->_M_ref_count > 1)
460951a39d68df598db08dfced8b4707755864a0492Ying Wang	return _S_leaf_concat_char_iter(__r, __iter, __len);
461951a39d68df598db08dfced8b4707755864a0492Ying Wang      size_t __old_len = __r->_M_size;
462951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (_S_allocated_capacity(__old_len) >= __old_len + __len)
463951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
464951a39d68df598db08dfced8b4707755864a0492Ying Wang	  // The space has been partially initialized for the standard
465951a39d68df598db08dfced8b4707755864a0492Ying Wang	  // character types.  But that doesn't matter for those types.
466951a39d68df598db08dfced8b4707755864a0492Ying Wang	  uninitialized_copy_n(__iter, __len, __r->_M_data + __old_len);
467951a39d68df598db08dfced8b4707755864a0492Ying Wang	  if (_S_is_basic_char_type((_CharT*)0))
468951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _S_cond_store_eos(__r->_M_data[__old_len + __len]);
469951a39d68df598db08dfced8b4707755864a0492Ying Wang	  else if (__r->_M_c_string != __r->_M_data && 0 != __r->_M_c_string)
470951a39d68df598db08dfced8b4707755864a0492Ying Wang	    {
471951a39d68df598db08dfced8b4707755864a0492Ying Wang	      __r->_M_free_c_string();
472951a39d68df598db08dfced8b4707755864a0492Ying Wang	      __r->_M_c_string = 0;
473951a39d68df598db08dfced8b4707755864a0492Ying Wang	    }
474951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __r->_M_size = __old_len + __len;
475951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __r->_M_ref_count = 2;
476951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return __r;
477951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
478951a39d68df598db08dfced8b4707755864a0492Ying Wang      else
479951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
480951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _RopeLeaf* __result = _S_leaf_concat_char_iter(__r, __iter, __len);
481951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return __result;
482951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
483951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
484951a39d68df598db08dfced8b4707755864a0492Ying Wang#endif
485951a39d68df598db08dfced8b4707755864a0492Ying Wang
486951a39d68df598db08dfced8b4707755864a0492Ying Wang  // Assumes left and right are not 0.
487951a39d68df598db08dfced8b4707755864a0492Ying Wang  // Does not increment (nor decrement on exception) child reference counts.
488951a39d68df598db08dfced8b4707755864a0492Ying Wang  // Result has ref count 1.
489951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
490951a39d68df598db08dfced8b4707755864a0492Ying Wang    typename rope<_CharT, _Alloc>::_RopeRep*
491951a39d68df598db08dfced8b4707755864a0492Ying Wang    rope<_CharT, _Alloc>::
492951a39d68df598db08dfced8b4707755864a0492Ying Wang    _S_tree_concat(_RopeRep* __left, _RopeRep* __right)
493951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
494951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RopeConcatenation* __result = _S_new_RopeConcatenation(__left, __right,
495951a39d68df598db08dfced8b4707755864a0492Ying Wang							      __left->
496951a39d68df598db08dfced8b4707755864a0492Ying Wang							      _M_get_allocator());
497951a39d68df598db08dfced8b4707755864a0492Ying Wang      size_t __depth = __result->_M_depth;
498951a39d68df598db08dfced8b4707755864a0492Ying Wang
499951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (__depth > 20
500951a39d68df598db08dfced8b4707755864a0492Ying Wang	  && (__result->_M_size < 1000
501951a39d68df598db08dfced8b4707755864a0492Ying Wang	      || __depth > size_t(__detail::_S_max_rope_depth)))
502951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
503951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _RopeRep* __balanced;
504951a39d68df598db08dfced8b4707755864a0492Ying Wang
505951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __try
506951a39d68df598db08dfced8b4707755864a0492Ying Wang	    {
507951a39d68df598db08dfced8b4707755864a0492Ying Wang	      __balanced = _S_balance(__result);
508951a39d68df598db08dfced8b4707755864a0492Ying Wang	      __result->_M_unref_nonnil();
509951a39d68df598db08dfced8b4707755864a0492Ying Wang	    }
510951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __catch(...)
511951a39d68df598db08dfced8b4707755864a0492Ying Wang	    {
512951a39d68df598db08dfced8b4707755864a0492Ying Wang	      _C_deallocate(__result,1);
513951a39d68df598db08dfced8b4707755864a0492Ying Wang	      __throw_exception_again;
514951a39d68df598db08dfced8b4707755864a0492Ying Wang	    }
515951a39d68df598db08dfced8b4707755864a0492Ying Wang	  // In case of exception, we need to deallocate
516951a39d68df598db08dfced8b4707755864a0492Ying Wang	  // otherwise dangling result node.  But caller
517951a39d68df598db08dfced8b4707755864a0492Ying Wang	  // still owns its children.  Thus unref is
518951a39d68df598db08dfced8b4707755864a0492Ying Wang	  // inappropriate.
519951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return __balanced;
520951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
521951a39d68df598db08dfced8b4707755864a0492Ying Wang      else
522951a39d68df598db08dfced8b4707755864a0492Ying Wang	return __result;
523951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
524951a39d68df598db08dfced8b4707755864a0492Ying Wang
525951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
526951a39d68df598db08dfced8b4707755864a0492Ying Wang    typename rope<_CharT, _Alloc>::_RopeRep*
527951a39d68df598db08dfced8b4707755864a0492Ying Wang    rope<_CharT, _Alloc>::
528951a39d68df598db08dfced8b4707755864a0492Ying Wang    _S_concat_char_iter(_RopeRep* __r, const _CharT*__s, size_t __slen)
529951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
530951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RopeRep* __result;
531951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (0 == __slen)
532951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
533951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _S_ref(__r);
534951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return __r;
535951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
536951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (0 == __r)
537951a39d68df598db08dfced8b4707755864a0492Ying Wang	return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen,
538951a39d68df598db08dfced8b4707755864a0492Ying Wang						__r->_M_get_allocator());
539951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (__r->_M_tag == __detail::_S_leaf
540951a39d68df598db08dfced8b4707755864a0492Ying Wang	  && __r->_M_size + __slen <= size_t(_S_copy_max))
541951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
542951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __result = _S_leaf_concat_char_iter((_RopeLeaf*)__r, __s, __slen);
543951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return __result;
544951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
545951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (__detail::_S_concat == __r->_M_tag
546951a39d68df598db08dfced8b4707755864a0492Ying Wang	  && __detail::_S_leaf == ((_RopeConcatenation*) __r)->_M_right->_M_tag)
547951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
548951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _RopeLeaf* __right =
549951a39d68df598db08dfced8b4707755864a0492Ying Wang	    (_RopeLeaf* )(((_RopeConcatenation* )__r)->_M_right);
550951a39d68df598db08dfced8b4707755864a0492Ying Wang	  if (__right->_M_size + __slen <= size_t(_S_copy_max))
551951a39d68df598db08dfced8b4707755864a0492Ying Wang	    {
552951a39d68df598db08dfced8b4707755864a0492Ying Wang	      _RopeRep* __left = ((_RopeConcatenation*)__r)->_M_left;
553951a39d68df598db08dfced8b4707755864a0492Ying Wang	      _RopeRep* __nright =
554951a39d68df598db08dfced8b4707755864a0492Ying Wang		_S_leaf_concat_char_iter((_RopeLeaf*)__right, __s, __slen);
555951a39d68df598db08dfced8b4707755864a0492Ying Wang	      __left->_M_ref_nonnil();
556951a39d68df598db08dfced8b4707755864a0492Ying Wang	      __try
557951a39d68df598db08dfced8b4707755864a0492Ying Wang		{ __result = _S_tree_concat(__left, __nright); }
558951a39d68df598db08dfced8b4707755864a0492Ying Wang	      __catch(...)
559951a39d68df598db08dfced8b4707755864a0492Ying Wang		{
560951a39d68df598db08dfced8b4707755864a0492Ying Wang		  _S_unref(__left);
561951a39d68df598db08dfced8b4707755864a0492Ying Wang		  _S_unref(__nright);
562951a39d68df598db08dfced8b4707755864a0492Ying Wang		  __throw_exception_again;
563951a39d68df598db08dfced8b4707755864a0492Ying Wang		}
564951a39d68df598db08dfced8b4707755864a0492Ying Wang	      return __result;
565951a39d68df598db08dfced8b4707755864a0492Ying Wang	    }
566951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
567951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RopeRep* __nright =
568951a39d68df598db08dfced8b4707755864a0492Ying Wang	__STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->_M_get_allocator());
569951a39d68df598db08dfced8b4707755864a0492Ying Wang      __try
570951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
571951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __r->_M_ref_nonnil();
572951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __result = _S_tree_concat(__r, __nright);
573951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
574951a39d68df598db08dfced8b4707755864a0492Ying Wang      __catch(...)
575951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
576951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _S_unref(__r);
577951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _S_unref(__nright);
578951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __throw_exception_again;
579951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
580951a39d68df598db08dfced8b4707755864a0492Ying Wang      return __result;
581951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
582951a39d68df598db08dfced8b4707755864a0492Ying Wang
583951a39d68df598db08dfced8b4707755864a0492Ying Wang#ifndef __GC
584951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
585951a39d68df598db08dfced8b4707755864a0492Ying Wang    typename rope<_CharT,_Alloc>::_RopeRep*
586951a39d68df598db08dfced8b4707755864a0492Ying Wang    rope<_CharT,_Alloc>::
587951a39d68df598db08dfced8b4707755864a0492Ying Wang    _S_destr_concat_char_iter(_RopeRep* __r, const _CharT* __s, size_t __slen)
588951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
589951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RopeRep* __result;
590951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (0 == __r)
591951a39d68df598db08dfced8b4707755864a0492Ying Wang	return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen,
592951a39d68df598db08dfced8b4707755864a0492Ying Wang						__r->_M_get_allocator());
593951a39d68df598db08dfced8b4707755864a0492Ying Wang      size_t __count = __r->_M_ref_count;
594951a39d68df598db08dfced8b4707755864a0492Ying Wang      size_t __orig_size = __r->_M_size;
595951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (__count > 1)
596951a39d68df598db08dfced8b4707755864a0492Ying Wang	return _S_concat_char_iter(__r, __s, __slen);
597951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (0 == __slen)
598951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
599951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __r->_M_ref_count = 2;      // One more than before
600951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return __r;
601951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
602951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (__orig_size + __slen <= size_t(_S_copy_max)
603951a39d68df598db08dfced8b4707755864a0492Ying Wang	  && __detail::_S_leaf == __r->_M_tag)
604951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
605951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __result = _S_destr_leaf_concat_char_iter((_RopeLeaf*)__r, __s,
606951a39d68df598db08dfced8b4707755864a0492Ying Wang						    __slen);
607951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return __result;
608951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
609951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (__detail::_S_concat == __r->_M_tag)
610951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
611951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _RopeLeaf* __right = (_RopeLeaf*)(((_RopeConcatenation*)
612951a39d68df598db08dfced8b4707755864a0492Ying Wang					     __r)->_M_right);
613951a39d68df598db08dfced8b4707755864a0492Ying Wang	  if (__detail::_S_leaf == __right->_M_tag
614951a39d68df598db08dfced8b4707755864a0492Ying Wang	      && __right->_M_size + __slen <= size_t(_S_copy_max))
615951a39d68df598db08dfced8b4707755864a0492Ying Wang	    {
616951a39d68df598db08dfced8b4707755864a0492Ying Wang	      _RopeRep* __new_right =
617951a39d68df598db08dfced8b4707755864a0492Ying Wang		_S_destr_leaf_concat_char_iter(__right, __s, __slen);
618951a39d68df598db08dfced8b4707755864a0492Ying Wang	      if (__right == __new_right)
619951a39d68df598db08dfced8b4707755864a0492Ying Wang		__new_right->_M_ref_count = 1;
620951a39d68df598db08dfced8b4707755864a0492Ying Wang	      else
621951a39d68df598db08dfced8b4707755864a0492Ying Wang		__right->_M_unref_nonnil();
622951a39d68df598db08dfced8b4707755864a0492Ying Wang	      __r->_M_ref_count = 2;    // One more than before.
623951a39d68df598db08dfced8b4707755864a0492Ying Wang	      ((_RopeConcatenation*)__r)->_M_right = __new_right;
624951a39d68df598db08dfced8b4707755864a0492Ying Wang	      __r->_M_size = __orig_size + __slen;
625951a39d68df598db08dfced8b4707755864a0492Ying Wang	      if (0 != __r->_M_c_string)
626951a39d68df598db08dfced8b4707755864a0492Ying Wang		{
627951a39d68df598db08dfced8b4707755864a0492Ying Wang		  __r->_M_free_c_string();
628951a39d68df598db08dfced8b4707755864a0492Ying Wang		  __r->_M_c_string = 0;
629951a39d68df598db08dfced8b4707755864a0492Ying Wang		}
630951a39d68df598db08dfced8b4707755864a0492Ying Wang	      return __r;
631951a39d68df598db08dfced8b4707755864a0492Ying Wang	    }
632951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
633951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RopeRep* __right =
634951a39d68df598db08dfced8b4707755864a0492Ying Wang	__STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->_M_get_allocator());
635951a39d68df598db08dfced8b4707755864a0492Ying Wang      __r->_M_ref_nonnil();
636951a39d68df598db08dfced8b4707755864a0492Ying Wang      __try
637951a39d68df598db08dfced8b4707755864a0492Ying Wang	{ __result = _S_tree_concat(__r, __right); }
638951a39d68df598db08dfced8b4707755864a0492Ying Wang      __catch(...)
639951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
640951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _S_unref(__r);
641951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _S_unref(__right);
642951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __throw_exception_again;
643951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
644951a39d68df598db08dfced8b4707755864a0492Ying Wang      return __result;
645951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
646951a39d68df598db08dfced8b4707755864a0492Ying Wang#endif /* !__GC */
647951a39d68df598db08dfced8b4707755864a0492Ying Wang
648951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
649951a39d68df598db08dfced8b4707755864a0492Ying Wang    typename rope<_CharT, _Alloc>::_RopeRep*
650951a39d68df598db08dfced8b4707755864a0492Ying Wang    rope<_CharT, _Alloc>::
651951a39d68df598db08dfced8b4707755864a0492Ying Wang    _S_concat(_RopeRep* __left, _RopeRep* __right)
652951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
653951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (0 == __left)
654951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
655951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _S_ref(__right);
656951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return __right;
657951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
658951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (0 == __right)
659951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
660951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __left->_M_ref_nonnil();
661951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return __left;
662951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
663951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (__detail::_S_leaf == __right->_M_tag)
664951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
665951a39d68df598db08dfced8b4707755864a0492Ying Wang	  if (__detail::_S_leaf == __left->_M_tag)
666951a39d68df598db08dfced8b4707755864a0492Ying Wang	    {
667951a39d68df598db08dfced8b4707755864a0492Ying Wang	      if (__right->_M_size + __left->_M_size <= size_t(_S_copy_max))
668951a39d68df598db08dfced8b4707755864a0492Ying Wang		return _S_leaf_concat_char_iter((_RopeLeaf*)__left,
669951a39d68df598db08dfced8b4707755864a0492Ying Wang						((_RopeLeaf*)__right)->_M_data,
670951a39d68df598db08dfced8b4707755864a0492Ying Wang						__right->_M_size);
671951a39d68df598db08dfced8b4707755864a0492Ying Wang	    }
672951a39d68df598db08dfced8b4707755864a0492Ying Wang	  else if (__detail::_S_concat == __left->_M_tag
673951a39d68df598db08dfced8b4707755864a0492Ying Wang		   && __detail::_S_leaf == ((_RopeConcatenation*)
674951a39d68df598db08dfced8b4707755864a0492Ying Wang						   __left)->_M_right->_M_tag)
675951a39d68df598db08dfced8b4707755864a0492Ying Wang	    {
676951a39d68df598db08dfced8b4707755864a0492Ying Wang	      _RopeLeaf* __leftright =
677951a39d68df598db08dfced8b4707755864a0492Ying Wang		(_RopeLeaf*)(((_RopeConcatenation*)__left)->_M_right);
678951a39d68df598db08dfced8b4707755864a0492Ying Wang	      if (__leftright->_M_size
679951a39d68df598db08dfced8b4707755864a0492Ying Wang		  + __right->_M_size <= size_t(_S_copy_max))
680951a39d68df598db08dfced8b4707755864a0492Ying Wang		{
681951a39d68df598db08dfced8b4707755864a0492Ying Wang		  _RopeRep* __leftleft = ((_RopeConcatenation*)__left)->_M_left;
682951a39d68df598db08dfced8b4707755864a0492Ying Wang		  _RopeRep* __rest = _S_leaf_concat_char_iter(__leftright,
683951a39d68df598db08dfced8b4707755864a0492Ying Wang							      ((_RopeLeaf*)
684951a39d68df598db08dfced8b4707755864a0492Ying Wang							       __right)->
685951a39d68df598db08dfced8b4707755864a0492Ying Wang							      _M_data,
686951a39d68df598db08dfced8b4707755864a0492Ying Wang							      __right->_M_size);
687951a39d68df598db08dfced8b4707755864a0492Ying Wang		  __leftleft->_M_ref_nonnil();
688951a39d68df598db08dfced8b4707755864a0492Ying Wang		  __try
689951a39d68df598db08dfced8b4707755864a0492Ying Wang		    { return(_S_tree_concat(__leftleft, __rest)); }
690951a39d68df598db08dfced8b4707755864a0492Ying Wang		  __catch(...)
691951a39d68df598db08dfced8b4707755864a0492Ying Wang		    {
692951a39d68df598db08dfced8b4707755864a0492Ying Wang		      _S_unref(__leftleft);
693951a39d68df598db08dfced8b4707755864a0492Ying Wang		      _S_unref(__rest);
694951a39d68df598db08dfced8b4707755864a0492Ying Wang		      __throw_exception_again;
695951a39d68df598db08dfced8b4707755864a0492Ying Wang		    }
696951a39d68df598db08dfced8b4707755864a0492Ying Wang		}
697951a39d68df598db08dfced8b4707755864a0492Ying Wang	    }
698951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
699951a39d68df598db08dfced8b4707755864a0492Ying Wang      __left->_M_ref_nonnil();
700951a39d68df598db08dfced8b4707755864a0492Ying Wang      __right->_M_ref_nonnil();
701951a39d68df598db08dfced8b4707755864a0492Ying Wang      __try
702951a39d68df598db08dfced8b4707755864a0492Ying Wang	{ return(_S_tree_concat(__left, __right)); }
703951a39d68df598db08dfced8b4707755864a0492Ying Wang      __catch(...)
704951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
705951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _S_unref(__left);
706951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _S_unref(__right);
707951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __throw_exception_again;
708951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
709951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
710951a39d68df598db08dfced8b4707755864a0492Ying Wang
711951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
712951a39d68df598db08dfced8b4707755864a0492Ying Wang    typename rope<_CharT, _Alloc>::_RopeRep*
713951a39d68df598db08dfced8b4707755864a0492Ying Wang    rope<_CharT, _Alloc>::
714951a39d68df598db08dfced8b4707755864a0492Ying Wang    _S_substring(_RopeRep* __base, size_t __start, size_t __endp1)
715951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
716951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (0 == __base)
717951a39d68df598db08dfced8b4707755864a0492Ying Wang	return 0;
718951a39d68df598db08dfced8b4707755864a0492Ying Wang      size_t __len = __base->_M_size;
719951a39d68df598db08dfced8b4707755864a0492Ying Wang      size_t __adj_endp1;
720951a39d68df598db08dfced8b4707755864a0492Ying Wang      const size_t __lazy_threshold = 128;
721951a39d68df598db08dfced8b4707755864a0492Ying Wang
722951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (__endp1 >= __len)
723951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
724951a39d68df598db08dfced8b4707755864a0492Ying Wang	  if (0 == __start)
725951a39d68df598db08dfced8b4707755864a0492Ying Wang	    {
726951a39d68df598db08dfced8b4707755864a0492Ying Wang	      __base->_M_ref_nonnil();
727951a39d68df598db08dfced8b4707755864a0492Ying Wang	      return __base;
728951a39d68df598db08dfced8b4707755864a0492Ying Wang	    }
729951a39d68df598db08dfced8b4707755864a0492Ying Wang	  else
730951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __adj_endp1 = __len;
731951a39d68df598db08dfced8b4707755864a0492Ying Wang
732951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
733951a39d68df598db08dfced8b4707755864a0492Ying Wang      else
734951a39d68df598db08dfced8b4707755864a0492Ying Wang	__adj_endp1 = __endp1;
735951a39d68df598db08dfced8b4707755864a0492Ying Wang
736951a39d68df598db08dfced8b4707755864a0492Ying Wang      switch(__base->_M_tag)
737951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
738951a39d68df598db08dfced8b4707755864a0492Ying Wang	case __detail::_S_concat:
739951a39d68df598db08dfced8b4707755864a0492Ying Wang	    {
740951a39d68df598db08dfced8b4707755864a0492Ying Wang	      _RopeConcatenation* __c = (_RopeConcatenation*)__base;
741951a39d68df598db08dfced8b4707755864a0492Ying Wang	      _RopeRep* __left = __c->_M_left;
742951a39d68df598db08dfced8b4707755864a0492Ying Wang	      _RopeRep* __right = __c->_M_right;
743951a39d68df598db08dfced8b4707755864a0492Ying Wang	      size_t __left_len = __left->_M_size;
744951a39d68df598db08dfced8b4707755864a0492Ying Wang	      _RopeRep* __result;
745951a39d68df598db08dfced8b4707755864a0492Ying Wang
746951a39d68df598db08dfced8b4707755864a0492Ying Wang	      if (__adj_endp1 <= __left_len)
747951a39d68df598db08dfced8b4707755864a0492Ying Wang		return _S_substring(__left, __start, __endp1);
748951a39d68df598db08dfced8b4707755864a0492Ying Wang	      else if (__start >= __left_len)
749951a39d68df598db08dfced8b4707755864a0492Ying Wang		return _S_substring(__right, __start - __left_len,
750951a39d68df598db08dfced8b4707755864a0492Ying Wang				    __adj_endp1 - __left_len);
751951a39d68df598db08dfced8b4707755864a0492Ying Wang	      _Self_destruct_ptr __left_result(_S_substring(__left,
752951a39d68df598db08dfced8b4707755864a0492Ying Wang							    __start,
753951a39d68df598db08dfced8b4707755864a0492Ying Wang							    __left_len));
754951a39d68df598db08dfced8b4707755864a0492Ying Wang	      _Self_destruct_ptr __right_result(_S_substring(__right, 0,
755951a39d68df598db08dfced8b4707755864a0492Ying Wang							     __endp1
756951a39d68df598db08dfced8b4707755864a0492Ying Wang							     - __left_len));
757951a39d68df598db08dfced8b4707755864a0492Ying Wang	      __result = _S_concat(__left_result, __right_result);
758951a39d68df598db08dfced8b4707755864a0492Ying Wang	      return __result;
759951a39d68df598db08dfced8b4707755864a0492Ying Wang	    }
760951a39d68df598db08dfced8b4707755864a0492Ying Wang	case __detail::_S_leaf:
761951a39d68df598db08dfced8b4707755864a0492Ying Wang	  {
762951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _RopeLeaf* __l = (_RopeLeaf*)__base;
763951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _RopeLeaf* __result;
764951a39d68df598db08dfced8b4707755864a0492Ying Wang	    size_t __result_len;
765951a39d68df598db08dfced8b4707755864a0492Ying Wang	    if (__start >= __adj_endp1)
766951a39d68df598db08dfced8b4707755864a0492Ying Wang	      return 0;
767951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __result_len = __adj_endp1 - __start;
768951a39d68df598db08dfced8b4707755864a0492Ying Wang	    if (__result_len > __lazy_threshold)
769951a39d68df598db08dfced8b4707755864a0492Ying Wang	      goto lazy;
770951a39d68df598db08dfced8b4707755864a0492Ying Wang#ifdef __GC
771951a39d68df598db08dfced8b4707755864a0492Ying Wang	    const _CharT* __section = __l->_M_data + __start;
772951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __result = _S_new_RopeLeaf(__section, __result_len,
773951a39d68df598db08dfced8b4707755864a0492Ying Wang				       __base->_M_get_allocator());
774951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __result->_M_c_string = 0;  // Not eos terminated.
775951a39d68df598db08dfced8b4707755864a0492Ying Wang#else
776951a39d68df598db08dfced8b4707755864a0492Ying Wang	    // We should sometimes create substring node instead.
777951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __result = __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__l->_M_data + __start,
778951a39d68df598db08dfced8b4707755864a0492Ying Wang							__result_len,
779951a39d68df598db08dfced8b4707755864a0492Ying Wang							__base->
780951a39d68df598db08dfced8b4707755864a0492Ying Wang							_M_get_allocator());
781951a39d68df598db08dfced8b4707755864a0492Ying Wang#endif
782951a39d68df598db08dfced8b4707755864a0492Ying Wang	    return __result;
783951a39d68df598db08dfced8b4707755864a0492Ying Wang	  }
784951a39d68df598db08dfced8b4707755864a0492Ying Wang	case __detail::_S_substringfn:
785951a39d68df598db08dfced8b4707755864a0492Ying Wang	  // Avoid introducing multiple layers of substring nodes.
786951a39d68df598db08dfced8b4707755864a0492Ying Wang	  {
787951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _RopeSubstring* __old = (_RopeSubstring*)__base;
788951a39d68df598db08dfced8b4707755864a0492Ying Wang	    size_t __result_len;
789951a39d68df598db08dfced8b4707755864a0492Ying Wang	    if (__start >= __adj_endp1)
790951a39d68df598db08dfced8b4707755864a0492Ying Wang	      return 0;
791951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __result_len = __adj_endp1 - __start;
792951a39d68df598db08dfced8b4707755864a0492Ying Wang	    if (__result_len > __lazy_threshold)
793951a39d68df598db08dfced8b4707755864a0492Ying Wang	      {
794951a39d68df598db08dfced8b4707755864a0492Ying Wang		_RopeSubstring* __result =
795951a39d68df598db08dfced8b4707755864a0492Ying Wang		  _S_new_RopeSubstring(__old->_M_base,
796951a39d68df598db08dfced8b4707755864a0492Ying Wang				       __start + __old->_M_start,
797951a39d68df598db08dfced8b4707755864a0492Ying Wang				       __adj_endp1 - __start,
798951a39d68df598db08dfced8b4707755864a0492Ying Wang				       __base->_M_get_allocator());
799951a39d68df598db08dfced8b4707755864a0492Ying Wang		return __result;
800951a39d68df598db08dfced8b4707755864a0492Ying Wang
801951a39d68df598db08dfced8b4707755864a0492Ying Wang	      } // *** else fall through: ***
802951a39d68df598db08dfced8b4707755864a0492Ying Wang	  }
803951a39d68df598db08dfced8b4707755864a0492Ying Wang	case __detail::_S_function:
804951a39d68df598db08dfced8b4707755864a0492Ying Wang	  {
805951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _RopeFunction* __f = (_RopeFunction*)__base;
806951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _CharT* __section;
807951a39d68df598db08dfced8b4707755864a0492Ying Wang	    size_t __result_len;
808951a39d68df598db08dfced8b4707755864a0492Ying Wang	    if (__start >= __adj_endp1)
809951a39d68df598db08dfced8b4707755864a0492Ying Wang	      return 0;
810951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __result_len = __adj_endp1 - __start;
811951a39d68df598db08dfced8b4707755864a0492Ying Wang
812951a39d68df598db08dfced8b4707755864a0492Ying Wang	    if (__result_len > __lazy_threshold)
813951a39d68df598db08dfced8b4707755864a0492Ying Wang	      goto lazy;
814951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __section = (_CharT*)
815951a39d68df598db08dfced8b4707755864a0492Ying Wang	      _Data_allocate(_S_rounded_up_size(__result_len));
816951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __try
817951a39d68df598db08dfced8b4707755864a0492Ying Wang	      {	(*(__f->_M_fn))(__start, __result_len, __section); }
818951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __catch(...)
819951a39d68df598db08dfced8b4707755864a0492Ying Wang	      {
820951a39d68df598db08dfced8b4707755864a0492Ying Wang		_RopeRep::__STL_FREE_STRING(__section, __result_len,
821951a39d68df598db08dfced8b4707755864a0492Ying Wang					    __base->_M_get_allocator());
822951a39d68df598db08dfced8b4707755864a0492Ying Wang		__throw_exception_again;
823951a39d68df598db08dfced8b4707755864a0492Ying Wang	      }
824951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _S_cond_store_eos(__section[__result_len]);
825951a39d68df598db08dfced8b4707755864a0492Ying Wang	    return _S_new_RopeLeaf(__section, __result_len,
826951a39d68df598db08dfced8b4707755864a0492Ying Wang				   __base->_M_get_allocator());
827951a39d68df598db08dfced8b4707755864a0492Ying Wang	  }
828951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
829951a39d68df598db08dfced8b4707755864a0492Ying Wang    lazy:
830951a39d68df598db08dfced8b4707755864a0492Ying Wang      {
831951a39d68df598db08dfced8b4707755864a0492Ying Wang	// Create substring node.
832951a39d68df598db08dfced8b4707755864a0492Ying Wang	return _S_new_RopeSubstring(__base, __start, __adj_endp1 - __start,
833951a39d68df598db08dfced8b4707755864a0492Ying Wang				    __base->_M_get_allocator());
834951a39d68df598db08dfced8b4707755864a0492Ying Wang      }
835951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
836951a39d68df598db08dfced8b4707755864a0492Ying Wang
837951a39d68df598db08dfced8b4707755864a0492Ying Wang  template<class _CharT>
838951a39d68df598db08dfced8b4707755864a0492Ying Wang    class _Rope_flatten_char_consumer
839951a39d68df598db08dfced8b4707755864a0492Ying Wang    : public _Rope_char_consumer<_CharT>
840951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
841951a39d68df598db08dfced8b4707755864a0492Ying Wang    private:
842951a39d68df598db08dfced8b4707755864a0492Ying Wang      _CharT* _M_buf_ptr;
843951a39d68df598db08dfced8b4707755864a0492Ying Wang    public:
844951a39d68df598db08dfced8b4707755864a0492Ying Wang
845951a39d68df598db08dfced8b4707755864a0492Ying Wang      _Rope_flatten_char_consumer(_CharT* __buffer)
846951a39d68df598db08dfced8b4707755864a0492Ying Wang      { _M_buf_ptr = __buffer; };
847951a39d68df598db08dfced8b4707755864a0492Ying Wang
848951a39d68df598db08dfced8b4707755864a0492Ying Wang      ~_Rope_flatten_char_consumer() {}
849951a39d68df598db08dfced8b4707755864a0492Ying Wang
850951a39d68df598db08dfced8b4707755864a0492Ying Wang      bool
851951a39d68df598db08dfced8b4707755864a0492Ying Wang      operator()(const _CharT* __leaf, size_t __n)
852951a39d68df598db08dfced8b4707755864a0492Ying Wang      {
853951a39d68df598db08dfced8b4707755864a0492Ying Wang	uninitialized_copy_n(__leaf, __n, _M_buf_ptr);
854951a39d68df598db08dfced8b4707755864a0492Ying Wang	_M_buf_ptr += __n;
855951a39d68df598db08dfced8b4707755864a0492Ying Wang	return true;
856951a39d68df598db08dfced8b4707755864a0492Ying Wang      }
857951a39d68df598db08dfced8b4707755864a0492Ying Wang    };
858951a39d68df598db08dfced8b4707755864a0492Ying Wang
859951a39d68df598db08dfced8b4707755864a0492Ying Wang  template<class _CharT>
860951a39d68df598db08dfced8b4707755864a0492Ying Wang    class _Rope_find_char_char_consumer
861951a39d68df598db08dfced8b4707755864a0492Ying Wang    : public _Rope_char_consumer<_CharT>
862951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
863951a39d68df598db08dfced8b4707755864a0492Ying Wang    private:
864951a39d68df598db08dfced8b4707755864a0492Ying Wang      _CharT _M_pattern;
865951a39d68df598db08dfced8b4707755864a0492Ying Wang    public:
866951a39d68df598db08dfced8b4707755864a0492Ying Wang      size_t _M_count;  // Number of nonmatching characters
867951a39d68df598db08dfced8b4707755864a0492Ying Wang
868951a39d68df598db08dfced8b4707755864a0492Ying Wang      _Rope_find_char_char_consumer(_CharT __p)
869951a39d68df598db08dfced8b4707755864a0492Ying Wang      : _M_pattern(__p), _M_count(0) {}
870951a39d68df598db08dfced8b4707755864a0492Ying Wang
871951a39d68df598db08dfced8b4707755864a0492Ying Wang      ~_Rope_find_char_char_consumer() {}
872951a39d68df598db08dfced8b4707755864a0492Ying Wang
873951a39d68df598db08dfced8b4707755864a0492Ying Wang      bool
874951a39d68df598db08dfced8b4707755864a0492Ying Wang      operator()(const _CharT* __leaf, size_t __n)
875951a39d68df598db08dfced8b4707755864a0492Ying Wang      {
876951a39d68df598db08dfced8b4707755864a0492Ying Wang	size_t __i;
877951a39d68df598db08dfced8b4707755864a0492Ying Wang	for (__i = 0; __i < __n; __i++)
878951a39d68df598db08dfced8b4707755864a0492Ying Wang	  {
879951a39d68df598db08dfced8b4707755864a0492Ying Wang	    if (__leaf[__i] == _M_pattern)
880951a39d68df598db08dfced8b4707755864a0492Ying Wang	      {
881951a39d68df598db08dfced8b4707755864a0492Ying Wang		_M_count += __i;
882951a39d68df598db08dfced8b4707755864a0492Ying Wang		return false;
883951a39d68df598db08dfced8b4707755864a0492Ying Wang	      }
884951a39d68df598db08dfced8b4707755864a0492Ying Wang	  }
885951a39d68df598db08dfced8b4707755864a0492Ying Wang	_M_count += __n; return true;
886951a39d68df598db08dfced8b4707755864a0492Ying Wang      }
887951a39d68df598db08dfced8b4707755864a0492Ying Wang    };
888951a39d68df598db08dfced8b4707755864a0492Ying Wang
889951a39d68df598db08dfced8b4707755864a0492Ying Wang  template<class _CharT, class _Traits>
890951a39d68df598db08dfced8b4707755864a0492Ying Wang  // Here _CharT is both the stream and rope character type.
891951a39d68df598db08dfced8b4707755864a0492Ying Wang    class _Rope_insert_char_consumer
892951a39d68df598db08dfced8b4707755864a0492Ying Wang    : public _Rope_char_consumer<_CharT>
893951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
894951a39d68df598db08dfced8b4707755864a0492Ying Wang    private:
895951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef basic_ostream<_CharT,_Traits> _Insert_ostream;
896951a39d68df598db08dfced8b4707755864a0492Ying Wang      _Insert_ostream& _M_o;
897951a39d68df598db08dfced8b4707755864a0492Ying Wang    public:
898951a39d68df598db08dfced8b4707755864a0492Ying Wang      _Rope_insert_char_consumer(_Insert_ostream& __writer)
899951a39d68df598db08dfced8b4707755864a0492Ying Wang	: _M_o(__writer) {};
900951a39d68df598db08dfced8b4707755864a0492Ying Wang      ~_Rope_insert_char_consumer() { };
901951a39d68df598db08dfced8b4707755864a0492Ying Wang      // Caller is presumed to own the ostream
902951a39d68df598db08dfced8b4707755864a0492Ying Wang      bool operator() (const _CharT* __leaf, size_t __n);
903951a39d68df598db08dfced8b4707755864a0492Ying Wang      // Returns true to continue traversal.
904951a39d68df598db08dfced8b4707755864a0492Ying Wang    };
905951a39d68df598db08dfced8b4707755864a0492Ying Wang
906951a39d68df598db08dfced8b4707755864a0492Ying Wang  template<class _CharT, class _Traits>
907951a39d68df598db08dfced8b4707755864a0492Ying Wang    bool
908951a39d68df598db08dfced8b4707755864a0492Ying Wang    _Rope_insert_char_consumer<_CharT, _Traits>::
909951a39d68df598db08dfced8b4707755864a0492Ying Wang    operator()(const _CharT* __leaf, size_t __n)
910951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
911951a39d68df598db08dfced8b4707755864a0492Ying Wang      size_t __i;
912951a39d68df598db08dfced8b4707755864a0492Ying Wang      //  We assume that formatting is set up correctly for each element.
913951a39d68df598db08dfced8b4707755864a0492Ying Wang      for (__i = 0; __i < __n; __i++)
914951a39d68df598db08dfced8b4707755864a0492Ying Wang	_M_o.put(__leaf[__i]);
915951a39d68df598db08dfced8b4707755864a0492Ying Wang      return true;
916951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
917951a39d68df598db08dfced8b4707755864a0492Ying Wang
918951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
919951a39d68df598db08dfced8b4707755864a0492Ying Wang    bool
920951a39d68df598db08dfced8b4707755864a0492Ying Wang    rope<_CharT, _Alloc>::
921951a39d68df598db08dfced8b4707755864a0492Ying Wang    _S_apply_to_pieces(_Rope_char_consumer<_CharT>& __c,
922951a39d68df598db08dfced8b4707755864a0492Ying Wang		       const _RopeRep* __r, size_t __begin, size_t __end)
923951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
924951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (0 == __r)
925951a39d68df598db08dfced8b4707755864a0492Ying Wang	return true;
926951a39d68df598db08dfced8b4707755864a0492Ying Wang      switch(__r->_M_tag)
927951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
928951a39d68df598db08dfced8b4707755864a0492Ying Wang	case __detail::_S_concat:
929951a39d68df598db08dfced8b4707755864a0492Ying Wang	  {
930951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _RopeConcatenation* __conc = (_RopeConcatenation*)__r;
931951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _RopeRep* __left =  __conc->_M_left;
932951a39d68df598db08dfced8b4707755864a0492Ying Wang	    size_t __left_len = __left->_M_size;
933951a39d68df598db08dfced8b4707755864a0492Ying Wang	    if (__begin < __left_len)
934951a39d68df598db08dfced8b4707755864a0492Ying Wang	      {
935951a39d68df598db08dfced8b4707755864a0492Ying Wang		size_t __left_end = std::min(__left_len, __end);
936951a39d68df598db08dfced8b4707755864a0492Ying Wang		if (!_S_apply_to_pieces(__c, __left, __begin, __left_end))
937951a39d68df598db08dfced8b4707755864a0492Ying Wang		  return false;
938951a39d68df598db08dfced8b4707755864a0492Ying Wang	      }
939951a39d68df598db08dfced8b4707755864a0492Ying Wang	    if (__end > __left_len)
940951a39d68df598db08dfced8b4707755864a0492Ying Wang	      {
941951a39d68df598db08dfced8b4707755864a0492Ying Wang		_RopeRep* __right =  __conc->_M_right;
942951a39d68df598db08dfced8b4707755864a0492Ying Wang		size_t __right_start = std::max(__left_len, __begin);
943951a39d68df598db08dfced8b4707755864a0492Ying Wang		if (!_S_apply_to_pieces(__c, __right,
944951a39d68df598db08dfced8b4707755864a0492Ying Wang					__right_start - __left_len,
945951a39d68df598db08dfced8b4707755864a0492Ying Wang					__end - __left_len))
946951a39d68df598db08dfced8b4707755864a0492Ying Wang		  return false;
947951a39d68df598db08dfced8b4707755864a0492Ying Wang	      }
948951a39d68df598db08dfced8b4707755864a0492Ying Wang	  }
949951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return true;
950951a39d68df598db08dfced8b4707755864a0492Ying Wang	case __detail::_S_leaf:
951951a39d68df598db08dfced8b4707755864a0492Ying Wang	  {
952951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _RopeLeaf* __l = (_RopeLeaf*)__r;
953951a39d68df598db08dfced8b4707755864a0492Ying Wang	    return __c(__l->_M_data + __begin, __end - __begin);
954951a39d68df598db08dfced8b4707755864a0492Ying Wang	  }
955951a39d68df598db08dfced8b4707755864a0492Ying Wang	case __detail::_S_function:
956951a39d68df598db08dfced8b4707755864a0492Ying Wang	case __detail::_S_substringfn:
957951a39d68df598db08dfced8b4707755864a0492Ying Wang	    {
958951a39d68df598db08dfced8b4707755864a0492Ying Wang	      _RopeFunction* __f = (_RopeFunction*)__r;
959951a39d68df598db08dfced8b4707755864a0492Ying Wang	      size_t __len = __end - __begin;
960951a39d68df598db08dfced8b4707755864a0492Ying Wang	      bool __result;
961951a39d68df598db08dfced8b4707755864a0492Ying Wang	      _CharT* __buffer =
962951a39d68df598db08dfced8b4707755864a0492Ying Wang		(_CharT*)_Alloc().allocate(__len * sizeof(_CharT));
963951a39d68df598db08dfced8b4707755864a0492Ying Wang	      __try
964951a39d68df598db08dfced8b4707755864a0492Ying Wang		{
965951a39d68df598db08dfced8b4707755864a0492Ying Wang		  (*(__f->_M_fn))(__begin, __len, __buffer);
966951a39d68df598db08dfced8b4707755864a0492Ying Wang		  __result = __c(__buffer, __len);
967951a39d68df598db08dfced8b4707755864a0492Ying Wang                  _Alloc().deallocate(__buffer, __len * sizeof(_CharT));
968951a39d68df598db08dfced8b4707755864a0492Ying Wang                }
969951a39d68df598db08dfced8b4707755864a0492Ying Wang	      __catch(...)
970951a39d68df598db08dfced8b4707755864a0492Ying Wang		{
971951a39d68df598db08dfced8b4707755864a0492Ying Wang		  _Alloc().deallocate(__buffer, __len * sizeof(_CharT));
972951a39d68df598db08dfced8b4707755864a0492Ying Wang		  __throw_exception_again;
973951a39d68df598db08dfced8b4707755864a0492Ying Wang		}
974951a39d68df598db08dfced8b4707755864a0492Ying Wang	      return __result;
975951a39d68df598db08dfced8b4707755864a0492Ying Wang	    }
976951a39d68df598db08dfced8b4707755864a0492Ying Wang	default:
977951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return false;
978951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
979951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
980951a39d68df598db08dfced8b4707755864a0492Ying Wang
981951a39d68df598db08dfced8b4707755864a0492Ying Wang  template<class _CharT, class _Traits>
982951a39d68df598db08dfced8b4707755864a0492Ying Wang    inline void
983951a39d68df598db08dfced8b4707755864a0492Ying Wang    _Rope_fill(basic_ostream<_CharT, _Traits>& __o, size_t __n)
984951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
985951a39d68df598db08dfced8b4707755864a0492Ying Wang      char __f = __o.fill();
986951a39d68df598db08dfced8b4707755864a0492Ying Wang      size_t __i;
987951a39d68df598db08dfced8b4707755864a0492Ying Wang
988951a39d68df598db08dfced8b4707755864a0492Ying Wang      for (__i = 0; __i < __n; __i++)
989951a39d68df598db08dfced8b4707755864a0492Ying Wang	__o.put(__f);
990951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
991951a39d68df598db08dfced8b4707755864a0492Ying Wang
992951a39d68df598db08dfced8b4707755864a0492Ying Wang
993951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT>
994951a39d68df598db08dfced8b4707755864a0492Ying Wang    inline bool
995951a39d68df598db08dfced8b4707755864a0492Ying Wang    _Rope_is_simple(_CharT*)
996951a39d68df598db08dfced8b4707755864a0492Ying Wang    { return false; }
997951a39d68df598db08dfced8b4707755864a0492Ying Wang
998951a39d68df598db08dfced8b4707755864a0492Ying Wang  inline bool
999951a39d68df598db08dfced8b4707755864a0492Ying Wang  _Rope_is_simple(char*)
1000951a39d68df598db08dfced8b4707755864a0492Ying Wang  { return true; }
1001951a39d68df598db08dfced8b4707755864a0492Ying Wang
1002951a39d68df598db08dfced8b4707755864a0492Ying Wang  inline bool
1003951a39d68df598db08dfced8b4707755864a0492Ying Wang  _Rope_is_simple(wchar_t*)
1004951a39d68df598db08dfced8b4707755864a0492Ying Wang  { return true; }
1005951a39d68df598db08dfced8b4707755864a0492Ying Wang
1006951a39d68df598db08dfced8b4707755864a0492Ying Wang  template<class _CharT, class _Traits, class _Alloc>
1007951a39d68df598db08dfced8b4707755864a0492Ying Wang    basic_ostream<_CharT, _Traits>&
1008951a39d68df598db08dfced8b4707755864a0492Ying Wang    operator<<(basic_ostream<_CharT, _Traits>& __o,
1009951a39d68df598db08dfced8b4707755864a0492Ying Wang	       const rope<_CharT, _Alloc>& __r)
1010951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
1011951a39d68df598db08dfced8b4707755864a0492Ying Wang      size_t __w = __o.width();
1012951a39d68df598db08dfced8b4707755864a0492Ying Wang      bool __left = bool(__o.flags() & std::ios::left);
1013951a39d68df598db08dfced8b4707755864a0492Ying Wang      size_t __pad_len;
1014951a39d68df598db08dfced8b4707755864a0492Ying Wang      size_t __rope_len = __r.size();
1015951a39d68df598db08dfced8b4707755864a0492Ying Wang      _Rope_insert_char_consumer<_CharT, _Traits> __c(__o);
1016951a39d68df598db08dfced8b4707755864a0492Ying Wang      bool __is_simple = _Rope_is_simple((_CharT*)0);
1017951a39d68df598db08dfced8b4707755864a0492Ying Wang
1018951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (__rope_len < __w)
1019951a39d68df598db08dfced8b4707755864a0492Ying Wang	__pad_len = __w - __rope_len;
1020951a39d68df598db08dfced8b4707755864a0492Ying Wang      else
1021951a39d68df598db08dfced8b4707755864a0492Ying Wang	__pad_len = 0;
1022951a39d68df598db08dfced8b4707755864a0492Ying Wang
1023951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (!__is_simple)
1024951a39d68df598db08dfced8b4707755864a0492Ying Wang	__o.width(__w / __rope_len);
1025951a39d68df598db08dfced8b4707755864a0492Ying Wang      __try
1026951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
1027951a39d68df598db08dfced8b4707755864a0492Ying Wang	  if (__is_simple && !__left && __pad_len > 0)
1028951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _Rope_fill(__o, __pad_len);
1029951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __r.apply_to_pieces(0, __r.size(), __c);
1030951a39d68df598db08dfced8b4707755864a0492Ying Wang	  if (__is_simple && __left && __pad_len > 0)
1031951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _Rope_fill(__o, __pad_len);
1032951a39d68df598db08dfced8b4707755864a0492Ying Wang	  if (!__is_simple)
1033951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __o.width(__w);
1034951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
1035951a39d68df598db08dfced8b4707755864a0492Ying Wang      __catch(...)
1036951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
1037951a39d68df598db08dfced8b4707755864a0492Ying Wang	  if (!__is_simple)
1038951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __o.width(__w);
1039951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __throw_exception_again;
1040951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
1041951a39d68df598db08dfced8b4707755864a0492Ying Wang      return __o;
1042951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
1043951a39d68df598db08dfced8b4707755864a0492Ying Wang
1044951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
1045951a39d68df598db08dfced8b4707755864a0492Ying Wang    _CharT*
1046951a39d68df598db08dfced8b4707755864a0492Ying Wang    rope<_CharT, _Alloc>::
1047951a39d68df598db08dfced8b4707755864a0492Ying Wang    _S_flatten(_RopeRep* __r, size_t __start, size_t __len,
1048951a39d68df598db08dfced8b4707755864a0492Ying Wang	       _CharT* __buffer)
1049951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
1050951a39d68df598db08dfced8b4707755864a0492Ying Wang      _Rope_flatten_char_consumer<_CharT> __c(__buffer);
1051951a39d68df598db08dfced8b4707755864a0492Ying Wang      _S_apply_to_pieces(__c, __r, __start, __start + __len);
1052951a39d68df598db08dfced8b4707755864a0492Ying Wang      return(__buffer + __len);
1053951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
1054951a39d68df598db08dfced8b4707755864a0492Ying Wang
1055951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
1056951a39d68df598db08dfced8b4707755864a0492Ying Wang    size_t
1057951a39d68df598db08dfced8b4707755864a0492Ying Wang    rope<_CharT, _Alloc>::
1058951a39d68df598db08dfced8b4707755864a0492Ying Wang    find(_CharT __pattern, size_t __start) const
1059951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
1060951a39d68df598db08dfced8b4707755864a0492Ying Wang      _Rope_find_char_char_consumer<_CharT> __c(__pattern);
1061951a39d68df598db08dfced8b4707755864a0492Ying Wang      _S_apply_to_pieces(__c, this->_M_tree_ptr, __start, size());
1062951a39d68df598db08dfced8b4707755864a0492Ying Wang      size_type __result_pos = __start + __c._M_count;
1063951a39d68df598db08dfced8b4707755864a0492Ying Wang#ifndef __STL_OLD_ROPE_SEMANTICS
1064951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (__result_pos == size())
1065951a39d68df598db08dfced8b4707755864a0492Ying Wang	__result_pos = npos;
1066951a39d68df598db08dfced8b4707755864a0492Ying Wang#endif
1067951a39d68df598db08dfced8b4707755864a0492Ying Wang      return __result_pos;
1068951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
1069951a39d68df598db08dfced8b4707755864a0492Ying Wang
1070951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
1071951a39d68df598db08dfced8b4707755864a0492Ying Wang    _CharT*
1072951a39d68df598db08dfced8b4707755864a0492Ying Wang    rope<_CharT, _Alloc>::
1073951a39d68df598db08dfced8b4707755864a0492Ying Wang    _S_flatten(_RopeRep* __r, _CharT* __buffer)
1074951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
1075951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (0 == __r)
1076951a39d68df598db08dfced8b4707755864a0492Ying Wang	return __buffer;
1077951a39d68df598db08dfced8b4707755864a0492Ying Wang      switch(__r->_M_tag)
1078951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
1079951a39d68df598db08dfced8b4707755864a0492Ying Wang	case __detail::_S_concat:
1080951a39d68df598db08dfced8b4707755864a0492Ying Wang	  {
1081951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _RopeConcatenation* __c = (_RopeConcatenation*)__r;
1082951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _RopeRep* __left = __c->_M_left;
1083951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _RopeRep* __right = __c->_M_right;
1084951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _CharT* __rest = _S_flatten(__left, __buffer);
1085951a39d68df598db08dfced8b4707755864a0492Ying Wang	    return _S_flatten(__right, __rest);
1086951a39d68df598db08dfced8b4707755864a0492Ying Wang	  }
1087951a39d68df598db08dfced8b4707755864a0492Ying Wang	case __detail::_S_leaf:
1088951a39d68df598db08dfced8b4707755864a0492Ying Wang	  {
1089951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _RopeLeaf* __l = (_RopeLeaf*)__r;
1090951a39d68df598db08dfced8b4707755864a0492Ying Wang	    return copy_n(__l->_M_data, __l->_M_size, __buffer).second;
1091951a39d68df598db08dfced8b4707755864a0492Ying Wang	  }
1092951a39d68df598db08dfced8b4707755864a0492Ying Wang	case __detail::_S_function:
1093951a39d68df598db08dfced8b4707755864a0492Ying Wang	case __detail::_S_substringfn:
1094951a39d68df598db08dfced8b4707755864a0492Ying Wang	  // We don't yet do anything with substring nodes.
1095951a39d68df598db08dfced8b4707755864a0492Ying Wang	  // This needs to be fixed before ropefiles will work well.
1096951a39d68df598db08dfced8b4707755864a0492Ying Wang	  {
1097951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _RopeFunction* __f = (_RopeFunction*)__r;
1098951a39d68df598db08dfced8b4707755864a0492Ying Wang	    (*(__f->_M_fn))(0, __f->_M_size, __buffer);
1099951a39d68df598db08dfced8b4707755864a0492Ying Wang	    return __buffer + __f->_M_size;
1100951a39d68df598db08dfced8b4707755864a0492Ying Wang	  }
1101951a39d68df598db08dfced8b4707755864a0492Ying Wang	default:
1102951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return 0;
1103951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
1104951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
1105951a39d68df598db08dfced8b4707755864a0492Ying Wang
1106951a39d68df598db08dfced8b4707755864a0492Ying Wang  // This needs work for _CharT != char
1107951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
1108951a39d68df598db08dfced8b4707755864a0492Ying Wang    void
1109951a39d68df598db08dfced8b4707755864a0492Ying Wang    rope<_CharT, _Alloc>::
1110951a39d68df598db08dfced8b4707755864a0492Ying Wang    _S_dump(_RopeRep* __r, int __indent)
1111951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
1112951a39d68df598db08dfced8b4707755864a0492Ying Wang      for (int __i = 0; __i < __indent; __i++)
1113951a39d68df598db08dfced8b4707755864a0492Ying Wang	putchar(' ');
1114951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (0 == __r)
1115951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
1116951a39d68df598db08dfced8b4707755864a0492Ying Wang	  printf("NULL\n");
1117951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return;
1118951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
1119951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (_S_concat == __r->_M_tag)
1120951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
1121951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _RopeConcatenation* __c = (_RopeConcatenation*)__r;
1122951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _RopeRep* __left = __c->_M_left;
1123951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _RopeRep* __right = __c->_M_right;
1124951a39d68df598db08dfced8b4707755864a0492Ying Wang
1125951a39d68df598db08dfced8b4707755864a0492Ying Wang#ifdef __GC
1126951a39d68df598db08dfced8b4707755864a0492Ying Wang	  printf("Concatenation %p (depth = %d, len = %ld, %s balanced)\n",
1127951a39d68df598db08dfced8b4707755864a0492Ying Wang		 __r, __r->_M_depth, __r->_M_size,
1128951a39d68df598db08dfced8b4707755864a0492Ying Wang		 __r->_M_is_balanced? "" : "not");
1129951a39d68df598db08dfced8b4707755864a0492Ying Wang#else
1130951a39d68df598db08dfced8b4707755864a0492Ying Wang	  printf("Concatenation %p (rc = %ld, depth = %d, "
1131951a39d68df598db08dfced8b4707755864a0492Ying Wang		 "len = %ld, %s balanced)\n",
1132951a39d68df598db08dfced8b4707755864a0492Ying Wang		 __r, __r->_M_ref_count, __r->_M_depth, __r->_M_size,
1133951a39d68df598db08dfced8b4707755864a0492Ying Wang		 __r->_M_is_balanced? "" : "not");
1134951a39d68df598db08dfced8b4707755864a0492Ying Wang#endif
1135951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _S_dump(__left, __indent + 2);
1136951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _S_dump(__right, __indent + 2);
1137951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return;
1138951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
1139951a39d68df598db08dfced8b4707755864a0492Ying Wang      else
1140951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
1141951a39d68df598db08dfced8b4707755864a0492Ying Wang	  char* __kind;
1142951a39d68df598db08dfced8b4707755864a0492Ying Wang
1143951a39d68df598db08dfced8b4707755864a0492Ying Wang	  switch (__r->_M_tag)
1144951a39d68df598db08dfced8b4707755864a0492Ying Wang	    {
1145951a39d68df598db08dfced8b4707755864a0492Ying Wang	    case __detail::_S_leaf:
1146951a39d68df598db08dfced8b4707755864a0492Ying Wang	      __kind = "Leaf";
1147951a39d68df598db08dfced8b4707755864a0492Ying Wang	      break;
1148951a39d68df598db08dfced8b4707755864a0492Ying Wang	    case __detail::_S_function:
1149951a39d68df598db08dfced8b4707755864a0492Ying Wang	      __kind = "Function";
1150951a39d68df598db08dfced8b4707755864a0492Ying Wang	      break;
1151951a39d68df598db08dfced8b4707755864a0492Ying Wang	    case __detail::_S_substringfn:
1152951a39d68df598db08dfced8b4707755864a0492Ying Wang	      __kind = "Function representing substring";
1153951a39d68df598db08dfced8b4707755864a0492Ying Wang	      break;
1154951a39d68df598db08dfced8b4707755864a0492Ying Wang	    default:
1155951a39d68df598db08dfced8b4707755864a0492Ying Wang	      __kind = "(corrupted kind field!)";
1156951a39d68df598db08dfced8b4707755864a0492Ying Wang	    }
1157951a39d68df598db08dfced8b4707755864a0492Ying Wang#ifdef __GC
1158951a39d68df598db08dfced8b4707755864a0492Ying Wang	  printf("%s %p (depth = %d, len = %ld) ",
1159951a39d68df598db08dfced8b4707755864a0492Ying Wang		 __kind, __r, __r->_M_depth, __r->_M_size);
1160951a39d68df598db08dfced8b4707755864a0492Ying Wang#else
1161951a39d68df598db08dfced8b4707755864a0492Ying Wang	  printf("%s %p (rc = %ld, depth = %d, len = %ld) ",
1162951a39d68df598db08dfced8b4707755864a0492Ying Wang		 __kind, __r, __r->_M_ref_count, __r->_M_depth, __r->_M_size);
1163951a39d68df598db08dfced8b4707755864a0492Ying Wang#endif
1164951a39d68df598db08dfced8b4707755864a0492Ying Wang	  if (_S_is_one_byte_char_type((_CharT*)0))
1165951a39d68df598db08dfced8b4707755864a0492Ying Wang	    {
1166951a39d68df598db08dfced8b4707755864a0492Ying Wang	      const int __max_len = 40;
1167951a39d68df598db08dfced8b4707755864a0492Ying Wang	      _Self_destruct_ptr __prefix(_S_substring(__r, 0, __max_len));
1168951a39d68df598db08dfced8b4707755864a0492Ying Wang	      _CharT __buffer[__max_len + 1];
1169951a39d68df598db08dfced8b4707755864a0492Ying Wang	      bool __too_big = __r->_M_size > __prefix->_M_size;
1170951a39d68df598db08dfced8b4707755864a0492Ying Wang
1171951a39d68df598db08dfced8b4707755864a0492Ying Wang	      _S_flatten(__prefix, __buffer);
1172951a39d68df598db08dfced8b4707755864a0492Ying Wang	      __buffer[__prefix->_M_size] = _S_eos((_CharT*)0);
1173951a39d68df598db08dfced8b4707755864a0492Ying Wang	      printf("%s%s\n", (char*)__buffer,
1174951a39d68df598db08dfced8b4707755864a0492Ying Wang		     __too_big? "...\n" : "\n");
1175951a39d68df598db08dfced8b4707755864a0492Ying Wang	    }
1176951a39d68df598db08dfced8b4707755864a0492Ying Wang	  else
1177951a39d68df598db08dfced8b4707755864a0492Ying Wang	    printf("\n");
1178951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
1179951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
1180951a39d68df598db08dfced8b4707755864a0492Ying Wang
1181951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
1182951a39d68df598db08dfced8b4707755864a0492Ying Wang    const unsigned long
1183951a39d68df598db08dfced8b4707755864a0492Ying Wang    rope<_CharT, _Alloc>::
1184951a39d68df598db08dfced8b4707755864a0492Ying Wang    _S_min_len[int(__detail::_S_max_rope_depth) + 1] = {
1185951a39d68df598db08dfced8b4707755864a0492Ying Wang      /* 0 */1, /* 1 */2, /* 2 */3, /* 3 */5, /* 4 */8, /* 5 */13, /* 6 */21,
1186951a39d68df598db08dfced8b4707755864a0492Ying Wang      /* 7 */34, /* 8 */55, /* 9 */89, /* 10 */144, /* 11 */233, /* 12 */377,
1187951a39d68df598db08dfced8b4707755864a0492Ying Wang      /* 13 */610, /* 14 */987, /* 15 */1597, /* 16 */2584, /* 17 */4181,
1188951a39d68df598db08dfced8b4707755864a0492Ying Wang      /* 18 */6765, /* 19 */10946, /* 20 */17711, /* 21 */28657, /* 22 */46368,
1189951a39d68df598db08dfced8b4707755864a0492Ying Wang      /* 23 */75025, /* 24 */121393, /* 25 */196418, /* 26 */317811,
1190951a39d68df598db08dfced8b4707755864a0492Ying Wang      /* 27 */514229, /* 28 */832040, /* 29 */1346269, /* 30 */2178309,
1191951a39d68df598db08dfced8b4707755864a0492Ying Wang      /* 31 */3524578, /* 32 */5702887, /* 33 */9227465, /* 34 */14930352,
1192951a39d68df598db08dfced8b4707755864a0492Ying Wang      /* 35 */24157817, /* 36 */39088169, /* 37 */63245986, /* 38 */102334155,
1193951a39d68df598db08dfced8b4707755864a0492Ying Wang      /* 39 */165580141, /* 40 */267914296, /* 41 */433494437,
1194951a39d68df598db08dfced8b4707755864a0492Ying Wang      /* 42 */701408733, /* 43 */1134903170, /* 44 */1836311903,
1195951a39d68df598db08dfced8b4707755864a0492Ying Wang      /* 45 */2971215073u };
1196951a39d68df598db08dfced8b4707755864a0492Ying Wang  // These are Fibonacci numbers < 2**32.
1197951a39d68df598db08dfced8b4707755864a0492Ying Wang
1198951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
1199951a39d68df598db08dfced8b4707755864a0492Ying Wang    typename rope<_CharT, _Alloc>::_RopeRep*
1200951a39d68df598db08dfced8b4707755864a0492Ying Wang    rope<_CharT, _Alloc>::
1201951a39d68df598db08dfced8b4707755864a0492Ying Wang    _S_balance(_RopeRep* __r)
1202951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
1203951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RopeRep* __forest[int(__detail::_S_max_rope_depth) + 1];
1204951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RopeRep* __result = 0;
1205951a39d68df598db08dfced8b4707755864a0492Ying Wang      int __i;
1206951a39d68df598db08dfced8b4707755864a0492Ying Wang      // Invariant:
1207951a39d68df598db08dfced8b4707755864a0492Ying Wang      // The concatenation of forest in descending order is equal to __r.
1208951a39d68df598db08dfced8b4707755864a0492Ying Wang      // __forest[__i]._M_size >= _S_min_len[__i]
1209951a39d68df598db08dfced8b4707755864a0492Ying Wang      // __forest[__i]._M_depth = __i
1210951a39d68df598db08dfced8b4707755864a0492Ying Wang      // References from forest are included in refcount.
1211951a39d68df598db08dfced8b4707755864a0492Ying Wang
1212951a39d68df598db08dfced8b4707755864a0492Ying Wang      for (__i = 0; __i <= int(__detail::_S_max_rope_depth); ++__i)
1213951a39d68df598db08dfced8b4707755864a0492Ying Wang	__forest[__i] = 0;
1214951a39d68df598db08dfced8b4707755864a0492Ying Wang      __try
1215951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
1216951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _S_add_to_forest(__r, __forest);
1217951a39d68df598db08dfced8b4707755864a0492Ying Wang	  for (__i = 0; __i <= int(__detail::_S_max_rope_depth); ++__i)
1218951a39d68df598db08dfced8b4707755864a0492Ying Wang	    if (0 != __forest[__i])
1219951a39d68df598db08dfced8b4707755864a0492Ying Wang	      {
1220951a39d68df598db08dfced8b4707755864a0492Ying Wang#ifndef __GC
1221951a39d68df598db08dfced8b4707755864a0492Ying Wang		_Self_destruct_ptr __old(__result);
1222951a39d68df598db08dfced8b4707755864a0492Ying Wang#endif
1223951a39d68df598db08dfced8b4707755864a0492Ying Wang		__result = _S_concat(__forest[__i], __result);
1224951a39d68df598db08dfced8b4707755864a0492Ying Wang		__forest[__i]->_M_unref_nonnil();
1225951a39d68df598db08dfced8b4707755864a0492Ying Wang#if !defined(__GC) && defined(__EXCEPTIONS)
1226951a39d68df598db08dfced8b4707755864a0492Ying Wang		__forest[__i] = 0;
1227951a39d68df598db08dfced8b4707755864a0492Ying Wang#endif
1228951a39d68df598db08dfced8b4707755864a0492Ying Wang	      }
1229951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
1230951a39d68df598db08dfced8b4707755864a0492Ying Wang      __catch(...)
1231951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
1232951a39d68df598db08dfced8b4707755864a0492Ying Wang	  for(__i = 0; __i <= int(__detail::_S_max_rope_depth); __i++)
1233951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _S_unref(__forest[__i]);
1234951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __throw_exception_again;
1235951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
1236951a39d68df598db08dfced8b4707755864a0492Ying Wang
1237951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (__result->_M_depth > int(__detail::_S_max_rope_depth))
1238951a39d68df598db08dfced8b4707755864a0492Ying Wang	__throw_length_error(__N("rope::_S_balance"));
1239951a39d68df598db08dfced8b4707755864a0492Ying Wang      return(__result);
1240951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
1241951a39d68df598db08dfced8b4707755864a0492Ying Wang
1242951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
1243951a39d68df598db08dfced8b4707755864a0492Ying Wang    void
1244951a39d68df598db08dfced8b4707755864a0492Ying Wang    rope<_CharT, _Alloc>::
1245951a39d68df598db08dfced8b4707755864a0492Ying Wang    _S_add_to_forest(_RopeRep* __r, _RopeRep** __forest)
1246951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
1247951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (__r->_M_is_balanced)
1248951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
1249951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _S_add_leaf_to_forest(__r, __forest);
1250951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return;
1251951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
1252951a39d68df598db08dfced8b4707755864a0492Ying Wang
1253951a39d68df598db08dfced8b4707755864a0492Ying Wang      {
1254951a39d68df598db08dfced8b4707755864a0492Ying Wang	_RopeConcatenation* __c = (_RopeConcatenation*)__r;
1255951a39d68df598db08dfced8b4707755864a0492Ying Wang
1256951a39d68df598db08dfced8b4707755864a0492Ying Wang	_S_add_to_forest(__c->_M_left, __forest);
1257951a39d68df598db08dfced8b4707755864a0492Ying Wang	_S_add_to_forest(__c->_M_right, __forest);
1258951a39d68df598db08dfced8b4707755864a0492Ying Wang      }
1259951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
1260951a39d68df598db08dfced8b4707755864a0492Ying Wang
1261951a39d68df598db08dfced8b4707755864a0492Ying Wang
1262951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
1263951a39d68df598db08dfced8b4707755864a0492Ying Wang    void
1264951a39d68df598db08dfced8b4707755864a0492Ying Wang    rope<_CharT, _Alloc>::
1265951a39d68df598db08dfced8b4707755864a0492Ying Wang    _S_add_leaf_to_forest(_RopeRep* __r, _RopeRep** __forest)
1266951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
1267951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RopeRep* __insertee;		// included in refcount
1268951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RopeRep* __too_tiny = 0;		// included in refcount
1269951a39d68df598db08dfced8b4707755864a0492Ying Wang      int __i;				// forest[0..__i-1] is empty
1270951a39d68df598db08dfced8b4707755864a0492Ying Wang      size_t __s = __r->_M_size;
1271951a39d68df598db08dfced8b4707755864a0492Ying Wang
1272951a39d68df598db08dfced8b4707755864a0492Ying Wang      for (__i = 0; __s >= _S_min_len[__i+1]/* not this bucket */; ++__i)
1273951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
1274951a39d68df598db08dfced8b4707755864a0492Ying Wang	  if (0 != __forest[__i])
1275951a39d68df598db08dfced8b4707755864a0492Ying Wang	    {
1276951a39d68df598db08dfced8b4707755864a0492Ying Wang#ifndef __GC
1277951a39d68df598db08dfced8b4707755864a0492Ying Wang	      _Self_destruct_ptr __old(__too_tiny);
1278951a39d68df598db08dfced8b4707755864a0492Ying Wang#endif
1279951a39d68df598db08dfced8b4707755864a0492Ying Wang	      __too_tiny = _S_concat_and_set_balanced(__forest[__i],
1280951a39d68df598db08dfced8b4707755864a0492Ying Wang						      __too_tiny);
1281951a39d68df598db08dfced8b4707755864a0492Ying Wang	      __forest[__i]->_M_unref_nonnil();
1282951a39d68df598db08dfced8b4707755864a0492Ying Wang	      __forest[__i] = 0;
1283951a39d68df598db08dfced8b4707755864a0492Ying Wang	    }
1284951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
1285951a39d68df598db08dfced8b4707755864a0492Ying Wang      {
1286951a39d68df598db08dfced8b4707755864a0492Ying Wang#ifndef __GC
1287951a39d68df598db08dfced8b4707755864a0492Ying Wang	_Self_destruct_ptr __old(__too_tiny);
1288951a39d68df598db08dfced8b4707755864a0492Ying Wang#endif
1289951a39d68df598db08dfced8b4707755864a0492Ying Wang	__insertee = _S_concat_and_set_balanced(__too_tiny, __r);
1290951a39d68df598db08dfced8b4707755864a0492Ying Wang      }
1291951a39d68df598db08dfced8b4707755864a0492Ying Wang      // Too_tiny dead, and no longer included in refcount.
1292951a39d68df598db08dfced8b4707755864a0492Ying Wang      // Insertee is live and included.
1293951a39d68df598db08dfced8b4707755864a0492Ying Wang      for (;; ++__i)
1294951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
1295951a39d68df598db08dfced8b4707755864a0492Ying Wang	  if (0 != __forest[__i])
1296951a39d68df598db08dfced8b4707755864a0492Ying Wang	    {
1297951a39d68df598db08dfced8b4707755864a0492Ying Wang#ifndef __GC
1298951a39d68df598db08dfced8b4707755864a0492Ying Wang	      _Self_destruct_ptr __old(__insertee);
1299951a39d68df598db08dfced8b4707755864a0492Ying Wang#endif
1300951a39d68df598db08dfced8b4707755864a0492Ying Wang	      __insertee = _S_concat_and_set_balanced(__forest[__i],
1301951a39d68df598db08dfced8b4707755864a0492Ying Wang						      __insertee);
1302951a39d68df598db08dfced8b4707755864a0492Ying Wang	      __forest[__i]->_M_unref_nonnil();
1303951a39d68df598db08dfced8b4707755864a0492Ying Wang	      __forest[__i] = 0;
1304951a39d68df598db08dfced8b4707755864a0492Ying Wang	    }
1305951a39d68df598db08dfced8b4707755864a0492Ying Wang	  if (__i == int(__detail::_S_max_rope_depth)
1306951a39d68df598db08dfced8b4707755864a0492Ying Wang	      || __insertee->_M_size < _S_min_len[__i+1])
1307951a39d68df598db08dfced8b4707755864a0492Ying Wang	    {
1308951a39d68df598db08dfced8b4707755864a0492Ying Wang	      __forest[__i] = __insertee;
1309951a39d68df598db08dfced8b4707755864a0492Ying Wang	      // refcount is OK since __insertee is now dead.
1310951a39d68df598db08dfced8b4707755864a0492Ying Wang	      return;
1311951a39d68df598db08dfced8b4707755864a0492Ying Wang	    }
1312951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
1313951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
1314951a39d68df598db08dfced8b4707755864a0492Ying Wang
1315951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
1316951a39d68df598db08dfced8b4707755864a0492Ying Wang    _CharT
1317951a39d68df598db08dfced8b4707755864a0492Ying Wang    rope<_CharT, _Alloc>::
1318951a39d68df598db08dfced8b4707755864a0492Ying Wang    _S_fetch(_RopeRep* __r, size_type __i)
1319951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
1320951a39d68df598db08dfced8b4707755864a0492Ying Wang      __GC_CONST _CharT* __cstr = __r->_M_c_string;
1321951a39d68df598db08dfced8b4707755864a0492Ying Wang
1322951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (0 != __cstr)
1323951a39d68df598db08dfced8b4707755864a0492Ying Wang	return __cstr[__i];
1324951a39d68df598db08dfced8b4707755864a0492Ying Wang      for(;;)
1325951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
1326951a39d68df598db08dfced8b4707755864a0492Ying Wang	  switch(__r->_M_tag)
1327951a39d68df598db08dfced8b4707755864a0492Ying Wang	    {
1328951a39d68df598db08dfced8b4707755864a0492Ying Wang	    case __detail::_S_concat:
1329951a39d68df598db08dfced8b4707755864a0492Ying Wang	      {
1330951a39d68df598db08dfced8b4707755864a0492Ying Wang		_RopeConcatenation* __c = (_RopeConcatenation*)__r;
1331951a39d68df598db08dfced8b4707755864a0492Ying Wang		_RopeRep* __left = __c->_M_left;
1332951a39d68df598db08dfced8b4707755864a0492Ying Wang		size_t __left_len = __left->_M_size;
1333951a39d68df598db08dfced8b4707755864a0492Ying Wang
1334951a39d68df598db08dfced8b4707755864a0492Ying Wang		if (__i >= __left_len)
1335951a39d68df598db08dfced8b4707755864a0492Ying Wang		  {
1336951a39d68df598db08dfced8b4707755864a0492Ying Wang		    __i -= __left_len;
1337951a39d68df598db08dfced8b4707755864a0492Ying Wang		    __r = __c->_M_right;
1338951a39d68df598db08dfced8b4707755864a0492Ying Wang		  }
1339951a39d68df598db08dfced8b4707755864a0492Ying Wang		else
1340951a39d68df598db08dfced8b4707755864a0492Ying Wang		  __r = __left;
1341951a39d68df598db08dfced8b4707755864a0492Ying Wang	      }
1342951a39d68df598db08dfced8b4707755864a0492Ying Wang	      break;
1343951a39d68df598db08dfced8b4707755864a0492Ying Wang	    case __detail::_S_leaf:
1344951a39d68df598db08dfced8b4707755864a0492Ying Wang	      {
1345951a39d68df598db08dfced8b4707755864a0492Ying Wang		_RopeLeaf* __l = (_RopeLeaf*)__r;
1346951a39d68df598db08dfced8b4707755864a0492Ying Wang		return __l->_M_data[__i];
1347951a39d68df598db08dfced8b4707755864a0492Ying Wang	      }
1348951a39d68df598db08dfced8b4707755864a0492Ying Wang	    case __detail::_S_function:
1349951a39d68df598db08dfced8b4707755864a0492Ying Wang	    case __detail::_S_substringfn:
1350951a39d68df598db08dfced8b4707755864a0492Ying Wang	      {
1351951a39d68df598db08dfced8b4707755864a0492Ying Wang		_RopeFunction* __f = (_RopeFunction*)__r;
1352951a39d68df598db08dfced8b4707755864a0492Ying Wang		_CharT __result;
1353951a39d68df598db08dfced8b4707755864a0492Ying Wang
1354951a39d68df598db08dfced8b4707755864a0492Ying Wang		(*(__f->_M_fn))(__i, 1, &__result);
1355951a39d68df598db08dfced8b4707755864a0492Ying Wang		return __result;
1356951a39d68df598db08dfced8b4707755864a0492Ying Wang	      }
1357951a39d68df598db08dfced8b4707755864a0492Ying Wang	    }
1358951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
1359951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
1360951a39d68df598db08dfced8b4707755864a0492Ying Wang
1361951a39d68df598db08dfced8b4707755864a0492Ying Wang#ifndef __GC
1362951a39d68df598db08dfced8b4707755864a0492Ying Wang  // Return a uniquely referenced character slot for the given
1363951a39d68df598db08dfced8b4707755864a0492Ying Wang  // position, or 0 if that's not possible.
1364951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
1365951a39d68df598db08dfced8b4707755864a0492Ying Wang    _CharT*
1366951a39d68df598db08dfced8b4707755864a0492Ying Wang    rope<_CharT, _Alloc>::
1367951a39d68df598db08dfced8b4707755864a0492Ying Wang    _S_fetch_ptr(_RopeRep* __r, size_type __i)
1368951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
1369951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RopeRep* __clrstack[__detail::_S_max_rope_depth];
1370951a39d68df598db08dfced8b4707755864a0492Ying Wang      size_t __csptr = 0;
1371951a39d68df598db08dfced8b4707755864a0492Ying Wang
1372951a39d68df598db08dfced8b4707755864a0492Ying Wang      for(;;)
1373951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
1374951a39d68df598db08dfced8b4707755864a0492Ying Wang	  if (__r->_M_ref_count > 1)
1375951a39d68df598db08dfced8b4707755864a0492Ying Wang	    return 0;
1376951a39d68df598db08dfced8b4707755864a0492Ying Wang	  switch(__r->_M_tag)
1377951a39d68df598db08dfced8b4707755864a0492Ying Wang	    {
1378951a39d68df598db08dfced8b4707755864a0492Ying Wang	    case __detail::_S_concat:
1379951a39d68df598db08dfced8b4707755864a0492Ying Wang	      {
1380951a39d68df598db08dfced8b4707755864a0492Ying Wang		_RopeConcatenation* __c = (_RopeConcatenation*)__r;
1381951a39d68df598db08dfced8b4707755864a0492Ying Wang		_RopeRep* __left = __c->_M_left;
1382951a39d68df598db08dfced8b4707755864a0492Ying Wang		size_t __left_len = __left->_M_size;
1383951a39d68df598db08dfced8b4707755864a0492Ying Wang
1384951a39d68df598db08dfced8b4707755864a0492Ying Wang		if (__c->_M_c_string != 0)
1385951a39d68df598db08dfced8b4707755864a0492Ying Wang		  __clrstack[__csptr++] = __c;
1386951a39d68df598db08dfced8b4707755864a0492Ying Wang		if (__i >= __left_len)
1387951a39d68df598db08dfced8b4707755864a0492Ying Wang		  {
1388951a39d68df598db08dfced8b4707755864a0492Ying Wang		    __i -= __left_len;
1389951a39d68df598db08dfced8b4707755864a0492Ying Wang		    __r = __c->_M_right;
1390951a39d68df598db08dfced8b4707755864a0492Ying Wang		  }
1391951a39d68df598db08dfced8b4707755864a0492Ying Wang		else
1392951a39d68df598db08dfced8b4707755864a0492Ying Wang		  __r = __left;
1393951a39d68df598db08dfced8b4707755864a0492Ying Wang	      }
1394951a39d68df598db08dfced8b4707755864a0492Ying Wang	      break;
1395951a39d68df598db08dfced8b4707755864a0492Ying Wang	    case __detail::_S_leaf:
1396951a39d68df598db08dfced8b4707755864a0492Ying Wang	      {
1397951a39d68df598db08dfced8b4707755864a0492Ying Wang		_RopeLeaf* __l = (_RopeLeaf*)__r;
1398951a39d68df598db08dfced8b4707755864a0492Ying Wang		if (__l->_M_c_string != __l->_M_data && __l->_M_c_string != 0)
1399951a39d68df598db08dfced8b4707755864a0492Ying Wang		  __clrstack[__csptr++] = __l;
1400951a39d68df598db08dfced8b4707755864a0492Ying Wang		while (__csptr > 0)
1401951a39d68df598db08dfced8b4707755864a0492Ying Wang		  {
1402951a39d68df598db08dfced8b4707755864a0492Ying Wang		    -- __csptr;
1403951a39d68df598db08dfced8b4707755864a0492Ying Wang		    _RopeRep* __d = __clrstack[__csptr];
1404951a39d68df598db08dfced8b4707755864a0492Ying Wang		    __d->_M_free_c_string();
1405951a39d68df598db08dfced8b4707755864a0492Ying Wang		    __d->_M_c_string = 0;
1406951a39d68df598db08dfced8b4707755864a0492Ying Wang		  }
1407951a39d68df598db08dfced8b4707755864a0492Ying Wang		return __l->_M_data + __i;
1408951a39d68df598db08dfced8b4707755864a0492Ying Wang	      }
1409951a39d68df598db08dfced8b4707755864a0492Ying Wang	    case __detail::_S_function:
1410951a39d68df598db08dfced8b4707755864a0492Ying Wang	    case __detail::_S_substringfn:
1411951a39d68df598db08dfced8b4707755864a0492Ying Wang	      return 0;
1412951a39d68df598db08dfced8b4707755864a0492Ying Wang	    }
1413951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
1414951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
1415951a39d68df598db08dfced8b4707755864a0492Ying Wang#endif /* __GC */
1416951a39d68df598db08dfced8b4707755864a0492Ying Wang
1417951a39d68df598db08dfced8b4707755864a0492Ying Wang  // The following could be implemented trivially using
1418951a39d68df598db08dfced8b4707755864a0492Ying Wang  // lexicographical_compare_3way.
1419951a39d68df598db08dfced8b4707755864a0492Ying Wang  // We do a little more work to avoid dealing with rope iterators for
1420951a39d68df598db08dfced8b4707755864a0492Ying Wang  // flat strings.
1421951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
1422951a39d68df598db08dfced8b4707755864a0492Ying Wang    int
1423951a39d68df598db08dfced8b4707755864a0492Ying Wang    rope<_CharT, _Alloc>::
1424951a39d68df598db08dfced8b4707755864a0492Ying Wang    _S_compare (const _RopeRep* __left, const _RopeRep* __right)
1425951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
1426951a39d68df598db08dfced8b4707755864a0492Ying Wang      size_t __left_len;
1427951a39d68df598db08dfced8b4707755864a0492Ying Wang      size_t __right_len;
1428951a39d68df598db08dfced8b4707755864a0492Ying Wang
1429951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (0 == __right)
1430951a39d68df598db08dfced8b4707755864a0492Ying Wang	return 0 != __left;
1431951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (0 == __left)
1432951a39d68df598db08dfced8b4707755864a0492Ying Wang	return -1;
1433951a39d68df598db08dfced8b4707755864a0492Ying Wang      __left_len = __left->_M_size;
1434951a39d68df598db08dfced8b4707755864a0492Ying Wang      __right_len = __right->_M_size;
1435951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (__detail::_S_leaf == __left->_M_tag)
1436951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
1437951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _RopeLeaf* __l = (_RopeLeaf*) __left;
1438951a39d68df598db08dfced8b4707755864a0492Ying Wang	  if (__detail::_S_leaf == __right->_M_tag)
1439951a39d68df598db08dfced8b4707755864a0492Ying Wang	    {
1440951a39d68df598db08dfced8b4707755864a0492Ying Wang	      _RopeLeaf* __r = (_RopeLeaf*) __right;
1441951a39d68df598db08dfced8b4707755864a0492Ying Wang	      return lexicographical_compare_3way(__l->_M_data,
1442951a39d68df598db08dfced8b4707755864a0492Ying Wang						  __l->_M_data + __left_len,
1443951a39d68df598db08dfced8b4707755864a0492Ying Wang						  __r->_M_data, __r->_M_data
1444951a39d68df598db08dfced8b4707755864a0492Ying Wang						  + __right_len);
1445951a39d68df598db08dfced8b4707755864a0492Ying Wang	    }
1446951a39d68df598db08dfced8b4707755864a0492Ying Wang	  else
1447951a39d68df598db08dfced8b4707755864a0492Ying Wang	    {
1448951a39d68df598db08dfced8b4707755864a0492Ying Wang	      const_iterator __rstart(__right, 0);
1449951a39d68df598db08dfced8b4707755864a0492Ying Wang	      const_iterator __rend(__right, __right_len);
1450951a39d68df598db08dfced8b4707755864a0492Ying Wang	      return lexicographical_compare_3way(__l->_M_data, __l->_M_data
1451951a39d68df598db08dfced8b4707755864a0492Ying Wang						  + __left_len,
1452951a39d68df598db08dfced8b4707755864a0492Ying Wang						  __rstart, __rend);
1453951a39d68df598db08dfced8b4707755864a0492Ying Wang	    }
1454951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
1455951a39d68df598db08dfced8b4707755864a0492Ying Wang      else
1456951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
1457951a39d68df598db08dfced8b4707755864a0492Ying Wang	  const_iterator __lstart(__left, 0);
1458951a39d68df598db08dfced8b4707755864a0492Ying Wang	  const_iterator __lend(__left, __left_len);
1459951a39d68df598db08dfced8b4707755864a0492Ying Wang	  if (__detail::_S_leaf == __right->_M_tag)
1460951a39d68df598db08dfced8b4707755864a0492Ying Wang	    {
1461951a39d68df598db08dfced8b4707755864a0492Ying Wang	      _RopeLeaf* __r = (_RopeLeaf*) __right;
1462951a39d68df598db08dfced8b4707755864a0492Ying Wang	      return lexicographical_compare_3way(__lstart, __lend,
1463951a39d68df598db08dfced8b4707755864a0492Ying Wang						  __r->_M_data, __r->_M_data
1464951a39d68df598db08dfced8b4707755864a0492Ying Wang						  + __right_len);
1465951a39d68df598db08dfced8b4707755864a0492Ying Wang	    }
1466951a39d68df598db08dfced8b4707755864a0492Ying Wang	  else
1467951a39d68df598db08dfced8b4707755864a0492Ying Wang	    {
1468951a39d68df598db08dfced8b4707755864a0492Ying Wang	      const_iterator __rstart(__right, 0);
1469951a39d68df598db08dfced8b4707755864a0492Ying Wang	      const_iterator __rend(__right, __right_len);
1470951a39d68df598db08dfced8b4707755864a0492Ying Wang	      return lexicographical_compare_3way(__lstart, __lend,
1471951a39d68df598db08dfced8b4707755864a0492Ying Wang						  __rstart, __rend);
1472951a39d68df598db08dfced8b4707755864a0492Ying Wang	    }
1473951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
1474951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
1475951a39d68df598db08dfced8b4707755864a0492Ying Wang
1476951a39d68df598db08dfced8b4707755864a0492Ying Wang  // Assignment to reference proxies.
1477951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
1478951a39d68df598db08dfced8b4707755864a0492Ying Wang    _Rope_char_ref_proxy<_CharT, _Alloc>&
1479951a39d68df598db08dfced8b4707755864a0492Ying Wang    _Rope_char_ref_proxy<_CharT, _Alloc>::
1480951a39d68df598db08dfced8b4707755864a0492Ying Wang    operator=(_CharT __c)
1481951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
1482951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RopeRep* __old = _M_root->_M_tree_ptr;
1483951a39d68df598db08dfced8b4707755864a0492Ying Wang#ifndef __GC
1484951a39d68df598db08dfced8b4707755864a0492Ying Wang      // First check for the case in which everything is uniquely
1485951a39d68df598db08dfced8b4707755864a0492Ying Wang      // referenced.  In that case we can do this destructively.
1486951a39d68df598db08dfced8b4707755864a0492Ying Wang      _CharT* __ptr = _My_rope::_S_fetch_ptr(__old, _M_pos);
1487951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (0 != __ptr)
1488951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
1489951a39d68df598db08dfced8b4707755864a0492Ying Wang	  *__ptr = __c;
1490951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return *this;
1491951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
1492951a39d68df598db08dfced8b4707755864a0492Ying Wang#endif
1493951a39d68df598db08dfced8b4707755864a0492Ying Wang      _Self_destruct_ptr __left(_My_rope::_S_substring(__old, 0, _M_pos));
1494951a39d68df598db08dfced8b4707755864a0492Ying Wang      _Self_destruct_ptr __right(_My_rope::_S_substring(__old, _M_pos + 1,
1495951a39d68df598db08dfced8b4707755864a0492Ying Wang							__old->_M_size));
1496951a39d68df598db08dfced8b4707755864a0492Ying Wang      _Self_destruct_ptr __result_left(_My_rope::
1497951a39d68df598db08dfced8b4707755864a0492Ying Wang				       _S_destr_concat_char_iter(__left,
1498951a39d68df598db08dfced8b4707755864a0492Ying Wang								 &__c, 1));
1499951a39d68df598db08dfced8b4707755864a0492Ying Wang
1500951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RopeRep* __result = _My_rope::_S_concat(__result_left, __right);
1501951a39d68df598db08dfced8b4707755864a0492Ying Wang#ifndef __GC
1502951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RopeRep::_S_unref(__old);
1503951a39d68df598db08dfced8b4707755864a0492Ying Wang#endif
1504951a39d68df598db08dfced8b4707755864a0492Ying Wang      _M_root->_M_tree_ptr = __result;
1505951a39d68df598db08dfced8b4707755864a0492Ying Wang      return *this;
1506951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
1507951a39d68df598db08dfced8b4707755864a0492Ying Wang
1508951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
1509951a39d68df598db08dfced8b4707755864a0492Ying Wang    inline _Rope_char_ref_proxy<_CharT, _Alloc>::
1510951a39d68df598db08dfced8b4707755864a0492Ying Wang    operator _CharT() const
1511951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
1512951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (_M_current_valid)
1513951a39d68df598db08dfced8b4707755864a0492Ying Wang	return _M_current;
1514951a39d68df598db08dfced8b4707755864a0492Ying Wang      else
1515951a39d68df598db08dfced8b4707755864a0492Ying Wang	return _My_rope::_S_fetch(_M_root->_M_tree_ptr, _M_pos);
1516951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
1517951a39d68df598db08dfced8b4707755864a0492Ying Wang
1518951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
1519951a39d68df598db08dfced8b4707755864a0492Ying Wang    _Rope_char_ptr_proxy<_CharT, _Alloc>
1520951a39d68df598db08dfced8b4707755864a0492Ying Wang    _Rope_char_ref_proxy<_CharT, _Alloc>::
1521951a39d68df598db08dfced8b4707755864a0492Ying Wang    operator&() const
1522951a39d68df598db08dfced8b4707755864a0492Ying Wang    { return _Rope_char_ptr_proxy<_CharT, _Alloc>(*this); }
1523951a39d68df598db08dfced8b4707755864a0492Ying Wang
1524951a39d68df598db08dfced8b4707755864a0492Ying Wang  template <class _CharT, class _Alloc>
1525951a39d68df598db08dfced8b4707755864a0492Ying Wang    rope<_CharT, _Alloc>::
1526951a39d68df598db08dfced8b4707755864a0492Ying Wang    rope(size_t __n, _CharT __c, const allocator_type& __a)
1527951a39d68df598db08dfced8b4707755864a0492Ying Wang    : _Base(__a)
1528951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
1529951a39d68df598db08dfced8b4707755864a0492Ying Wang      rope<_CharT,_Alloc> __result;
1530951a39d68df598db08dfced8b4707755864a0492Ying Wang      const size_t __exponentiate_threshold = 32;
1531951a39d68df598db08dfced8b4707755864a0492Ying Wang      size_t __exponent;
1532951a39d68df598db08dfced8b4707755864a0492Ying Wang      size_t __rest;
1533951a39d68df598db08dfced8b4707755864a0492Ying Wang      _CharT* __rest_buffer;
1534951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RopeRep* __remainder;
1535951a39d68df598db08dfced8b4707755864a0492Ying Wang      rope<_CharT, _Alloc> __remainder_rope;
1536951a39d68df598db08dfced8b4707755864a0492Ying Wang
1537951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (0 == __n)
1538951a39d68df598db08dfced8b4707755864a0492Ying Wang	return;
1539951a39d68df598db08dfced8b4707755864a0492Ying Wang
1540951a39d68df598db08dfced8b4707755864a0492Ying Wang      __exponent = __n / __exponentiate_threshold;
1541951a39d68df598db08dfced8b4707755864a0492Ying Wang      __rest = __n % __exponentiate_threshold;
1542951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (0 == __rest)
1543951a39d68df598db08dfced8b4707755864a0492Ying Wang	__remainder = 0;
1544951a39d68df598db08dfced8b4707755864a0492Ying Wang      else
1545951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
1546951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __rest_buffer = this->_Data_allocate(_S_rounded_up_size(__rest));
1547951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __uninitialized_fill_n_a(__rest_buffer, __rest, __c,
1548951a39d68df598db08dfced8b4707755864a0492Ying Wang				   _M_get_allocator());
1549951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _S_cond_store_eos(__rest_buffer[__rest]);
1550951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __try
1551951a39d68df598db08dfced8b4707755864a0492Ying Wang	    { __remainder = _S_new_RopeLeaf(__rest_buffer, __rest,
1552951a39d68df598db08dfced8b4707755864a0492Ying Wang					    _M_get_allocator()); }
1553951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __catch(...)
1554951a39d68df598db08dfced8b4707755864a0492Ying Wang	    {
1555951a39d68df598db08dfced8b4707755864a0492Ying Wang	      _RopeRep::__STL_FREE_STRING(__rest_buffer, __rest,
1556951a39d68df598db08dfced8b4707755864a0492Ying Wang					  _M_get_allocator());
1557951a39d68df598db08dfced8b4707755864a0492Ying Wang	      __throw_exception_again;
1558951a39d68df598db08dfced8b4707755864a0492Ying Wang	    }
1559951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
1560951a39d68df598db08dfced8b4707755864a0492Ying Wang      __remainder_rope._M_tree_ptr = __remainder;
1561951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (__exponent != 0)
1562951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
1563951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _CharT* __base_buffer =
1564951a39d68df598db08dfced8b4707755864a0492Ying Wang	    this->_Data_allocate(_S_rounded_up_size(__exponentiate_threshold));
1565951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _RopeLeaf* __base_leaf;
1566951a39d68df598db08dfced8b4707755864a0492Ying Wang	  rope __base_rope;
1567951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __uninitialized_fill_n_a(__base_buffer, __exponentiate_threshold, __c,
1568951a39d68df598db08dfced8b4707755864a0492Ying Wang				   _M_get_allocator());
1569951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _S_cond_store_eos(__base_buffer[__exponentiate_threshold]);
1570951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __try
1571951a39d68df598db08dfced8b4707755864a0492Ying Wang	    {
1572951a39d68df598db08dfced8b4707755864a0492Ying Wang	      __base_leaf = _S_new_RopeLeaf(__base_buffer,
1573951a39d68df598db08dfced8b4707755864a0492Ying Wang					    __exponentiate_threshold,
1574951a39d68df598db08dfced8b4707755864a0492Ying Wang					    _M_get_allocator());
1575951a39d68df598db08dfced8b4707755864a0492Ying Wang	    }
1576951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __catch(...)
1577951a39d68df598db08dfced8b4707755864a0492Ying Wang	    {
1578951a39d68df598db08dfced8b4707755864a0492Ying Wang	      _RopeRep::__STL_FREE_STRING(__base_buffer,
1579951a39d68df598db08dfced8b4707755864a0492Ying Wang					  __exponentiate_threshold,
1580951a39d68df598db08dfced8b4707755864a0492Ying Wang					  _M_get_allocator());
1581951a39d68df598db08dfced8b4707755864a0492Ying Wang	      __throw_exception_again;
1582951a39d68df598db08dfced8b4707755864a0492Ying Wang	    }
1583951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __base_rope._M_tree_ptr = __base_leaf;
1584951a39d68df598db08dfced8b4707755864a0492Ying Wang	  if (1 == __exponent)
1585951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __result = __base_rope;
1586951a39d68df598db08dfced8b4707755864a0492Ying Wang	  else
1587951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __result = power(__base_rope, __exponent,
1588951a39d68df598db08dfced8b4707755864a0492Ying Wang			     _Rope_Concat_fn<_CharT, _Alloc>());
1589951a39d68df598db08dfced8b4707755864a0492Ying Wang
1590951a39d68df598db08dfced8b4707755864a0492Ying Wang	  if (0 != __remainder)
1591951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __result += __remainder_rope;
1592951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
1593951a39d68df598db08dfced8b4707755864a0492Ying Wang      else
1594951a39d68df598db08dfced8b4707755864a0492Ying Wang	__result = __remainder_rope;
1595951a39d68df598db08dfced8b4707755864a0492Ying Wang
1596951a39d68df598db08dfced8b4707755864a0492Ying Wang      this->_M_tree_ptr = __result._M_tree_ptr;
1597951a39d68df598db08dfced8b4707755864a0492Ying Wang      this->_M_tree_ptr->_M_ref_nonnil();
1598951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
1599951a39d68df598db08dfced8b4707755864a0492Ying Wang
1600951a39d68df598db08dfced8b4707755864a0492Ying Wang  template<class _CharT, class _Alloc>
1601951a39d68df598db08dfced8b4707755864a0492Ying Wang    _CharT
1602951a39d68df598db08dfced8b4707755864a0492Ying Wang    rope<_CharT, _Alloc>::_S_empty_c_str[1];
1603951a39d68df598db08dfced8b4707755864a0492Ying Wang
1604951a39d68df598db08dfced8b4707755864a0492Ying Wang  template<class _CharT, class _Alloc>
1605951a39d68df598db08dfced8b4707755864a0492Ying Wang    const _CharT*
1606951a39d68df598db08dfced8b4707755864a0492Ying Wang    rope<_CharT, _Alloc>::
1607951a39d68df598db08dfced8b4707755864a0492Ying Wang    c_str() const
1608951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
1609951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (0 == this->_M_tree_ptr)
1610951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
1611951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _S_empty_c_str[0] = _S_eos((_CharT*)0);  // Possibly redundant,
1612951a39d68df598db08dfced8b4707755864a0492Ying Wang	                                           // but probably fast.
1613951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return _S_empty_c_str;
1614951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
1615951a39d68df598db08dfced8b4707755864a0492Ying Wang      __gthread_mutex_lock (&this->_M_tree_ptr->_M_c_string_lock);
1616951a39d68df598db08dfced8b4707755864a0492Ying Wang      __GC_CONST _CharT* __result = this->_M_tree_ptr->_M_c_string;
1617951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (0 == __result)
1618951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
1619951a39d68df598db08dfced8b4707755864a0492Ying Wang	  size_t __s = size();
1620951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __result = this->_Data_allocate(__s + 1);
1621951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _S_flatten(this->_M_tree_ptr, __result);
1622951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __result[__s] = _S_eos((_CharT*)0);
1623951a39d68df598db08dfced8b4707755864a0492Ying Wang	  this->_M_tree_ptr->_M_c_string = __result;
1624951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
1625951a39d68df598db08dfced8b4707755864a0492Ying Wang      __gthread_mutex_unlock (&this->_M_tree_ptr->_M_c_string_lock);
1626951a39d68df598db08dfced8b4707755864a0492Ying Wang      return(__result);
1627951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
1628951a39d68df598db08dfced8b4707755864a0492Ying Wang
1629951a39d68df598db08dfced8b4707755864a0492Ying Wang  template<class _CharT, class _Alloc>
1630951a39d68df598db08dfced8b4707755864a0492Ying Wang    const _CharT* rope<_CharT, _Alloc>::
1631951a39d68df598db08dfced8b4707755864a0492Ying Wang    replace_with_c_str()
1632951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
1633951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (0 == this->_M_tree_ptr)
1634951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
1635951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _S_empty_c_str[0] = _S_eos((_CharT*)0);
1636951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return _S_empty_c_str;
1637951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
1638951a39d68df598db08dfced8b4707755864a0492Ying Wang      __GC_CONST _CharT* __old_c_string = this->_M_tree_ptr->_M_c_string;
1639951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (__detail::_S_leaf == this->_M_tree_ptr->_M_tag
1640951a39d68df598db08dfced8b4707755864a0492Ying Wang	  && 0 != __old_c_string)
1641951a39d68df598db08dfced8b4707755864a0492Ying Wang	return(__old_c_string);
1642951a39d68df598db08dfced8b4707755864a0492Ying Wang      size_t __s = size();
1643951a39d68df598db08dfced8b4707755864a0492Ying Wang      _CharT* __result = this->_Data_allocate(_S_rounded_up_size(__s));
1644951a39d68df598db08dfced8b4707755864a0492Ying Wang      _S_flatten(this->_M_tree_ptr, __result);
1645951a39d68df598db08dfced8b4707755864a0492Ying Wang      __result[__s] = _S_eos((_CharT*)0);
1646951a39d68df598db08dfced8b4707755864a0492Ying Wang      this->_M_tree_ptr->_M_unref_nonnil();
1647951a39d68df598db08dfced8b4707755864a0492Ying Wang      this->_M_tree_ptr = _S_new_RopeLeaf(__result, __s,
1648951a39d68df598db08dfced8b4707755864a0492Ying Wang					  this->_M_get_allocator());
1649951a39d68df598db08dfced8b4707755864a0492Ying Wang      return(__result);
1650951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
1651951a39d68df598db08dfced8b4707755864a0492Ying Wang
1652951a39d68df598db08dfced8b4707755864a0492Ying Wang  // Algorithm specializations.  More should be added.
1653951a39d68df598db08dfced8b4707755864a0492Ying Wang
1654951a39d68df598db08dfced8b4707755864a0492Ying Wang  template<class _Rope_iterator>  // was templated on CharT and Alloc
1655951a39d68df598db08dfced8b4707755864a0492Ying Wang    void		          // VC++ workaround
1656951a39d68df598db08dfced8b4707755864a0492Ying Wang    _Rope_rotate(_Rope_iterator __first,
1657951a39d68df598db08dfced8b4707755864a0492Ying Wang		 _Rope_iterator __middle,
1658951a39d68df598db08dfced8b4707755864a0492Ying Wang		 _Rope_iterator __last)
1659951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
1660951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef typename _Rope_iterator::value_type _CharT;
1661951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef typename _Rope_iterator::_allocator_type _Alloc;
1662951a39d68df598db08dfced8b4707755864a0492Ying Wang
1663951a39d68df598db08dfced8b4707755864a0492Ying Wang      rope<_CharT, _Alloc>& __r(__first.container());
1664951a39d68df598db08dfced8b4707755864a0492Ying Wang      rope<_CharT, _Alloc> __prefix = __r.substr(0, __first.index());
1665951a39d68df598db08dfced8b4707755864a0492Ying Wang      rope<_CharT, _Alloc> __suffix =
1666951a39d68df598db08dfced8b4707755864a0492Ying Wang	__r.substr(__last.index(), __r.size() - __last.index());
1667951a39d68df598db08dfced8b4707755864a0492Ying Wang      rope<_CharT, _Alloc> __part1 =
1668951a39d68df598db08dfced8b4707755864a0492Ying Wang	__r.substr(__middle.index(), __last.index() - __middle.index());
1669951a39d68df598db08dfced8b4707755864a0492Ying Wang      rope<_CharT, _Alloc> __part2 =
1670951a39d68df598db08dfced8b4707755864a0492Ying Wang	__r.substr(__first.index(), __middle.index() - __first.index());
1671951a39d68df598db08dfced8b4707755864a0492Ying Wang      __r = __prefix;
1672951a39d68df598db08dfced8b4707755864a0492Ying Wang      __r += __part1;
1673951a39d68df598db08dfced8b4707755864a0492Ying Wang      __r += __part2;
1674951a39d68df598db08dfced8b4707755864a0492Ying Wang      __r += __suffix;
1675951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
1676951a39d68df598db08dfced8b4707755864a0492Ying Wang
1677951a39d68df598db08dfced8b4707755864a0492Ying Wang#if !defined(__GNUC__)
1678951a39d68df598db08dfced8b4707755864a0492Ying Wang  // Appears to confuse g++
1679951a39d68df598db08dfced8b4707755864a0492Ying Wang  inline void
1680951a39d68df598db08dfced8b4707755864a0492Ying Wang  rotate(_Rope_iterator<char, __STL_DEFAULT_ALLOCATOR(char)> __first,
1681951a39d68df598db08dfced8b4707755864a0492Ying Wang	 _Rope_iterator<char, __STL_DEFAULT_ALLOCATOR(char)> __middle,
1682951a39d68df598db08dfced8b4707755864a0492Ying Wang	 _Rope_iterator<char, __STL_DEFAULT_ALLOCATOR(char)> __last)
1683951a39d68df598db08dfced8b4707755864a0492Ying Wang  { _Rope_rotate(__first, __middle, __last); }
1684951a39d68df598db08dfced8b4707755864a0492Ying Wang#endif
1685951a39d68df598db08dfced8b4707755864a0492Ying Wang
1686951a39d68df598db08dfced8b4707755864a0492Ying Wang# if 0
1687951a39d68df598db08dfced8b4707755864a0492Ying Wang  // Probably not useful for several reasons:
1688951a39d68df598db08dfced8b4707755864a0492Ying Wang  // - for SGIs 7.1 compiler and probably some others,
1689951a39d68df598db08dfced8b4707755864a0492Ying Wang  //   this forces lots of rope<wchar_t, ...> instantiations, creating a
1690951a39d68df598db08dfced8b4707755864a0492Ying Wang  //   code bloat and compile time problem.  (Fixed in 7.2.)
1691951a39d68df598db08dfced8b4707755864a0492Ying Wang  // - wchar_t is 4 bytes wide on most UNIX platforms, making it
1692951a39d68df598db08dfced8b4707755864a0492Ying Wang  //   unattractive for unicode strings.  Unsigned short may be a better
1693951a39d68df598db08dfced8b4707755864a0492Ying Wang  //   character type.
1694951a39d68df598db08dfced8b4707755864a0492Ying Wang  inline void
1695951a39d68df598db08dfced8b4707755864a0492Ying Wang  rotate(_Rope_iterator<wchar_t, __STL_DEFAULT_ALLOCATOR(char)> __first,
1696951a39d68df598db08dfced8b4707755864a0492Ying Wang	 _Rope_iterator<wchar_t, __STL_DEFAULT_ALLOCATOR(char)> __middle,
1697951a39d68df598db08dfced8b4707755864a0492Ying Wang	 _Rope_iterator<wchar_t, __STL_DEFAULT_ALLOCATOR(char)> __last)
1698951a39d68df598db08dfced8b4707755864a0492Ying Wang  { _Rope_rotate(__first, __middle, __last); }
1699951a39d68df598db08dfced8b4707755864a0492Ying Wang# endif
1700951a39d68df598db08dfced8b4707755864a0492Ying Wang
1701951a39d68df598db08dfced8b4707755864a0492Ying Wang_GLIBCXX_END_NAMESPACE
1702