111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/*
211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Copyright (c) 1996,1997
311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Silicon Graphics Computer Systems, Inc.
411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Copyright (c) 1999
611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Boris Fomitchev
711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * This material is provided "as is", with absolutely no warranty expressed
911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * or implied. Any use is at your own risk.
1011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
1111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Permission to use or copy this software for any purpose is hereby granted
1211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * without fee, provided the above notices are retained on all copies.
1311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Permission to modify the code and to distribute modified code is granted,
1411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * provided the above notices are retained, and a notice that the code was
1511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * modified is included with the above copyright notice.
1611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
1711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
1811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
1911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* NOTE: This is an internal header file, included by other STL headers.
2011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *   You should not attempt to use it directly.
2111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
2211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
2311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Set buf_start, buf_end, and buf_ptr appropriately, filling tmp_buf
2411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// if necessary.  Assumes path_end[leaf_index] and leaf_pos are correct.
2511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Results in a valid buf_ptr if the iterator can be legitimately
2611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// dereferenced.
2711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef _STLP_ROPEIMPL_H
2811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define _STLP_ROPEIMPL_H
2911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
3011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef _STLP_INTERNAL_ROPE_H
3111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  include <stl/_rope.h>
3211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
3311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
3411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef _STLP_INTERNAL_CSTDIO
3511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  include <stl/_cstdio.h>
3611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
3711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
3811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if !defined (_STLP_USE_NO_IOSTREAMS)
3911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  ifndef _STLP_INTERNAL_OSTREAM_H
4011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    include <stl/_ostream.h>
4111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  endif
4211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
4311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  ifndef _STLP_INTERNAL_ISTREAM
4411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    include <stl/_istream.h>
4511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  endif
4611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
4711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
4811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <stl/_range_errors.h>
4911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
5011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_STLP_BEGIN_NAMESPACE
5111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
5211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined ( _STLP_NESTED_TYPE_PARAM_BUG )
5311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define __allocator__ _Alloc
5411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
5511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define __allocator__ allocator_type
5611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
5711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
5811cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate<class _CharT, class _Alloc>
5911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_Rope_iterator<_CharT, _Alloc>::_Rope_iterator(rope<_CharT,_Alloc>* __r, size_t __pos)
6011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  : _Rope_iterator_base<_CharT,_Alloc>(__r->_M_tree_ptr._M_data, __pos),
6111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _M_root_rope(__r) { _RopeRep::_S_ref(this->_M_root); }
6211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
6311cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate<class _CharT, class _Alloc>
6411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_Rope_iterator<_CharT, _Alloc>::_Rope_iterator(rope<_CharT,_Alloc>& __r, size_t __pos):
6511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _Rope_iterator_base<_CharT,_Alloc>(__r._M_tree_ptr._M_data, __pos),
6611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _M_root_rope(&__r) {
6711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if !defined (__DMC__)
6811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _RopeRep::_S_ref(this->_M_root); if (!(__r.empty()))_S_setcache(*this);
6911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
7011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _Rope_iterator_base<_CharT, _Alloc>* __x = this;
7111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _RopeRep::_S_ref(this->_M_root); if (!(__r.empty()))_S_setcache(*__x);
7211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
7311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
7411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
7511cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate<class _CharT, class _Alloc>
7611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid _Rope_RopeRep<_CharT, _Alloc>::_M_free_c_string() {
7711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _CharT* __cstr = _M_c_string;
7811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (0 != __cstr) {
7911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    size_t _p_size = _M_size._M_data + 1;
8011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _STLP_STD::_Destroy_Range(__cstr, __cstr + _p_size);
8111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _M_size.deallocate(__cstr, _p_size);
8211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
8311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
8411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
8511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Set buf_start, buf_end, and buf_ptr appropriately, filling tmp_buf
8611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// if necessary.  Assumes _M_path_end[leaf_index] and leaf_pos are correct.
8711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Results in a valid buf_ptr if the iterator can be legitimately
8811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// dereferenced.
8911cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc>
9011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid _Rope_iterator_base<_CharT,_Alloc>::_S_setbuf(
9111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _Rope_iterator_base<_CharT,_Alloc>& __x) {
9211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const _RopeRep* __leaf = __x._M_path_end._M_data[__x._M_leaf_index];
9311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  size_t __leaf_pos = __x._M_leaf_pos;
9411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  size_t __pos = __x._M_current_pos;
9511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
9611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  switch(__leaf->_M_tag) {
9711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  case _RopeRep::_S_leaf:
9811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    typedef _Rope_RopeLeaf<_CharT, _Alloc> _RopeLeaf;
9911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __x._M_buf_start = __STATIC_CAST(const _RopeLeaf*, __leaf)->_M_data;
10011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __x._M_buf_ptr = __x._M_buf_start + (__pos - __leaf_pos);
10111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __x._M_buf_end = __x._M_buf_start + __leaf->_M_size._M_data;
10211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    break;
10311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  case _RopeRep::_S_function:
10411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  case _RopeRep::_S_substringfn:
10511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
10611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      size_t __len = _S_iterator_buf_len;
10711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      size_t __buf_start_pos = __leaf_pos;
10811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      size_t __leaf_end = __leaf_pos + __leaf->_M_size._M_data;
10911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef _Rope_RopeFunction<_CharT, _Alloc> _RopeFunction;
11011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      char_producer<_CharT>* __fn = __STATIC_CAST(const _RopeFunction*, __leaf)->_M_fn;
11111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
11211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      if (__buf_start_pos + __len <= __pos) {
11311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        __buf_start_pos = __pos - __len/4;
11411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        if (__buf_start_pos + __len > __leaf_end) {
11511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert          __buf_start_pos = __leaf_end - __len;
11611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        }
11711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
11811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      if (__buf_start_pos + __len > __leaf_end) {
11911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        __len = __leaf_end - __buf_start_pos;
12011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
12111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      (*__fn)(__buf_start_pos - __leaf_pos, __len, __x._M_tmp_buf._M_data);
12211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __x._M_buf_ptr = __x._M_tmp_buf._M_data + (__pos - __buf_start_pos);
12311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __x._M_buf_start = __x._M_tmp_buf._M_data;
12411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __x._M_buf_end = __x._M_tmp_buf._M_data + __len;
12511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
12611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    break;
12711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  default:
12811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _STLP_ASSERT(0)
12911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      ;
13011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
13111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
13211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
13311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Set path and buffer inside a rope iterator.  We assume that
13411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// pos and root are already set.
13511cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc>
13611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid _Rope_iterator_base<_CharT,_Alloc>::_S_setcache(
13711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _Rope_iterator_base<_CharT,_Alloc>& __x) {
13811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const _RopeRep* __path[_RopeRep::_S_max_rope_depth+1];
13911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const _RopeRep* __curr_rope;
14011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  int __curr_depth = -1;  /* index into path    */
14111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  size_t __curr_start_pos = 0;
14211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  size_t __pos = __x._M_current_pos;
14311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  unsigned char __dirns = 0; // Bit vector marking right turns in the path
14411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
14511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _STLP_ASSERT(__pos <= __x._M_root->_M_size._M_data)
14611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (__pos >= __x._M_root->_M_size._M_data) {
14711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __x._M_buf_ptr = 0;
14811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return;
14911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
15011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __curr_rope = __x._M_root;
15111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (0 != __curr_rope->_M_c_string) {
15211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    /* Treat the root as a leaf. */
15311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __x._M_buf_start = __curr_rope->_M_c_string;
15411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __x._M_buf_end = __curr_rope->_M_c_string + __curr_rope->_M_size._M_data;
15511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __x._M_buf_ptr = __curr_rope->_M_c_string + __pos;
15611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __x._M_path_end._M_data[0] = __curr_rope;
15711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __x._M_leaf_index = 0;
15811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __x._M_leaf_pos = 0;
15911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return;
16011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
16111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  for(;;) {
16211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    ++__curr_depth;
16311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _STLP_ASSERT(__curr_depth <= _RopeRep::_S_max_rope_depth)
16411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __path[__curr_depth] = __curr_rope;
16511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    switch(__curr_rope->_M_tag) {
16611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    case _RopeRep::_S_leaf:
16711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    case _RopeRep::_S_function:
16811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    case _RopeRep::_S_substringfn:
16911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __x._M_leaf_pos = __curr_start_pos;
17011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      goto done;
17111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    case _RopeRep::_S_concat:
17211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      {
17311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        const _RopeConcat* __c = __STATIC_CAST(const _RopeConcat*, __curr_rope);
17411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        _RopeRep* __left = __c->_M_left;
17511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        size_t __left_len = __left->_M_size._M_data;
17611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
17711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        __dirns <<= 1;
17811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        if (__pos >= __curr_start_pos + __left_len) {
17911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert          __dirns |= 1;
18011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert          __curr_rope = __c->_M_right;
18111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert          __curr_start_pos += __left_len;
18211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        } else {
18311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert          __curr_rope = __left;
18411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        }
18511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
18611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      break;
18711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
18811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
18911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertdone:
19011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // Copy last section of path into _M_path_end.
19111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  {
19211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    int __i = -1;
19311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    int __j = __curr_depth + 1 - _S_path_cache_len;
19411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
19511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (__j < 0) __j = 0;
19611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    while (__j <= __curr_depth) {
19711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __x._M_path_end._M_data[++__i] = __path[__j++];
19811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
19911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __x._M_leaf_index = __i;
20011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
20111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __x._M_path_directions = __dirns;
20211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _S_setbuf(__x);
20311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
20411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
20511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Specialized version of the above.  Assumes that
20611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// the path cache is valid for the previous position.
20711cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc>
20811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid _Rope_iterator_base<_CharT,_Alloc>::_S_setcache_for_incr(
20911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_Rope_iterator_base<_CharT,_Alloc>& __x) {
21011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  int __current_index = __x._M_leaf_index;
21111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const _RopeRep* __current_node = __x._M_path_end._M_data[__current_index];
21211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  size_t __len = __current_node->_M_size._M_data;
21311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  size_t __node_start_pos = __x._M_leaf_pos;
21411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  unsigned char __dirns = __x._M_path_directions;
21511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const _RopeConcat* __c;
21611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
21711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _STLP_ASSERT(__x._M_current_pos <= __x._M_root->_M_size._M_data)
21811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (__x._M_current_pos - __node_start_pos < __len) {
21911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    /* More stuff in this leaf, we just didn't cache it. */
22011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _S_setbuf(__x);
22111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return;
22211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
22311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _STLP_ASSERT(__node_start_pos + __len == __x._M_current_pos)
22411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    //  node_start_pos is starting position of last_node.
22511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  while (--__current_index >= 0) {
22611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (!(__dirns & 1) /* Path turned left */)
22711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      break;
22811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __current_node = __x._M_path_end._M_data[__current_index];
22911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __c = __STATIC_CAST(const _RopeConcat*, __current_node);
23011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // Otherwise we were in the right child.  Thus we should pop
23111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // the concatenation node.
23211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __node_start_pos -= __c->_M_left->_M_size._M_data;
23311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __dirns >>= 1;
23411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
23511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (__current_index < 0) {
23611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // We underflowed the cache. Punt.
23711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _S_setcache(__x);
23811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return;
23911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
24011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __current_node = __x._M_path_end._M_data[__current_index];
24111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __c = __STATIC_CAST(const _RopeConcat*, __current_node);
24211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // current_node is a concatenation node.  We are positioned on the first
24311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // character in its right child.
24411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // node_start_pos is starting position of current_node.
24511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __node_start_pos += __c->_M_left->_M_size._M_data;
24611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __current_node = __c->_M_right;
24711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __x._M_path_end._M_data[++__current_index] = __current_node;
24811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __dirns |= 1;
24911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  while (_RopeRep::_S_concat == __current_node->_M_tag) {
25011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    ++__current_index;
25111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (_S_path_cache_len == __current_index) {
25211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      int __i;
25311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      for (__i = 0; __i < _S_path_cache_len-1; ++__i) {
25411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        __x._M_path_end._M_data[__i] = __x._M_path_end._M_data[__i+1];
25511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
25611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      --__current_index;
25711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
25811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __current_node = __STATIC_CAST(const _RopeConcat*, __current_node)->_M_left;
25911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __x._M_path_end._M_data[__current_index] = __current_node;
26011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __dirns <<= 1;
26111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // node_start_pos is unchanged.
26211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
26311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __x._M_leaf_index = __current_index;
26411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __x._M_leaf_pos = __node_start_pos;
26511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __x._M_path_directions = __dirns;
26611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _S_setbuf(__x);
26711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
26811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
26911cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc>
27011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid _Rope_iterator_base<_CharT,_Alloc>::_M_incr(size_t __n) {
27111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _M_current_pos += __n;
27211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (0 != _M_buf_ptr) {
27311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    size_t __chars_left = _M_buf_end - _M_buf_ptr;
27411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (__chars_left > __n) {
27511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _M_buf_ptr += __n;
27611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    } else if (__chars_left == __n) {
27711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _M_buf_ptr += __n;
27811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _S_setcache_for_incr(*this);
27911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    } else {
28011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _M_buf_ptr = 0;
28111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
28211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
28311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
28411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
28511cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc>
28611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid _Rope_iterator_base<_CharT,_Alloc>::_M_decr(size_t __n) {
28711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (0 != _M_buf_ptr) {
28811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    size_t __chars_left = _M_buf_ptr - _M_buf_start;
28911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (__chars_left >= __n) {
29011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _M_buf_ptr -= __n;
29111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    } else {
29211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _M_buf_ptr = 0;
29311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
29411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
29511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _M_current_pos -= __n;
29611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
29711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
29811cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc>
29911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid _Rope_iterator<_CharT,_Alloc>::_M_check() {
30011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (_M_root_rope->_M_tree_ptr._M_data != this->_M_root) {
30111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // _Rope was modified.  Get things fixed up.
30211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeRep::_S_unref(this->_M_root);
30311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    this->_M_root = _M_root_rope->_M_tree_ptr._M_data;
30411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeRep::_S_ref(this->_M_root);
30511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    this->_M_buf_ptr = 0;
30611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
30711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
30811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
30911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//  There are several reasons for not doing this with virtual destructors
31011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//  and a class specific delete operator:
31111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//  - A class specific delete operator can't easily get access to
31211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//    allocator instances if we need them.
31311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//  - Any virtual function would need a 4 or byte vtable pointer;
31411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//    this only requires a one byte tag per object.
31511cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc>
31611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid _Rope_RopeRep<_CharT,_Alloc>::_M_free_tree() {
31711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  switch (_M_tag) {
31811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  case _S_leaf:
31911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
32011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef _Rope_RopeLeaf<_CharT, _Alloc> _RopeLeaf;
32111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _RopeLeaf* __l = __STATIC_CAST(_RopeLeaf*, this);
32211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _STLP_STD::_Destroy(__l); // ->_Rope_RopeLeaf<_CharT,_Alloc>::~_Rope_RopeLeaf();
32311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _STLP_CREATE_ALLOCATOR(allocator_type,(const allocator_type&)_M_size,
32411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                             _RopeLeaf).deallocate(__l, 1);
32511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      break;
32611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
32711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  case _S_concat:
32811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
32911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef _Rope_RopeConcatenation<_CharT, _Alloc> _RopeConcatenation;
33011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _RopeConcatenation* __c  = __STATIC_CAST(_RopeConcatenation*, this);
33111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _STLP_STD::_Destroy(__c);
33211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _STLP_CREATE_ALLOCATOR(allocator_type,(const allocator_type&)_M_size,
33311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                             _RopeConcatenation).deallocate(__c, 1);
33411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      break;
33511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
33611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  case _S_function:
33711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
33811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef _Rope_RopeFunction<_CharT, _Alloc> _RopeFunction;
33911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _RopeFunction* __f = __STATIC_CAST(_RopeFunction*, this);
34011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _STLP_STD::_Destroy(__f);
34111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _STLP_CREATE_ALLOCATOR(allocator_type, (const allocator_type&)_M_size,
34211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                             _RopeFunction).deallocate(__f, 1);
34311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      break;
34411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
34511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  case _S_substringfn:
34611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
34711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef _Rope_RopeSubstring<_CharT, _Alloc> _RopeSubstring;
34811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _RopeSubstring* __rss = __STATIC_CAST(_RopeSubstring*, this);
34911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _STLP_STD::_Destroy(__rss);
35011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _STLP_CREATE_ALLOCATOR(allocator_type, (const allocator_type&)_M_size,
35111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                             _RopeSubstring).deallocate(__rss, 1);
35211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      break;
35311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
35411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
35511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
35611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
35711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# if defined ( _STLP_NESTED_TYPE_PARAM_BUG )
35811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#   define __RopeLeaf__ _Rope_RopeLeaf<_CharT,_Alloc>
35911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#   define __RopeRep__ _Rope_RopeRep<_CharT,_Alloc>
36011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#   define _RopeLeaf _Rope_RopeLeaf<_CharT,_Alloc>
36111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#   define _RopeRep _Rope_RopeRep<_CharT,_Alloc>
36211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#   define size_type size_t
36311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# else
36411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#   define __RopeLeaf__ _STLP_TYPENAME_ON_RETURN_TYPE rope<_CharT,_Alloc>::_RopeLeaf
36511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#   define __RopeRep__ _STLP_TYPENAME_ON_RETURN_TYPE rope<_CharT,_Alloc>::_RopeRep
36611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# endif
36711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
36811cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc>
36911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid rope<_CharT, _Alloc>::_M_throw_out_of_range() const {
37011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __stl_throw_out_of_range("rope");
37111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
37211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
37311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Concatenate a C string onto a leaf rope by copying the rope data.
37411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Used for short ropes.
37511cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc>
37611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__RopeLeaf__*
37711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertrope<_CharT,_Alloc>::_S_leaf_concat_char_iter (
37811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _RopeLeaf* __r, const _CharT* __iter, size_t __len) {
37911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  size_t __old_len = __r->_M_size._M_data;
38011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _CharT* __new_data = __r->_M_size.allocate(_S_rounded_up_size(__old_len + __len));
38111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _RopeLeaf* __result;
38211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
38311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _STLP_PRIV __ucopy_n(__r->_M_data, __old_len, __new_data);
38411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _STLP_PRIV __ucopy_n(__iter, __len, __new_data + __old_len);
38511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _S_construct_null(__new_data + __old_len + __len);
38611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _STLP_TRY {
38711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __result = _S_new_RopeLeaf(__new_data, __old_len + __len, __r->get_allocator());
38811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
38911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _STLP_UNWIND(_RopeRep::_S_free_string(__new_data, __old_len + __len,
39011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                        __r->get_allocator()))
39111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return __result;
39211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
39311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
39411cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc>
39511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid _Terminate_RopeLeaf(_Rope_RopeLeaf<_CharT,_Alloc> *__r,
39611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                         size_t __size, const __true_type& /*basic char type*/) {
39711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _S_construct_null(__r->_M_data + __size);
39811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _STLP_ASSERT(__r->_M_c_string == __r->_M_data)
39911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
40011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
40111cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc>
40211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid _Terminate_RopeLeaf(_Rope_RopeLeaf<_CharT,_Alloc> *__r,
40311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                         size_t, const __false_type& /*basic char type*/) {
40411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (__r->_M_c_string != __r->_M_data && 0 != __r->_M_c_string) {
40511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __r->_M_free_c_string();
40611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __r->_M_c_string = 0;
40711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
40811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
40911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
41011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// As above, but it's OK to clobber original if refcount is 1
41111cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc>
41211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__RopeLeaf__*
41311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertrope<_CharT,_Alloc>::_S_destr_leaf_concat_char_iter (_RopeLeaf* __r, const _CharT* __iter, size_t __len) {
41411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  //_STLP_ASSERT(__r->_M_ref_count >= 1)
41511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if ( /* __r->_M_ref_count > 1 */  __r->_M_incr() > 2 ) { // - ptr
41611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __r->_M_decr(); // - ptr
41711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return _S_leaf_concat_char_iter(__r, __iter, __len);
41811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
41911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __r->_M_decr(); // - ptr, __r->_M_ref_count == 1 or 0
42011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  size_t __old_len = __r->_M_size._M_data;
42111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (_S_rounded_up_size(__old_len) == _S_rounded_up_size(__old_len + __len)) {
42211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // The space has been partially initialized for the standard
42311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // character types.  But that doesn't matter for those types.
42411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _STLP_PRIV __ucopy_n(__iter, __len, __r->_M_data + __old_len);
42511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _Terminate_RopeLeaf(__r, __old_len + __len, _IsBasicCharType());
42611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __r->_M_size._M_data = __old_len + __len;
42711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // _STLP_ASSERT(__r->_M_ref_count == 1)
42811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // __r->_M_ref_count = 2;
42911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __r->_M_incr(); // i.e.  __r->_M_ref_count = 2
43011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return __r;
43111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  } else {
43211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeLeaf* __result = _S_leaf_concat_char_iter(__r, __iter, __len);
43311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    //_STLP_ASSERT(__result->_M_ref_count == 1)
43411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return __result;
43511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
43611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
43711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
43811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Assumes left and right are not 0.
43911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Does not increment (nor decrement on exception) child reference counts.
44011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Result has ref count 1.
44111cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc>
44211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__RopeRep__*
44311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertrope<_CharT,_Alloc>::_S_tree_concat (_RopeRep* __left, _RopeRep* __right) {
44411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _RopeConcatenation* __result =
44511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _S_new_RopeConcatenation(__left, __right, __left->get_allocator());
44611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  size_t __depth = __result->_M_depth;
44711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
44811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _STLP_ASSERT(__left->get_allocator() == __right->get_allocator())
44911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (__depth > 20 && (__result->_M_size._M_data < 1000 ||
45011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __depth > _RopeRep::_S_max_rope_depth)) {
45111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeRep* __balanced;
45211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
45311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _STLP_TRY {
45411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __balanced = _S_balance(__result);
45511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert     // _STLP_ASSERT(__result == __balanced ||
45611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert     //              1 == __result->_M_ref_count &&
45711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert     //              1 == __balanced->_M_ref_count)
45811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __result->_M_unref_nonnil();
45911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
46011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _STLP_UNWIND((_STLP_CREATE_ALLOCATOR(allocator_type,(allocator_type&)__left->_M_size,
46111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                         _RopeConcatenation).deallocate(__result,1)))
46211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // In case of exception, we need to deallocate
46311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // otherwise dangling result node.  But caller
46411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // still owns its children.  Thus unref is
46511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // inappropriate.
46611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return __balanced;
46711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  } else {
46811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return __result;
46911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
47011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
47111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
47211cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc>
47311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__RopeRep__*
47411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertrope<_CharT,_Alloc>::_S_concat_char_iter (_RopeRep* __r,
47511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                          const _CharT*__s, size_t __slen) {
47611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _RopeRep* __result;
47711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (0 == __slen) {
47811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _S_ref(__r);
47911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return __r;
48011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
48111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (0 == __r)
48211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return _S_RopeLeaf_from_unowned_char_ptr(__s, __slen, __r->get_allocator());
48311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (_RopeRep::_S_leaf == __r->_M_tag &&
48411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __r->_M_size._M_data + __slen <= _S_copy_max) {
48511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __result = _S_leaf_concat_char_iter((_RopeLeaf*)__r, __s, __slen);
48611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // _STLP_ASSERT(1 == __result->_M_ref_count)
48711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return __result;
48811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
48911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (_RopeRep::_S_concat == __r->_M_tag &&
49011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _RopeRep::_S_leaf == ((_RopeConcatenation*)__r)->_M_right->_M_tag) {
49111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeLeaf* __right = (_RopeLeaf* )(((_RopeConcatenation* )__r)->_M_right);
49211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (__right->_M_size._M_data + __slen <= _S_copy_max) {
49311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _RopeRep* __left = ((_RopeConcatenation*)__r)->_M_left;
49411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _RopeRep* __nright = _S_leaf_concat_char_iter((_RopeLeaf*)__right, __s, __slen);
49511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __left->_M_ref_nonnil();
49611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _STLP_TRY {
49711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        __result = _S_tree_concat(__left, __nright);
49811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
49911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _STLP_UNWIND(_S_unref(__left); _S_unref(__nright))
50011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      // _STLP_ASSERT(1 == __result->_M_ref_count)
50111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return __result;
50211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
50311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
50411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _RopeRep* __nright =
50511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _S_RopeLeaf_from_unowned_char_ptr(__s, __slen, __r->get_allocator());
50611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _STLP_TRY {
50711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __r->_M_ref_nonnil();
50811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __result = _S_tree_concat(__r, __nright);
50911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
51011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _STLP_UNWIND(_S_unref(__r); _S_unref(__nright))
51111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // _STLP_ASSERT(1 == __result->_M_ref_count)
51211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return __result;
51311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
51411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
51511cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc>
51611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__RopeRep__*
51711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertrope<_CharT,_Alloc>::_S_destr_concat_char_iter(
51811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _RopeRep* __r, const _CharT* __s, size_t __slen) {
51911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _RopeRep* __result;
52011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (0 == __r)
52111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return _S_RopeLeaf_from_unowned_char_ptr(__s, __slen,
52211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                             __r->get_allocator());
52311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // size_t __count = __r->_M_ref_count;
52411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  size_t __orig_size = __r->_M_size._M_data;
52511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // _STLP_ASSERT(__count >= 1)
52611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if ( /* __count > 1 */ __r->_M_incr() > 2 ) {
52711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __r->_M_decr();
52811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return _S_concat_char_iter(__r, __s, __slen);
52911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
53011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (0 == __slen) {
53111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return __r;
53211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
53311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __r->_M_decr();
53411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (__orig_size + __slen <= _S_copy_max && _RopeRep::_S_leaf == __r->_M_tag) {
53511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return _S_destr_leaf_concat_char_iter((_RopeLeaf*)__r, __s, __slen);
53611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
53711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (_RopeRep::_S_concat == __r->_M_tag) {
53811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeLeaf* __right = __STATIC_CAST(_RopeLeaf*, __STATIC_CAST(_RopeConcatenation*, __r)->_M_right);
53911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (_RopeRep::_S_leaf == __right->_M_tag &&
54011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        __right->_M_size._M_data + __slen <= _S_copy_max) {
54111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _RopeRep* __new_right = _S_destr_leaf_concat_char_iter(__right, __s, __slen);
54211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      if (__right == __new_right) {
54311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        // _STLP_ASSERT(__new_right->_M_ref_count == 2)
54411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        // __new_right->_M_ref_count = 1;
54511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        __new_right->_M_decr();
54611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      } else {
54711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        // _STLP_ASSERT(__new_right->_M_ref_count >= 1)
54811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        __right->_M_unref_nonnil();
54911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
55011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      // _STLP_ASSERT(__r->_M_ref_count == 1)
55111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      // __r->_M_ref_count = 2;    // One more than before.
55211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __r->_M_incr();
55311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __STATIC_CAST(_RopeConcatenation*, __r)->_M_right = __new_right;
55411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      // E.Musser : moved below
55511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      //    __r->_M_size._M_data = __orig_size + __slen;
55611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      if (0 != __r->_M_c_string) {
55711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        __r->_M_free_c_string();
55811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        __r->_M_c_string = 0;
55911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
56011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __r->_M_size._M_data = __orig_size + __slen;
56111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return __r;
56211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
56311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
56411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _RopeRep* __right =
56511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _S_RopeLeaf_from_unowned_char_ptr(__s, __slen, __r->get_allocator());
56611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __r->_M_ref_nonnil();
56711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _STLP_TRY {
56811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __result = _S_tree_concat(__r, __right);
56911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
57011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _STLP_UNWIND(_S_unref(__r); _S_unref(__right))
57111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // _STLP_ASSERT(1 == __result->_M_ref_count)
57211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return __result;
57311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
57411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
57511cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc>
57611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__RopeRep__*
57711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertrope<_CharT,_Alloc>::_S_concat_rep(_RopeRep* __left, _RopeRep* __right) {
57811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (0 == __left) {
57911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _S_ref(__right);
58011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return __right;
58111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
58211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (0 == __right) {
58311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __left->_M_ref_nonnil();
58411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return __left;
58511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
58611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (_RopeRep::_S_leaf == __right->_M_tag) {
58711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (_RopeRep::_S_leaf == __left->_M_tag) {
58811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      if (__right->_M_size._M_data + __left->_M_size._M_data <= _S_copy_max) {
58911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        return _S_leaf_concat_char_iter(__STATIC_CAST(_RopeLeaf*, __left),
59011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                        __STATIC_CAST(_RopeLeaf*, __right)->_M_data,
59111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                        __right->_M_size._M_data);
59211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
59311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    } else if (_RopeRep::_S_concat == __left->_M_tag &&
59411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert               _RopeRep::_S_leaf == __STATIC_CAST(_RopeConcatenation*, __left)->_M_right->_M_tag) {
59511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _RopeLeaf* __leftright =
59611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        __STATIC_CAST(_RopeLeaf*, __STATIC_CAST(_RopeConcatenation*, __left)->_M_right);
59711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      if (__leftright->_M_size._M_data + __right->_M_size._M_data <= _S_copy_max) {
59811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        _RopeRep* __leftleft = __STATIC_CAST(_RopeConcatenation*, __left)->_M_left;
59911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        _RopeRep* __rest = _S_leaf_concat_char_iter(__leftright,
60011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                                    __STATIC_CAST(_RopeLeaf*, __right)->_M_data,
60111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                                    __right->_M_size._M_data);
60211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        __leftleft->_M_ref_nonnil();
60311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        _STLP_TRY {
60411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert          return _S_tree_concat(__leftleft, __rest);
60511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        }
60611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        _STLP_UNWIND(_S_unref(__leftleft); _S_unref(__rest))
60711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
60811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
60911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
61011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __left->_M_ref_nonnil();
61111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __right->_M_ref_nonnil();
61211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _STLP_TRY {
61311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return _S_tree_concat(__left, __right);
61411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
61511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _STLP_UNWIND(_S_unref(__left); _S_unref(__right))
61611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _STLP_RET_AFTER_THROW(0)
61711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
61811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
61911cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc>
62011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__RopeRep__*
62111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertrope<_CharT,_Alloc>::_S_substring(_RopeRep* __base,
62211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                  size_t __start, size_t __endp1) {
62311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (0 == __base) return 0;
62411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  size_t __len = __base->_M_size._M_data;
62511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  size_t __adj_endp1;
62611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const size_t __lazy_threshold = 128;
62711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
62811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (__endp1 >= __len) {
62911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (0 == __start) {
63011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __base->_M_ref_nonnil();
63111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return __base;
63211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    } else {
63311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __adj_endp1 = __len;
63411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
63511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  } else {
63611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __adj_endp1 = __endp1;
63711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
63811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  switch(__base->_M_tag) {
63911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  case _RopeRep::_S_concat:
64011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  {
64111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeConcatenation* __c = __STATIC_CAST(_RopeConcatenation*, __base);
64211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeRep* __left = __c->_M_left;
64311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeRep* __right = __c->_M_right;
64411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    size_t __left_len = __left->_M_size._M_data;
64511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeRep* __result;
64611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
64711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (__adj_endp1 <= __left_len) {
64811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return _S_substring(__left, __start, __endp1);
64911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    } else if (__start >= __left_len) {
65011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return _S_substring(__right, __start - __left_len,
65111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                          __adj_endp1 - __left_len);
65211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
65311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _Self_destruct_ptr __left_result(_S_substring(__left, __start, __left_len));
65411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _Self_destruct_ptr __right_result(_S_substring(__right, 0, __endp1 - __left_len));
65511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _STLP_MPWFIX_TRY    //*TY 06/01/2000 - mpw forgets to call dtor on __left_result and __right_result without this try block
65611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __result = _S_concat_rep(__left_result, __right_result);
65711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // _STLP_ASSERT(1 == __result->_M_ref_count)
65811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return __result;
65911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _STLP_MPWFIX_CATCH    //*TY 06/01/2000 -
66011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
66111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  case _RopeRep::_S_leaf:
66211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  {
66311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeLeaf* __l = __STATIC_CAST(_RopeLeaf*, __base);
66411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeLeaf* __result;
66511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    size_t __result_len;
66611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (__start >= __adj_endp1) return 0;
66711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __result_len = __adj_endp1 - __start;
66811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (__result_len > __lazy_threshold) goto lazy;
66911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    const _CharT* __section = __l->_M_data + __start;
67011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // We should sometimes create substring node instead.
67111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __result = _S_RopeLeaf_from_unowned_char_ptr(__section, __result_len,
67211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                                 __base->get_allocator());
67311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return __result;
67411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
67511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  case _RopeRep::_S_substringfn:
67611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // Avoid introducing multiple layers of substring nodes.
67711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  {
67811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeSubstring* __old = __STATIC_CAST(_RopeSubstring*, __base);
67911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    size_t __result_len;
68011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (__start >= __adj_endp1) return 0;
68111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __result_len = __adj_endp1 - __start;
68211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (__result_len > __lazy_threshold) {
68311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _RopeSubstring* __result = _S_new_RopeSubstring(__old->_M_base,
68411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                                      __start + __old->_M_start,
68511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                                      __adj_endp1 - __start,
68611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                                      __base->get_allocator());
68711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return __result;
68811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    } // *** else fall through: ***
68911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
69011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  case _RopeRep::_S_function:
69111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  {
69211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeFunction* __f = __STATIC_CAST(_RopeFunction*, __base);
69311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (__start >= __adj_endp1) return 0;
69411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    size_t __result_len = __adj_endp1 - __start;
69511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
69611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (__result_len > __lazy_threshold) goto lazy;
69711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _CharT* __section = __base->_M_size.allocate(_S_rounded_up_size(__result_len));
69811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _STLP_TRY {
69911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      (*(__f->_M_fn))(__start, __result_len, __section);
70011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
70111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _STLP_UNWIND(_RopeRep::_S_free_string(__section,
70211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                          __result_len, __base->get_allocator()))
70311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _S_construct_null(__section + __result_len);
70411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return _S_new_RopeLeaf(__section, __result_len,
70511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                           __base->get_allocator());
70611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
70711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
70811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  /*NOTREACHED*/
70911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _STLP_ASSERT(false)
71011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  lazy:
71111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  {
71211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // Create substring node.
71311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return _S_new_RopeSubstring(__base, __start, __adj_endp1 - __start,
71411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                __base->get_allocator());
71511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
71611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
71711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
71811cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate<class _CharT>
71911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass _Rope_flatten_char_consumer : public _Rope_char_consumer<_CharT> {
72011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertprivate:
72111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _CharT* _M_buf_ptr;
72211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertpublic:
72311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _Rope_flatten_char_consumer(_CharT* __buffer) {
72411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _M_buf_ptr = __buffer;
72511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
72611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  ~_Rope_flatten_char_consumer() {}
72711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  bool operator() (const _CharT* __leaf, size_t __n) {
72811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _STLP_PRIV __ucopy_n(__leaf, __n, _M_buf_ptr);
72911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _M_buf_ptr += __n;
73011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return true;
73111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
73211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
73311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
73411cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate<class _CharT>
73511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass _Rope_find_char_char_consumer : public _Rope_char_consumer<_CharT> {
73611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertprivate:
73711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _CharT _M_pattern;
73811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertpublic:
73911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  size_t _M_count;  // Number of nonmatching characters
74011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _Rope_find_char_char_consumer(_CharT __p)
74111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    : _M_pattern(__p), _M_count(0) {}
74211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  ~_Rope_find_char_char_consumer() {}
74311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  bool operator() (const _CharT* __leaf, size_t __n) {
74411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    size_t __i;
74511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    for (__i = 0; __i < __n; ++__i) {
74611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      if (__leaf[__i] == _M_pattern) {
74711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        _M_count += __i; return false;
74811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
74911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
75011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _M_count += __n; return true;
75111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
75211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
75311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
75411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if !defined (_STLP_USE_NO_IOSTREAMS)
75511cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate<class _CharT, class _Traits>
75611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Here _CharT is both the stream and rope character type.
75711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass _Rope_insert_char_consumer : public _Rope_char_consumer<_CharT> {
75811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertprivate:
75911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef basic_ostream<_CharT,_Traits> _Insert_ostream;
76011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef _Rope_insert_char_consumer<_CharT,_Traits> _Self;
76111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _Insert_ostream& _M_o;
76211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
76311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  //explicitely defined as private to avoid warnings:
76411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _Self& operator = (_Self const&);
76511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertpublic:
76611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _Rope_insert_char_consumer(_Insert_ostream& __writer)
76711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    : _M_o(__writer) {}
76811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  ~_Rope_insert_char_consumer() {}
76911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // Caller is presumed to own the ostream
77011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  bool operator() (const _CharT* __leaf, size_t __n);
77111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // Returns true to continue traversal.
77211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
77311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
77411cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate<class _CharT, class _Traits>
77511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbool _Rope_insert_char_consumer<_CharT, _Traits>::operator()
77611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  (const _CharT* __leaf, size_t __n) {
77711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  size_t __i;
77811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  //  We assume that formatting is set up correctly for each element.
77911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  for (__i = 0; __i < __n; ++__i) _M_o.put(__leaf[__i]);
78011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return true;
78111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
78211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif /* !_STLP_USE_NO_IOSTREAMS */
78311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
78411cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc, class _CharConsumer>
78511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbool _S_apply_to_pieces(_CharConsumer& __c,
78611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                        _Rope_RopeRep<_CharT, _Alloc> * __r,
78711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                        size_t __begin, size_t __end) {
78811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep;
78911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef _Rope_RopeConcatenation<_CharT,_Alloc> _RopeConcatenation;
79011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef _Rope_RopeLeaf<_CharT,_Alloc> _RopeLeaf;
79111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef _Rope_RopeFunction<_CharT,_Alloc> _RopeFunction;
79211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
79311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (0 == __r) return true;
79411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  switch(__r->_M_tag) {
79511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  case _RopeRep::_S_concat:
79611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  {
79711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeConcatenation* __conc = __STATIC_CAST(_RopeConcatenation*, __r);
79811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeRep* __left =  __conc->_M_left;
79911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    size_t __left_len = __left->_M_size._M_data;
80011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (__begin < __left_len) {
80111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      size_t __left_end = (min) (__left_len, __end);
80211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      if (!_S_apply_to_pieces(__c, __left, __begin, __left_end))
80311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        return false;
80411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
80511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (__end > __left_len) {
80611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _RopeRep* __right =  __conc->_M_right;
80711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      size_t __right_start = (max)(__left_len, __begin);
80811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      if (!_S_apply_to_pieces(__c, __right,
80911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                              __right_start - __left_len,
81011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                              __end - __left_len)) {
81111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        return false;
81211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
81311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
81411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
81511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return true;
81611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  case _RopeRep::_S_leaf:
81711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  {
81811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeLeaf* __l = __STATIC_CAST(_RopeLeaf*, __r);
81911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return __c(__l->_M_data + __begin, __end - __begin);
82011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
82111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  case _RopeRep::_S_function:
82211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  case _RopeRep::_S_substringfn:
82311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  {
82411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeFunction* __f = __STATIC_CAST(_RopeFunction*, __r);
82511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    size_t __len = __end - __begin;
82611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    bool __result;
82711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _CharT* __buffer = __r->get_allocator().allocate(__len);
82811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _STLP_TRY {
82911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      (*(__f->_M_fn))(__begin, __len, __buffer);
83011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __result = __c(__buffer, __len);
83111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __r->get_allocator().deallocate(__buffer, __len);
83211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
83311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _STLP_UNWIND((__r->get_allocator().deallocate(__buffer, __len)))
83411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return __result;
83511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
83611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  default:
83711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _STLP_ASSERT(false)
83811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    /*NOTREACHED*/
83911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return false;
84011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
84111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
84211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
84311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if !defined (_STLP_USE_NO_IOSTREAMS)
84411cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate<class _CharT, class _Traits>
84511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertinline void _Rope_fill(basic_ostream<_CharT, _Traits>& __o, streamsize __n) {
84611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  char __f = __o.fill();
84711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  for (streamsize __i = 0; __i < __n; ++__i) __o.put(__f);
84811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
84911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
85011cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate<class _CharT, class _Traits, class _Alloc>
85111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbasic_ostream<_CharT, _Traits>& _S_io_get(basic_ostream<_CharT, _Traits>& __o,
85211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                          const rope<_CharT, _Alloc>& __r, const __true_type& /*_IsBasicCharType*/) {
85311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  streamsize __w = __o.width();
85411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const bool __left = (__o.flags() & ios::left) != 0;
85511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  size_t __rope_len = __r.size();
85611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _Rope_insert_char_consumer<_CharT, _Traits> __c(__o);
85711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
85811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const bool __need_pad = (((sizeof(streamsize) > sizeof(size_t)) && (__STATIC_CAST(streamsize, __rope_len) < __w)) ||
85911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                           ((sizeof(streamsize) <= sizeof(size_t)) && (__rope_len < __STATIC_CAST(size_t, __w))));
86011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  streamsize __pad_len = __need_pad ? __w - __rope_len : 0;
86111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
86211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (!__left && __pad_len > 0) {
86311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _Rope_fill(__o, __pad_len);
86411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
86511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __r.apply_to_pieces(0, __rope_len, __c);
86611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (__left && __pad_len > 0) {
86711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _Rope_fill(__o, __pad_len);
86811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
86911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return __o;
87011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
87111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
87211cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate<class _CharT, class _Traits, class _Alloc>
87311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbasic_ostream<_CharT, _Traits>& _S_io_get(basic_ostream<_CharT, _Traits>& __o,
87411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                         const rope<_CharT, _Alloc>& __r, const __false_type& /*_IsBasicCharType*/) {
87511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  streamsize __w = __o.width();
87611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  size_t __rope_len = __r.size();
87711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _Rope_insert_char_consumer<_CharT, _Traits> __c(__o);
87811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
87911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __o.width(__w /__rope_len);
88011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _STLP_TRY {
88111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __r.apply_to_pieces(0, __rope_len, __c);
88211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __o.width(__w);
88311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
88411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _STLP_UNWIND(__o.width(__w))
88511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return __o;
88611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
88711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
88811cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate<class _CharT, class _Traits, class _Alloc>
88911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbasic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __o,
89011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                           const rope<_CharT, _Alloc>& __r) {
89111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef typename _IsIntegral<_CharT>::_Ret _Char_Is_Integral;
89211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return _S_io_get(__o, __r, _Char_Is_Integral());
89311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
89411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif /* NO_IOSTREAMS */
89511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
89611cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc>
89711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_CharT* rope<_CharT,_Alloc>::_S_flatten(_RopeRep* __r,
89811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                        size_t __start, size_t __len,
89911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                        _CharT* __buffer) {
90011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _Rope_flatten_char_consumer<_CharT> __c(__buffer);
90111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _S_apply_to_pieces(__c, __r, __start, __start + __len);
90211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return(__buffer + __len);
90311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
90411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
90511cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc>
90611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertsize_t rope<_CharT,_Alloc>::find(_CharT __pattern, size_t __start) const {
90711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _Rope_find_char_char_consumer<_CharT> __c(__pattern);
90811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _S_apply_to_pieces(__c, _M_tree_ptr._M_data, __start, size());
90911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  size_type __result_pos = __start + __c._M_count;
91011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef _STLP_OLD_ROPE_SEMANTICS
91111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (__result_pos == size()) __result_pos = npos;
91211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
91311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return __result_pos;
91411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
91511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
91611cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc>
91711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_CharT*
91811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertrope<_CharT,_Alloc>::_S_flatten(_Rope_RopeRep<_CharT, _Alloc>* __r, _CharT* __buffer) {
91911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (0 == __r) return __buffer;
92011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  switch(__r->_M_tag) {
92111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  case _RopeRep::_S_concat:
92211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  {
92311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeConcatenation* __c = __STATIC_CAST(_RopeConcatenation*, __r);
92411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeRep* __left = __c->_M_left;
92511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeRep* __right = __c->_M_right;
92611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _CharT* __rest = _S_flatten(__left, __buffer);
92711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return _S_flatten(__right, __rest);
92811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
92911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  case _RopeRep::_S_leaf:
93011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  {
93111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeLeaf* __l = __STATIC_CAST(_RopeLeaf*, __r);
93211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return _STLP_PRIV __ucopy_n(__l->_M_data, __l->_M_size._M_data, __buffer).second;
93311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
93411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  case _RopeRep::_S_function:
93511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  case _RopeRep::_S_substringfn:
93611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // We dont yet do anything with substring nodes.
93711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // This needs to be fixed before ropefiles will work well.
93811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  {
93911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeFunction* __f = __STATIC_CAST(_RopeFunction*, __r);
94011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    (*(__f->_M_fn))(0, __f->_M_size._M_data, __buffer);
94111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return __buffer + __f->_M_size._M_data;
94211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
94311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  default:
94411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _STLP_ASSERT(false)
94511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    /*NOTREACHED*/
94611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return 0;
94711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
94811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
94911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
95011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef _STLP_DEBUG
95111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// This needs work for _CharT != char
95211cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc>
95311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid rope<_CharT,_Alloc>::_S_dump(_RopeRep* __r, int __indent) {
95411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  for (int __i = 0; __i < __indent; ++__i) putchar(' ');
95511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (0 == __r) {
95611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    printf("NULL\n"); return;
95711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
95811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (_RopeRep::_S_concat == __r->_M_tag) {
95911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeConcatenation* __c = __STATIC_CAST(_RopeConcatenation*, __r);
96011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeRep* __left = __c->_M_left;
96111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeRep* __right = __c->_M_right;
96211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    printf("Concatenation %p (rc = %ld, depth = %d, len = %ld, %s balanced)\n",
96311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __r, __r->_M_ref_count, __r->_M_depth, __r->_M_size._M_data,
96411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __r->_M_is_balanced? "" : "not");
96511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _S_dump(__left, __indent + 2);
96611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _S_dump(__right, __indent + 2);
96711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return;
96811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
96911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  else {
97011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    const char* __kind;
97111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
97211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    switch (__r->_M_tag) {
97311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      case _RopeRep::_S_leaf:
97411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        __kind = "Leaf";
97511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        break;
97611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      case _RopeRep::_S_function:
97711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        __kind = "Function";
97811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        break;
97911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      case _RopeRep::_S_substringfn:
98011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        __kind = "Function representing substring";
98111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        break;
98211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      default:
98311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        __kind = "(corrupted kind field!)";
98411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
98511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    printf("%s %p (rc = %ld, depth = %d, len = %ld) ",
98611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert     __kind, __r, __r->_M_ref_count, __r->_M_depth, __r->_M_size._M_data);
98711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (sizeof(_CharT) == 1) {
98811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      const int __max_len = 40;
98911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _Self_destruct_ptr __prefix(_S_substring(__r, 0, __max_len));
99011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _CharT __buffer[__max_len + 1];
99111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      bool __too_big = __r->_M_size._M_data > __prefix->_M_size._M_data;
99211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
99311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _S_flatten(__prefix, __buffer);
99411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __buffer[__prefix->_M_size._M_data] = _STLP_DEFAULT_CONSTRUCTED(_CharT);
99511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      printf("%s%s\n", (char*)__buffer, __too_big? "...\n" : "\n");
99611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    } else {
99711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      printf("\n");
99811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
99911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
100011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
100111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif /* _STLP_DEBUG */
100211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
100311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# define __ROPE_TABLE_BODY  = { \
100411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* 0 */1, /* 1 */2, /* 2 */3, /* 3 */5, /* 4 */8, /* 5 */13, /* 6 */21,         \
100511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* 7 */34, /* 8 */55, /* 9 */89, /* 10 */144, /* 11 */233, /* 12 */377,         \
100611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* 13 */610, /* 14 */987, /* 15 */1597, /* 16 */2584, /* 17 */4181,             \
100711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* 18 */6765ul, /* 19 */10946ul, /* 20 */17711ul, /* 21 */28657ul, /* 22 */46368ul,   \
100811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* 23 */75025ul, /* 24 */121393ul, /* 25 */196418ul, /* 26 */317811ul,                \
100911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* 27 */514229ul, /* 28 */832040ul, /* 29 */1346269ul, /* 30 */2178309ul,             \
101011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* 31 */3524578ul, /* 32 */5702887ul, /* 33 */9227465ul, /* 34 */14930352ul,          \
101111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* 35 */24157817ul, /* 36 */39088169ul, /* 37 */63245986ul, /* 38 */102334155ul,      \
101211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* 39 */165580141ul, /* 40 */267914296ul, /* 41 */433494437ul,                        \
101311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* 42 */701408733ul, /* 43 */1134903170ul, /* 44 */1836311903ul,                      \
101411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* 45 */2971215073ul }
101511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
101611cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc>
101711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertconst unsigned long
101811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertrope<_CharT,_Alloc>::_S_min_len[__ROPE_DEPTH_SIZE] __ROPE_TABLE_BODY;
101911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# undef __ROPE_DEPTH_SIZE
102011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# undef __ROPE_MAX_DEPTH
102111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# undef __ROPE_TABLE_BODY
102211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
102311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// These are Fibonacci numbers < 2**32.
102411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
102511cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc>
102611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__RopeRep__* rope<_CharT,_Alloc>::_S_balance(_RopeRep* __r) {
102711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _RopeRep* __forest[_RopeRep::_S_max_rope_depth + 1] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
102811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                                         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
102911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                                         0,0,0,0,0,0};
103011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _RopeRep* __result = 0;
103111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  int __i;
103211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // Invariant:
103311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // The concatenation of forest in descending order is equal to __r.
103411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // __forest[__i]._M_size._M_data >= _S_min_len[__i]
103511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // __forest[__i]._M_depth = __i
103611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // References from forest are included in refcount.
103711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
103811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _STLP_TRY {
103911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _S_add_to_forest(__r, __forest);
104011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    for (__i = 0; __i <= _RopeRep::_S_max_rope_depth; ++__i)
104111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      if (0 != __forest[__i]) {
104211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        _Self_destruct_ptr __old(__result);
104311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        __result = _S_concat_rep(__forest[__i], __result);
104411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        __forest[__i]->_M_unref_nonnil();
104511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# ifdef _STLP_USE_EXCEPTIONS
104611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        __forest[__i] = 0;
104711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# endif
104811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
104911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
105011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _STLP_UNWIND(for(__i = 0; __i <= _RopeRep::_S_max_rope_depth; ++__i)
105111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _S_unref(__forest[__i]))
105211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (__result->_M_depth > _RopeRep::_S_max_rope_depth) {
105311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __stl_throw_range_error("rope too long");
105411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
105511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return(__result);
105611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
105711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
105811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
105911cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc>
106011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid
106111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertrope<_CharT,_Alloc>::_S_add_to_forest(_RopeRep* __r, _RopeRep** __forest)
106211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
106311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (__r -> _M_is_balanced) {
106411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _S_add_leaf_to_forest(__r, __forest);
106511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return;
106611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
106711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _STLP_ASSERT(__r->_M_tag == _RopeRep::_S_concat)
106811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
106911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _RopeConcatenation* __c = (_RopeConcatenation*)__r;
107011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
107111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _S_add_to_forest(__c->_M_left, __forest);
107211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _S_add_to_forest(__c->_M_right, __forest);
107311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
107411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
107511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
107611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
107711cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc>
107811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid
107911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertrope<_CharT,_Alloc>::_S_add_leaf_to_forest(_RopeRep* __r, _RopeRep** __forest)
108011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
108111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeRep* __insertee;       // included in refcount
108211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeRep* __too_tiny = 0;      // included in refcount
108311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    int __i;          // forest[0..__i-1] is empty
108411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    size_t __s = __r->_M_size._M_data;
108511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
108611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    for (__i = 0; __s >= _S_min_len[__i+1]/* not this bucket */; ++__i) {
108711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (0 != __forest[__i]) {
108811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        _Self_destruct_ptr __old(__too_tiny);
108911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __too_tiny = _S_concat_and_set_balanced(__forest[__i], __too_tiny);
109011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __forest[__i]->_M_unref_nonnil();
109111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __forest[__i] = 0;
109211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
109311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
109411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
109511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _Self_destruct_ptr __old(__too_tiny);
109611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __insertee = _S_concat_and_set_balanced(__too_tiny, __r);
109711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
109811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // Too_tiny dead, and no longer included in refcount.
109911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // Insertee is live and included.
110011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _STLP_ASSERT(_S_is_almost_balanced(__insertee))
110111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _STLP_ASSERT(__insertee->_M_depth <= __r->_M_depth + 1)
110211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    for (;; ++__i) {
110311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      if (0 != __forest[__i]) {
110411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        _Self_destruct_ptr __old(__insertee);
110511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __insertee = _S_concat_and_set_balanced(__forest[__i], __insertee);
110611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __forest[__i]->_M_unref_nonnil();
110711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __forest[__i] = 0;
110811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _STLP_ASSERT(_S_is_almost_balanced(__insertee))
110911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
111011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _STLP_ASSERT(_S_min_len[__i] <= __insertee->_M_size._M_data)
111111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _STLP_ASSERT(__forest[__i] == 0)
111211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (__i == _RopeRep::_S_max_rope_depth ||
111311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        __insertee->_M_size._M_data < _S_min_len[__i+1]) {
111411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __forest[__i] = __insertee;
111511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      // refcount is OK since __insertee is now dead.
111611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return;
111711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
111811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
111911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
112011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
112111cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc>
112211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_CharT
112311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertrope<_CharT,_Alloc>::_S_fetch(_RopeRep* __r, size_type __i)
112411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
112511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _CharT* __cstr = __r->_M_c_string;
112611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
112711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _STLP_ASSERT(__i < __r->_M_size._M_data)
112811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (0 != __cstr) return __cstr[__i];
112911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    for(;;) {
113011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      switch(__r->_M_tag) {
113111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  case _RopeRep::_S_concat:
113211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      {
113311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeConcatenation* __c = (_RopeConcatenation*)__r;
113411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeRep* __left = __c->_M_left;
113511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    size_t __left_len = __left->_M_size._M_data;
113611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
113711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (__i >= __left_len) {
113811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        __i -= __left_len;
113911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        __r = __c->_M_right;
114011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    } else {
114111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        __r = __left;
114211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
114311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
114411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      break;
114511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  case _RopeRep::_S_leaf:
114611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      {
114711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeLeaf* __l = (_RopeLeaf*)__r;
114811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return __l->_M_data[__i];
114911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
115011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  case _RopeRep::_S_function:
115111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  case _RopeRep::_S_substringfn:
115211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      {
115311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeFunction* __f = (_RopeFunction*)__r;
115411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _CharT __result;
115511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
115611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    (*(__f->_M_fn))(__i, 1, &__result);
115711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return __result;
115811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
115911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
116011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
116111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined(_STLP_NEED_UNREACHABLE_RETURN)
116211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return 0;
116311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
116411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
116511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
116611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Return a uniquely referenced character slot for the given
116711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// position, or 0 if that's not possible.
116811cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc>
116911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_CharT*
117011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertrope<_CharT,_Alloc>::_S_fetch_ptr(_RopeRep* __r, size_type __i)
117111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
117211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeRep* __clrstack[_RopeRep::_S_max_rope_depth];
117311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    size_t __csptr = 0;
117411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
117511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    for(;;) {
117611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      // if (__r->_M_ref_count > 1) return 0;
117711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      if ( __r->_M_incr() > 2 ) {
117811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        __r->_M_decr();
117911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        return 0;
118011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
118111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      switch(__r->_M_tag) {
118211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  case _RopeRep::_S_concat:
118311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      {
118411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeConcatenation* __c = (_RopeConcatenation*)__r;
118511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeRep* __left = __c->_M_left;
118611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    size_t __left_len = __left->_M_size._M_data;
118711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
118811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (__c->_M_c_string != 0) __clrstack[__csptr++] = __c;
118911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (__i >= __left_len) {
119011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        __i -= __left_len;
119111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        __r = __c->_M_right;
119211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    } else {
119311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        __r = __left;
119411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
119511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
119611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      break;
119711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  case _RopeRep::_S_leaf:
119811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      {
119911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeLeaf* __l = (_RopeLeaf*)__r;
120011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (__l->_M_c_string != __l->_M_data && __l->_M_c_string != 0)
120111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        __clrstack[__csptr++] = __l;
120211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    while (__csptr > 0) {
120311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        -- __csptr;
120411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        _RopeRep* __d = __clrstack[__csptr];
120511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        __d->_M_free_c_string();
120611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        __d->_M_c_string = 0;
120711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
120811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return __l->_M_data + __i;
120911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
121011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  case _RopeRep::_S_function:
121111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  case _RopeRep::_S_substringfn:
121211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return 0;
121311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
121411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
121511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined(_STLP_NEED_UNREACHABLE_RETURN)
121611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return 0;
121711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
121811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
121911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
122011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
122111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// The following could be implemented trivially using
122211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// lexicographical_compare_3way.
122311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// We do a little more work to avoid dealing with rope iterators for
122411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// flat strings.
122511cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc>
122611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertint
122711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertrope<_CharT,_Alloc>::_S_compare (const _RopeRep* __left,
122811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                 const _RopeRep* __right) {
122911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  size_t __left_len;
123011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  size_t __right_len;
123111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
123211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (0 == __right) return 0 != __left;
123311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (0 == __left) return -1;
123411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __left_len = __left->_M_size._M_data;
123511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __right_len = __right->_M_size._M_data;
123611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (_RopeRep::_S_leaf == __left->_M_tag) {
123711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    const _RopeLeaf* __l = __STATIC_CAST(const _RopeLeaf*, __left);
123811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (_RopeRep::_S_leaf == __right->_M_tag) {
123911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      const _RopeLeaf* __r = __STATIC_CAST(const _RopeLeaf*, __right);
124011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return _STLP_PRIV __lexicographical_compare_3way(__l->_M_data, __l->_M_data + __left_len,
124111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                                       __r->_M_data, __r->_M_data + __right_len);
124211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
124311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    else {
124411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      const_iterator __rstart(__right, 0);
124511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      const_iterator __rend(__right, __right_len);
124611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return _STLP_PRIV __lexicographical_compare_3way(__l->_M_data, __l->_M_data + __left_len,
124711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                                       __rstart, __rend);
124811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
124911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
125011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  else {
125111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    const_iterator __lstart(__left, 0);
125211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    const_iterator __lend(__left, __left_len);
125311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (_RopeRep::_S_leaf == __right->_M_tag) {
125411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      const _RopeLeaf* __r = __STATIC_CAST(const _RopeLeaf*, __right);
125511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return _STLP_PRIV __lexicographical_compare_3way(__lstart, __lend,
125611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                                       __r->_M_data, __r->_M_data + __right_len);
125711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
125811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    else {
125911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      const_iterator __rstart(__right, 0);
126011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      const_iterator __rend(__right, __right_len);
126111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return _STLP_PRIV __lexicographical_compare_3way(__lstart, __lend, __rstart, __rend);
126211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
126311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
126411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
126511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
126611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Assignment to reference proxies.
126711cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc>
126811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_Rope_char_ref_proxy<_CharT, _Alloc>&
126911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_Rope_char_ref_proxy<_CharT, _Alloc>::operator= (_CharT __c) {
127011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeRep* __old = _M_root->_M_tree_ptr._M_data;
127111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // First check for the case in which everything is uniquely
127211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // referenced.  In that case we can do this destructively.
127311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _CharT* __ptr = _My_rope::_S_fetch_ptr(__old, _M_pos);
127411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (0 != __ptr) {
127511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      *__ptr = __c;
127611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return *this;
127711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
127811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _Self_destruct_ptr __left(
127911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _My_rope::_S_substring(__old, 0, _M_pos));
128011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _Self_destruct_ptr __right(
128111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _My_rope::_S_substring(__old, _M_pos+1, __old->_M_size._M_data));
128211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _Self_destruct_ptr __result_left(
128311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _My_rope::_S_destr_concat_char_iter(__left, &__c, 1));
128411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
128511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // _STLP_ASSERT(__left == __result_left || 1 == __result_left->_M_ref_count)
128611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeRep* __result =
128711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _My_rope::_S_concat_rep(__result_left, __right);
128811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // _STLP_ASSERT(1 <= __result->_M_ref_count)
128911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _RopeRep::_S_unref(__old);
129011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _M_root->_M_tree_ptr._M_data = __result;
129111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return *this;
129211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
129311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
129411cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc>
129511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_Rope_char_ptr_proxy<_CharT, _Alloc>
129611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_Rope_char_ref_proxy<_CharT, _Alloc>::operator& () const {
129711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return _Rope_char_ptr_proxy<_CharT, _Alloc>(*this);
129811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
129911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
130011cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate<class _CharT, class _Alloc>
130111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_CharT rope<_CharT,_Alloc>::_S_empty_c_str[1] = { _CharT() };
130211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// # endif
130311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
130411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if !defined (_STLP_STATIC_CONST_INIT_BUG) && !defined (_STLP_NO_STATIC_CONST_DEFINITION)
130511cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Alloc>
130611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertconst size_t rope<_CharT, _Alloc>::npos;
130711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
130811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
130911cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate<class _CharT, class _Alloc>
131011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertconst _CharT* rope<_CharT,_Alloc>::c_str() const {
131111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (0 == _M_tree_ptr._M_data) {
131211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // Possibly redundant, but probably fast.
131311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _S_empty_c_str[0] = _STLP_DEFAULT_CONSTRUCTED(_CharT);
131411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return _S_empty_c_str;
131511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
131611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _CharT* __old_c_string = _M_tree_ptr._M_data->_M_c_string;
131711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (0 != __old_c_string) return __old_c_string;
131811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  size_t __s = size();
131911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _CharT* __result = _STLP_CREATE_ALLOCATOR(allocator_type,(const allocator_type&)_M_tree_ptr, _CharT).allocate(__s + 1);
132011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _S_flatten(_M_tree_ptr._M_data, __result);
132111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _S_construct_null(__result + __s);
132211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __old_c_string = __STATIC_CAST(_CharT*, _Atomic_swap_ptr(__REINTERPRET_CAST(void* _STLP_VOLATILE*, &(_M_tree_ptr._M_data->_M_c_string)),
132311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                                           __result));
132411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (0 != __old_c_string) {
132511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // It must have been added in the interim.  Hence it had to have been
132611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // separately allocated.  Deallocate the old copy, since we just
132711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // replaced it.
132811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _STLP_STD::_Destroy_Range(__old_c_string, __old_c_string + __s + 1);
132911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _STLP_CREATE_ALLOCATOR(allocator_type,(const allocator_type&)_M_tree_ptr, _CharT).deallocate(__old_c_string, __s + 1);
133011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
133111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return __result;
133211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
133311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
133411cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate<class _CharT, class _Alloc>
133511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertconst _CharT* rope<_CharT,_Alloc>::replace_with_c_str() {
133611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (0 == _M_tree_ptr._M_data) {
133711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _S_empty_c_str[0] = _STLP_DEFAULT_CONSTRUCTED(_CharT);
133811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return _S_empty_c_str;
133911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
134011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _CharT* __old_c_string = _M_tree_ptr._M_data->_M_c_string;
134111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (_RopeRep::_S_leaf == _M_tree_ptr._M_data->_M_tag && 0 != __old_c_string) {
134211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return __old_c_string;
134311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
134411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  size_t __s = size();
134511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _CharT* __result = _M_tree_ptr.allocate(_S_rounded_up_size(__s));
134611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _S_flatten(_M_tree_ptr._M_data, __result);
134711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _S_construct_null(__result + __s);
134811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _M_tree_ptr._M_data->_M_unref_nonnil();
134911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _M_tree_ptr._M_data = _S_new_RopeLeaf(__result, __s, _M_tree_ptr);
135011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return __result;
135111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
135211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
135311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Algorithm specializations.  More should be added.
135411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
135511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if (!defined (_STLP_MSVC) || (_STLP_MSVC >= 1310)) && !defined (__DMC__)
135611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// I couldn't get this to work with VC++
135711cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate<class _CharT,class _Alloc>
135811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid _Rope_rotate(_Rope_iterator<_CharT,_Alloc> __first,
135911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                  _Rope_iterator<_CharT,_Alloc> __middle,
136011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                  _Rope_iterator<_CharT,_Alloc> __last) {
136111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _STLP_ASSERT(__first.container() == __middle.container() &&
136211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert               __middle.container() == __last.container())
136311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  rope<_CharT,_Alloc>& __r(__first.container());
136411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  rope<_CharT,_Alloc> __prefix = __r.substr(0, __first.index());
136511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  rope<_CharT,_Alloc> __suffix =
136611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __r.substr(__last.index(), __r.size() - __last.index());
136711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  rope<_CharT,_Alloc> __part1 =
136811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __r.substr(__middle.index(), __last.index() - __middle.index());
136911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  rope<_CharT,_Alloc> __part2 =
137011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __r.substr(__first.index(), __middle.index() - __first.index());
137111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __r = __prefix;
137211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __r += __part1;
137311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __r += __part2;
137411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __r += __suffix;
137511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
137611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
137711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
137811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# if 0
137911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Probably not useful for several reasons:
138011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// - for SGIs 7.1 compiler and probably some others,
138111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//   this forces lots of rope<wchar_t, ...> instantiations, creating a
138211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//   code bloat and compile time problem.  (Fixed in 7.2.)
138311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// - wchar_t is 4 bytes wide on most UNIX platforms, making it unattractive
138411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//   for unicode strings.  Unsigned short may be a better character
138511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//   type.
138611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertinline void rotate(
138711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _Rope_iterator<wchar_t, allocator<char> > __first,
138811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                _Rope_iterator<wchar_t, allocator<char> > __middle,
138911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                _Rope_iterator<wchar_t, allocator<char> > __last) {
139011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _Rope_rotate(__first, __middle, __last);
139111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
139211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# endif
139311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif /* _STLP_MSVC */
139411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
139511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#   undef __RopeLeaf__
139611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#   undef __RopeRep__
139711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#   undef __RopeLeaf
139811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#   undef __RopeRep
139911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#   undef size_type
140011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
140111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_STLP_END_NAMESPACE
140211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
140311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# endif /* ROPEIMPL_H */
140411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
140511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Local Variables:
140611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// mode:C++
140711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// End:
1408