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