47 #include <ext/algorithm>
49 #include <ext/numeric>
51 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
53 _GLIBCXX_BEGIN_NAMESPACE_VERSION
57 using std::basic_ostream;
58 using std::__throw_length_error;
60 using std::__uninitialized_fill_n_a;
66 template <
class _CharT,
class _Alloc>
68 _Rope_iterator_base<_CharT, _Alloc>::
69 _S_setbuf(_Rope_iterator_base<_CharT, _Alloc>& __x)
71 const _RopeRep* __leaf = __x._M_path_end[__x._M_leaf_index];
72 size_t __leaf_pos = __x._M_leaf_pos;
73 size_t __pos = __x._M_current_pos;
75 switch(__leaf->_M_tag)
77 case __detail::_S_leaf:
78 __x._M_buf_start = ((_Rope_RopeLeaf<_CharT, _Alloc>*)__leaf)->_M_data;
79 __x._M_buf_ptr = __x._M_buf_start + (__pos - __leaf_pos);
80 __x._M_buf_end = __x._M_buf_start + __leaf->_M_size;
82 case __detail::_S_function:
83 case __detail::_S_substringfn:
85 size_t __len = _S_iterator_buf_len;
86 size_t __buf_start_pos = __leaf_pos;
87 size_t __leaf_end = __leaf_pos + __leaf->_M_size;
88 char_producer<_CharT>* __fn = ((_Rope_RopeFunction<_CharT,
89 _Alloc>*)__leaf)->_M_fn;
90 if (__buf_start_pos + __len <= __pos)
92 __buf_start_pos = __pos - __len / 4;
93 if (__buf_start_pos + __len > __leaf_end)
94 __buf_start_pos = __leaf_end - __len;
96 if (__buf_start_pos + __len > __leaf_end)
97 __len = __leaf_end - __buf_start_pos;
98 (*__fn)(__buf_start_pos - __leaf_pos, __len, __x._M_tmp_buf);
99 __x._M_buf_ptr = __x._M_tmp_buf + (__pos - __buf_start_pos);
100 __x._M_buf_start = __x._M_tmp_buf;
101 __x._M_buf_end = __x._M_tmp_buf + __len;
111 template <
class _CharT,
class _Alloc>
113 _Rope_iterator_base<_CharT, _Alloc>::
114 _S_setcache(_Rope_iterator_base<_CharT, _Alloc>& __x)
116 const _RopeRep* __path[int(__detail::_S_max_rope_depth) + 1];
117 const _RopeRep* __curr_rope;
118 int __curr_depth = -1;
119 size_t __curr_start_pos = 0;
120 size_t __pos = __x._M_current_pos;
121 unsigned char __dirns = 0;
123 if (__pos >= __x._M_root->_M_size)
128 __curr_rope = __x._M_root;
129 if (0 != __curr_rope->_M_c_string)
132 __x._M_buf_start = __curr_rope->_M_c_string;
133 __x._M_buf_end = __curr_rope->_M_c_string + __curr_rope->_M_size;
134 __x._M_buf_ptr = __curr_rope->_M_c_string + __pos;
135 __x._M_path_end[0] = __curr_rope;
136 __x._M_leaf_index = 0;
143 __path[__curr_depth] = __curr_rope;
144 switch(__curr_rope->_M_tag)
146 case __detail::_S_leaf:
147 case __detail::_S_function:
148 case __detail::_S_substringfn:
149 __x._M_leaf_pos = __curr_start_pos;
151 case __detail::_S_concat:
153 _Rope_RopeConcatenation<_CharT, _Alloc>* __c =
154 (_Rope_RopeConcatenation<_CharT, _Alloc>*)__curr_rope;
155 _RopeRep* __left = __c->_M_left;
156 size_t __left_len = __left->_M_size;
159 if (__pos >= __curr_start_pos + __left_len)
162 __curr_rope = __c->_M_right;
163 __curr_start_pos += __left_len;
166 __curr_rope = __left;
175 int __j = __curr_depth + 1 - int(_S_path_cache_len);
177 if (__j < 0) __j = 0;
178 while (__j <= __curr_depth)
179 __x._M_path_end[++__i] = __path[__j++];
180 __x._M_leaf_index = __i;
182 __x._M_path_directions = __dirns;
188 template <
class _CharT,
class _Alloc>
190 _Rope_iterator_base<_CharT, _Alloc>::
191 _S_setcache_for_incr(_Rope_iterator_base<_CharT, _Alloc>& __x)
193 int __current_index = __x._M_leaf_index;
194 const _RopeRep* __current_node = __x._M_path_end[__current_index];
195 size_t __len = __current_node->_M_size;
196 size_t __node_start_pos = __x._M_leaf_pos;
197 unsigned char __dirns = __x._M_path_directions;
198 _Rope_RopeConcatenation<_CharT, _Alloc>* __c;
200 if (__x._M_current_pos - __node_start_pos < __len)
207 while (--__current_index >= 0)
211 __current_node = __x._M_path_end[__current_index];
212 __c = (_Rope_RopeConcatenation<_CharT, _Alloc>*)__current_node;
215 __node_start_pos -= __c->_M_left->_M_size;
218 if (__current_index < 0)
224 __current_node = __x._M_path_end[__current_index];
225 __c = (_Rope_RopeConcatenation<_CharT, _Alloc>*)__current_node;
229 __node_start_pos += __c->_M_left->_M_size;
230 __current_node = __c->_M_right;
231 __x._M_path_end[++__current_index] = __current_node;
233 while (__detail::_S_concat == __current_node->_M_tag)
236 if (
int(_S_path_cache_len) == __current_index)
239 for (__i = 0; __i < int(_S_path_cache_len) - 1; __i++)
240 __x._M_path_end[__i] = __x._M_path_end[__i+1];
244 ((_Rope_RopeConcatenation<_CharT, _Alloc>*)__current_node)->_M_left;
245 __x._M_path_end[__current_index] = __current_node;
249 __x._M_leaf_index = __current_index;
250 __x._M_leaf_pos = __node_start_pos;
251 __x._M_path_directions = __dirns;
255 template <
class _CharT,
class _Alloc>
257 _Rope_iterator_base<_CharT, _Alloc>::
260 _M_current_pos += __n;
263 size_t __chars_left = _M_buf_end - _M_buf_ptr;
264 if (__chars_left > __n)
266 else if (__chars_left == __n)
269 _S_setcache_for_incr(*
this);
276 template <
class _CharT,
class _Alloc>
278 _Rope_iterator_base<_CharT, _Alloc>::
283 size_t __chars_left = _M_buf_ptr - _M_buf_start;
284 if (__chars_left >= __n)
289 _M_current_pos -= __n;
292 template <
class _CharT,
class _Alloc>
294 _Rope_iterator<_CharT, _Alloc>::
297 if (_M_root_rope->_M_tree_ptr != this->_M_root)
300 _RopeRep::_S_unref(this->_M_root);
301 this->_M_root = _M_root_rope->_M_tree_ptr;
302 _RopeRep::_S_ref(this->_M_root);
303 this->_M_buf_ptr = 0;
307 template <
class _CharT,
class _Alloc>
309 _Rope_const_iterator<_CharT, _Alloc>::
310 _Rope_const_iterator(
const _Rope_iterator<_CharT, _Alloc>& __x)
311 : _Rope_iterator_base<_CharT, _Alloc>(__x)
314 template <
class _CharT,
class _Alloc>
316 _Rope_iterator<_CharT, _Alloc>::
317 _Rope_iterator(rope<_CharT, _Alloc>& __r,
size_t __pos)
318 : _Rope_iterator_base<_CharT,_Alloc>(__r._M_tree_ptr, __pos),
320 { _RopeRep::_S_ref(this->_M_root); }
322 template <
class _CharT,
class _Alloc>
324 rope<_CharT, _Alloc>::
325 _S_char_ptr_len(
const _CharT* __s)
327 const _CharT* __p = __s;
329 while (!_S_is0(*__p))
337 template <
class _CharT,
class _Alloc>
339 _Rope_RopeRep<_CharT, _Alloc>::
342 _CharT* __cstr = _M_c_string;
345 size_t __size = this->_M_size + 1;
346 _Destroy(__cstr, __cstr + __size, _M_get_allocator());
347 this->_Data_deallocate(__cstr, __size);
351 template <
class _CharT,
class _Alloc>
353 _Rope_RopeRep<_CharT, _Alloc>::
354 _S_free_string(_CharT* __s,
size_t __n, allocator_type& __a)
356 if (!_S_is_basic_char_type((_CharT*)0))
361 _Rope_RopeLeaf<_CharT, _Alloc>::_S_rounded_up_size(__n));
370 template <
class _CharT,
class _Alloc>
372 _Rope_RopeRep<_CharT, _Alloc>::
377 case __detail::_S_leaf:
379 _Rope_RopeLeaf<_CharT, _Alloc>* __l
380 = (_Rope_RopeLeaf<_CharT, _Alloc>*)
this;
381 __l->_Rope_RopeLeaf<_CharT, _Alloc>::~_Rope_RopeLeaf();
382 this->_L_deallocate(__l, 1);
385 case __detail::_S_concat:
387 _Rope_RopeConcatenation<_CharT,_Alloc>* __c
388 = (_Rope_RopeConcatenation<_CharT, _Alloc>*)
this;
389 __c->_Rope_RopeConcatenation<_CharT, _Alloc>::
~_Rope_RopeConcatenation();
390 this->_C_deallocate(__c, 1);
393 case __detail::_S_function:
395 _Rope_RopeFunction<_CharT, _Alloc>* __f
396 = (_Rope_RopeFunction<_CharT, _Alloc>*)
this;
397 __f->_Rope_RopeFunction<_CharT, _Alloc>::~_Rope_RopeFunction();
398 this->_F_deallocate(__f, 1);
401 case __detail::_S_substringfn:
403 _Rope_RopeSubstring<_CharT, _Alloc>* __ss =
404 (_Rope_RopeSubstring<_CharT, _Alloc>*)
this;
405 __ss->_Rope_RopeSubstring<_CharT, _Alloc>::
~_Rope_RopeSubstring();
406 this->_S_deallocate(__ss, 1);
413 template <
class _CharT,
class _Alloc>
415 _Rope_RopeRep<_CharT, _Alloc>::
416 _S_free_string(
const _CharT*,
size_t, allocator_type)
423 template <
class _CharT,
class _Alloc>
424 typename rope<_CharT, _Alloc>::_RopeLeaf*
425 rope<_CharT, _Alloc>::
426 _S_leaf_concat_char_iter(_RopeLeaf* __r,
const _CharT* __iter,
size_t __len)
428 size_t __old_len = __r->_M_size;
429 _CharT* __new_data = (_CharT*)
430 rope::_Data_allocate(_S_rounded_up_size(__old_len + __len));
435 _S_cond_store_eos(__new_data[__old_len + __len]);
438 __result = _S_new_RopeLeaf(__new_data, __old_len + __len,
439 __r->_M_get_allocator());
443 _RopeRep::__STL_FREE_STRING(__new_data, __old_len + __len,
444 __r->_M_get_allocator());
445 __throw_exception_again;
452 template <
class _CharT,
class _Alloc>
453 typename rope<_CharT,_Alloc>::_RopeLeaf*
454 rope<_CharT, _Alloc>::
455 _S_destr_leaf_concat_char_iter(_RopeLeaf* __r,
const _CharT* __iter,
458 if (__r->_M_ref_count > 1)
459 return _S_leaf_concat_char_iter(__r, __iter, __len);
460 size_t __old_len = __r->_M_size;
461 if (_S_allocated_capacity(__old_len) >= __old_len + __len)
466 if (_S_is_basic_char_type((_CharT*)0))
467 _S_cond_store_eos(__r->_M_data[__old_len + __len]);
468 else if (__r->_M_c_string != __r->_M_data && 0 != __r->_M_c_string)
470 __r->_M_free_c_string();
471 __r->_M_c_string = 0;
473 __r->_M_size = __old_len + __len;
474 __r->_M_ref_count = 2;
479 _RopeLeaf* __result = _S_leaf_concat_char_iter(__r, __iter, __len);
488 template <
class _CharT,
class _Alloc>
489 typename rope<_CharT, _Alloc>::_RopeRep*
490 rope<_CharT, _Alloc>::
491 _S_tree_concat(_RopeRep* __left, _RopeRep* __right)
493 _RopeConcatenation* __result = _S_new_RopeConcatenation(__left, __right,
496 size_t __depth = __result->_M_depth;
499 && (__result->_M_size < 1000
500 || __depth >
size_t(__detail::_S_max_rope_depth)))
502 _RopeRep* __balanced;
506 __balanced = _S_balance(__result);
507 __result->_M_unref_nonnil();
511 rope::_C_deallocate(__result,1);
512 __throw_exception_again;
524 template <
class _CharT,
class _Alloc>
525 typename rope<_CharT, _Alloc>::_RopeRep*
526 rope<_CharT, _Alloc>::
527 _S_concat_char_iter(_RopeRep* __r,
const _CharT*__s,
size_t __slen)
536 return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen,
537 __r->_M_get_allocator());
538 if (__r->_M_tag == __detail::_S_leaf
539 && __r->_M_size + __slen <=
size_t(_S_copy_max))
541 __result = _S_leaf_concat_char_iter((_RopeLeaf*)__r, __s, __slen);
544 if (__detail::_S_concat == __r->_M_tag
545 && __detail::_S_leaf == ((_RopeConcatenation*) __r)->_M_right->_M_tag)
548 (_RopeLeaf* )(((_RopeConcatenation* )__r)->_M_right);
549 if (__right->_M_size + __slen <=
size_t(_S_copy_max))
551 _RopeRep* __left = ((_RopeConcatenation*)__r)->_M_left;
553 _S_leaf_concat_char_iter((_RopeLeaf*)__right, __s, __slen);
554 __left->_M_ref_nonnil();
556 { __result = _S_tree_concat(__left, __nright); }
561 __throw_exception_again;
567 __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->_M_get_allocator());
570 __r->_M_ref_nonnil();
571 __result = _S_tree_concat(__r, __nright);
577 __throw_exception_again;
583 template <
class _CharT,
class _Alloc>
584 typename rope<_CharT,_Alloc>::_RopeRep*
585 rope<_CharT,_Alloc>::
586 _S_destr_concat_char_iter(_RopeRep* __r,
const _CharT* __s,
size_t __slen)
590 return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen,
591 __r->_M_get_allocator());
592 size_t __count = __r->_M_ref_count;
593 size_t __orig_size = __r->_M_size;
595 return _S_concat_char_iter(__r, __s, __slen);
598 __r->_M_ref_count = 2;
601 if (__orig_size + __slen <=
size_t(_S_copy_max)
602 && __detail::_S_leaf == __r->_M_tag)
604 __result = _S_destr_leaf_concat_char_iter((_RopeLeaf*)__r, __s,
608 if (__detail::_S_concat == __r->_M_tag)
610 _RopeLeaf* __right = (_RopeLeaf*)(((_RopeConcatenation*)
612 if (__detail::_S_leaf == __right->_M_tag
613 && __right->_M_size + __slen <=
size_t(_S_copy_max))
615 _RopeRep* __new_right =
616 _S_destr_leaf_concat_char_iter(__right, __s, __slen);
617 if (__right == __new_right)
618 __new_right->_M_ref_count = 1;
620 __right->_M_unref_nonnil();
621 __r->_M_ref_count = 2;
622 ((_RopeConcatenation*)__r)->_M_right = __new_right;
623 __r->_M_size = __orig_size + __slen;
624 if (0 != __r->_M_c_string)
626 __r->_M_free_c_string();
627 __r->_M_c_string = 0;
633 __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->_M_get_allocator());
634 __r->_M_ref_nonnil();
636 { __result = _S_tree_concat(__r, __right); }
641 __throw_exception_again;
647 template <
class _CharT,
class _Alloc>
648 typename rope<_CharT, _Alloc>::_RopeRep*
649 rope<_CharT, _Alloc>::
650 _S_concat(_RopeRep* __left, _RopeRep* __right)
659 __left->_M_ref_nonnil();
662 if (__detail::_S_leaf == __right->_M_tag)
664 if (__detail::_S_leaf == __left->_M_tag)
666 if (__right->_M_size + __left->_M_size <=
size_t(_S_copy_max))
667 return _S_leaf_concat_char_iter((_RopeLeaf*)__left,
668 ((_RopeLeaf*)__right)->_M_data,
671 else if (__detail::_S_concat == __left->_M_tag
672 && __detail::_S_leaf == ((_RopeConcatenation*)
673 __left)->_M_right->_M_tag)
675 _RopeLeaf* __leftright =
676 (_RopeLeaf*)(((_RopeConcatenation*)__left)->_M_right);
677 if (__leftright->_M_size
678 + __right->_M_size <=
size_t(_S_copy_max))
680 _RopeRep* __leftleft = ((_RopeConcatenation*)__left)->_M_left;
681 _RopeRep* __rest = _S_leaf_concat_char_iter(__leftright,
686 __leftleft->_M_ref_nonnil();
688 {
return(_S_tree_concat(__leftleft, __rest)); }
691 _S_unref(__leftleft);
693 __throw_exception_again;
698 __left->_M_ref_nonnil();
699 __right->_M_ref_nonnil();
701 {
return(_S_tree_concat(__left, __right)); }
706 __throw_exception_again;
710 template <
class _CharT,
class _Alloc>
711 typename rope<_CharT, _Alloc>::_RopeRep*
712 rope<_CharT, _Alloc>::
713 _S_substring(_RopeRep*
__base,
size_t __start,
size_t __endp1)
717 size_t __len = __base->_M_size;
719 const size_t __lazy_threshold = 128;
721 if (__endp1 >= __len)
725 __base->_M_ref_nonnil();
733 __adj_endp1 = __endp1;
735 switch(__base->_M_tag)
737 case __detail::_S_concat:
739 _RopeConcatenation* __c = (_RopeConcatenation*)__base;
740 _RopeRep* __left = __c->_M_left;
741 _RopeRep* __right = __c->_M_right;
742 size_t __left_len = __left->_M_size;
745 if (__adj_endp1 <= __left_len)
746 return _S_substring(__left, __start, __endp1);
747 else if (__start >= __left_len)
748 return _S_substring(__right, __start - __left_len,
749 __adj_endp1 - __left_len);
750 _Self_destruct_ptr __left_result(_S_substring(__left,
753 _Self_destruct_ptr __right_result(_S_substring(__right, 0,
756 __result = _S_concat(__left_result, __right_result);
759 case __detail::_S_leaf:
761 _RopeLeaf* __l = (_RopeLeaf*)__base;
764 if (__start >= __adj_endp1)
766 __result_len = __adj_endp1 - __start;
767 if (__result_len > __lazy_threshold)
770 const _CharT* __section = __l->_M_data + __start;
771 __result = _S_new_RopeLeaf(__section, __result_len,
772 __base->_M_get_allocator());
773 __result->_M_c_string = 0;
776 __result = __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__l->_M_data + __start,
783 case __detail::_S_substringfn:
786 _RopeSubstring* __old = (_RopeSubstring*)__base;
788 if (__start >= __adj_endp1)
790 __result_len = __adj_endp1 - __start;
791 if (__result_len > __lazy_threshold)
793 _RopeSubstring* __result =
794 _S_new_RopeSubstring(__old->_M_base,
795 __start + __old->_M_start,
796 __adj_endp1 - __start,
797 __base->_M_get_allocator());
802 case __detail::_S_function:
804 _RopeFunction* __f = (_RopeFunction*)__base;
807 if (__start >= __adj_endp1)
809 __result_len = __adj_endp1 - __start;
811 if (__result_len > __lazy_threshold)
813 __section = (_CharT*)
814 rope::_Data_allocate(_S_rounded_up_size(__result_len));
816 { (*(__f->_M_fn))(__start, __result_len, __section); }
819 _RopeRep::__STL_FREE_STRING(__section, __result_len,
820 __base->_M_get_allocator());
821 __throw_exception_again;
823 _S_cond_store_eos(__section[__result_len]);
824 return _S_new_RopeLeaf(__section, __result_len,
825 __base->_M_get_allocator());
831 return _S_new_RopeSubstring(__base, __start, __adj_endp1 - __start,
832 __base->_M_get_allocator());
836 template<
class _CharT>
837 class _Rope_flatten_char_consumer
838 :
public _Rope_char_consumer<_CharT>
844 _Rope_flatten_char_consumer(_CharT* __buffer)
845 { _M_buf_ptr = __buffer; };
847 ~_Rope_flatten_char_consumer() {}
850 operator()(
const _CharT* __leaf,
size_t __n)
858 template<
class _CharT>
859 class _Rope_find_char_char_consumer
860 :
public _Rope_char_consumer<_CharT>
867 _Rope_find_char_char_consumer(_CharT __p)
868 : _M_pattern(__p), _M_count(0) {}
870 ~_Rope_find_char_char_consumer() {}
873 operator()(
const _CharT* __leaf,
size_t __n)
876 for (__i = 0; __i < __n; __i++)
878 if (__leaf[__i] == _M_pattern)
884 _M_count += __n;
return true;
888 template<
class _CharT,
class _Traits>
890 class _Rope_insert_char_consumer
891 :
public _Rope_char_consumer<_CharT>
894 typedef basic_ostream<_CharT,_Traits> _Insert_ostream;
895 _Insert_ostream& _M_o;
897 _Rope_insert_char_consumer(_Insert_ostream& __writer)
899 ~_Rope_insert_char_consumer() { };
901 bool operator() (
const _CharT* __leaf,
size_t __n);
905 template<
class _CharT,
class _Traits>
907 _Rope_insert_char_consumer<_CharT, _Traits>::
908 operator()(
const _CharT* __leaf,
size_t __n)
912 for (__i = 0; __i < __n; __i++)
913 _M_o.put(__leaf[__i]);
917 template <
class _CharT,
class _Alloc>
919 rope<_CharT, _Alloc>::
920 _S_apply_to_pieces(_Rope_char_consumer<_CharT>& __c,
921 const _RopeRep* __r,
size_t __begin,
size_t __end)
927 case __detail::_S_concat:
929 _RopeConcatenation* __conc = (_RopeConcatenation*)__r;
930 _RopeRep* __left = __conc->_M_left;
931 size_t __left_len = __left->_M_size;
932 if (__begin < __left_len)
934 size_t __left_end =
std::min(__left_len, __end);
935 if (!_S_apply_to_pieces(__c, __left, __begin, __left_end))
938 if (__end > __left_len)
940 _RopeRep* __right = __conc->_M_right;
941 size_t __right_start =
std::max(__left_len, __begin);
942 if (!_S_apply_to_pieces(__c, __right,
943 __right_start - __left_len,
949 case __detail::_S_leaf:
951 _RopeLeaf* __l = (_RopeLeaf*)__r;
952 return __c(__l->_M_data + __begin, __end - __begin);
954 case __detail::_S_function:
955 case __detail::_S_substringfn:
957 _RopeFunction* __f = (_RopeFunction*)__r;
958 size_t __len = __end - __begin;
961 (_CharT*)_Alloc().allocate(__len *
sizeof(_CharT));
964 (*(__f->_M_fn))(__begin, __len, __buffer);
965 __result = __c(__buffer, __len);
966 _Alloc().deallocate(__buffer, __len *
sizeof(_CharT));
970 _Alloc().deallocate(__buffer, __len *
sizeof(_CharT));
971 __throw_exception_again;
980 template<
class _CharT,
class _Traits>
982 _Rope_fill(basic_ostream<_CharT, _Traits>& __o,
size_t __n)
984 char __f = __o.fill();
987 for (__i = 0; __i < __n; __i++)
992 template <
class _CharT>
994 _Rope_is_simple(_CharT*)
998 _Rope_is_simple(
char*)
1002 _Rope_is_simple(
wchar_t*)
1005 template<
class _CharT,
class _Traits,
class _Alloc>
1006 basic_ostream<_CharT, _Traits>&
1007 operator<<(basic_ostream<_CharT, _Traits>& __o,
1008 const rope<_CharT, _Alloc>& __r)
1010 size_t __w = __o.width();
1013 size_t __rope_len = __r.size();
1014 _Rope_insert_char_consumer<_CharT, _Traits> __c(__o);
1015 bool __is_simple = _Rope_is_simple((_CharT*)0);
1017 if (__rope_len < __w)
1018 __pad_len = __w - __rope_len;
1023 __o.width(__w / __rope_len);
1026 if (__is_simple && !__left && __pad_len > 0)
1027 _Rope_fill(__o, __pad_len);
1028 __r.apply_to_pieces(0, __r.size(), __c);
1029 if (__is_simple && __left && __pad_len > 0)
1030 _Rope_fill(__o, __pad_len);
1038 __throw_exception_again;
1043 template <
class _CharT,
class _Alloc>
1045 rope<_CharT, _Alloc>::
1046 _S_flatten(_RopeRep* __r,
size_t __start,
size_t __len,
1049 _Rope_flatten_char_consumer<_CharT> __c(__buffer);
1050 _S_apply_to_pieces(__c, __r, __start, __start + __len);
1051 return(__buffer + __len);
1054 template <
class _CharT,
class _Alloc>
1056 rope<_CharT, _Alloc>::
1057 find(_CharT __pattern,
size_t __start)
const
1059 _Rope_find_char_char_consumer<_CharT> __c(__pattern);
1060 _S_apply_to_pieces(__c, this->_M_tree_ptr, __start, size());
1061 size_type __result_pos = __start + __c._M_count;
1062 #ifndef __STL_OLD_ROPE_SEMANTICS
1063 if (__result_pos == size())
1064 __result_pos = npos;
1066 return __result_pos;
1069 template <
class _CharT,
class _Alloc>
1071 rope<_CharT, _Alloc>::
1072 _S_flatten(_RopeRep* __r, _CharT* __buffer)
1078 case __detail::_S_concat:
1080 _RopeConcatenation* __c = (_RopeConcatenation*)__r;
1081 _RopeRep* __left = __c->_M_left;
1082 _RopeRep* __right = __c->_M_right;
1083 _CharT* __rest = _S_flatten(__left, __buffer);
1084 return _S_flatten(__right, __rest);
1086 case __detail::_S_leaf:
1088 _RopeLeaf* __l = (_RopeLeaf*)__r;
1089 return copy_n(__l->_M_data, __l->_M_size, __buffer).second;
1091 case __detail::_S_function:
1092 case __detail::_S_substringfn:
1096 _RopeFunction* __f = (_RopeFunction*)__r;
1097 (*(__f->_M_fn))(0, __f->_M_size, __buffer);
1098 return __buffer + __f->_M_size;
1106 template <
class _CharT,
class _Alloc>
1108 rope<_CharT, _Alloc>::
1109 _S_dump(_RopeRep* __r,
int __indent)
1111 for (
int __i = 0; __i < __indent; __i++)
1118 if (_S_concat == __r->_M_tag)
1120 _RopeConcatenation* __c = (_RopeConcatenation*)__r;
1121 _RopeRep* __left = __c->_M_left;
1122 _RopeRep* __right = __c->_M_right;
1125 printf(
"Concatenation %p (depth = %d, len = %ld, %s balanced)\n",
1126 __r, __r->_M_depth, __r->_M_size,
1127 __r->_M_is_balanced?
"" :
"not");
1129 printf(
"Concatenation %p (rc = %ld, depth = %d, "
1130 "len = %ld, %s balanced)\n",
1131 __r, __r->_M_ref_count, __r->_M_depth, __r->_M_size,
1132 __r->_M_is_balanced?
"" :
"not");
1134 _S_dump(__left, __indent + 2);
1135 _S_dump(__right, __indent + 2);
1142 switch (__r->_M_tag)
1144 case __detail::_S_leaf:
1147 case __detail::_S_function:
1148 __kind =
"Function";
1150 case __detail::_S_substringfn:
1151 __kind =
"Function representing substring";
1154 __kind =
"(corrupted kind field!)";
1157 printf(
"%s %p (depth = %d, len = %ld) ",
1158 __kind, __r, __r->_M_depth, __r->_M_size);
1160 printf(
"%s %p (rc = %ld, depth = %d, len = %ld) ",
1161 __kind, __r, __r->_M_ref_count, __r->_M_depth, __r->_M_size);
1163 if (_S_is_one_byte_char_type((_CharT*)0))
1165 const int __max_len = 40;
1166 _Self_destruct_ptr __prefix(_S_substring(__r, 0, __max_len));
1167 _CharT __buffer[__max_len + 1];
1168 bool __too_big = __r->_M_size > __prefix->_M_size;
1170 _S_flatten(__prefix, __buffer);
1171 __buffer[__prefix->_M_size] = _S_eos((_CharT*)0);
1172 printf(
"%s%s\n", (
char*)__buffer,
1173 __too_big?
"...\n" :
"\n");
1180 template <
class _CharT,
class _Alloc>
1182 rope<_CharT, _Alloc>::
1183 _S_min_len[int(__detail::_S_max_rope_depth) + 1] = {
1184 1, 2, 3, 5, 8, 13, 21,
1185 34, 55, 89, 144, 233, 377,
1186 610, 987, 1597, 2584, 4181,
1187 6765, 10946, 17711, 28657, 46368,
1188 75025, 121393, 196418, 317811,
1189 514229, 832040, 1346269, 2178309,
1190 3524578, 5702887, 9227465, 14930352,
1191 24157817, 39088169, 63245986, 102334155,
1192 165580141, 267914296, 433494437,
1193 701408733, 1134903170, 1836311903,
1197 template <
class _CharT,
class _Alloc>
1198 typename rope<_CharT, _Alloc>::_RopeRep*
1199 rope<_CharT, _Alloc>::
1200 _S_balance(_RopeRep* __r)
1202 _RopeRep* __forest[int(__detail::_S_max_rope_depth) + 1];
1203 _RopeRep* __result = 0;
1211 for (__i = 0; __i <= int(__detail::_S_max_rope_depth); ++__i)
1215 _S_add_to_forest(__r, __forest);
1216 for (__i = 0; __i <= int(__detail::_S_max_rope_depth); ++__i)
1217 if (0 != __forest[__i])
1220 _Self_destruct_ptr __old(__result);
1222 __result = _S_concat(__forest[__i], __result);
1223 __forest[__i]->_M_unref_nonnil();
1224 #if !defined(__GC) && defined(__EXCEPTIONS)
1231 for(__i = 0; __i <= int(__detail::_S_max_rope_depth); __i++)
1232 _S_unref(__forest[__i]);
1233 __throw_exception_again;
1236 if (__result->_M_depth >
int(__detail::_S_max_rope_depth))
1237 __throw_length_error(__N(
"rope::_S_balance"));
1241 template <
class _CharT,
class _Alloc>
1243 rope<_CharT, _Alloc>::
1244 _S_add_to_forest(_RopeRep* __r, _RopeRep** __forest)
1246 if (__r->_M_is_balanced)
1248 _S_add_leaf_to_forest(__r, __forest);
1253 _RopeConcatenation* __c = (_RopeConcatenation*)__r;
1255 _S_add_to_forest(__c->_M_left, __forest);
1256 _S_add_to_forest(__c->_M_right, __forest);
1261 template <
class _CharT,
class _Alloc>
1263 rope<_CharT, _Alloc>::
1264 _S_add_leaf_to_forest(_RopeRep* __r, _RopeRep** __forest)
1266 _RopeRep* __insertee;
1267 _RopeRep* __too_tiny = 0;
1269 size_t __s = __r->_M_size;
1271 for (__i = 0; __s >= _S_min_len[__i+1]; ++__i)
1273 if (0 != __forest[__i])
1276 _Self_destruct_ptr __old(__too_tiny);
1278 __too_tiny = _S_concat_and_set_balanced(__forest[__i],
1280 __forest[__i]->_M_unref_nonnil();
1286 _Self_destruct_ptr __old(__too_tiny);
1288 __insertee = _S_concat_and_set_balanced(__too_tiny, __r);
1294 if (0 != __forest[__i])
1297 _Self_destruct_ptr __old(__insertee);
1299 __insertee = _S_concat_and_set_balanced(__forest[__i],
1301 __forest[__i]->_M_unref_nonnil();
1304 if (__i ==
int(__detail::_S_max_rope_depth)
1305 || __insertee->_M_size < _S_min_len[__i+1])
1307 __forest[__i] = __insertee;
1314 template <
class _CharT,
class _Alloc>
1316 rope<_CharT, _Alloc>::
1317 _S_fetch(_RopeRep* __r, size_type __i)
1319 __GC_CONST _CharT* __cstr = __r->_M_c_string;
1327 case __detail::_S_concat:
1329 _RopeConcatenation* __c = (_RopeConcatenation*)__r;
1330 _RopeRep* __left = __c->_M_left;
1331 size_t __left_len = __left->_M_size;
1333 if (__i >= __left_len)
1336 __r = __c->_M_right;
1342 case __detail::_S_leaf:
1344 _RopeLeaf* __l = (_RopeLeaf*)__r;
1345 return __l->_M_data[__i];
1347 case __detail::_S_function:
1348 case __detail::_S_substringfn:
1350 _RopeFunction* __f = (_RopeFunction*)__r;
1353 (*(__f->_M_fn))(__i, 1, &__result);
1363 template <
class _CharT,
class _Alloc>
1365 rope<_CharT, _Alloc>::
1366 _S_fetch_ptr(_RopeRep* __r, size_type __i)
1368 _RopeRep* __clrstack[__detail::_S_max_rope_depth];
1373 if (__r->_M_ref_count > 1)
1377 case __detail::_S_concat:
1379 _RopeConcatenation* __c = (_RopeConcatenation*)__r;
1380 _RopeRep* __left = __c->_M_left;
1381 size_t __left_len = __left->_M_size;
1383 if (__c->_M_c_string != 0)
1384 __clrstack[__csptr++] = __c;
1385 if (__i >= __left_len)
1388 __r = __c->_M_right;
1394 case __detail::_S_leaf:
1396 _RopeLeaf* __l = (_RopeLeaf*)__r;
1397 if (__l->_M_c_string != __l->_M_data && __l->_M_c_string != 0)
1398 __clrstack[__csptr++] = __l;
1402 _RopeRep* __d = __clrstack[__csptr];
1403 __d->_M_free_c_string();
1404 __d->_M_c_string = 0;
1406 return __l->_M_data + __i;
1408 case __detail::_S_function:
1409 case __detail::_S_substringfn:
1420 template <
class _CharT,
class _Alloc>
1422 rope<_CharT, _Alloc>::
1423 _S_compare (
const _RopeRep* __left,
const _RopeRep* __right)
1432 __left_len = __left->_M_size;
1433 __right_len = __right->_M_size;
1434 if (__detail::_S_leaf == __left->_M_tag)
1436 _RopeLeaf* __l = (_RopeLeaf*) __left;
1437 if (__detail::_S_leaf == __right->_M_tag)
1439 _RopeLeaf* __r = (_RopeLeaf*) __right;
1440 return lexicographical_compare_3way(__l->_M_data,
1441 __l->_M_data + __left_len,
1442 __r->_M_data, __r->_M_data
1447 const_iterator __rstart(__right, 0);
1448 const_iterator __rend(__right, __right_len);
1449 return lexicographical_compare_3way(__l->_M_data, __l->_M_data
1456 const_iterator __lstart(__left, 0);
1457 const_iterator __lend(__left, __left_len);
1458 if (__detail::_S_leaf == __right->_M_tag)
1460 _RopeLeaf* __r = (_RopeLeaf*) __right;
1461 return lexicographical_compare_3way(__lstart, __lend,
1462 __r->_M_data, __r->_M_data
1467 const_iterator __rstart(__right, 0);
1468 const_iterator __rend(__right, __right_len);
1469 return lexicographical_compare_3way(__lstart, __lend,
1476 template <
class _CharT,
class _Alloc>
1477 _Rope_char_ref_proxy<_CharT, _Alloc>&
1478 _Rope_char_ref_proxy<_CharT, _Alloc>::
1479 operator=(_CharT __c)
1481 _RopeRep* __old = _M_root->_M_tree_ptr;
1485 _CharT* __ptr = _My_rope::_S_fetch_ptr(__old, _M_pos);
1492 _Self_destruct_ptr __left(_My_rope::_S_substring(__old, 0, _M_pos));
1493 _Self_destruct_ptr __right(_My_rope::_S_substring(__old, _M_pos + 1,
1495 _Self_destruct_ptr __result_left(_My_rope::
1496 _S_destr_concat_char_iter(__left,
1499 _RopeRep* __result = _My_rope::_S_concat(__result_left, __right);
1501 _RopeRep::_S_unref(__old);
1503 _M_root->_M_tree_ptr = __result;
1507 template <
class _CharT,
class _Alloc>
1508 inline _Rope_char_ref_proxy<_CharT, _Alloc>::
1509 operator _CharT()
const
1511 if (_M_current_valid)
1514 return _My_rope::_S_fetch(_M_root->_M_tree_ptr, _M_pos);
1517 template <
class _CharT,
class _Alloc>
1518 _Rope_char_ptr_proxy<_CharT, _Alloc>
1519 _Rope_char_ref_proxy<_CharT, _Alloc>::
1521 {
return _Rope_char_ptr_proxy<_CharT, _Alloc>(*this); }
1523 template <
class _CharT,
class _Alloc>
1524 rope<_CharT, _Alloc>::
1525 rope(
size_t __n, _CharT __c,
const allocator_type& __a)
1528 rope<_CharT,_Alloc> __result;
1529 const size_t __exponentiate_threshold = 32;
1532 _CharT* __rest_buffer;
1533 _RopeRep* __remainder;
1534 rope<_CharT, _Alloc> __remainder_rope;
1539 __exponent = __n / __exponentiate_threshold;
1540 __rest = __n % __exponentiate_threshold;
1545 __rest_buffer = this->_Data_allocate(_S_rounded_up_size(__rest));
1546 __uninitialized_fill_n_a(__rest_buffer, __rest, __c,
1547 _M_get_allocator());
1548 _S_cond_store_eos(__rest_buffer[__rest]);
1550 { __remainder = _S_new_RopeLeaf(__rest_buffer, __rest,
1551 _M_get_allocator()); }
1554 _RopeRep::__STL_FREE_STRING(__rest_buffer, __rest,
1555 _M_get_allocator());
1556 __throw_exception_again;
1559 __remainder_rope._M_tree_ptr = __remainder;
1560 if (__exponent != 0)
1562 _CharT* __base_buffer =
1563 this->_Data_allocate(_S_rounded_up_size(__exponentiate_threshold));
1564 _RopeLeaf* __base_leaf;
1566 __uninitialized_fill_n_a(__base_buffer, __exponentiate_threshold, __c,
1567 _M_get_allocator());
1568 _S_cond_store_eos(__base_buffer[__exponentiate_threshold]);
1571 __base_leaf = _S_new_RopeLeaf(__base_buffer,
1572 __exponentiate_threshold,
1573 _M_get_allocator());
1577 _RopeRep::__STL_FREE_STRING(__base_buffer,
1578 __exponentiate_threshold,
1579 _M_get_allocator());
1580 __throw_exception_again;
1582 __base_rope._M_tree_ptr = __base_leaf;
1583 if (1 == __exponent)
1584 __result = __base_rope;
1586 __result = power(__base_rope, __exponent,
1587 _Rope_Concat_fn<_CharT, _Alloc>());
1589 if (0 != __remainder)
1590 __result += __remainder_rope;
1593 __result = __remainder_rope;
1595 this->_M_tree_ptr = __result._M_tree_ptr;
1596 this->_M_tree_ptr->_M_ref_nonnil();
1599 template<
class _CharT,
class _Alloc>
1601 rope<_CharT, _Alloc>::_S_empty_c_str[1];
1603 template<
class _CharT,
class _Alloc>
1605 rope<_CharT, _Alloc>::
1608 if (0 == this->_M_tree_ptr)
1610 _S_empty_c_str[0] = _S_eos((_CharT*)0);
1612 return _S_empty_c_str;
1614 __gthread_mutex_lock (&this->_M_tree_ptr->_M_c_string_lock);
1615 __GC_CONST _CharT* __result = this->_M_tree_ptr->_M_c_string;
1618 size_t __s = size();
1619 __result = this->_Data_allocate(__s + 1);
1620 _S_flatten(this->_M_tree_ptr, __result);
1621 __result[__s] = _S_eos((_CharT*)0);
1622 this->_M_tree_ptr->_M_c_string = __result;
1624 __gthread_mutex_unlock (&this->_M_tree_ptr->_M_c_string_lock);
1628 template<
class _CharT,
class _Alloc>
1629 const _CharT* rope<_CharT, _Alloc>::
1630 replace_with_c_str()
1632 if (0 == this->_M_tree_ptr)
1634 _S_empty_c_str[0] = _S_eos((_CharT*)0);
1635 return _S_empty_c_str;
1637 __GC_CONST _CharT* __old_c_string = this->_M_tree_ptr->_M_c_string;
1638 if (__detail::_S_leaf == this->_M_tree_ptr->_M_tag
1639 && 0 != __old_c_string)
1640 return(__old_c_string);
1641 size_t __s = size();
1642 _CharT* __result = this->_Data_allocate(_S_rounded_up_size(__s));
1643 _S_flatten(this->_M_tree_ptr, __result);
1644 __result[__s] = _S_eos((_CharT*)0);
1645 this->_M_tree_ptr->_M_unref_nonnil();
1646 this->_M_tree_ptr = _S_new_RopeLeaf(__result, __s,
1647 this->_M_get_allocator());
1653 template<
class _Rope_iterator>
1655 _Rope_rotate(_Rope_iterator __first,
1656 _Rope_iterator __middle,
1657 _Rope_iterator __last)
1659 typedef typename _Rope_iterator::value_type _CharT;
1660 typedef typename _Rope_iterator::_allocator_type _Alloc;
1662 rope<_CharT, _Alloc>& __r(__first.container());
1663 rope<_CharT, _Alloc> __prefix = __r.substr(0, __first.index());
1664 rope<_CharT, _Alloc> __suffix =
1665 __r.substr(__last.index(), __r.size() - __last.index());
1666 rope<_CharT, _Alloc> __part1 =
1667 __r.substr(__middle.index(), __last.index() - __middle.index());
1668 rope<_CharT, _Alloc> __part2 =
1669 __r.substr(__first.index(), __middle.index() - __first.index());
1676 #if !defined(__GNUC__)
1679 rotate(_Rope_iterator<
char, __STL_DEFAULT_ALLOCATOR(
char)> __first,
1680 _Rope_iterator<
char, __STL_DEFAULT_ALLOCATOR(
char)> __middle,
1681 _Rope_iterator<
char, __STL_DEFAULT_ALLOCATOR(
char)> __last)
1682 { _Rope_rotate(__first, __middle, __last); }
1694 rotate(_Rope_iterator<
wchar_t, __STL_DEFAULT_ALLOCATOR(
char)> __first,
1695 _Rope_iterator<
wchar_t, __STL_DEFAULT_ALLOCATOR(
char)> __middle,
1696 _Rope_iterator<
wchar_t, __STL_DEFAULT_ALLOCATOR(
char)> __last)
1697 { _Rope_rotate(__first, __middle, __last); }
1700 _GLIBCXX_END_NAMESPACE_VERSION
1702 GNU extensions for public use.
_ForwardIterator uninitialized_copy_n(_InputIterator __first, _Size __n, _ForwardIterator __result)
Copies the range [first,first+n) into result.
const _Tp & max(const _Tp &, const _Tp &)
This does what you think it does.
_Siter_base< _Iterator >::iterator_type __base(_Iterator __it)
void _Destroy(_Tp *__pointer)
const _Tp & min(const _Tp &, const _Tp &)
This does what you think it does.
ios_base & left(ios_base &__base)
Calls base.setf(ios_base::left, ios_base::adjustfield).