00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef UNDER_CE
00019 # include <stdio.h>
00020 #ifdef __STL_USE_NEW_IOSTREAMS
00021 # include <iostream>
00022 #else
00023 # include <iostream.h>
00024 #endif
00025 #else
00026 #include <wce_defs.h>
00027 #endif
00028
00029 #ifdef __STL_USE_EXCEPTIONS
00030 # include <stdexcept>
00031 #endif
00032
00033 __STL_BEGIN_NAMESPACE
00034
00035 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
00036 #pragma set woff 1174
00037 #endif
00038
00039
00040
00041
00042
00043 template <class _CharT, class _Alloc>
00044 void _Rope_iterator_base<_CharT,_Alloc>::_S_setbuf(
00045 _Rope_iterator_base<_CharT,_Alloc>& __x)
00046 {
00047 const _RopeRep* __leaf = __x._M_path_end[__x._M_leaf_index];
00048 size_t __leaf_pos = __x._M_leaf_pos;
00049 size_t __pos = __x._M_current_pos;
00050
00051 switch(__leaf->_M_tag) {
00052 case _RopeRep::_S_leaf:
00053 __x._M_buf_start =
00054 ((_Rope_RopeLeaf<_CharT,_Alloc>*)__leaf)->_M_data;
00055 __x._M_buf_ptr = __x._M_buf_start + (__pos - __leaf_pos);
00056 __x._M_buf_end = __x._M_buf_start + __leaf->_M_size;
00057 break;
00058 case _RopeRep::_S_function:
00059 case _RopeRep::_S_substringfn:
00060 {
00061 size_t __len = _S_iterator_buf_len;
00062 size_t __buf_start_pos = __leaf_pos;
00063 size_t __leaf_end = __leaf_pos + __leaf->_M_size;
00064 char_producer<_CharT>* __fn =
00065 ((_Rope_RopeFunction<_CharT,_Alloc>*)__leaf)->_M_fn;
00066
00067 if (__buf_start_pos + __len <= __pos) {
00068 __buf_start_pos = __pos - __len/4;
00069 if (__buf_start_pos + __len > __leaf_end) {
00070 __buf_start_pos = __leaf_end - __len;
00071 }
00072 }
00073 if (__buf_start_pos + __len > __leaf_end) {
00074 __len = __leaf_end - __buf_start_pos;
00075 }
00076 (*__fn)(__buf_start_pos - __leaf_pos, __len, __x._M_tmp_buf);
00077 __x._M_buf_ptr = __x._M_tmp_buf + (__pos - __buf_start_pos);
00078 __x._M_buf_start = __x._M_tmp_buf;
00079 __x._M_buf_end = __x._M_tmp_buf + __len;
00080 }
00081 break;
00082 default:
00083 __stl_assert(0);
00084 }
00085 }
00086
00087
00088
00089 template <class _CharT, class _Alloc>
00090 void _Rope_iterator_base<_CharT,_Alloc>::_S_setcache
00091 (_Rope_iterator_base<_CharT,_Alloc>& __x)
00092 {
00093 const _RopeRep* __path[_RopeRep::_S_max_rope_depth+1];
00094 const _RopeRep* __curr_rope;
00095 int __curr_depth = -1;
00096 size_t __curr_start_pos = 0;
00097 size_t __pos = __x._M_current_pos;
00098 unsigned char __dirns = 0;
00099
00100 __stl_assert(__pos <= __x._M_root->_M_size);
00101 if (__pos >= __x._M_root->_M_size) {
00102 __x._M_buf_ptr = 0;
00103 return;
00104 }
00105 __curr_rope = __x._M_root;
00106 if (0 != __curr_rope->_M_c_string) {
00107
00108 __x._M_buf_start = __curr_rope->_M_c_string;
00109 __x._M_buf_end = __curr_rope->_M_c_string + __curr_rope->_M_size;
00110 __x._M_buf_ptr = __curr_rope->_M_c_string + __pos;
00111 __x._M_path_end[0] = __curr_rope;
00112 __x._M_leaf_index = 0;
00113 __x._M_leaf_pos = 0;
00114 return;
00115 }
00116 for(;;) {
00117 ++__curr_depth;
00118 __stl_assert(__curr_depth <= _RopeRep::_S_max_rope_depth);
00119 __path[__curr_depth] = __curr_rope;
00120 switch(__curr_rope->_M_tag) {
00121 case _RopeRep::_S_leaf:
00122 case _RopeRep::_S_function:
00123 case _RopeRep::_S_substringfn:
00124 __x._M_leaf_pos = __curr_start_pos;
00125 goto done;
00126 case _RopeRep::_S_concat:
00127 {
00128 _Rope_RopeConcatenation<_CharT,_Alloc>* __c =
00129 (_Rope_RopeConcatenation<_CharT,_Alloc>*)__curr_rope;
00130 _RopeRep* __left = __c->_M_left;
00131 size_t __left_len = __left->_M_size;
00132
00133 __dirns <<= 1;
00134 if (__pos >= __curr_start_pos + __left_len) {
00135 __dirns |= 1;
00136 __curr_rope = __c->_M_right;
00137 __curr_start_pos += __left_len;
00138 } else {
00139 __curr_rope = __left;
00140 }
00141 }
00142 break;
00143 }
00144 }
00145 done:
00146
00147 {
00148 int __i = -1;
00149 int __j = __curr_depth + 1 - _S_path_cache_len;
00150
00151 if (__j < 0) __j = 0;
00152 while (__j <= __curr_depth) {
00153 __x._M_path_end[++__i] = __path[__j++];
00154 }
00155 __x._M_leaf_index = __i;
00156 }
00157 __x._M_path_directions = __dirns;
00158 _S_setbuf(__x);
00159 }
00160
00161
00162
00163 template <class _CharT, class _Alloc>
00164 void _Rope_iterator_base<_CharT,_Alloc>::_S_setcache_for_incr
00165 (_Rope_iterator_base<_CharT,_Alloc>& __x)
00166 {
00167 int __current_index = __x._M_leaf_index;
00168 const _RopeRep* __current_node = __x._M_path_end[__current_index];
00169 size_t __len = __current_node->_M_size;
00170 size_t __node_start_pos = __x._M_leaf_pos;
00171 unsigned char __dirns = __x._M_path_directions;
00172 _Rope_RopeConcatenation<_CharT,_Alloc>* __c;
00173
00174 __stl_assert(__x._M_current_pos <= __x._M_root->_M_size);
00175 if (__x._M_current_pos - __node_start_pos < __len) {
00176
00177 _S_setbuf(__x);
00178 return;
00179 }
00180 __stl_assert(__node_start_pos + __len == __x._M_current_pos);
00181
00182 while (--__current_index >= 0) {
00183 if (!(__dirns & 1) )
00184 break;
00185 __current_node = __x._M_path_end[__current_index];
00186 __c = (_Rope_RopeConcatenation<_CharT,_Alloc>*)__current_node;
00187
00188
00189 __node_start_pos -= __c->_M_left->_M_size;
00190 __dirns >>= 1;
00191 }
00192 if (__current_index < 0) {
00193
00194 _S_setcache(__x);
00195 return;
00196 }
00197 __current_node = __x._M_path_end[__current_index];
00198 __c = (_Rope_RopeConcatenation<_CharT,_Alloc>*)__current_node;
00199
00200
00201
00202 __node_start_pos += __c->_M_left->_M_size;
00203 __current_node = __c->_M_right;
00204 __x._M_path_end[++__current_index] = __current_node;
00205 __dirns |= 1;
00206 while (_RopeRep::_S_concat == __current_node->_M_tag) {
00207 ++__current_index;
00208 if (_S_path_cache_len == __current_index) {
00209 int __i;
00210 for (__i = 0; __i < _S_path_cache_len-1; __i++) {
00211 __x._M_path_end[__i] = __x._M_path_end[__i+1];
00212 }
00213 --__current_index;
00214 }
00215 __current_node =
00216 ((_Rope_RopeConcatenation<_CharT,_Alloc>*)__current_node)->_M_left;
00217 __x._M_path_end[__current_index] = __current_node;
00218 __dirns <<= 1;
00219
00220 }
00221 __x._M_leaf_index = __current_index;
00222 __x._M_leaf_pos = __node_start_pos;
00223 __x._M_path_directions = __dirns;
00224 _S_setbuf(__x);
00225 }
00226
00227 template <class _CharT, class _Alloc>
00228 void _Rope_iterator_base<_CharT,_Alloc>::_M_incr(size_t __n) {
00229 _M_current_pos += __n;
00230 if (0 != _M_buf_ptr) {
00231 size_t __chars_left = _M_buf_end - _M_buf_ptr;
00232 if (__chars_left > __n) {
00233 _M_buf_ptr += __n;
00234 } else if (__chars_left == __n) {
00235 _M_buf_ptr += __n;
00236 _S_setcache_for_incr(*this);
00237 } else {
00238 _M_buf_ptr = 0;
00239 }
00240 }
00241 }
00242
00243 template <class _CharT, class _Alloc>
00244 void _Rope_iterator_base<_CharT,_Alloc>::_M_decr(size_t __n) {
00245 if (0 != _M_buf_ptr) {
00246 size_t __chars_left = _M_buf_ptr - _M_buf_start;
00247 if (__chars_left >= __n) {
00248 _M_buf_ptr -= __n;
00249 } else {
00250 _M_buf_ptr = 0;
00251 }
00252 }
00253 _M_current_pos -= __n;
00254 }
00255
00256 template <class _CharT, class _Alloc>
00257 void _Rope_iterator<_CharT,_Alloc>::_M_check() {
00258 if (_M_root_rope->_M_tree_ptr != _M_root) {
00259
00260 _RopeRep::_S_unref(_M_root);
00261 _M_root = _M_root_rope->_M_tree_ptr;
00262 _RopeRep::_S_ref(_M_root);
00263 _M_buf_ptr = 0;
00264 }
00265 }
00266
00267 template <class _CharT, class _Alloc>
00268 inline
00269 _Rope_const_iterator<_CharT, _Alloc>::_Rope_const_iterator(
00270 const _Rope_iterator<_CharT,_Alloc>& __x)
00271 : _Rope_iterator_base<_CharT,_Alloc>(__x)
00272 { }
00273
00274 template <class _CharT, class _Alloc>
00275 inline _Rope_iterator<_CharT,_Alloc>::_Rope_iterator(
00276 rope<_CharT,_Alloc>& __r, size_t __pos)
00277 : _Rope_iterator_base<_CharT,_Alloc>(__r._M_tree_ptr, __pos),
00278 _M_root_rope(&__r)
00279 {
00280 _RopeRep::_S_ref(_M_root);
00281 }
00282
00283 template <class _CharT, class _Alloc>
00284 inline size_t
00285 rope<_CharT,_Alloc>::_S_char_ptr_len(const _CharT* __s)
00286 {
00287 const _CharT* __p = __s;
00288
00289 while (!_S_is0(*__p)) { ++__p; }
00290 return (__p - __s);
00291 }
00292
00293
00294 #ifndef __GC
00295
00296 template <class _CharT, class _Alloc>
00297 inline void _Rope_RopeRep<_CharT,_Alloc>::_M_free_c_string()
00298 {
00299 _CharT* __cstr = _M_c_string;
00300 if (0 != __cstr) {
00301 size_t __size = _M_size + 1;
00302 destroy(__cstr, __cstr + __size);
00303 _Data_deallocate(__cstr, __size);
00304 }
00305 }
00306
00307
00308 template <class _CharT, class _Alloc>
00309 #ifdef __STL_USE_STD_ALLOCATORS
00310 inline void _Rope_RopeRep<_CharT,_Alloc>::_S_free_string(_CharT* __s,
00311 size_t __n,
00312 allocator_type __a)
00313 #else
00314 inline void _Rope_RopeRep<_CharT,_Alloc>::_S_free_string(_CharT* __s,
00315 size_t __n)
00316 #endif
00317 {
00318 if (!_S_is_basic_char_type((_CharT*)0)) {
00319 destroy(__s, __s + __n);
00320 }
00321
00322 # ifdef __STL_USE_STD_ALLOCATORS
00323 __a.deallocate(
00324 __s, _Rope_RopeLeaf<_CharT,_Alloc>::_S_rounded_up_size(__n));
00325 # else
00326 _Data_deallocate(
00327 __s, _Rope_RopeLeaf<_CharT,_Alloc>::_S_rounded_up_size(__n));
00328 # endif
00329 }
00330
00331
00332
00333
00334
00335
00336
00337
00338 template <class _CharT, class _Alloc>
00339 void _Rope_RopeRep<_CharT,_Alloc>::_M_free_tree()
00340 {
00341 switch(_M_tag) {
00342 case _S_leaf:
00343 {
00344 _Rope_RopeLeaf<_CharT,_Alloc>* __l
00345 = (_Rope_RopeLeaf<_CharT,_Alloc>*)this;
00346 __l->_Rope_RopeLeaf<_CharT,_Alloc>::~_Rope_RopeLeaf();
00347 _L_deallocate(__l, 1);
00348 break;
00349 }
00350 case _S_concat:
00351 {
00352 _Rope_RopeConcatenation<_CharT,_Alloc>* __c
00353 = (_Rope_RopeConcatenation<_CharT,_Alloc>*)this;
00354 __c->_Rope_RopeConcatenation<_CharT,_Alloc>::
~_Rope_RopeConcatenation();
00355 _C_deallocate(__c, 1);
00356 break;
00357 }
00358 case _S_function:
00359 {
00360 _Rope_RopeFunction<_CharT,_Alloc>* __f
00361 = (_Rope_RopeFunction<_CharT,_Alloc>*)this;
00362 __f->_Rope_RopeFunction<_CharT,_Alloc>::~_Rope_RopeFunction();
00363 _F_deallocate(__f, 1);
00364 break;
00365 }
00366 case _S_substringfn:
00367 {
00368 _Rope_RopeSubstring<_CharT,_Alloc>* __ss =
00369 (_Rope_RopeSubstring<_CharT,_Alloc>*)this;
00370 __ss->_Rope_RopeSubstring<_CharT,_Alloc>::
~_Rope_RopeSubstring();
00371 _S_deallocate(__ss, 1);
00372 break;
00373 }
00374 }
00375 }
00376 #else
00377
00378 template <class _CharT, class _Alloc>
00379 #ifdef __STL_USE_STD_ALLOCATORS
00380 inline void _Rope_RopeRep<_CharT,_Alloc>::_S_free_string
00381 (const _CharT*, size_t, allocator_type)
00382 #else
00383 inline void _Rope_RopeRep<_CharT,_Alloc>::_S_free_string
00384 (const _CharT*, size_t)
00385 #endif
00386 {}
00387
00388 #endif
00389
00390
00391
00392
00393 template <class _CharT, class _Alloc>
00394 rope<_CharT,_Alloc>::_RopeLeaf*
00395 rope<_CharT,_Alloc>::_S_leaf_concat_char_iter
00396 (_RopeLeaf* __r, const _CharT* __iter, size_t __len)
00397 {
00398 size_t __old_len = __r->_M_size;
00399 _CharT* __new_data = (_CharT*)
00400 _Data_allocate(_S_rounded_up_size(__old_len + __len));
00401 _RopeLeaf* __result;
00402
00403 uninitialized_copy_n(__r->_M_data, __old_len, __new_data);
00404 uninitialized_copy_n(__iter, __len, __new_data + __old_len);
00405 _S_cond_store_eos(__new_data[__old_len + __len]);
00406 __STL_TRY {
00407 __result = _S_new_RopeLeaf(__new_data, __old_len + __len,
00408 __r->get_allocator());
00409 }
00410 __STL_UNWIND(_RopeRep::__STL_FREE_STRING(__new_data, __old_len + __len,
00411 __r->get_allocator()));
00412 return __result;
00413 }
00414
00415 #ifndef __GC
00416
00417 template <class _CharT, class _Alloc>
00418 rope<_CharT,_Alloc>::_RopeLeaf*
00419 rope<_CharT,_Alloc>::_S_destr_leaf_concat_char_iter
00420 (_RopeLeaf* __r, const _CharT* __iter, size_t __len)
00421 {
00422 __stl_assert(__r->_M_ref_count >= 1);
00423 if (__r->_M_ref_count > 1)
00424 return _S_leaf_concat_char_iter(__r, __iter, __len);
00425 size_t __old_len = __r->_M_size;
00426 if (_S_allocated_capacity(__old_len) >= __old_len + __len) {
00427
00428
00429 uninitialized_copy_n(__iter, __len, __r->_M_data + __old_len);
00430 if (_S_is_basic_char_type((_CharT*)0)) {
00431 _S_cond_store_eos(__r->_M_data[__old_len + __len]);
00432 __stl_assert(__r->_M_c_string == __r->_M_data);
00433 } else if (__r->_M_c_string != __r->_M_data && 0 != __r->_M_c_string) {
00434 __r->_M_free_c_string();
00435 __r->_M_c_string = 0;
00436 }
00437 __r->_M_size = __old_len + __len;
00438 __stl_assert(__r->_M_ref_count == 1);
00439 __r->_M_ref_count = 2;
00440 return __r;
00441 } else {
00442 _RopeLeaf* __result = _S_leaf_concat_char_iter(__r, __iter, __len);
00443 __stl_assert(__result->_M_ref_count == 1);
00444 return __result;
00445 }
00446 }
00447 #endif
00448
00449
00450
00451
00452 template <class _CharT, class _Alloc>
00453 rope<_CharT,_Alloc>::_RopeRep*
00454 rope<_CharT,_Alloc>::_S_tree_concat (_RopeRep* __left, _RopeRep* __right)
00455 {
00456 _RopeConcatenation* __result =
00457 _S_new_RopeConcatenation(__left, __right, __left->get_allocator());
00458 size_t __depth = __result->_M_depth;
00459
00460 # ifdef __STL_USE_STD_ALLOCATORS
00461 __stl_assert(__left->get_allocator() == __right->get_allocator());
00462 # endif
00463 if (__depth > 20 && (__result->_M_size < 1000 ||
00464 __depth > _RopeRep::_S_max_rope_depth)) {
00465 _RopeRep* __balanced;
00466
00467 __STL_TRY {
00468 __balanced = _S_balance(__result);
00469 # ifndef __GC
00470 if (__result != __balanced) {
00471 __stl_assert(1 == __result->_M_ref_count
00472 && 1 == __balanced->_M_ref_count);
00473 }
00474 # endif
00475 __result->_M_unref_nonnil();
00476 }
00477 __STL_UNWIND((_C_deallocate(__result,1)));
00478
00479
00480
00481
00482 return __balanced;
00483 } else {
00484 return __result;
00485 }
00486 }
00487
00488 template <class _CharT, class _Alloc>
00489 rope<_CharT,_Alloc>::_RopeRep* rope<_CharT,_Alloc>::_S_concat_char_iter
00490 (_RopeRep* __r, const _CharT*__s, size_t __slen)
00491 {
00492 _RopeRep* __result;
00493 if (0 == __slen) {
00494 _S_ref(__r);
00495 return __r;
00496 }
00497 if (0 == __r)
00498 return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen,
00499 __r->get_allocator());
00500 if (_RopeRep::_S_leaf == __r->_M_tag &&
00501 __r->_M_size + __slen <= _S_copy_max) {
00502 __result = _S_leaf_concat_char_iter((_RopeLeaf*)__r, __s, __slen);
00503 # ifndef __GC
00504 __stl_assert(1 == __result->_M_ref_count);
00505 # endif
00506 return __result;
00507 }
00508 if (_RopeRep::_S_concat == __r->_M_tag
00509 && _RopeRep::_S_leaf == ((_RopeConcatenation*)__r)->_M_right->_M_tag) {
00510 _RopeLeaf* __right =
00511 (_RopeLeaf* )(((_RopeConcatenation* )__r)->_M_right);
00512 if (__right->_M_size + __slen <= _S_copy_max) {
00513 _RopeRep* __left = ((_RopeConcatenation*)__r)->_M_left;
00514 _RopeRep* __nright =
00515 _S_leaf_concat_char_iter((_RopeLeaf*)__right, __s, __slen);
00516 __left->_M_ref_nonnil();
00517 __STL_TRY {
00518 __result = _S_tree_concat(__left, __nright);
00519 }
00520 __STL_UNWIND(_S_unref(__left); _S_unref(__nright));
00521 # ifndef __GC
00522 __stl_assert(1 == __result->_M_ref_count);
00523 # endif
00524 return __result;
00525 }
00526 }
00527 _RopeRep* __nright =
00528 __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->get_allocator());
00529 __STL_TRY {
00530 __r->_M_ref_nonnil();
00531 __result = _S_tree_concat(__r, __nright);
00532 }
00533 __STL_UNWIND(_S_unref(__r); _S_unref(__nright));
00534 # ifndef __GC
00535 __stl_assert(1 == __result->_M_ref_count);
00536 # endif
00537 return __result;
00538 }
00539
00540 #ifndef __GC
00541 template <class _CharT, class _Alloc>
00542 rope<_CharT,_Alloc>::_RopeRep*
00543 rope<_CharT,_Alloc>::_S_destr_concat_char_iter(
00544 _RopeRep* __r, const _CharT* __s, size_t __slen)
00545 {
00546 _RopeRep* __result;
00547 if (0 == __r)
00548 return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen,
00549 __r->get_allocator());
00550 size_t __count = __r->_M_ref_count;
00551 size_t __orig_size = __r->_M_size;
00552 __stl_assert(__count >= 1);
00553 if (__count > 1) return _S_concat_char_iter(__r, __s, __slen);
00554 if (0 == __slen) {
00555 __r->_M_ref_count = 2;
00556 return __r;
00557 }
00558 if (__orig_size + __slen <= _S_copy_max &&
00559 _RopeRep::_S_leaf == __r->_M_tag) {
00560 __result = _S_destr_leaf_concat_char_iter((_RopeLeaf*)__r, __s, __slen);
00561 return __result;
00562 }
00563 if (_RopeRep::_S_concat == __r->_M_tag) {
00564 _RopeLeaf* __right = (_RopeLeaf*)(((_RopeConcatenation*)__r)->_M_right);
00565 if (_RopeRep::_S_leaf == __right->_M_tag
00566 && __right->_M_size + __slen <= _S_copy_max) {
00567 _RopeRep* __new_right =
00568 _S_destr_leaf_concat_char_iter(__right, __s, __slen);
00569 if (__right == __new_right) {
00570 __stl_assert(__new_right->_M_ref_count == 2);
00571 __new_right->_M_ref_count = 1;
00572 } else {
00573 __stl_assert(__new_right->_M_ref_count >= 1);
00574 __right->_M_unref_nonnil();
00575 }
00576 __stl_assert(__r->_M_ref_count == 1);
00577 __r->_M_ref_count = 2;
00578 ((_RopeConcatenation*)__r)->_M_right = __new_right;
00579 __r->_M_size = __orig_size + __slen;
00580 if (0 != __r->_M_c_string) {
00581 __r->_M_free_c_string();
00582 __r->_M_c_string = 0;
00583 }
00584 return __r;
00585 }
00586 }
00587 _RopeRep* __right =
00588 __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->get_allocator());
00589 __r->_M_ref_nonnil();
00590 __STL_TRY {
00591 __result = _S_tree_concat(__r, __right);
00592 }
00593 __STL_UNWIND(_S_unref(__r); _S_unref(__right))
00594 __stl_assert(1 == __result->_M_ref_count);
00595 return __result;
00596 }
00597 #endif
00598
00599 template <class _CharT, class _Alloc>
00600 rope<_CharT,_Alloc>::_RopeRep*
00601 rope<_CharT,_Alloc>::_S_concat(_RopeRep* __left, _RopeRep* __right)
00602 {
00603 if (0 == __left) {
00604 _S_ref(__right);
00605 return __right;
00606 }
00607 if (0 == __right) {
00608 __left->_M_ref_nonnil();
00609 return __left;
00610 }
00611 if (_RopeRep::_S_leaf == __right->_M_tag) {
00612 if (_RopeRep::_S_leaf == __left->_M_tag) {
00613 if (__right->_M_size + __left->_M_size <= _S_copy_max) {
00614 return _S_leaf_concat_char_iter((_RopeLeaf*)__left,
00615 ((_RopeLeaf*)__right)->_M_data,
00616 __right->_M_size);
00617 }
00618 } else if (_RopeRep::_S_concat == __left->_M_tag
00619 && _RopeRep::_S_leaf ==
00620 ((_RopeConcatenation*)__left)->_M_right->_M_tag) {
00621 _RopeLeaf* __leftright =
00622 (_RopeLeaf*)(((_RopeConcatenation*)__left)->_M_right);
00623 if (__leftright->_M_size + __right->_M_size <= _S_copy_max) {
00624 _RopeRep* __leftleft = ((_RopeConcatenation*)__left)->_M_left;
00625 _RopeRep* __rest = _S_leaf_concat_char_iter(__leftright,
00626 ((_RopeLeaf*)__right)->_M_data,
00627 __right->_M_size);
00628 __leftleft->_M_ref_nonnil();
00629 __STL_TRY {
00630 return(_S_tree_concat(__leftleft, __rest));
00631 }
00632 __STL_UNWIND(_S_unref(__leftleft); _S_unref(__rest))
00633 }
00634 }
00635 }
00636 __left->_M_ref_nonnil();
00637 __right->_M_ref_nonnil();
00638 __STL_TRY {
00639 return(_S_tree_concat(__left, __right));
00640 }
00641 __STL_UNWIND(_S_unref(__left); _S_unref(__right));
00642 }
00643
00644 template <class _CharT, class _Alloc>
00645 rope<_CharT,_Alloc>::_RopeRep*
00646 rope<_CharT,_Alloc>::_S_substring(_RopeRep* __base,
00647 size_t __start, size_t __endp1)
00648 {
00649 if (0 == __base) return 0;
00650 size_t __len = __base->_M_size;
00651 size_t __adj_endp1;
00652 const size_t __lazy_threshold = 128;
00653
00654 if (__endp1 >= __len) {
00655 if (0 == __start) {
00656 __base->_M_ref_nonnil();
00657 return __base;
00658 } else {
00659 __adj_endp1 = __len;
00660 }
00661 } else {
00662 __adj_endp1 = __endp1;
00663 }
00664 switch(__base->_M_tag) {
00665 case _RopeRep::_S_concat:
00666 {
00667 _RopeConcatenation* __c = (_RopeConcatenation*)__base;
00668 _RopeRep* __left = __c->_M_left;
00669 _RopeRep* __right = __c->_M_right;
00670 size_t __left_len = __left->_M_size;
00671 _RopeRep* __result;
00672
00673 if (__adj_endp1 <= __left_len) {
00674 return _S_substring(__left, __start, __endp1);
00675 } else if (__start >= __left_len) {
00676 return _S_substring(__right, __start - __left_len,
00677 __adj_endp1 - __left_len);
00678 }
00679 _Self_destruct_ptr __left_result(
00680 _S_substring(__left, __start, __left_len));
00681 _Self_destruct_ptr __right_result(
00682 _S_substring(__right, 0, __endp1 - __left_len));
00683 __result = _S_concat(__left_result, __right_result);
00684 # ifndef __GC
00685 __stl_assert(1 == __result->_M_ref_count);
00686 # endif
00687 return __result;
00688 }
00689 case _RopeRep::_S_leaf:
00690 {
00691 _RopeLeaf* __l = (_RopeLeaf*)__base;
00692 _RopeLeaf* __result;
00693 size_t __result_len;
00694 if (__start >= __adj_endp1) return 0;
00695 __result_len = __adj_endp1 - __start;
00696 if (__result_len > __lazy_threshold) goto lazy;
00697 # ifdef __GC
00698 const _CharT* __section = __l->_M_data + __start;
00699 __result = _S_new_RopeLeaf(__section, __result_len,
00700 __base->get_allocator());
00701 __result->_M_c_string = 0;
00702 # else
00703
00704 __result = __STL_ROPE_FROM_UNOWNED_CHAR_PTR(
00705 __l->_M_data + __start, __result_len,
00706 __base->get_allocator());
00707 # endif
00708 return __result;
00709 }
00710 case _RopeRep::_S_substringfn:
00711
00712 {
00713 _RopeSubstring* __old = (_RopeSubstring*)__base;
00714 size_t __result_len;
00715 if (__start >= __adj_endp1) return 0;
00716 __result_len = __adj_endp1 - __start;
00717 if (__result_len > __lazy_threshold) {
00718 _RopeSubstring* __result =
00719 _S_new_RopeSubstring(__old->_M_base,
00720 __start + __old->_M_start,
00721 __adj_endp1 - __start,
00722 __base->get_allocator());
00723 return __result;
00724
00725 }
00726 }
00727 case _RopeRep::_S_function:
00728 {
00729 _RopeFunction* __f = (_RopeFunction*)__base;
00730 _CharT* __section;
00731 size_t __result_len;
00732 if (__start >= __adj_endp1) return 0;
00733 __result_len = __adj_endp1 - __start;
00734
00735 if (__result_len > __lazy_threshold) goto lazy;
00736 __section = (_CharT*)
00737 _Data_allocate(_S_rounded_up_size(__result_len));
00738 __STL_TRY {
00739 (*(__f->_M_fn))(__start, __result_len, __section);
00740 }
00741 __STL_UNWIND(_RopeRep::__STL_FREE_STRING(
00742 __section, __result_len, __base->get_allocator()));
00743 _S_cond_store_eos(__section[__result_len]);
00744 return _S_new_RopeLeaf(__section, __result_len,
00745 __base->get_allocator());
00746 }
00747 }
00748
00749 __stl_assert(false);
00750 lazy:
00751 {
00752
00753 return _S_new_RopeSubstring(__base, __start, __adj_endp1 - __start,
00754 __base->get_allocator());
00755 }
00756 }
00757
00758 template<class _CharT>
00759 class _Rope_flatten_char_consumer : public _Rope_char_consumer<_CharT> {
00760 private:
00761 _CharT* _M_buf_ptr;
00762 public:
00763
00764 _Rope_flatten_char_consumer(_CharT* __buffer) {
00765 _M_buf_ptr = __buffer;
00766 };
00767 ~_Rope_flatten_char_consumer() {}
00768 bool operator() (const _CharT* __leaf, size_t __n) {
00769 uninitialized_copy_n(__leaf, __n, _M_buf_ptr);
00770 _M_buf_ptr += __n;
00771 return true;
00772 }
00773 };
00774
00775 template<class _CharT>
00776 class _Rope_find_char_char_consumer : public _Rope_char_consumer<_CharT> {
00777 private:
00778 _CharT _M_pattern;
00779 public:
00780 size_t _M_count;
00781 _Rope_find_char_char_consumer(_CharT __p)
00782 : _M_pattern(__p), _M_count(0) {}
00783 ~_Rope_find_char_char_consumer() {}
00784 bool operator() (const _CharT* __leaf, size_t __n) {
00785 size_t __i;
00786 for (__i = 0; __i < __n; __i++) {
00787 if (__leaf[__i] == _M_pattern) {
00788 _M_count += __i; return false;
00789 }
00790 }
00791 _M_count += __n; return true;
00792 }
00793 };
00794
00795 #ifndef UNDER_CE
00796 #ifdef __STL_USE_NEW_IOSTREAMS
00797 template<class _CharT, class _Traits>
00798
00799 #else
00800 template<class _CharT>
00801
00802
00803
00804 #endif
00805 class _Rope_insert_char_consumer : public _Rope_char_consumer<_CharT> {
00806 private:
00807 # ifdef __STL_USE_NEW_IOSTREAMS
00808 typedef basic_ostream<_CharT,_Traits> _Insert_ostream;
00809 # else
00810 typedef ostream _Insert_ostream;
00811 # endif
00812 _Insert_ostream& _M_o;
00813 public:
00814 _Rope_insert_char_consumer(_Insert_ostream& __writer)
00815 : _M_o(__writer) {};
00816 ~_Rope_insert_char_consumer() { };
00817
00818 bool operator() (const _CharT* __leaf, size_t __n);
00819
00820 };
00821
00822 #ifdef __STL_USE_NEW_IOSTREAMS
00823 template<class _CharT, class _Traits>
00824 bool _Rope_insert_char_consumer<_CharT, _Traits>::operator()
00825 (const _CharT* __leaf, size_t __n)
00826 {
00827 size_t __i;
00828
00829 for (__i = 0; __i < __n; __i++) _M_o.put(__leaf[__i]);
00830 return true;
00831 }
00832
00833 #else
00834 template<class _CharT>
00835 bool _Rope_insert_char_consumer<_CharT>::operator()
00836 (const _CharT* __leaf, size_t __n)
00837 {
00838 size_t __i;
00839
00840 for (__i = 0; __i < __n; __i++) _M_o << __leaf[__i];
00841 return true;
00842 }
00843
00844
00845 __STL_TEMPLATE_NULL
00846 inline bool _Rope_insert_char_consumer<char>::operator()
00847 (const char* __leaf, size_t __n)
00848 {
00849 size_t __i;
00850 for (__i = 0; __i < __n; __i++) _M_o.put(__leaf[__i]);
00851 return true;
00852 }
00853 #endif
00854
00855 #endif //UNDER_CE
00856
00857 template <class _CharT, class _Alloc>
00858 bool rope<_CharT, _Alloc>::_S_apply_to_pieces(
00859 _Rope_char_consumer<_CharT>& __c,
00860 const _RopeRep* __r,
00861 size_t __begin, size_t __end)
00862 {
00863 if (0 == __r) return true;
00864 switch(__r->_M_tag) {
00865 case _RopeRep::_S_concat:
00866 {
00867 _RopeConcatenation* __conc = (_RopeConcatenation*)__r;
00868 _RopeRep* __left = __conc->_M_left;
00869 size_t __left_len = __left->_M_size;
00870 if (__begin < __left_len) {
00871 size_t __left_end = min(__left_len, __end);
00872 if (!_S_apply_to_pieces(__c, __left, __begin, __left_end))
00873 return false;
00874 }
00875 if (__end > __left_len) {
00876 _RopeRep* __right = __conc->_M_right;
00877 size_t __right_start = max(__left_len, __begin);
00878 if (!_S_apply_to_pieces(__c, __right,
00879 __right_start - __left_len,
00880 __end - __left_len)) {
00881 return false;
00882 }
00883 }
00884 }
00885 return true;
00886 case _RopeRep::_S_leaf:
00887 {
00888 _RopeLeaf* __l = (_RopeLeaf*)__r;
00889 return __c(__l->_M_data + __begin, __end - __begin);
00890 }
00891 case _RopeRep::_S_function:
00892 case _RopeRep::_S_substringfn:
00893 {
00894 _RopeFunction* __f = (_RopeFunction*)__r;
00895 size_t __len = __end - __begin;
00896 bool __result;
00897 _CharT* __buffer =
00898 (_CharT*)alloc::allocate(__len * sizeof(_CharT));
00899 __STL_TRY {
00900 (*(__f->_M_fn))(__begin, __len, __buffer);
00901 __result = __c(__buffer, __len);
00902 alloc::deallocate(__buffer, __len * sizeof(_CharT));
00903 }
00904 __STL_UNWIND((alloc::deallocate(__buffer,
00905 __len * sizeof(_CharT))))
00906 return __result;
00907 }
00908 default:
00909 __stl_assert(false);
00910
00911 return false;
00912 }
00913 }
00914
00915 #ifndef UNDER_CE
00916
00917 #ifdef __STL_USE_NEW_IOSTREAMS
00918 template<class _CharT, class _Traits>
00919 inline void _Rope_fill(basic_ostream<_CharT, _Traits>& __o, size_t __n)
00920 #else
00921 inline void _Rope_fill(ostream& __o, size_t __n)
00922 #endif
00923 {
00924 char __f = __o.fill();
00925 size_t __i;
00926
00927 for (__i = 0; __i < __n; __i++) __o.put(__f);
00928 }
00929 #endif //UNDER_CE
00930
00931 template <class _CharT> inline bool _Rope_is_simple(_CharT*) { return false; }
00932 inline bool _Rope_is_simple(char*) { return true; }
00933 inline bool _Rope_is_simple(wchar_t*) { return true; }
00934
00935 #ifndef UNDER_CE
00936
00937 #ifdef __STL_USE_NEW_IOSTREAMS
00938 template<class _CharT, class _Traits, class _Alloc>
00939 basic_ostream<_CharT, _Traits>& operator<<
00940 (basic_ostream<_CharT, _Traits>& __o,
00941 const rope<_CharT, _Alloc>& __r)
00942 #else
00943 template<class _CharT, class _Alloc>
00944 ostream& operator<< (ostream& __o, const rope<_CharT, _Alloc>& __r)
00945 #endif
00946 {
00947 size_t __w = __o.width();
00948 bool __left = bool(__o.flags() & ios::left);
00949 size_t __pad_len;
00950 size_t __rope_len = __r.size();
00951 # ifdef __STL_USE_NEW_IOSTREAMS
00952 _Rope_insert_char_consumer<_CharT, _Traits> __c(__o);
00953 # else
00954 _Rope_insert_char_consumer<_CharT> __c(__o);
00955 # endif
00956 bool __is_simple = _Rope_is_simple((_CharT*)0);
00957
00958 if (__rope_len < __w) {
00959 __pad_len = __w - __rope_len;
00960 } else {
00961 __pad_len = 0;
00962 }
00963 if (!__is_simple) __o.width(__w/__rope_len);
00964 __STL_TRY {
00965 if (__is_simple && !__left && __pad_len > 0) {
00966 _Rope_fill(__o, __pad_len);
00967 }
00968 __r.apply_to_pieces(0, __r.size(), __c);
00969 if (__is_simple && __left && __pad_len > 0) {
00970 _Rope_fill(__o, __pad_len);
00971 }
00972 if (!__is_simple)
00973 __o.width(__w);
00974 }
00975 __STL_UNWIND(if (!__is_simple) __o.width(__w))
00976 return __o;
00977 }
00978
00979 #endif //UNDER_CE
00980
00981 template <class _CharT, class _Alloc>
00982 _CharT*
00983 rope<_CharT,_Alloc>::_S_flatten(_RopeRep* __r,
00984 size_t __start, size_t __len,
00985 _CharT* __buffer)
00986 {
00987 _Rope_flatten_char_consumer<_CharT> __c(__buffer);
00988 _S_apply_to_pieces(__c, __r, __start, __start + __len);
00989 return(__buffer + __len);
00990 }
00991
00992 template <class _CharT, class _Alloc>
00993 size_t
00994 rope<_CharT,_Alloc>::find(_CharT __pattern, size_t __start) const
00995 {
00996 _Rope_find_char_char_consumer<_CharT> __c(__pattern);
00997 _S_apply_to_pieces(__c, _M_tree_ptr, __start, size());
00998 size_type __result_pos = __start + __c._M_count;
00999 # ifndef __STL_OLD_ROPE_SEMANTICS
01000 if (__result_pos == size()) __result_pos = npos;
01001 # endif
01002 return __result_pos;
01003 }
01004
01005 template <class _CharT, class _Alloc>
01006 _CharT*
01007 rope<_CharT,_Alloc>::_S_flatten(_RopeRep* __r, _CharT* __buffer)
01008 {
01009 if (0 == __r) return __buffer;
01010 switch(__r->_M_tag) {
01011 case _RopeRep::_S_concat:
01012 {
01013 _RopeConcatenation* __c = (_RopeConcatenation*)__r;
01014 _RopeRep* __left = __c->_M_left;
01015 _RopeRep* __right = __c->_M_right;
01016 _CharT* __rest = _S_flatten(__left, __buffer);
01017 return _S_flatten(__right, __rest);
01018 }
01019 case _RopeRep::_S_leaf:
01020 {
01021 _RopeLeaf* __l = (_RopeLeaf*)__r;
01022 return copy_n(__l->_M_data, __l->_M_size, __buffer).second;
01023 }
01024 case _RopeRep::_S_function:
01025 case _RopeRep::_S_substringfn:
01026
01027
01028 {
01029 _RopeFunction* __f = (_RopeFunction*)__r;
01030 (*(__f->_M_fn))(0, __f->_M_size, __buffer);
01031 return __buffer + __f->_M_size;
01032 }
01033 default:
01034 __stl_assert(false);
01035
01036 return 0;
01037 }
01038 }
01039
01040
01041 #ifndef UNDER_CE
01042
01043
01044 template <class _CharT, class _Alloc>
01045 void
01046 rope<_CharT,_Alloc>::_S_dump(_RopeRep* __r, int __indent)
01047 {
01048 for (int __i = 0; __i < __indent; __i++) putchar(' ');
01049 if (0 == __r) {
01050 printf("NULL\n"); return;
01051 }
01052 if (_RopeRep::_S_concat == __r->_M_tag) {
01053 _RopeConcatenation* __c = (_RopeConcatenation*)__r;
01054 _RopeRep* __left = __c->_M_left;
01055 _RopeRep* __right = __c->_M_right;
01056
01057 # ifdef __GC
01058 printf("Concatenation %p (depth = %d, len = %ld, %s balanced)\n",
01059 __r, __r->_M_depth, __r->_M_size, __r->_M_is_balanced? "" : "not");
01060 # else
01061 printf("Concatenation %p (rc = %ld, depth = %d, "
01062 "len = %ld, %s balanced)\n",
01063 __r, __r->_M_ref_count, __r->_M_depth, __r->_M_size,
01064 __r->_M_is_balanced? "" : "not");
01065 # endif
01066 _S_dump(__left, __indent + 2);
01067 _S_dump(__right, __indent + 2);
01068 return;
01069 } else {
01070 char* __kind;
01071
01072 switch (__r->_M_tag) {
01073 case _RopeRep::_S_leaf:
01074 __kind = "Leaf";
01075 break;
01076 case _RopeRep::_S_function:
01077 __kind = "Function";
01078 break;
01079 case _RopeRep::_S_substringfn:
01080 __kind = "Function representing substring";
01081 break;
01082 default:
01083 __kind = "(corrupted kind field!)";
01084 }
01085 # ifdef __GC
01086 printf("%s %p (depth = %d, len = %ld) ",
01087 __kind, __r, __r->_M_depth, __r->_M_size);
01088 # else
01089 printf("%s %p (rc = %ld, depth = %d, len = %ld) ",
01090 __kind, __r, __r->_M_ref_count, __r->_M_depth, __r->_M_size);
01091 # endif
01092 if (_S_is_one_byte_char_type((_CharT*)0)) {
01093 const int __max_len = 40;
01094 _Self_destruct_ptr __prefix(_S_substring(__r, 0, __max_len));
01095 _CharT __buffer[__max_len + 1];
01096 bool __too_big = __r->_M_size > __prefix->_M_size;
01097
01098 _S_flatten(__prefix, __buffer);
01099 __buffer[__prefix->_M_size] = _S_eos((_CharT*)0);
01100 printf("%s%s\n",
01101 (char*)__buffer, __too_big? "...\n" : "\n");
01102 } else {
01103 printf("\n");
01104 }
01105 }
01106 }
01107
01108 #endif //UNDER_CE
01109
01110 template <class _CharT, class _Alloc>
01111 const unsigned long
01112 rope<_CharT,_Alloc>::_S_min_len[
01113 _Rope_RopeRep<_CharT,_Alloc>::_S_max_rope_depth + 1] = {
01114 1, 2, 3, 5, 8, 13, 21,
01115 34, 55, 89, 144, 233, 377,
01116 610, 987, 1597, 2584, 4181,
01117 6765, 10946, 17711, 28657, 46368,
01118 75025, 121393, 196418, 317811,
01119 514229, 832040, 1346269, 2178309,
01120 3524578, 5702887, 9227465, 14930352,
01121 24157817, 39088169, 63245986, 102334155,
01122 165580141, 267914296, 433494437,
01123 701408733, 1134903170, 1836311903,
01124 2971215073u };
01125
01126
01127 template <class _CharT, class _Alloc>
01128 rope<_CharT,_Alloc>::_RopeRep*
01129 rope<_CharT,_Alloc>::_S_balance(_RopeRep* __r)
01130 {
01131 _RopeRep* __forest[_RopeRep::_S_max_rope_depth + 1];
01132 _RopeRep* __result = 0;
01133 int __i;
01134
01135
01136
01137
01138
01139
01140 for (__i = 0; __i <= _RopeRep::_S_max_rope_depth; ++__i)
01141 __forest[__i] = 0;
01142 __STL_TRY {
01143 _S_add_to_forest(__r, __forest);
01144 for (__i = 0; __i <= _RopeRep::_S_max_rope_depth; ++__i)
01145 if (0 != __forest[__i]) {
01146 # ifndef __GC
01147 _Self_destruct_ptr __old(__result);
01148 # endif
01149 __result = _S_concat(__forest[__i], __result);
01150 __forest[__i]->_M_unref_nonnil();
01151 # if !defined(__GC) && defined(__STL_USE_EXCEPTIONS)
01152 __forest[__i] = 0;
01153 # endif
01154 }
01155 }
01156 __STL_UNWIND(for(__i = 0; __i <= _RopeRep::_S_max_rope_depth; __i++)
01157 _S_unref(__forest[__i]))
01158 if (__result->_M_depth > _RopeRep::_S_max_rope_depth) {
01159 # ifdef __STL_USE_EXCEPTIONS
01160 __STL_THROW(length_error("rope too long"));
01161 # else
01162 abort();
01163 # endif
01164 }
01165 return(__result);
01166 }
01167
01168
01169 template <class _CharT, class _Alloc>
01170 void
01171 rope<_CharT,_Alloc>::_S_add_to_forest(_RopeRep* __r, _RopeRep** __forest)
01172 {
01173 if (__r->_M_is_balanced) {
01174 _S_add_leaf_to_forest(__r, __forest);
01175 return;
01176 }
01177 __stl_assert(__r->_M_tag == _RopeRep::_S_concat);
01178 {
01179 _RopeConcatenation* __c = (_RopeConcatenation*)__r;
01180
01181 _S_add_to_forest(__c->_M_left, __forest);
01182 _S_add_to_forest(__c->_M_right, __forest);
01183 }
01184 }
01185
01186
01187 template <class _CharT, class _Alloc>
01188 void
01189 rope<_CharT,_Alloc>::_S_add_leaf_to_forest(_RopeRep* __r, _RopeRep** __forest)
01190 {
01191 _RopeRep* __insertee;
01192 _RopeRep* __too_tiny = 0;
01193 int __i;
01194 size_t __s = __r->_M_size;
01195
01196 for (__i = 0; __s >= _S_min_len[__i+1]; ++__i) {
01197 if (0 != __forest[__i]) {
01198 # ifndef __GC
01199 _Self_destruct_ptr __old(__too_tiny);
01200 # endif
01201 __too_tiny = _S_concat_and_set_balanced(__forest[__i], __too_tiny);
01202 __forest[__i]->_M_unref_nonnil();
01203 __forest[__i] = 0;
01204 }
01205 }
01206 {
01207 # ifndef __GC
01208 _Self_destruct_ptr __old(__too_tiny);
01209 # endif
01210 __insertee = _S_concat_and_set_balanced(__too_tiny, __r);
01211 }
01212
01213
01214 __stl_assert(_S_is_almost_balanced(__insertee));
01215 __stl_assert(__insertee->_M_depth <= __r->_M_depth + 1);
01216 for (;; ++__i) {
01217 if (0 != __forest[__i]) {
01218 # ifndef __GC
01219 _Self_destruct_ptr __old(__insertee);
01220 # endif
01221 __insertee = _S_concat_and_set_balanced(__forest[__i], __insertee);
01222 __forest[__i]->_M_unref_nonnil();
01223 __forest[__i] = 0;
01224 __stl_assert(_S_is_almost_balanced(__insertee));
01225 }
01226 __stl_assert(_S_min_len[__i] <= __insertee->_M_size);
01227 __stl_assert(__forest[__i] == 0);
01228 if (__i == _RopeRep::_S_max_rope_depth ||
01229 __insertee->_M_size < _S_min_len[__i+1]) {
01230 __forest[__i] = __insertee;
01231
01232 return;
01233 }
01234 }
01235 }
01236
01237 template <class _CharT, class _Alloc>
01238 _CharT
01239 rope<_CharT,_Alloc>::_S_fetch(_RopeRep* __r, size_type __i)
01240 {
01241 __GC_CONST _CharT* __cstr = __r->_M_c_string;
01242
01243 __stl_assert(__i < __r->_M_size);
01244 if (0 != __cstr) return __cstr[__i];
01245 for(;;) {
01246 switch(__r->_M_tag) {
01247 case _RopeRep::_S_concat:
01248 {
01249 _RopeConcatenation* __c = (_RopeConcatenation*)__r;
01250 _RopeRep* __left = __c->_M_left;
01251 size_t __left_len = __left->_M_size;
01252
01253 if (__i >= __left_len) {
01254 __i -= __left_len;
01255 __r = __c->_M_right;
01256 } else {
01257 __r = __left;
01258 }
01259 }
01260 break;
01261 case _RopeRep::_S_leaf:
01262 {
01263 _RopeLeaf* __l = (_RopeLeaf*)__r;
01264 return __l->_M_data[__i];
01265 }
01266 case _RopeRep::_S_function:
01267 case _RopeRep::_S_substringfn:
01268 {
01269 _RopeFunction* __f = (_RopeFunction*)__r;
01270 _CharT __result;
01271
01272 (*(__f->_M_fn))(__i, 1, &__result);
01273 return __result;
01274 }
01275 }
01276 }
01277 }
01278
01279 # ifndef __GC
01280
01281
01282 template <class _CharT, class _Alloc>
01283 _CharT*
01284 rope<_CharT,_Alloc>::_S_fetch_ptr(_RopeRep* __r, size_type __i)
01285 {
01286 _RopeRep* __clrstack[_RopeRep::_S_max_rope_depth];
01287 size_t __csptr = 0;
01288
01289 for(;;) {
01290 if (__r->_M_ref_count > 1) return 0;
01291 switch(__r->_M_tag) {
01292 case _RopeRep::_S_concat:
01293 {
01294 _RopeConcatenation* __c = (_RopeConcatenation*)__r;
01295 _RopeRep* __left = __c->_M_left;
01296 size_t __left_len = __left->_M_size;
01297
01298 if (__c->_M_c_string != 0) __clrstack[__csptr++] = __c;
01299 if (__i >= __left_len) {
01300 __i -= __left_len;
01301 __r = __c->_M_right;
01302 } else {
01303 __r = __left;
01304 }
01305 }
01306 break;
01307 case _RopeRep::_S_leaf:
01308 {
01309 _RopeLeaf* __l = (_RopeLeaf*)__r;
01310 if (__l->_M_c_string != __l->_M_data && __l->_M_c_string != 0)
01311 __clrstack[__csptr++] = __l;
01312 while (__csptr > 0) {
01313 -- __csptr;
01314 _RopeRep* __d = __clrstack[__csptr];
01315 __d->_M_free_c_string();
01316 __d->_M_c_string = 0;
01317 }
01318 return __l->_M_data + __i;
01319 }
01320 case _RopeRep::_S_function:
01321 case _RopeRep::_S_substringfn:
01322 return 0;
01323 }
01324 }
01325 }
01326 # endif
01327
01328
01329
01330
01331
01332 template <class _CharT, class _Alloc>
01333 int
01334 rope<_CharT,_Alloc>::_S_compare (const _RopeRep* __left,
01335 const _RopeRep* __right)
01336 {
01337 size_t __left_len;
01338 size_t __right_len;
01339
01340 if (0 == __right) return 0 != __left;
01341 if (0 == __left) return -1;
01342 __left_len = __left->_M_size;
01343 __right_len = __right->_M_size;
01344 if (_RopeRep::_S_leaf == __left->_M_tag) {
01345 _RopeLeaf* __l = (_RopeLeaf*) __left;
01346 if (_RopeRep::_S_leaf == __right->_M_tag) {
01347 _RopeLeaf* __r = (_RopeLeaf*) __right;
01348 return lexicographical_compare_3way(
01349 __l->_M_data, __l->_M_data + __left_len,
01350 __r->_M_data, __r->_M_data + __right_len);
01351 } else {
01352 const_iterator __rstart(__right, 0);
01353 const_iterator __rend(__right, __right_len);
01354 return lexicographical_compare_3way(
01355 __l->_M_data, __l->_M_data + __left_len,
01356 __rstart, __rend);
01357 }
01358 } else {
01359 const_iterator __lstart(__left, 0);
01360 const_iterator __lend(__left, __left_len);
01361 if (_RopeRep::_S_leaf == __right->_M_tag) {
01362 _RopeLeaf* __r = (_RopeLeaf*) __right;
01363 return lexicographical_compare_3way(
01364 __lstart, __lend,
01365 __r->_M_data, __r->_M_data + __right_len);
01366 } else {
01367 const_iterator __rstart(__right, 0);
01368 const_iterator __rend(__right, __right_len);
01369 return lexicographical_compare_3way(
01370 __lstart, __lend,
01371 __rstart, __rend);
01372 }
01373 }
01374 }
01375
01376
01377 template <class _CharT, class _Alloc>
01378 _Rope_char_ref_proxy<_CharT, _Alloc>&
01379 _Rope_char_ref_proxy<_CharT, _Alloc>::operator= (_CharT __c) {
01380 _RopeRep* __old = _M_root->_M_tree_ptr;
01381 # ifndef __GC
01382
01383
01384 _CharT* __ptr = _My_rope::_S_fetch_ptr(__old, _M_pos);
01385 if (0 != __ptr) {
01386 *__ptr = __c;
01387 return *this;
01388 }
01389 # endif
01390 _Self_destruct_ptr __left(
01391 _My_rope::_S_substring(__old, 0, _M_pos));
01392 _Self_destruct_ptr __right(
01393 _My_rope::_S_substring(__old, _M_pos+1, __old->_M_size));
01394 _Self_destruct_ptr __result_left(
01395 _My_rope::_S_destr_concat_char_iter(__left, &__c, 1));
01396
01397 # ifndef __GC
01398 __stl_assert(__left == __result_left || 1 == __result_left->_M_ref_count);
01399 # endif
01400 _RopeRep* __result =
01401 _My_rope::_S_concat(__result_left, __right);
01402 # ifndef __GC
01403 __stl_assert(1 <= __result->_M_ref_count);
01404 _RopeRep::_S_unref(__old);
01405 # endif
01406 _M_root->_M_tree_ptr = __result;
01407 return *this;
01408 }
01409
01410 template <class _CharT, class _Alloc>
01411 inline _Rope_char_ref_proxy<_CharT, _Alloc>::operator _CharT () const
01412 {
01413 if (_M_current_valid) {
01414 return _M_current;
01415 } else {
01416 return _My_rope::_S_fetch(_M_root->_M_tree_ptr, _M_pos);
01417 }
01418 }
01419 template <class _CharT, class _Alloc>
01420 _Rope_char_ptr_proxy<_CharT, _Alloc>
01421 _Rope_char_ref_proxy<_CharT, _Alloc>::operator& () const {
01422 return _Rope_char_ptr_proxy<_CharT, _Alloc>(*this);
01423 }
01424
01425 template <class _CharT, class _Alloc>
01426 rope<_CharT, _Alloc>::rope(size_t __n, _CharT __c,
01427 const allocator_type& __a)
01428 : _Base(__a)
01429 {
01430 rope<_CharT,_Alloc> __result;
01431 const size_t __exponentiate_threshold = 32;
01432 size_t __exponent;
01433 size_t __rest;
01434 _CharT* __rest_buffer;
01435 _RopeRep* __remainder;
01436 rope<_CharT,_Alloc> __remainder_rope;
01437
01438 if (0 == __n)
01439 return;
01440
01441 __exponent = __n / __exponentiate_threshold;
01442 __rest = __n % __exponentiate_threshold;
01443 if (0 == __rest) {
01444 __remainder = 0;
01445 } else {
01446 __rest_buffer = _Data_allocate(_S_rounded_up_size(__rest));
01447 uninitialized_fill_n(__rest_buffer, __rest, __c);
01448 _S_cond_store_eos(__rest_buffer[__rest]);
01449 __STL_TRY {
01450 __remainder = _S_new_RopeLeaf(__rest_buffer, __rest, __a);
01451 }
01452 __STL_UNWIND(_RopeRep::__STL_FREE_STRING(__rest_buffer, __rest, __a))
01453 }
01454 __remainder_rope._M_tree_ptr = __remainder;
01455 if (__exponent != 0) {
01456 _CharT* __base_buffer =
01457 _Data_allocate(_S_rounded_up_size(__exponentiate_threshold));
01458 _RopeLeaf* __base_leaf;
01459 rope __base_rope;
01460 uninitialized_fill_n(__base_buffer, __exponentiate_threshold, __c);
01461 _S_cond_store_eos(__base_buffer[__exponentiate_threshold]);
01462 __STL_TRY {
01463 __base_leaf = _S_new_RopeLeaf(__base_buffer,
01464 __exponentiate_threshold, __a);
01465 }
01466 __STL_UNWIND(_RopeRep::__STL_FREE_STRING(__base_buffer,
01467 __exponentiate_threshold, __a))
01468 __base_rope._M_tree_ptr = __base_leaf;
01469 if (1 == __exponent) {
01470 __result = __base_rope;
01471 # ifndef __GC
01472 __stl_assert(2 == __result._M_tree_ptr->_M_ref_count);
01473
01474 # endif
01475 } else {
01476 __result = power(__base_rope, __exponent,
01477 _Rope_Concat_fn<_CharT,_Alloc>());
01478 }
01479 if (0 != __remainder) {
01480 __result += __remainder_rope;
01481 }
01482 } else {
01483 __result = __remainder_rope;
01484 }
01485 _M_tree_ptr = __result._M_tree_ptr;
01486 _M_tree_ptr->_M_ref_nonnil();
01487 }
01488
01489 template<class _CharT, class _Alloc>
01490 _CharT rope<_CharT,_Alloc>::_S_empty_c_str[1];
01491
01492 template<class _CharT, class _Alloc>
01493 const _CharT* rope<_CharT,_Alloc>::c_str() const {
01494 if (0 == _M_tree_ptr) {
01495 _S_empty_c_str[0] = _S_eos((_CharT*)0);
01496
01497 return _S_empty_c_str;
01498 }
01499 __GC_CONST _CharT* __old_c_string = _M_tree_ptr->_M_c_string;
01500 if (0 != __old_c_string) return(__old_c_string);
01501 size_t __s = size();
01502 _CharT* __result = _Data_allocate(__s + 1);
01503 _S_flatten(_M_tree_ptr, __result);
01504 __result[__s] = _S_eos((_CharT*)0);
01505 # ifdef __GC
01506 _M_tree_ptr->_M_c_string = __result;
01507 # else
01508 if ((__old_c_string = (__GC_CONST _CharT*)
01509 _Atomic_swap((unsigned long *)(&(_M_tree_ptr->_M_c_string)),
01510 (unsigned long)__result)) != 0) {
01511
01512
01513
01514 destroy(__old_c_string, __old_c_string + __s + 1);
01515 _Data_deallocate(__old_c_string, __s + 1);
01516 }
01517 # endif
01518 return(__result);
01519 }
01520
01521 template<class _CharT, class _Alloc>
01522 const _CharT* rope<_CharT,_Alloc>::replace_with_c_str() {
01523 if (0 == _M_tree_ptr) {
01524 _S_empty_c_str[0] = _S_eos((_CharT*)0);
01525 return _S_empty_c_str;
01526 }
01527 __GC_CONST _CharT* __old_c_string = _M_tree_ptr->_M_c_string;
01528 if (_RopeRep::_S_leaf == _M_tree_ptr->_M_tag && 0 != __old_c_string) {
01529 return(__old_c_string);
01530 }
01531 size_t __s = size();
01532 _CharT* __result = _Data_allocate(_S_rounded_up_size(__s));
01533 _S_flatten(_M_tree_ptr, __result);
01534 __result[__s] = _S_eos((_CharT*)0);
01535 _M_tree_ptr->_M_unref_nonnil();
01536 _M_tree_ptr = _S_new_RopeLeaf(__result, __s, get_allocator());
01537 return(__result);
01538 }
01539
01540
01541
01542 template<class _Rope_iterator>
01543 void
01544 _Rope_rotate(_Rope_iterator __first,
01545 _Rope_iterator __middle,
01546 _Rope_iterator __last)
01547 {
01548 typedef typename _Rope_iterator::value_type _CharT;
01549 typedef typename _Rope_iterator::_allocator_type _Alloc;
01550
01551 __stl_assert(__first.container() == __middle.container()
01552 && __middle.container() == __last.container());
01553 rope<_CharT,_Alloc>& __r(__first.container());
01554 rope<_CharT,_Alloc> __prefix = __r.substr(0, __first.index());
01555 rope<_CharT,_Alloc> __suffix =
01556 __r.substr(__last.index(), __r.size() - __last.index());
01557 rope<_CharT,_Alloc> __part1 =
01558 __r.substr(__middle.index(), __last.index() - __middle.index());
01559 rope<_CharT,_Alloc> __part2 =
01560 __r.substr(__first.index(), __middle.index() - __first.index());
01561 __r = __prefix;
01562 __r += __part1;
01563 __r += __part2;
01564 __r += __suffix;
01565 }
01566
01567 #if !defined(__GNUC__) && !defined (UNDER_CE)
01568
01569 inline void rotate(_Rope_iterator<char,__STL_DEFAULT_ALLOCATOR(char)> __first,
01570 _Rope_iterator<char,__STL_DEFAULT_ALLOCATOR(char)> __middle,
01571 _Rope_iterator<char,__STL_DEFAULT_ALLOCATOR(char)> __last) {
01572 _Rope_rotate(__first, __middle, __last);
01573 }
01574 #endif
01575
01576 # if 0
01577
01578
01579
01580
01581
01582
01583
01584 inline void rotate(
01585 _Rope_iterator<wchar_t,__STL_DEFAULT_ALLOCATOR(char)> __first,
01586 _Rope_iterator<wchar_t,__STL_DEFAULT_ALLOCATOR(char)> __middle,
01587 _Rope_iterator<wchar_t,__STL_DEFAULT_ALLOCATOR(char)> __last) {
01588 _Rope_rotate(__first, __middle, __last);
01589 }
01590 # endif
01591
01592
01593 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
01594 #pragma reset woff 1174
01595 #endif
01596
01597 __STL_END_NAMESPACE
01598
01599
01600
01601
01602