1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/epoc32/include/tools/stlport/stl/_rope.c Wed Mar 31 12:33:34 2010 +0100
1.3 @@ -0,0 +1,1433 @@
1.4 +/*
1.5 + * Copyright (c) 1996,1997
1.6 + * Silicon Graphics Computer Systems, Inc.
1.7 + *
1.8 + * Copyright (c) 1999
1.9 + * Boris Fomitchev
1.10 + *
1.11 + * This material is provided "as is", with absolutely no warranty expressed
1.12 + * or implied. Any use is at your own risk.
1.13 + *
1.14 + * Permission to use or copy this software for any purpose is hereby granted
1.15 + * without fee, provided the above notices are retained on all copies.
1.16 + * Permission to modify the code and to distribute modified code is granted,
1.17 + * provided the above notices are retained, and a notice that the code was
1.18 + * modified is included with the above copyright notice.
1.19 + *
1.20 + */
1.21 +
1.22 +/* NOTE: This is an internal header file, included by other STL headers.
1.23 + * You should not attempt to use it directly.
1.24 + */
1.25 +
1.26 +// Set buf_start, buf_end, and buf_ptr appropriately, filling tmp_buf
1.27 +// if necessary. Assumes path_end[leaf_index] and leaf_pos are correct.
1.28 +// Results in a valid buf_ptr if the iterator can be legitimately
1.29 +// dereferenced.
1.30 +#ifndef _STLP_ROPEIMPL_H
1.31 +#define _STLP_ROPEIMPL_H
1.32 +
1.33 +#ifndef _STLP_INTERNAL_ROPE_H
1.34 +# include <stl/_rope.h>
1.35 +#endif
1.36 +
1.37 +#ifndef _STLP_INTERNAL_CSTDIO
1.38 +# include <stl/_cstdio.h>
1.39 +#endif
1.40 +
1.41 +#if !defined (_STLP_USE_NO_IOSTREAMS)
1.42 +# ifndef _STLP_IOSTREAM
1.43 +# include <iostream>
1.44 +# endif
1.45 +#endif
1.46 +
1.47 +#include <stl/_range_errors.h>
1.48 +
1.49 +_STLP_BEGIN_NAMESPACE
1.50 +
1.51 +# if defined ( _STLP_NESTED_TYPE_PARAM_BUG )
1.52 +# define __allocator__ _Alloc
1.53 +# else
1.54 +# define __allocator__ allocator_type
1.55 +# endif
1.56 +
1.57 +template<class _CharT, class _Alloc>
1.58 +_Rope_iterator<_CharT, _Alloc>::_Rope_iterator(rope<_CharT,_Alloc>* __r, size_t __pos)
1.59 + : _Rope_iterator_base<_CharT,_Alloc>(__r->_M_tree_ptr._M_data, __pos),
1.60 + _M_root_rope(__r) { _RopeRep::_S_ref(this->_M_root); }
1.61 +
1.62 +template<class _CharT, class _Alloc>
1.63 +_Rope_iterator<_CharT, _Alloc>::_Rope_iterator(rope<_CharT,_Alloc>& __r, size_t __pos):
1.64 + _Rope_iterator_base<_CharT,_Alloc>(__r._M_tree_ptr._M_data, __pos),
1.65 + _M_root_rope(&__r) {
1.66 +#if !defined (__DMC__)
1.67 + _RopeRep::_S_ref(this->_M_root); if (!(__r.empty()))_S_setcache(*this);
1.68 +#else
1.69 + _Rope_iterator_base<_CharT, _Alloc>* __x = this;
1.70 + _RopeRep::_S_ref(this->_M_root); if (!(__r.empty()))_S_setcache(*__x);
1.71 +#endif
1.72 +}
1.73 +
1.74 +template<class _CharT, class _Alloc>
1.75 +void _Rope_RopeRep<_CharT, _Alloc>::_M_free_c_string() {
1.76 + _CharT* __cstr = _M_c_string;
1.77 + if (0 != __cstr) {
1.78 + size_t _p_size = _M_size._M_data + 1;
1.79 + _STLP_STD::_Destroy_Range(__cstr, __cstr + _p_size);
1.80 + _M_size.deallocate(__cstr, _p_size);
1.81 + }
1.82 +}
1.83 +
1.84 +// Set buf_start, buf_end, and buf_ptr appropriately, filling tmp_buf
1.85 +// if necessary. Assumes _M_path_end[leaf_index] and leaf_pos are correct.
1.86 +// Results in a valid buf_ptr if the iterator can be legitimately
1.87 +// dereferenced.
1.88 +template <class _CharT, class _Alloc>
1.89 +void _Rope_iterator_base<_CharT,_Alloc>::_S_setbuf(
1.90 + _Rope_iterator_base<_CharT,_Alloc>& __x) {
1.91 + const _RopeRep* __leaf = __x._M_path_end._M_data[__x._M_leaf_index];
1.92 + size_t __leaf_pos = __x._M_leaf_pos;
1.93 + size_t __pos = __x._M_current_pos;
1.94 +
1.95 + switch(__leaf->_M_tag) {
1.96 + case _RopeRep::_S_leaf:
1.97 + typedef _Rope_RopeLeaf<_CharT, _Alloc> _RopeLeaf;
1.98 + __x._M_buf_start = __STATIC_CAST(const _RopeLeaf*, __leaf)->_M_data;
1.99 + __x._M_buf_ptr = __x._M_buf_start + (__pos - __leaf_pos);
1.100 + __x._M_buf_end = __x._M_buf_start + __leaf->_M_size._M_data;
1.101 + break;
1.102 + case _RopeRep::_S_function:
1.103 + case _RopeRep::_S_substringfn:
1.104 + {
1.105 + size_t __len = _S_iterator_buf_len;
1.106 + size_t __buf_start_pos = __leaf_pos;
1.107 + size_t __leaf_end = __leaf_pos + __leaf->_M_size._M_data;
1.108 + typedef _Rope_RopeFunction<_CharT, _Alloc> _RopeFunction;
1.109 + char_producer<_CharT>* __fn = __STATIC_CAST(const _RopeFunction*, __leaf)->_M_fn;
1.110 +
1.111 + if (__buf_start_pos + __len <= __pos) {
1.112 + __buf_start_pos = __pos - __len/4;
1.113 + if (__buf_start_pos + __len > __leaf_end) {
1.114 + __buf_start_pos = __leaf_end - __len;
1.115 + }
1.116 + }
1.117 + if (__buf_start_pos + __len > __leaf_end) {
1.118 + __len = __leaf_end - __buf_start_pos;
1.119 + }
1.120 + (*__fn)(__buf_start_pos - __leaf_pos, __len, __x._M_tmp_buf._M_data);
1.121 + __x._M_buf_ptr = __x._M_tmp_buf._M_data + (__pos - __buf_start_pos);
1.122 + __x._M_buf_start = __x._M_tmp_buf._M_data;
1.123 + __x._M_buf_end = __x._M_tmp_buf._M_data + __len;
1.124 + }
1.125 + break;
1.126 + default:
1.127 + _STLP_ASSERT(0)
1.128 + ;
1.129 + }
1.130 +}
1.131 +
1.132 +// Set path and buffer inside a rope iterator. We assume that
1.133 +// pos and root are already set.
1.134 +template <class _CharT, class _Alloc>
1.135 +void _Rope_iterator_base<_CharT,_Alloc>::_S_setcache(
1.136 + _Rope_iterator_base<_CharT,_Alloc>& __x) {
1.137 + const _RopeRep* __path[_RopeRep::_S_max_rope_depth+1];
1.138 + const _RopeRep* __curr_rope;
1.139 + int __curr_depth = -1; /* index into path */
1.140 + size_t __curr_start_pos = 0;
1.141 + size_t __pos = __x._M_current_pos;
1.142 + unsigned char __dirns = 0; // Bit vector marking right turns in the path
1.143 +
1.144 + _STLP_ASSERT(__pos <= __x._M_root->_M_size._M_data)
1.145 + if (__pos >= __x._M_root->_M_size._M_data) {
1.146 + __x._M_buf_ptr = 0;
1.147 + return;
1.148 + }
1.149 + __curr_rope = __x._M_root;
1.150 + if (0 != __curr_rope->_M_c_string) {
1.151 + /* Treat the root as a leaf. */
1.152 + __x._M_buf_start = __curr_rope->_M_c_string;
1.153 + __x._M_buf_end = __curr_rope->_M_c_string + __curr_rope->_M_size._M_data;
1.154 + __x._M_buf_ptr = __curr_rope->_M_c_string + __pos;
1.155 + __x._M_path_end._M_data[0] = __curr_rope;
1.156 + __x._M_leaf_index = 0;
1.157 + __x._M_leaf_pos = 0;
1.158 + return;
1.159 + }
1.160 + for(;;) {
1.161 + ++__curr_depth;
1.162 + _STLP_ASSERT(__curr_depth <= _RopeRep::_S_max_rope_depth)
1.163 + __path[__curr_depth] = __curr_rope;
1.164 + switch(__curr_rope->_M_tag) {
1.165 + case _RopeRep::_S_leaf:
1.166 + case _RopeRep::_S_function:
1.167 + case _RopeRep::_S_substringfn:
1.168 + __x._M_leaf_pos = __curr_start_pos;
1.169 + goto done;
1.170 + case _RopeRep::_S_concat:
1.171 + {
1.172 + const _RopeConcat* __c = __STATIC_CAST(const _RopeConcat*, __curr_rope);
1.173 + _RopeRep* __left = __c->_M_left;
1.174 + size_t __left_len = __left->_M_size._M_data;
1.175 +
1.176 + __dirns <<= 1;
1.177 + if (__pos >= __curr_start_pos + __left_len) {
1.178 + __dirns |= 1;
1.179 + __curr_rope = __c->_M_right;
1.180 + __curr_start_pos += __left_len;
1.181 + } else {
1.182 + __curr_rope = __left;
1.183 + }
1.184 + }
1.185 + break;
1.186 + }
1.187 + }
1.188 +done:
1.189 + // Copy last section of path into _M_path_end.
1.190 + {
1.191 + int __i = -1;
1.192 + int __j = __curr_depth + 1 - _S_path_cache_len;
1.193 +
1.194 + if (__j < 0) __j = 0;
1.195 + while (__j <= __curr_depth) {
1.196 + __x._M_path_end._M_data[++__i] = __path[__j++];
1.197 + }
1.198 + __x._M_leaf_index = __i;
1.199 + }
1.200 + __x._M_path_directions = __dirns;
1.201 + _S_setbuf(__x);
1.202 +}
1.203 +
1.204 +// Specialized version of the above. Assumes that
1.205 +// the path cache is valid for the previous position.
1.206 +template <class _CharT, class _Alloc>
1.207 +void _Rope_iterator_base<_CharT,_Alloc>::_S_setcache_for_incr(
1.208 +_Rope_iterator_base<_CharT,_Alloc>& __x) {
1.209 + int __current_index = __x._M_leaf_index;
1.210 + const _RopeRep* __current_node = __x._M_path_end._M_data[__current_index];
1.211 + size_t __len = __current_node->_M_size._M_data;
1.212 + size_t __node_start_pos = __x._M_leaf_pos;
1.213 + unsigned char __dirns = __x._M_path_directions;
1.214 + const _RopeConcat* __c;
1.215 +
1.216 + _STLP_ASSERT(__x._M_current_pos <= __x._M_root->_M_size._M_data)
1.217 + if (__x._M_current_pos - __node_start_pos < __len) {
1.218 + /* More stuff in this leaf, we just didn't cache it. */
1.219 + _S_setbuf(__x);
1.220 + return;
1.221 + }
1.222 + _STLP_ASSERT(__node_start_pos + __len == __x._M_current_pos)
1.223 + // node_start_pos is starting position of last_node.
1.224 + while (--__current_index >= 0) {
1.225 + if (!(__dirns & 1) /* Path turned left */)
1.226 + break;
1.227 + __current_node = __x._M_path_end._M_data[__current_index];
1.228 + __c = __STATIC_CAST(const _RopeConcat*, __current_node);
1.229 + // Otherwise we were in the right child. Thus we should pop
1.230 + // the concatenation node.
1.231 + __node_start_pos -= __c->_M_left->_M_size._M_data;
1.232 + __dirns >>= 1;
1.233 + }
1.234 + if (__current_index < 0) {
1.235 + // We underflowed the cache. Punt.
1.236 + _S_setcache(__x);
1.237 + return;
1.238 + }
1.239 + __current_node = __x._M_path_end._M_data[__current_index];
1.240 + __c = __STATIC_CAST(const _RopeConcat*, __current_node);
1.241 + // current_node is a concatenation node. We are positioned on the first
1.242 + // character in its right child.
1.243 + // node_start_pos is starting position of current_node.
1.244 + __node_start_pos += __c->_M_left->_M_size._M_data;
1.245 + __current_node = __c->_M_right;
1.246 + __x._M_path_end._M_data[++__current_index] = __current_node;
1.247 + __dirns |= 1;
1.248 + while (_RopeRep::_S_concat == __current_node->_M_tag) {
1.249 + ++__current_index;
1.250 + if (_S_path_cache_len == __current_index) {
1.251 + int __i;
1.252 + for (__i = 0; __i < _S_path_cache_len-1; ++__i) {
1.253 + __x._M_path_end._M_data[__i] = __x._M_path_end._M_data[__i+1];
1.254 + }
1.255 + --__current_index;
1.256 + }
1.257 + __current_node = __STATIC_CAST(const _RopeConcat*, __current_node)->_M_left;
1.258 + __x._M_path_end._M_data[__current_index] = __current_node;
1.259 + __dirns <<= 1;
1.260 + // node_start_pos is unchanged.
1.261 + }
1.262 + __x._M_leaf_index = __current_index;
1.263 + __x._M_leaf_pos = __node_start_pos;
1.264 + __x._M_path_directions = __dirns;
1.265 + _S_setbuf(__x);
1.266 +}
1.267 +
1.268 +template <class _CharT, class _Alloc>
1.269 +void _Rope_iterator_base<_CharT,_Alloc>::_M_incr(size_t __n) {
1.270 + _M_current_pos += __n;
1.271 + if (0 != _M_buf_ptr) {
1.272 + size_t __chars_left = _M_buf_end - _M_buf_ptr;
1.273 + if (__chars_left > __n) {
1.274 + _M_buf_ptr += __n;
1.275 + } else if (__chars_left == __n) {
1.276 + _M_buf_ptr += __n;
1.277 + _S_setcache_for_incr(*this);
1.278 + } else {
1.279 + _M_buf_ptr = 0;
1.280 + }
1.281 + }
1.282 +}
1.283 +
1.284 +template <class _CharT, class _Alloc>
1.285 +void _Rope_iterator_base<_CharT,_Alloc>::_M_decr(size_t __n) {
1.286 + if (0 != _M_buf_ptr) {
1.287 + size_t __chars_left = _M_buf_ptr - _M_buf_start;
1.288 + if (__chars_left >= __n) {
1.289 + _M_buf_ptr -= __n;
1.290 + } else {
1.291 + _M_buf_ptr = 0;
1.292 + }
1.293 + }
1.294 + _M_current_pos -= __n;
1.295 +}
1.296 +
1.297 +template <class _CharT, class _Alloc>
1.298 +void _Rope_iterator<_CharT,_Alloc>::_M_check() {
1.299 + if (_M_root_rope->_M_tree_ptr._M_data != this->_M_root) {
1.300 + // _Rope was modified. Get things fixed up.
1.301 + _RopeRep::_S_unref(this->_M_root);
1.302 + this->_M_root = _M_root_rope->_M_tree_ptr._M_data;
1.303 + _RopeRep::_S_ref(this->_M_root);
1.304 + this->_M_buf_ptr = 0;
1.305 + }
1.306 +}
1.307 +
1.308 +// There are several reasons for not doing this with virtual destructors
1.309 +// and a class specific delete operator:
1.310 +// - A class specific delete operator can't easily get access to
1.311 +// allocator instances if we need them.
1.312 +// - Any virtual function would need a 4 or byte vtable pointer;
1.313 +// this only requires a one byte tag per object.
1.314 +template <class _CharT, class _Alloc>
1.315 +void _Rope_RopeRep<_CharT,_Alloc>::_M_free_tree() {
1.316 + switch (_M_tag) {
1.317 + case _S_leaf:
1.318 + {
1.319 + typedef _Rope_RopeLeaf<_CharT, _Alloc> _RopeLeaf;
1.320 + _RopeLeaf* __l = __STATIC_CAST(_RopeLeaf*, this);
1.321 + _STLP_STD::_Destroy(__l); // ->_Rope_RopeLeaf<_CharT,_Alloc>::~_Rope_RopeLeaf();
1.322 + _STLP_CREATE_ALLOCATOR(allocator_type,(const allocator_type&)_M_size,
1.323 + _RopeLeaf).deallocate(__l, 1);
1.324 + break;
1.325 + }
1.326 + case _S_concat:
1.327 + {
1.328 + typedef _Rope_RopeConcatenation<_CharT, _Alloc> _RopeConcatenation;
1.329 + _RopeConcatenation* __c = __STATIC_CAST(_RopeConcatenation*, this);
1.330 + _STLP_STD::_Destroy(__c);
1.331 + _STLP_CREATE_ALLOCATOR(allocator_type,(const allocator_type&)_M_size,
1.332 + _RopeConcatenation).deallocate(__c, 1);
1.333 + break;
1.334 + }
1.335 + case _S_function:
1.336 + {
1.337 + typedef _Rope_RopeFunction<_CharT, _Alloc> _RopeFunction;
1.338 + _RopeFunction* __f = __STATIC_CAST(_RopeFunction*, this);
1.339 + _STLP_STD::_Destroy(__f);
1.340 + _STLP_CREATE_ALLOCATOR(allocator_type, (const allocator_type&)_M_size,
1.341 + _RopeFunction).deallocate(__f, 1);
1.342 + break;
1.343 + }
1.344 + case _S_substringfn:
1.345 + {
1.346 + typedef _Rope_RopeSubstring<_CharT, _Alloc> _RopeSubstring;
1.347 + _RopeSubstring* __rss = __STATIC_CAST(_RopeSubstring*, this);
1.348 + _STLP_STD::_Destroy(__rss);
1.349 + _STLP_CREATE_ALLOCATOR(allocator_type, (const allocator_type&)_M_size,
1.350 + _RopeSubstring).deallocate(__rss, 1);
1.351 + break;
1.352 + }
1.353 + }
1.354 +}
1.355 +
1.356 +# if defined ( _STLP_NESTED_TYPE_PARAM_BUG )
1.357 +# define __RopeLeaf__ _Rope_RopeLeaf<_CharT,_Alloc>
1.358 +# define __RopeRep__ _Rope_RopeRep<_CharT,_Alloc>
1.359 +# define _RopeLeaf _Rope_RopeLeaf<_CharT,_Alloc>
1.360 +# define _RopeRep _Rope_RopeRep<_CharT,_Alloc>
1.361 +# define size_type size_t
1.362 +# else
1.363 +# define __RopeLeaf__ _STLP_TYPENAME_ON_RETURN_TYPE rope<_CharT,_Alloc>::_RopeLeaf
1.364 +# define __RopeRep__ _STLP_TYPENAME_ON_RETURN_TYPE rope<_CharT,_Alloc>::_RopeRep
1.365 +# endif
1.366 +
1.367 +template <class _CharT, class _Alloc>
1.368 +void rope<_CharT, _Alloc>::_M_throw_out_of_range() const {
1.369 + __stl_throw_out_of_range("rope");
1.370 +}
1.371 +
1.372 +// Concatenate a C string onto a leaf rope by copying the rope data.
1.373 +// Used for short ropes.
1.374 +template <class _CharT, class _Alloc>
1.375 +__RopeLeaf__*
1.376 +rope<_CharT,_Alloc>::_S_leaf_concat_char_iter (
1.377 + _RopeLeaf* __r, const _CharT* __iter, size_t __len) {
1.378 + size_t __old_len = __r->_M_size._M_data;
1.379 + _CharT* __new_data = __r->_M_size.allocate(_S_rounded_up_size(__old_len + __len));
1.380 + _RopeLeaf* __result;
1.381 +
1.382 + _STLP_PRIV __ucopy_n(__r->_M_data, __old_len, __new_data);
1.383 + _STLP_PRIV __ucopy_n(__iter, __len, __new_data + __old_len);
1.384 + _S_construct_null(__new_data + __old_len + __len);
1.385 + _STLP_TRY {
1.386 + __result = _S_new_RopeLeaf(__new_data, __old_len + __len, __r->get_allocator());
1.387 + }
1.388 + _STLP_UNWIND(_RopeRep::_S_free_string(__new_data, __old_len + __len,
1.389 + __r->get_allocator()))
1.390 + return __result;
1.391 +}
1.392 +
1.393 +template <class _CharT, class _Alloc>
1.394 +void _Terminate_RopeLeaf(_Rope_RopeLeaf<_CharT,_Alloc> *__r,
1.395 + size_t __size, const __true_type& /*basic char type*/) {
1.396 + _S_construct_null(__r->_M_data + __size);
1.397 + _STLP_ASSERT(__r->_M_c_string == __r->_M_data)
1.398 +}
1.399 +
1.400 +template <class _CharT, class _Alloc>
1.401 +void _Terminate_RopeLeaf(_Rope_RopeLeaf<_CharT,_Alloc> *__r,
1.402 + size_t, const __false_type& /*basic char type*/) {
1.403 + if (__r->_M_c_string != __r->_M_data && 0 != __r->_M_c_string) {
1.404 + __r->_M_free_c_string();
1.405 + __r->_M_c_string = 0;
1.406 + }
1.407 +}
1.408 +
1.409 +// As above, but it's OK to clobber original if refcount is 1
1.410 +template <class _CharT, class _Alloc>
1.411 +__RopeLeaf__*
1.412 +rope<_CharT,_Alloc>::_S_destr_leaf_concat_char_iter (_RopeLeaf* __r, const _CharT* __iter, size_t __len) {
1.413 + //_STLP_ASSERT(__r->_M_ref_count >= 1)
1.414 + if ( /* __r->_M_ref_count > 1 */ __r->_M_incr() > 2 ) { // - ptr
1.415 + __r->_M_decr(); // - ptr
1.416 + return _S_leaf_concat_char_iter(__r, __iter, __len);
1.417 + }
1.418 + __r->_M_decr(); // - ptr, __r->_M_ref_count == 1 or 0
1.419 + size_t __old_len = __r->_M_size._M_data;
1.420 + if (_S_rounded_up_size(__old_len) == _S_rounded_up_size(__old_len + __len)) {
1.421 + // The space has been partially initialized for the standard
1.422 + // character types. But that doesn't matter for those types.
1.423 + _STLP_PRIV __ucopy_n(__iter, __len, __r->_M_data + __old_len);
1.424 + _Terminate_RopeLeaf(__r, __old_len + __len, _IsBasicCharType());
1.425 + __r->_M_size._M_data = __old_len + __len;
1.426 + // _STLP_ASSERT(__r->_M_ref_count == 1)
1.427 + // __r->_M_ref_count = 2;
1.428 + __r->_M_incr(); // i.e. __r->_M_ref_count = 2
1.429 + return __r;
1.430 + } else {
1.431 + _RopeLeaf* __result = _S_leaf_concat_char_iter(__r, __iter, __len);
1.432 + //_STLP_ASSERT(__result->_M_ref_count == 1)
1.433 + return __result;
1.434 + }
1.435 +}
1.436 +
1.437 +// Assumes left and right are not 0.
1.438 +// Does not increment (nor decrement on exception) child reference counts.
1.439 +// Result has ref count 1.
1.440 +template <class _CharT, class _Alloc>
1.441 +__RopeRep__*
1.442 +rope<_CharT,_Alloc>::_S_tree_concat (_RopeRep* __left, _RopeRep* __right) {
1.443 + _RopeConcatenation* __result =
1.444 + _S_new_RopeConcatenation(__left, __right, __left->get_allocator());
1.445 + size_t __depth = __result->_M_depth;
1.446 +
1.447 + _STLP_ASSERT(__left->get_allocator() == __right->get_allocator())
1.448 + if (__depth > 20 && (__result->_M_size._M_data < 1000 ||
1.449 + __depth > _RopeRep::_S_max_rope_depth)) {
1.450 + _RopeRep* __balanced;
1.451 +
1.452 + _STLP_TRY {
1.453 + __balanced = _S_balance(__result);
1.454 + // _STLP_ASSERT(__result == __balanced ||
1.455 + // 1 == __result->_M_ref_count &&
1.456 + // 1 == __balanced->_M_ref_count)
1.457 + __result->_M_unref_nonnil();
1.458 + }
1.459 + _STLP_UNWIND((_STLP_CREATE_ALLOCATOR(allocator_type,(allocator_type&)__left->_M_size,
1.460 + _RopeConcatenation).deallocate(__result,1)))
1.461 + // In case of exception, we need to deallocate
1.462 + // otherwise dangling result node. But caller
1.463 + // still owns its children. Thus unref is
1.464 + // inappropriate.
1.465 + return __balanced;
1.466 + } else {
1.467 + return __result;
1.468 + }
1.469 +}
1.470 +
1.471 +template <class _CharT, class _Alloc>
1.472 +__RopeRep__*
1.473 +rope<_CharT,_Alloc>::_S_concat_char_iter (_RopeRep* __r,
1.474 + const _CharT*__s, size_t __slen) {
1.475 + _RopeRep* __result;
1.476 + if (0 == __slen) {
1.477 + _S_ref(__r);
1.478 + return __r;
1.479 + }
1.480 + if (0 == __r)
1.481 + return _S_RopeLeaf_from_unowned_char_ptr(__s, __slen, __r->get_allocator());
1.482 + if (_RopeRep::_S_leaf == __r->_M_tag &&
1.483 + __r->_M_size._M_data + __slen <= _S_copy_max) {
1.484 + __result = _S_leaf_concat_char_iter((_RopeLeaf*)__r, __s, __slen);
1.485 + // _STLP_ASSERT(1 == __result->_M_ref_count)
1.486 + return __result;
1.487 + }
1.488 + if (_RopeRep::_S_concat == __r->_M_tag &&
1.489 + _RopeRep::_S_leaf == ((_RopeConcatenation*)__r)->_M_right->_M_tag) {
1.490 + _RopeLeaf* __right = (_RopeLeaf* )(((_RopeConcatenation* )__r)->_M_right);
1.491 + if (__right->_M_size._M_data + __slen <= _S_copy_max) {
1.492 + _RopeRep* __left = ((_RopeConcatenation*)__r)->_M_left;
1.493 + _RopeRep* __nright = _S_leaf_concat_char_iter((_RopeLeaf*)__right, __s, __slen);
1.494 + __left->_M_ref_nonnil();
1.495 + _STLP_TRY {
1.496 + __result = _S_tree_concat(__left, __nright);
1.497 + }
1.498 + _STLP_UNWIND(_S_unref(__left); _S_unref(__nright))
1.499 + // _STLP_ASSERT(1 == __result->_M_ref_count)
1.500 + return __result;
1.501 + }
1.502 + }
1.503 + _RopeRep* __nright =
1.504 + _S_RopeLeaf_from_unowned_char_ptr(__s, __slen, __r->get_allocator());
1.505 + _STLP_TRY {
1.506 + __r->_M_ref_nonnil();
1.507 + __result = _S_tree_concat(__r, __nright);
1.508 + }
1.509 + _STLP_UNWIND(_S_unref(__r); _S_unref(__nright))
1.510 + // _STLP_ASSERT(1 == __result->_M_ref_count)
1.511 + return __result;
1.512 +}
1.513 +
1.514 +template <class _CharT, class _Alloc>
1.515 +__RopeRep__*
1.516 +rope<_CharT,_Alloc>::_S_destr_concat_char_iter(
1.517 + _RopeRep* __r, const _CharT* __s, size_t __slen) {
1.518 + _RopeRep* __result;
1.519 + if (0 == __r)
1.520 + return _S_RopeLeaf_from_unowned_char_ptr(__s, __slen,
1.521 + __r->get_allocator());
1.522 + // size_t __count = __r->_M_ref_count;
1.523 + size_t __orig_size = __r->_M_size._M_data;
1.524 + // _STLP_ASSERT(__count >= 1)
1.525 + if ( /* __count > 1 */ __r->_M_incr() > 2 ) {
1.526 + __r->_M_decr();
1.527 + return _S_concat_char_iter(__r, __s, __slen);
1.528 + }
1.529 + if (0 == __slen) {
1.530 + return __r;
1.531 + }
1.532 + __r->_M_decr();
1.533 + if (__orig_size + __slen <= _S_copy_max && _RopeRep::_S_leaf == __r->_M_tag) {
1.534 + return _S_destr_leaf_concat_char_iter((_RopeLeaf*)__r, __s, __slen);
1.535 + }
1.536 + if (_RopeRep::_S_concat == __r->_M_tag) {
1.537 + _RopeLeaf* __right = __STATIC_CAST(_RopeLeaf*, __STATIC_CAST(_RopeConcatenation*, __r)->_M_right);
1.538 + if (_RopeRep::_S_leaf == __right->_M_tag &&
1.539 + __right->_M_size._M_data + __slen <= _S_copy_max) {
1.540 + _RopeRep* __new_right = _S_destr_leaf_concat_char_iter(__right, __s, __slen);
1.541 + if (__right == __new_right) {
1.542 + // _STLP_ASSERT(__new_right->_M_ref_count == 2)
1.543 + // __new_right->_M_ref_count = 1;
1.544 + __new_right->_M_decr();
1.545 + } else {
1.546 + // _STLP_ASSERT(__new_right->_M_ref_count >= 1)
1.547 + __right->_M_unref_nonnil();
1.548 + }
1.549 + // _STLP_ASSERT(__r->_M_ref_count == 1)
1.550 + // __r->_M_ref_count = 2; // One more than before.
1.551 + __r->_M_incr();
1.552 + __STATIC_CAST(_RopeConcatenation*, __r)->_M_right = __new_right;
1.553 + // E.Musser : moved below
1.554 + // __r->_M_size._M_data = __orig_size + __slen;
1.555 + if (0 != __r->_M_c_string) {
1.556 + __r->_M_free_c_string();
1.557 + __r->_M_c_string = 0;
1.558 + }
1.559 + __r->_M_size._M_data = __orig_size + __slen;
1.560 + return __r;
1.561 + }
1.562 + }
1.563 + _RopeRep* __right =
1.564 + _S_RopeLeaf_from_unowned_char_ptr(__s, __slen, __r->get_allocator());
1.565 + __r->_M_ref_nonnil();
1.566 + _STLP_TRY {
1.567 + __result = _S_tree_concat(__r, __right);
1.568 + }
1.569 + _STLP_UNWIND(_S_unref(__r); _S_unref(__right))
1.570 + // _STLP_ASSERT(1 == __result->_M_ref_count)
1.571 + return __result;
1.572 +}
1.573 +
1.574 +template <class _CharT, class _Alloc>
1.575 +__RopeRep__*
1.576 +rope<_CharT,_Alloc>::_S_concat_rep(_RopeRep* __left, _RopeRep* __right) {
1.577 + if (0 == __left) {
1.578 + _S_ref(__right);
1.579 + return __right;
1.580 + }
1.581 + if (0 == __right) {
1.582 + __left->_M_ref_nonnil();
1.583 + return __left;
1.584 + }
1.585 + if (_RopeRep::_S_leaf == __right->_M_tag) {
1.586 + if (_RopeRep::_S_leaf == __left->_M_tag) {
1.587 + if (__right->_M_size._M_data + __left->_M_size._M_data <= _S_copy_max) {
1.588 + return _S_leaf_concat_char_iter(__STATIC_CAST(_RopeLeaf*, __left),
1.589 + __STATIC_CAST(_RopeLeaf*, __right)->_M_data,
1.590 + __right->_M_size._M_data);
1.591 + }
1.592 + } else if (_RopeRep::_S_concat == __left->_M_tag &&
1.593 + _RopeRep::_S_leaf == __STATIC_CAST(_RopeConcatenation*, __left)->_M_right->_M_tag) {
1.594 + _RopeLeaf* __leftright =
1.595 + __STATIC_CAST(_RopeLeaf*, __STATIC_CAST(_RopeConcatenation*, __left)->_M_right);
1.596 + if (__leftright->_M_size._M_data + __right->_M_size._M_data <= _S_copy_max) {
1.597 + _RopeRep* __leftleft = __STATIC_CAST(_RopeConcatenation*, __left)->_M_left;
1.598 + _RopeRep* __rest = _S_leaf_concat_char_iter(__leftright,
1.599 + __STATIC_CAST(_RopeLeaf*, __right)->_M_data,
1.600 + __right->_M_size._M_data);
1.601 + __leftleft->_M_ref_nonnil();
1.602 + _STLP_TRY {
1.603 + return _S_tree_concat(__leftleft, __rest);
1.604 + }
1.605 + _STLP_UNWIND(_S_unref(__leftleft); _S_unref(__rest))
1.606 + }
1.607 + }
1.608 + }
1.609 + __left->_M_ref_nonnil();
1.610 + __right->_M_ref_nonnil();
1.611 + _STLP_TRY {
1.612 + return _S_tree_concat(__left, __right);
1.613 + }
1.614 + _STLP_UNWIND(_S_unref(__left); _S_unref(__right))
1.615 + _STLP_RET_AFTER_THROW(0)
1.616 +}
1.617 +
1.618 +template <class _CharT, class _Alloc>
1.619 +__RopeRep__*
1.620 +rope<_CharT,_Alloc>::_S_substring(_RopeRep* __base,
1.621 + size_t __start, size_t __endp1) {
1.622 + if (0 == __base) return 0;
1.623 + size_t __len = __base->_M_size._M_data;
1.624 + size_t __adj_endp1;
1.625 + const size_t __lazy_threshold = 128;
1.626 +
1.627 + if (__endp1 >= __len) {
1.628 + if (0 == __start) {
1.629 + __base->_M_ref_nonnil();
1.630 + return __base;
1.631 + } else {
1.632 + __adj_endp1 = __len;
1.633 + }
1.634 + } else {
1.635 + __adj_endp1 = __endp1;
1.636 + }
1.637 + switch(__base->_M_tag) {
1.638 + case _RopeRep::_S_concat:
1.639 + {
1.640 + _RopeConcatenation* __c = __STATIC_CAST(_RopeConcatenation*, __base);
1.641 + _RopeRep* __left = __c->_M_left;
1.642 + _RopeRep* __right = __c->_M_right;
1.643 + size_t __left_len = __left->_M_size._M_data;
1.644 + _RopeRep* __result;
1.645 +
1.646 + if (__adj_endp1 <= __left_len) {
1.647 + return _S_substring(__left, __start, __endp1);
1.648 + } else if (__start >= __left_len) {
1.649 + return _S_substring(__right, __start - __left_len,
1.650 + __adj_endp1 - __left_len);
1.651 + }
1.652 + _Self_destruct_ptr __left_result(_S_substring(__left, __start, __left_len));
1.653 + _Self_destruct_ptr __right_result(_S_substring(__right, 0, __endp1 - __left_len));
1.654 + _STLP_MPWFIX_TRY //*TY 06/01/2000 - mpw forgets to call dtor on __left_result and __right_result without this try block
1.655 + __result = _S_concat_rep(__left_result, __right_result);
1.656 + // _STLP_ASSERT(1 == __result->_M_ref_count)
1.657 + return __result;
1.658 + _STLP_MPWFIX_CATCH //*TY 06/01/2000 -
1.659 + }
1.660 + case _RopeRep::_S_leaf:
1.661 + {
1.662 + _RopeLeaf* __l = __STATIC_CAST(_RopeLeaf*, __base);
1.663 + _RopeLeaf* __result;
1.664 + size_t __result_len;
1.665 + if (__start >= __adj_endp1) return 0;
1.666 + __result_len = __adj_endp1 - __start;
1.667 + if (__result_len > __lazy_threshold) goto lazy;
1.668 + const _CharT* __section = __l->_M_data + __start;
1.669 + // We should sometimes create substring node instead.
1.670 + __result = _S_RopeLeaf_from_unowned_char_ptr(__section, __result_len,
1.671 + __base->get_allocator());
1.672 + return __result;
1.673 + }
1.674 + case _RopeRep::_S_substringfn:
1.675 + // Avoid introducing multiple layers of substring nodes.
1.676 + {
1.677 + _RopeSubstring* __old = __STATIC_CAST(_RopeSubstring*, __base);
1.678 + size_t __result_len;
1.679 + if (__start >= __adj_endp1) return 0;
1.680 + __result_len = __adj_endp1 - __start;
1.681 + if (__result_len > __lazy_threshold) {
1.682 + _RopeSubstring* __result = _S_new_RopeSubstring(__old->_M_base,
1.683 + __start + __old->_M_start,
1.684 + __adj_endp1 - __start,
1.685 + __base->get_allocator());
1.686 + return __result;
1.687 + } // *** else fall through: ***
1.688 + }
1.689 + case _RopeRep::_S_function:
1.690 + {
1.691 + _RopeFunction* __f = __STATIC_CAST(_RopeFunction*, __base);
1.692 + if (__start >= __adj_endp1) return 0;
1.693 + size_t __result_len = __adj_endp1 - __start;
1.694 +
1.695 + if (__result_len > __lazy_threshold) goto lazy;
1.696 + _CharT* __section = __base->_M_size.allocate(_S_rounded_up_size(__result_len));
1.697 + _STLP_TRY {
1.698 + (*(__f->_M_fn))(__start, __result_len, __section);
1.699 + }
1.700 + _STLP_UNWIND(_RopeRep::_S_free_string(__section,
1.701 + __result_len, __base->get_allocator()))
1.702 + _S_construct_null(__section + __result_len);
1.703 + return _S_new_RopeLeaf(__section, __result_len,
1.704 + __base->get_allocator());
1.705 + }
1.706 + }
1.707 + /*NOTREACHED*/
1.708 + _STLP_ASSERT(false)
1.709 + lazy:
1.710 + {
1.711 + // Create substring node.
1.712 + return _S_new_RopeSubstring(__base, __start, __adj_endp1 - __start,
1.713 + __base->get_allocator());
1.714 + }
1.715 +}
1.716 +
1.717 +template<class _CharT>
1.718 +class _Rope_flatten_char_consumer : public _Rope_char_consumer<_CharT> {
1.719 +private:
1.720 + _CharT* _M_buf_ptr;
1.721 +public:
1.722 + _Rope_flatten_char_consumer(_CharT* __buffer) {
1.723 + _M_buf_ptr = __buffer;
1.724 + }
1.725 + ~_Rope_flatten_char_consumer() {}
1.726 + bool operator() (const _CharT* __leaf, size_t __n) {
1.727 + _STLP_PRIV __ucopy_n(__leaf, __n, _M_buf_ptr);
1.728 + _M_buf_ptr += __n;
1.729 + return true;
1.730 + }
1.731 +};
1.732 +
1.733 +template<class _CharT>
1.734 +class _Rope_find_char_char_consumer : public _Rope_char_consumer<_CharT> {
1.735 +private:
1.736 + _CharT _M_pattern;
1.737 +public:
1.738 + size_t _M_count; // Number of nonmatching characters
1.739 + _Rope_find_char_char_consumer(_CharT __p)
1.740 + : _M_pattern(__p), _M_count(0) {}
1.741 + ~_Rope_find_char_char_consumer() {}
1.742 + bool operator() (const _CharT* __leaf, size_t __n) {
1.743 + size_t __i;
1.744 + for (__i = 0; __i < __n; ++__i) {
1.745 + if (__leaf[__i] == _M_pattern) {
1.746 + _M_count += __i; return false;
1.747 + }
1.748 + }
1.749 + _M_count += __n; return true;
1.750 + }
1.751 +};
1.752 +
1.753 +#if !defined (_STLP_USE_NO_IOSTREAMS)
1.754 +template<class _CharT, class _Traits>
1.755 +// Here _CharT is both the stream and rope character type.
1.756 +class _Rope_insert_char_consumer : public _Rope_char_consumer<_CharT> {
1.757 +private:
1.758 + typedef basic_ostream<_CharT,_Traits> _Insert_ostream;
1.759 + typedef _Rope_insert_char_consumer<_CharT,_Traits> _Self;
1.760 + _Insert_ostream& _M_o;
1.761 +
1.762 + //explicitely defined as private to avoid warnings:
1.763 + _Self& operator = (_Self const&);
1.764 +public:
1.765 + _Rope_insert_char_consumer(_Insert_ostream& __writer)
1.766 + : _M_o(__writer) {}
1.767 +# if defined(__MRC__) || (defined(__SC__) && !defined(__DMC__)) //*TY 05/23/2000 - added support for mpw compiler's trigger function approach to generate vtable
1.768 + ~_Rope_insert_char_consumer(); //*TY 05/23/2000 -
1.769 +# else //*TY 05/23/2000 -
1.770 + ~_Rope_insert_char_consumer() {}
1.771 +# endif //*TY 05/23/2000 -
1.772 + // Caller is presumed to own the ostream
1.773 + bool operator() (const _CharT* __leaf, size_t __n);
1.774 + // Returns true to continue traversal.
1.775 +};
1.776 +
1.777 +# if defined (__MRC__) || (defined (__SC__) && !defined (__DMC__)) //*TY 05/23/2000 - added support for mpw compiler's trigger function approach to generate vtable
1.778 +template<class _CharT, class _Traits>
1.779 +_Rope_insert_char_consumer<_CharT, _Traits>:: ~_Rope_insert_char_consumer() {}
1.780 +# endif //*TY 05/23/2000 -
1.781 +
1.782 +template<class _CharT, class _Traits>
1.783 +bool _Rope_insert_char_consumer<_CharT, _Traits>::operator()
1.784 + (const _CharT* __leaf, size_t __n) {
1.785 + size_t __i;
1.786 + // We assume that formatting is set up correctly for each element.
1.787 + for (__i = 0; __i < __n; ++__i) _M_o.put(__leaf[__i]);
1.788 + return true;
1.789 +}
1.790 +#endif /* !_STLP_USE_NO_IOSTREAMS */
1.791 +
1.792 +template <class _CharT, class _Alloc, class _CharConsumer>
1.793 +bool _S_apply_to_pieces(_CharConsumer& __c,
1.794 + _Rope_RopeRep<_CharT, _Alloc> * __r,
1.795 + size_t __begin, size_t __end) {
1.796 + typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep;
1.797 + typedef _Rope_RopeConcatenation<_CharT,_Alloc> _RopeConcatenation;
1.798 + typedef _Rope_RopeLeaf<_CharT,_Alloc> _RopeLeaf;
1.799 + typedef _Rope_RopeFunction<_CharT,_Alloc> _RopeFunction;
1.800 +
1.801 + if (0 == __r) return true;
1.802 + switch(__r->_M_tag) {
1.803 + case _RopeRep::_S_concat:
1.804 + {
1.805 + _RopeConcatenation* __conc = __STATIC_CAST(_RopeConcatenation*, __r);
1.806 + _RopeRep* __left = __conc->_M_left;
1.807 + size_t __left_len = __left->_M_size._M_data;
1.808 + if (__begin < __left_len) {
1.809 + size_t __left_end = (min) (__left_len, __end);
1.810 + if (!_S_apply_to_pieces(__c, __left, __begin, __left_end))
1.811 + return false;
1.812 + }
1.813 + if (__end > __left_len) {
1.814 + _RopeRep* __right = __conc->_M_right;
1.815 + size_t __right_start = (max)(__left_len, __begin);
1.816 + if (!_S_apply_to_pieces(__c, __right,
1.817 + __right_start - __left_len,
1.818 + __end - __left_len)) {
1.819 + return false;
1.820 + }
1.821 + }
1.822 + }
1.823 + return true;
1.824 + case _RopeRep::_S_leaf:
1.825 + {
1.826 + _RopeLeaf* __l = __STATIC_CAST(_RopeLeaf*, __r);
1.827 + return __c(__l->_M_data + __begin, __end - __begin);
1.828 + }
1.829 + case _RopeRep::_S_function:
1.830 + case _RopeRep::_S_substringfn:
1.831 + {
1.832 + _RopeFunction* __f = __STATIC_CAST(_RopeFunction*, __r);
1.833 + size_t __len = __end - __begin;
1.834 + bool __result;
1.835 + _CharT* __buffer = __r->get_allocator().allocate(__len);
1.836 + _STLP_TRY {
1.837 + (*(__f->_M_fn))(__begin, __len, __buffer);
1.838 + __result = __c(__buffer, __len);
1.839 + __r->get_allocator().deallocate(__buffer, __len);
1.840 + }
1.841 + _STLP_UNWIND((__r->get_allocator().deallocate(__buffer, __len)))
1.842 + return __result;
1.843 + }
1.844 + default:
1.845 + _STLP_ASSERT(false)
1.846 + /*NOTREACHED*/
1.847 + return false;
1.848 + }
1.849 +}
1.850 +
1.851 +#if !defined (_STLP_USE_NO_IOSTREAMS)
1.852 +template<class _CharT, class _Traits>
1.853 +inline void _Rope_fill(basic_ostream<_CharT, _Traits>& __o, streamsize __n) {
1.854 + char __f = __o.fill();
1.855 + for (streamsize __i = 0; __i < __n; ++__i) __o.put(__f);
1.856 +}
1.857 +
1.858 +template<class _CharT, class _Traits, class _Alloc>
1.859 +basic_ostream<_CharT, _Traits>& _S_io_get(basic_ostream<_CharT, _Traits>& __o,
1.860 + const rope<_CharT, _Alloc>& __r, const __true_type& /*_IsBasicCharType*/) {
1.861 + streamsize __w = __o.width();
1.862 + const bool __left = (__o.flags() & ios::left) != 0;
1.863 + size_t __rope_len = __r.size();
1.864 + _Rope_insert_char_consumer<_CharT, _Traits> __c(__o);
1.865 +
1.866 + const bool __need_pad = (((sizeof(streamsize) > sizeof(size_t)) && (__STATIC_CAST(streamsize, __rope_len) < __w)) ||
1.867 + ((sizeof(streamsize) <= sizeof(size_t)) && (__rope_len < __STATIC_CAST(size_t, __w))));
1.868 + streamsize __pad_len = __need_pad ? __w - __rope_len : 0;
1.869 +
1.870 + if (!__left && __pad_len > 0) {
1.871 + _Rope_fill(__o, __pad_len);
1.872 + }
1.873 + __r.apply_to_pieces(0, __rope_len, __c);
1.874 + if (__left && __pad_len > 0) {
1.875 + _Rope_fill(__o, __pad_len);
1.876 + }
1.877 + return __o;
1.878 +}
1.879 +
1.880 +template<class _CharT, class _Traits, class _Alloc>
1.881 +basic_ostream<_CharT, _Traits>& _S_io_get(basic_ostream<_CharT, _Traits>& __o,
1.882 + const rope<_CharT, _Alloc>& __r, const __false_type& /*_IsBasicCharType*/) {
1.883 + streamsize __w = __o.width();
1.884 + size_t __rope_len = __r.size();
1.885 + _Rope_insert_char_consumer<_CharT, _Traits> __c(__o);
1.886 +
1.887 + __o.width(__w /__rope_len);
1.888 + _STLP_TRY {
1.889 + __r.apply_to_pieces(0, __rope_len, __c);
1.890 + __o.width(__w);
1.891 + }
1.892 + _STLP_UNWIND(__o.width(__w))
1.893 + return __o;
1.894 +}
1.895 +
1.896 +template<class _CharT, class _Traits, class _Alloc>
1.897 +basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __o,
1.898 + const rope<_CharT, _Alloc>& __r) {
1.899 + typedef typename _IsIntegral<_CharT>::_Ret _Char_Is_Integral;
1.900 + return _S_io_get(__o, __r, _Char_Is_Integral());
1.901 +}
1.902 +#endif /* NO_IOSTREAMS */
1.903 +
1.904 +template <class _CharT, class _Alloc>
1.905 +_CharT* rope<_CharT,_Alloc>::_S_flatten(_RopeRep* __r,
1.906 + size_t __start, size_t __len,
1.907 + _CharT* __buffer) {
1.908 + _Rope_flatten_char_consumer<_CharT> __c(__buffer);
1.909 + _S_apply_to_pieces(__c, __r, __start, __start + __len);
1.910 + return(__buffer + __len);
1.911 +}
1.912 +
1.913 +template <class _CharT, class _Alloc>
1.914 +size_t rope<_CharT,_Alloc>::find(_CharT __pattern, size_t __start) const {
1.915 + _Rope_find_char_char_consumer<_CharT> __c(__pattern);
1.916 + _S_apply_to_pieces(__c, _M_tree_ptr._M_data, __start, size());
1.917 + size_type __result_pos = __start + __c._M_count;
1.918 +#ifndef _STLP_OLD_ROPE_SEMANTICS
1.919 + if (__result_pos == size()) __result_pos = npos;
1.920 +#endif
1.921 + return __result_pos;
1.922 +}
1.923 +
1.924 +template <class _CharT, class _Alloc>
1.925 +_CharT*
1.926 +rope<_CharT,_Alloc>::_S_flatten(_Rope_RopeRep<_CharT, _Alloc>* __r, _CharT* __buffer) {
1.927 + if (0 == __r) return __buffer;
1.928 + switch(__r->_M_tag) {
1.929 + case _RopeRep::_S_concat:
1.930 + {
1.931 + _RopeConcatenation* __c = __STATIC_CAST(_RopeConcatenation*, __r);
1.932 + _RopeRep* __left = __c->_M_left;
1.933 + _RopeRep* __right = __c->_M_right;
1.934 + _CharT* __rest = _S_flatten(__left, __buffer);
1.935 + return _S_flatten(__right, __rest);
1.936 + }
1.937 + case _RopeRep::_S_leaf:
1.938 + {
1.939 + _RopeLeaf* __l = __STATIC_CAST(_RopeLeaf*, __r);
1.940 + return _STLP_PRIV __ucopy_n(__l->_M_data, __l->_M_size._M_data, __buffer).second;
1.941 + }
1.942 + case _RopeRep::_S_function:
1.943 + case _RopeRep::_S_substringfn:
1.944 + // We dont yet do anything with substring nodes.
1.945 + // This needs to be fixed before ropefiles will work well.
1.946 + {
1.947 + _RopeFunction* __f = __STATIC_CAST(_RopeFunction*, __r);
1.948 + (*(__f->_M_fn))(0, __f->_M_size._M_data, __buffer);
1.949 + return __buffer + __f->_M_size._M_data;
1.950 + }
1.951 + default:
1.952 + _STLP_ASSERT(false)
1.953 + /*NOTREACHED*/
1.954 + return 0;
1.955 + }
1.956 +}
1.957 +
1.958 +#ifdef _STLP_DEBUG
1.959 +// This needs work for _CharT != char
1.960 +template <class _CharT, class _Alloc>
1.961 +void rope<_CharT,_Alloc>::_S_dump(_RopeRep* __r, int __indent) {
1.962 + for (int __i = 0; __i < __indent; ++__i) putchar(' ');
1.963 + if (0 == __r) {
1.964 + printf("NULL\n"); return;
1.965 + }
1.966 + if (_RopeRep::_S_concat == __r->_M_tag) {
1.967 + _RopeConcatenation* __c = __STATIC_CAST(_RopeConcatenation*, __r);
1.968 + _RopeRep* __left = __c->_M_left;
1.969 + _RopeRep* __right = __c->_M_right;
1.970 + printf("Concatenation %p (rc = %ld, depth = %d, len = %ld, %s balanced)\n",
1.971 + __r, __r->_M_ref_count, __r->_M_depth, __r->_M_size._M_data,
1.972 + __r->_M_is_balanced? "" : "not");
1.973 + _S_dump(__left, __indent + 2);
1.974 + _S_dump(__right, __indent + 2);
1.975 + return;
1.976 + }
1.977 + else {
1.978 + const char* __kind;
1.979 +
1.980 + switch (__r->_M_tag) {
1.981 + case _RopeRep::_S_leaf:
1.982 + __kind = "Leaf";
1.983 + break;
1.984 + case _RopeRep::_S_function:
1.985 + __kind = "Function";
1.986 + break;
1.987 + case _RopeRep::_S_substringfn:
1.988 + __kind = "Function representing substring";
1.989 + break;
1.990 + default:
1.991 + __kind = "(corrupted kind field!)";
1.992 + }
1.993 + printf("%s %p (rc = %ld, depth = %d, len = %ld) ",
1.994 + __kind, __r, __r->_M_ref_count, __r->_M_depth, __r->_M_size._M_data);
1.995 + if (sizeof(_CharT) == 1) {
1.996 + const int __max_len = 40;
1.997 + _Self_destruct_ptr __prefix(_S_substring(__r, 0, __max_len));
1.998 + _CharT __buffer[__max_len + 1];
1.999 + bool __too_big = __r->_M_size._M_data > __prefix->_M_size._M_data;
1.1000 +
1.1001 + _S_flatten(__prefix, __buffer);
1.1002 + __buffer[__prefix->_M_size._M_data] = _STLP_DEFAULT_CONSTRUCTED(_CharT);
1.1003 + printf("%s%s\n", (char*)__buffer, __too_big? "...\n" : "\n");
1.1004 + } else {
1.1005 + printf("\n");
1.1006 + }
1.1007 + }
1.1008 +}
1.1009 +#endif /* _STLP_DEBUG */
1.1010 +
1.1011 +# define __ROPE_TABLE_BODY = { \
1.1012 +/* 0 */1, /* 1 */2, /* 2 */3, /* 3 */5, /* 4 */8, /* 5 */13, /* 6 */21, \
1.1013 +/* 7 */34, /* 8 */55, /* 9 */89, /* 10 */144, /* 11 */233, /* 12 */377, \
1.1014 +/* 13 */610, /* 14 */987, /* 15 */1597, /* 16 */2584, /* 17 */4181, \
1.1015 +/* 18 */6765ul, /* 19 */10946ul, /* 20 */17711ul, /* 21 */28657ul, /* 22 */46368ul, \
1.1016 +/* 23 */75025ul, /* 24 */121393ul, /* 25 */196418ul, /* 26 */317811ul, \
1.1017 +/* 27 */514229ul, /* 28 */832040ul, /* 29 */1346269ul, /* 30 */2178309ul, \
1.1018 +/* 31 */3524578ul, /* 32 */5702887ul, /* 33 */9227465ul, /* 34 */14930352ul, \
1.1019 +/* 35 */24157817ul, /* 36 */39088169ul, /* 37 */63245986ul, /* 38 */102334155ul, \
1.1020 +/* 39 */165580141ul, /* 40 */267914296ul, /* 41 */433494437ul, \
1.1021 +/* 42 */701408733ul, /* 43 */1134903170ul, /* 44 */1836311903ul, \
1.1022 +/* 45 */2971215073ul }
1.1023 +
1.1024 +# if ( _STLP_STATIC_TEMPLATE_DATA > 0 )
1.1025 +template <class _CharT, class _Alloc>
1.1026 +const unsigned long
1.1027 +rope<_CharT,_Alloc>::_S_min_len[__ROPE_DEPTH_SIZE] __ROPE_TABLE_BODY;
1.1028 +# else
1.1029 +__DECLARE_INSTANCE(const unsigned long,
1.1030 + crope::_S_min_len[__ROPE_DEPTH_SIZE],
1.1031 + __ROPE_TABLE_BODY);
1.1032 +# ifndef _STLP_NO_WCHAR_T
1.1033 +__DECLARE_INSTANCE(const unsigned long,
1.1034 + wrope::_S_min_len[__ROPE_DEPTH_SIZE],
1.1035 + __ROPE_TABLE_BODY);
1.1036 +# endif
1.1037 +# endif
1.1038 +# undef __ROPE_DEPTH_SIZE
1.1039 +# undef __ROPE_MAX_DEPTH
1.1040 +# undef __ROPE_TABLE_BODY
1.1041 +
1.1042 +// These are Fibonacci numbers < 2**32.
1.1043 +
1.1044 +template <class _CharT, class _Alloc>
1.1045 +__RopeRep__* rope<_CharT,_Alloc>::_S_balance(_RopeRep* __r) {
1.1046 + _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,
1.1047 + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1.1048 + 0,0,0,0,0,0};
1.1049 + _RopeRep* __result = 0;
1.1050 + int __i;
1.1051 + // Invariant:
1.1052 + // The concatenation of forest in descending order is equal to __r.
1.1053 + // __forest[__i]._M_size._M_data >= _S_min_len[__i]
1.1054 + // __forest[__i]._M_depth = __i
1.1055 + // References from forest are included in refcount.
1.1056 +
1.1057 + _STLP_TRY {
1.1058 + _S_add_to_forest(__r, __forest);
1.1059 + for (__i = 0; __i <= _RopeRep::_S_max_rope_depth; ++__i)
1.1060 + if (0 != __forest[__i]) {
1.1061 + _Self_destruct_ptr __old(__result);
1.1062 + __result = _S_concat_rep(__forest[__i], __result);
1.1063 + __forest[__i]->_M_unref_nonnil();
1.1064 +# ifdef _STLP_USE_EXCEPTIONS
1.1065 + __forest[__i] = 0;
1.1066 +# endif
1.1067 + }
1.1068 + }
1.1069 + _STLP_UNWIND(for(__i = 0; __i <= _RopeRep::_S_max_rope_depth; ++__i)
1.1070 + _S_unref(__forest[__i]))
1.1071 + if (__result->_M_depth > _RopeRep::_S_max_rope_depth) {
1.1072 + __stl_throw_range_error("rope too long");
1.1073 + }
1.1074 + return(__result);
1.1075 +}
1.1076 +
1.1077 +
1.1078 +template <class _CharT, class _Alloc>
1.1079 +void
1.1080 +rope<_CharT,_Alloc>::_S_add_to_forest(_RopeRep* __r, _RopeRep** __forest)
1.1081 +{
1.1082 + if (__r -> _M_is_balanced) {
1.1083 + _S_add_leaf_to_forest(__r, __forest);
1.1084 + return;
1.1085 + }
1.1086 + _STLP_ASSERT(__r->_M_tag == _RopeRep::_S_concat)
1.1087 + {
1.1088 + _RopeConcatenation* __c = (_RopeConcatenation*)__r;
1.1089 +
1.1090 + _S_add_to_forest(__c->_M_left, __forest);
1.1091 + _S_add_to_forest(__c->_M_right, __forest);
1.1092 + }
1.1093 +}
1.1094 +
1.1095 +
1.1096 +template <class _CharT, class _Alloc>
1.1097 +void
1.1098 +rope<_CharT,_Alloc>::_S_add_leaf_to_forest(_RopeRep* __r, _RopeRep** __forest)
1.1099 +{
1.1100 + _RopeRep* __insertee; // included in refcount
1.1101 + _RopeRep* __too_tiny = 0; // included in refcount
1.1102 + int __i; // forest[0..__i-1] is empty
1.1103 + size_t __s = __r->_M_size._M_data;
1.1104 +
1.1105 + for (__i = 0; __s >= _S_min_len[__i+1]/* not this bucket */; ++__i) {
1.1106 + if (0 != __forest[__i]) {
1.1107 + _Self_destruct_ptr __old(__too_tiny);
1.1108 + __too_tiny = _S_concat_and_set_balanced(__forest[__i], __too_tiny);
1.1109 + __forest[__i]->_M_unref_nonnil();
1.1110 + __forest[__i] = 0;
1.1111 + }
1.1112 + }
1.1113 + {
1.1114 + _Self_destruct_ptr __old(__too_tiny);
1.1115 + __insertee = _S_concat_and_set_balanced(__too_tiny, __r);
1.1116 + }
1.1117 + // Too_tiny dead, and no longer included in refcount.
1.1118 + // Insertee is live and included.
1.1119 + _STLP_ASSERT(_S_is_almost_balanced(__insertee))
1.1120 + _STLP_ASSERT(__insertee->_M_depth <= __r->_M_depth + 1)
1.1121 + for (;; ++__i) {
1.1122 + if (0 != __forest[__i]) {
1.1123 + _Self_destruct_ptr __old(__insertee);
1.1124 + __insertee = _S_concat_and_set_balanced(__forest[__i], __insertee);
1.1125 + __forest[__i]->_M_unref_nonnil();
1.1126 + __forest[__i] = 0;
1.1127 + _STLP_ASSERT(_S_is_almost_balanced(__insertee))
1.1128 + }
1.1129 + _STLP_ASSERT(_S_min_len[__i] <= __insertee->_M_size._M_data)
1.1130 + _STLP_ASSERT(__forest[__i] == 0)
1.1131 + if (__i == _RopeRep::_S_max_rope_depth ||
1.1132 + __insertee->_M_size._M_data < _S_min_len[__i+1]) {
1.1133 + __forest[__i] = __insertee;
1.1134 + // refcount is OK since __insertee is now dead.
1.1135 + return;
1.1136 + }
1.1137 + }
1.1138 +}
1.1139 +
1.1140 +template <class _CharT, class _Alloc>
1.1141 +_CharT
1.1142 +rope<_CharT,_Alloc>::_S_fetch(_RopeRep* __r, size_type __i)
1.1143 +{
1.1144 + _CharT* __cstr = __r->_M_c_string;
1.1145 +
1.1146 + _STLP_ASSERT(__i < __r->_M_size._M_data)
1.1147 + if (0 != __cstr) return __cstr[__i];
1.1148 + for(;;) {
1.1149 + switch(__r->_M_tag) {
1.1150 + case _RopeRep::_S_concat:
1.1151 + {
1.1152 + _RopeConcatenation* __c = (_RopeConcatenation*)__r;
1.1153 + _RopeRep* __left = __c->_M_left;
1.1154 + size_t __left_len = __left->_M_size._M_data;
1.1155 +
1.1156 + if (__i >= __left_len) {
1.1157 + __i -= __left_len;
1.1158 + __r = __c->_M_right;
1.1159 + } else {
1.1160 + __r = __left;
1.1161 + }
1.1162 + }
1.1163 + break;
1.1164 + case _RopeRep::_S_leaf:
1.1165 + {
1.1166 + _RopeLeaf* __l = (_RopeLeaf*)__r;
1.1167 + return __l->_M_data[__i];
1.1168 + }
1.1169 + case _RopeRep::_S_function:
1.1170 + case _RopeRep::_S_substringfn:
1.1171 + {
1.1172 + _RopeFunction* __f = (_RopeFunction*)__r;
1.1173 + _CharT __result;
1.1174 +
1.1175 + (*(__f->_M_fn))(__i, 1, &__result);
1.1176 + return __result;
1.1177 + }
1.1178 + }
1.1179 + }
1.1180 +#if defined(_STLP_NEED_UNREACHABLE_RETURN)
1.1181 + return 0;
1.1182 +#endif
1.1183 +}
1.1184 +
1.1185 +// Return a uniquely referenced character slot for the given
1.1186 +// position, or 0 if that's not possible.
1.1187 +template <class _CharT, class _Alloc>
1.1188 +_CharT*
1.1189 +rope<_CharT,_Alloc>::_S_fetch_ptr(_RopeRep* __r, size_type __i)
1.1190 +{
1.1191 + _RopeRep* __clrstack[_RopeRep::_S_max_rope_depth];
1.1192 + size_t __csptr = 0;
1.1193 +
1.1194 + for(;;) {
1.1195 + // if (__r->_M_ref_count > 1) return 0;
1.1196 + if ( __r->_M_incr() > 2 ) {
1.1197 + __r->_M_decr();
1.1198 + return 0;
1.1199 + }
1.1200 + switch(__r->_M_tag) {
1.1201 + case _RopeRep::_S_concat:
1.1202 + {
1.1203 + _RopeConcatenation* __c = (_RopeConcatenation*)__r;
1.1204 + _RopeRep* __left = __c->_M_left;
1.1205 + size_t __left_len = __left->_M_size._M_data;
1.1206 +
1.1207 + if (__c->_M_c_string != 0) __clrstack[__csptr++] = __c;
1.1208 + if (__i >= __left_len) {
1.1209 + __i -= __left_len;
1.1210 + __r = __c->_M_right;
1.1211 + } else {
1.1212 + __r = __left;
1.1213 + }
1.1214 + }
1.1215 + break;
1.1216 + case _RopeRep::_S_leaf:
1.1217 + {
1.1218 + _RopeLeaf* __l = (_RopeLeaf*)__r;
1.1219 + if (__l->_M_c_string != __l->_M_data && __l->_M_c_string != 0)
1.1220 + __clrstack[__csptr++] = __l;
1.1221 + while (__csptr > 0) {
1.1222 + -- __csptr;
1.1223 + _RopeRep* __d = __clrstack[__csptr];
1.1224 + __d->_M_free_c_string();
1.1225 + __d->_M_c_string = 0;
1.1226 + }
1.1227 + return __l->_M_data + __i;
1.1228 + }
1.1229 + case _RopeRep::_S_function:
1.1230 + case _RopeRep::_S_substringfn:
1.1231 + return 0;
1.1232 + }
1.1233 + }
1.1234 +#if defined(_STLP_NEED_UNREACHABLE_RETURN)
1.1235 + return 0;
1.1236 +#endif
1.1237 +
1.1238 +}
1.1239 +
1.1240 +// The following could be implemented trivially using
1.1241 +// lexicographical_compare_3way.
1.1242 +// We do a little more work to avoid dealing with rope iterators for
1.1243 +// flat strings.
1.1244 +template <class _CharT, class _Alloc>
1.1245 +int
1.1246 +rope<_CharT,_Alloc>::_S_compare (const _RopeRep* __left,
1.1247 + const _RopeRep* __right) {
1.1248 + size_t __left_len;
1.1249 + size_t __right_len;
1.1250 +
1.1251 + if (0 == __right) return 0 != __left;
1.1252 + if (0 == __left) return -1;
1.1253 + __left_len = __left->_M_size._M_data;
1.1254 + __right_len = __right->_M_size._M_data;
1.1255 + if (_RopeRep::_S_leaf == __left->_M_tag) {
1.1256 + const _RopeLeaf* __l = __STATIC_CAST(const _RopeLeaf*, __left);
1.1257 + if (_RopeRep::_S_leaf == __right->_M_tag) {
1.1258 + const _RopeLeaf* __r = __STATIC_CAST(const _RopeLeaf*, __right);
1.1259 + return _STLP_PRIV __lexicographical_compare_3way(__l->_M_data, __l->_M_data + __left_len,
1.1260 + __r->_M_data, __r->_M_data + __right_len);
1.1261 + }
1.1262 + else {
1.1263 + const_iterator __rstart(__right, 0);
1.1264 + const_iterator __rend(__right, __right_len);
1.1265 + return _STLP_PRIV __lexicographical_compare_3way(__l->_M_data, __l->_M_data + __left_len,
1.1266 + __rstart, __rend);
1.1267 + }
1.1268 + }
1.1269 + else {
1.1270 + const_iterator __lstart(__left, 0);
1.1271 + const_iterator __lend(__left, __left_len);
1.1272 + if (_RopeRep::_S_leaf == __right->_M_tag) {
1.1273 + const _RopeLeaf* __r = __STATIC_CAST(const _RopeLeaf*, __right);
1.1274 + return _STLP_PRIV __lexicographical_compare_3way(__lstart, __lend,
1.1275 + __r->_M_data, __r->_M_data + __right_len);
1.1276 + }
1.1277 + else {
1.1278 + const_iterator __rstart(__right, 0);
1.1279 + const_iterator __rend(__right, __right_len);
1.1280 + return _STLP_PRIV __lexicographical_compare_3way(__lstart, __lend, __rstart, __rend);
1.1281 + }
1.1282 + }
1.1283 +}
1.1284 +
1.1285 +// Assignment to reference proxies.
1.1286 +template <class _CharT, class _Alloc>
1.1287 +_Rope_char_ref_proxy<_CharT, _Alloc>&
1.1288 +_Rope_char_ref_proxy<_CharT, _Alloc>::operator= (_CharT __c) {
1.1289 + _RopeRep* __old = _M_root->_M_tree_ptr._M_data;
1.1290 + // First check for the case in which everything is uniquely
1.1291 + // referenced. In that case we can do this destructively.
1.1292 + _CharT* __ptr = _My_rope::_S_fetch_ptr(__old, _M_pos);
1.1293 + if (0 != __ptr) {
1.1294 + *__ptr = __c;
1.1295 + return *this;
1.1296 + }
1.1297 + _Self_destruct_ptr __left(
1.1298 + _My_rope::_S_substring(__old, 0, _M_pos));
1.1299 + _Self_destruct_ptr __right(
1.1300 + _My_rope::_S_substring(__old, _M_pos+1, __old->_M_size._M_data));
1.1301 + _Self_destruct_ptr __result_left(
1.1302 + _My_rope::_S_destr_concat_char_iter(__left, &__c, 1));
1.1303 +
1.1304 + // _STLP_ASSERT(__left == __result_left || 1 == __result_left->_M_ref_count)
1.1305 + _RopeRep* __result =
1.1306 + _My_rope::_S_concat_rep(__result_left, __right);
1.1307 + // _STLP_ASSERT(1 <= __result->_M_ref_count)
1.1308 + _RopeRep::_S_unref(__old);
1.1309 + _M_root->_M_tree_ptr._M_data = __result;
1.1310 + return *this;
1.1311 +}
1.1312 +
1.1313 +template <class _CharT, class _Alloc>
1.1314 +_Rope_char_ptr_proxy<_CharT, _Alloc>
1.1315 +_Rope_char_ref_proxy<_CharT, _Alloc>::operator& () const {
1.1316 + return _Rope_char_ptr_proxy<_CharT, _Alloc>(*this);
1.1317 +}
1.1318 +
1.1319 +# if ( _STLP_STATIC_TEMPLATE_DATA > 0 )
1.1320 +template<class _CharT, class _Alloc>
1.1321 +_CharT rope<_CharT,_Alloc>::_S_empty_c_str[1] = { _CharT() };
1.1322 +# else
1.1323 +__DECLARE_INSTANCE(char, crope::_S_empty_c_str[1], ={0});
1.1324 +# ifdef _STLP_HAS_WCHAR_T
1.1325 +__DECLARE_INSTANCE(wchar_t, wrope::_S_empty_c_str[1], ={0});
1.1326 +# endif /* _STLP_HAS_WCHAR_T */
1.1327 +# endif /* _STLP_STATIC_TEMPLATE_DATA */
1.1328 +// # endif
1.1329 +
1.1330 +#if !defined (_STLP_STATIC_CONST_INIT_BUG)
1.1331 +# if !defined (__GNUC__) || (__GNUC__ != 2) || (__GNUC_MINOR__ != 96)
1.1332 +template <class _CharT, class _Alloc>
1.1333 +const size_t rope<_CharT, _Alloc>::npos;
1.1334 +# endif
1.1335 +#endif
1.1336 +
1.1337 +template<class _CharT, class _Alloc>
1.1338 +const _CharT* rope<_CharT,_Alloc>::c_str() const {
1.1339 + if (0 == _M_tree_ptr._M_data) {
1.1340 + // Possibly redundant, but probably fast.
1.1341 + _S_empty_c_str[0] = _STLP_DEFAULT_CONSTRUCTED(_CharT);
1.1342 + return _S_empty_c_str;
1.1343 + }
1.1344 + _CharT* __old_c_string = _M_tree_ptr._M_data->_M_c_string;
1.1345 + if (0 != __old_c_string) return __old_c_string;
1.1346 + size_t __s = size();
1.1347 + _CharT* __result = _STLP_CREATE_ALLOCATOR(allocator_type,(const allocator_type&)_M_tree_ptr, _CharT).allocate(__s + 1);
1.1348 + _S_flatten(_M_tree_ptr._M_data, __result);
1.1349 + _S_construct_null(__result + __s);
1.1350 + __old_c_string = __STATIC_CAST(_CharT*, _Atomic_swap_ptr(__REINTERPRET_CAST(void* _STLP_VOLATILE*, &(_M_tree_ptr._M_data->_M_c_string)),
1.1351 + __result));
1.1352 + if (0 != __old_c_string) {
1.1353 + // It must have been added in the interim. Hence it had to have been
1.1354 + // separately allocated. Deallocate the old copy, since we just
1.1355 + // replaced it.
1.1356 + _STLP_STD::_Destroy_Range(__old_c_string, __old_c_string + __s + 1);
1.1357 + _STLP_CREATE_ALLOCATOR(allocator_type,(const allocator_type&)_M_tree_ptr, _CharT).deallocate(__old_c_string, __s + 1);
1.1358 + }
1.1359 + return __result;
1.1360 +}
1.1361 +
1.1362 +template<class _CharT, class _Alloc>
1.1363 +const _CharT* rope<_CharT,_Alloc>::replace_with_c_str() {
1.1364 + if (0 == _M_tree_ptr._M_data) {
1.1365 + _S_empty_c_str[0] = _STLP_DEFAULT_CONSTRUCTED(_CharT);
1.1366 + return _S_empty_c_str;
1.1367 + }
1.1368 + _CharT* __old_c_string = _M_tree_ptr._M_data->_M_c_string;
1.1369 + if (_RopeRep::_S_leaf == _M_tree_ptr._M_data->_M_tag && 0 != __old_c_string) {
1.1370 + return __old_c_string;
1.1371 + }
1.1372 + size_t __s = size();
1.1373 + _CharT* __result = _M_tree_ptr.allocate(_S_rounded_up_size(__s));
1.1374 + _S_flatten(_M_tree_ptr._M_data, __result);
1.1375 + _S_construct_null(__result + __s);
1.1376 + _M_tree_ptr._M_data->_M_unref_nonnil();
1.1377 + _M_tree_ptr._M_data = _S_new_RopeLeaf(__result, __s, _M_tree_ptr);
1.1378 + return __result;
1.1379 +}
1.1380 +
1.1381 +// Algorithm specializations. More should be added.
1.1382 +
1.1383 +#if (!defined (_STLP_MSVC) || (_STLP_MSVC >= 1310)) && \
1.1384 + (!defined (__DMC__) || defined (__PUT_STATIC_DATA_MEMBERS_HERE))
1.1385 +// I couldn't get this to work with VC++
1.1386 +template<class _CharT,class _Alloc>
1.1387 +void _Rope_rotate(_Rope_iterator<_CharT,_Alloc> __first,
1.1388 + _Rope_iterator<_CharT,_Alloc> __middle,
1.1389 + _Rope_iterator<_CharT,_Alloc> __last) {
1.1390 + _STLP_ASSERT(__first.container() == __middle.container() &&
1.1391 + __middle.container() == __last.container())
1.1392 + rope<_CharT,_Alloc>& __r(__first.container());
1.1393 + rope<_CharT,_Alloc> __prefix = __r.substr(0, __first.index());
1.1394 + rope<_CharT,_Alloc> __suffix =
1.1395 + __r.substr(__last.index(), __r.size() - __last.index());
1.1396 + rope<_CharT,_Alloc> __part1 =
1.1397 + __r.substr(__middle.index(), __last.index() - __middle.index());
1.1398 + rope<_CharT,_Alloc> __part2 =
1.1399 + __r.substr(__first.index(), __middle.index() - __first.index());
1.1400 + __r = __prefix;
1.1401 + __r += __part1;
1.1402 + __r += __part2;
1.1403 + __r += __suffix;
1.1404 +}
1.1405 +
1.1406 +
1.1407 +# if 0
1.1408 +// Probably not useful for several reasons:
1.1409 +// - for SGIs 7.1 compiler and probably some others,
1.1410 +// this forces lots of rope<wchar_t, ...> instantiations, creating a
1.1411 +// code bloat and compile time problem. (Fixed in 7.2.)
1.1412 +// - wchar_t is 4 bytes wide on most UNIX platforms, making it unattractive
1.1413 +// for unicode strings. Unsigned short may be a better character
1.1414 +// type.
1.1415 +inline void rotate(
1.1416 + _Rope_iterator<wchar_t,_STLP_DEFAULT_ALLOCATOR(char) > __first,
1.1417 + _Rope_iterator<wchar_t,_STLP_DEFAULT_ALLOCATOR(char) > __middle,
1.1418 + _Rope_iterator<wchar_t,_STLP_DEFAULT_ALLOCATOR(char) > __last) {
1.1419 + _Rope_rotate(__first, __middle, __last);
1.1420 +}
1.1421 +# endif
1.1422 +#endif /* _STLP_MSVC */
1.1423 +
1.1424 +# undef __RopeLeaf__
1.1425 +# undef __RopeRep__
1.1426 +# undef __RopeLeaf
1.1427 +# undef __RopeRep
1.1428 +# undef size_type
1.1429 +
1.1430 +_STLP_END_NAMESPACE
1.1431 +
1.1432 +# endif /* ROPEIMPL_H */
1.1433 +
1.1434 +// Local Variables:
1.1435 +// mode:C++
1.1436 +// End: