_rope.c

来自「stl的源码」· C语言 代码 · 共 1,408 行 · 第 1/4 页

C
1,408
字号
    }  }}# if defined ( _STLP_NESTED_TYPE_PARAM_BUG )#   define __RopeLeaf__ _Rope_RopeLeaf<_CharT,_Alloc>#   define __RopeRep__ _Rope_RopeRep<_CharT,_Alloc>#   define _RopeLeaf _Rope_RopeLeaf<_CharT,_Alloc>#   define _RopeRep _Rope_RopeRep<_CharT,_Alloc>#   define size_type size_t# else#   define __RopeLeaf__ _STLP_TYPENAME_ON_RETURN_TYPE rope<_CharT,_Alloc>::_RopeLeaf#   define __RopeRep__ _STLP_TYPENAME_ON_RETURN_TYPE rope<_CharT,_Alloc>::_RopeRep# endiftemplate <class _CharT, class _Alloc>void rope<_CharT, _Alloc>::_M_throw_out_of_range() const {  __stl_throw_out_of_range("rope");}// Concatenate a C string onto a leaf rope by copying the rope data.// Used for short ropes.template <class _CharT, class _Alloc>__RopeLeaf__*rope<_CharT,_Alloc>::_S_leaf_concat_char_iter (  _RopeLeaf* __r, const _CharT* __iter, size_t __len) {  size_t __old_len = __r->_M_size._M_data;  _CharT* __new_data = __r->_M_size.allocate(_S_rounded_up_size(__old_len + __len));  _RopeLeaf* __result;  _STLP_PRIV __ucopy_n(__r->_M_data, __old_len, __new_data);  _STLP_PRIV __ucopy_n(__iter, __len, __new_data + __old_len);  _S_construct_null(__new_data + __old_len + __len);  _STLP_TRY {    __result = _S_new_RopeLeaf(__new_data, __old_len + __len, __r->get_allocator());  }  _STLP_UNWIND(_RopeRep::_S_free_string(__new_data, __old_len + __len,                                        __r->get_allocator()))  return __result;}template <class _CharT, class _Alloc>void _Terminate_RopeLeaf(_Rope_RopeLeaf<_CharT,_Alloc> *__r,                         size_t __size, const __true_type& /*basic char type*/) {  _S_construct_null(__r->_M_data + __size);  _STLP_ASSERT(__r->_M_c_string == __r->_M_data)}template <class _CharT, class _Alloc>void _Terminate_RopeLeaf(_Rope_RopeLeaf<_CharT,_Alloc> *__r,                         size_t, const __false_type& /*basic char type*/) {  if (__r->_M_c_string != __r->_M_data && 0 != __r->_M_c_string) {    __r->_M_free_c_string();    __r->_M_c_string = 0;  }}// As above, but it's OK to clobber original if refcount is 1template <class _CharT, class _Alloc>__RopeLeaf__*rope<_CharT,_Alloc>::_S_destr_leaf_concat_char_iter (_RopeLeaf* __r, const _CharT* __iter, size_t __len) {  //_STLP_ASSERT(__r->_M_ref_count >= 1)  if ( /* __r->_M_ref_count > 1 */  __r->_M_incr() > 2 ) { // - ptr    __r->_M_decr(); // - ptr    return _S_leaf_concat_char_iter(__r, __iter, __len);  }  __r->_M_decr(); // - ptr, __r->_M_ref_count == 1 or 0  size_t __old_len = __r->_M_size._M_data;  if (_S_rounded_up_size(__old_len) == _S_rounded_up_size(__old_len + __len)) {    // The space has been partially initialized for the standard    // character types.  But that doesn't matter for those types.    _STLP_PRIV __ucopy_n(__iter, __len, __r->_M_data + __old_len);    _Terminate_RopeLeaf(__r, __old_len + __len, _IsBasicCharType());    __r->_M_size._M_data = __old_len + __len;    // _STLP_ASSERT(__r->_M_ref_count == 1)    // __r->_M_ref_count = 2;    __r->_M_incr(); // i.e.  __r->_M_ref_count = 2    return __r;  } else {    _RopeLeaf* __result = _S_leaf_concat_char_iter(__r, __iter, __len);    //_STLP_ASSERT(__result->_M_ref_count == 1)    return __result;  }}// Assumes left and right are not 0.// Does not increment (nor decrement on exception) child reference counts.// Result has ref count 1.template <class _CharT, class _Alloc>__RopeRep__*rope<_CharT,_Alloc>::_S_tree_concat (_RopeRep* __left, _RopeRep* __right) {  _RopeConcatenation* __result =    _S_new_RopeConcatenation(__left, __right, __left->get_allocator());  size_t __depth = __result->_M_depth;  _STLP_ASSERT(__left->get_allocator() == __right->get_allocator())  if (__depth > 20 && (__result->_M_size._M_data < 1000 ||      __depth > _RopeRep::_S_max_rope_depth)) {    _RopeRep* __balanced;    _STLP_TRY {      __balanced = _S_balance(__result);     // _STLP_ASSERT(__result == __balanced ||     //              1 == __result->_M_ref_count &&     //              1 == __balanced->_M_ref_count)      __result->_M_unref_nonnil();    }    _STLP_UNWIND((_STLP_CREATE_ALLOCATOR(allocator_type,(allocator_type&)__left->_M_size,                                         _RopeConcatenation).deallocate(__result,1)))    // In case of exception, we need to deallocate    // otherwise dangling result node.  But caller    // still owns its children.  Thus unref is    // inappropriate.    return __balanced;  } else {    return __result;  }}template <class _CharT, class _Alloc>__RopeRep__*rope<_CharT,_Alloc>::_S_concat_char_iter (_RopeRep* __r,                                          const _CharT*__s, size_t __slen) {  _RopeRep* __result;  if (0 == __slen) {    _S_ref(__r);    return __r;  }  if (0 == __r)    return _S_RopeLeaf_from_unowned_char_ptr(__s, __slen, __r->get_allocator());  if (_RopeRep::_S_leaf == __r->_M_tag &&      __r->_M_size._M_data + __slen <= _S_copy_max) {    __result = _S_leaf_concat_char_iter((_RopeLeaf*)__r, __s, __slen);    // _STLP_ASSERT(1 == __result->_M_ref_count)    return __result;  }  if (_RopeRep::_S_concat == __r->_M_tag &&      _RopeRep::_S_leaf == ((_RopeConcatenation*)__r)->_M_right->_M_tag) {    _RopeLeaf* __right = (_RopeLeaf* )(((_RopeConcatenation* )__r)->_M_right);    if (__right->_M_size._M_data + __slen <= _S_copy_max) {      _RopeRep* __left = ((_RopeConcatenation*)__r)->_M_left;      _RopeRep* __nright = _S_leaf_concat_char_iter((_RopeLeaf*)__right, __s, __slen);      __left->_M_ref_nonnil();      _STLP_TRY {        __result = _S_tree_concat(__left, __nright);      }      _STLP_UNWIND(_S_unref(__left); _S_unref(__nright))      // _STLP_ASSERT(1 == __result->_M_ref_count)      return __result;    }  }  _RopeRep* __nright =    _S_RopeLeaf_from_unowned_char_ptr(__s, __slen, __r->get_allocator());  _STLP_TRY {    __r->_M_ref_nonnil();    __result = _S_tree_concat(__r, __nright);  }  _STLP_UNWIND(_S_unref(__r); _S_unref(__nright))  // _STLP_ASSERT(1 == __result->_M_ref_count)  return __result;}template <class _CharT, class _Alloc>__RopeRep__*rope<_CharT,_Alloc>::_S_destr_concat_char_iter(  _RopeRep* __r, const _CharT* __s, size_t __slen) {  _RopeRep* __result;  if (0 == __r)    return _S_RopeLeaf_from_unowned_char_ptr(__s, __slen,                                             __r->get_allocator());  // size_t __count = __r->_M_ref_count;  size_t __orig_size = __r->_M_size._M_data;  // _STLP_ASSERT(__count >= 1)  if ( /* __count > 1 */ __r->_M_incr() > 2 ) {    __r->_M_decr();    return _S_concat_char_iter(__r, __s, __slen);  }  if (0 == __slen) {    return __r;  }  __r->_M_decr();  if (__orig_size + __slen <= _S_copy_max && _RopeRep::_S_leaf == __r->_M_tag) {    return _S_destr_leaf_concat_char_iter((_RopeLeaf*)__r, __s, __slen);  }  if (_RopeRep::_S_concat == __r->_M_tag) {    _RopeLeaf* __right = __STATIC_CAST(_RopeLeaf*, __STATIC_CAST(_RopeConcatenation*, __r)->_M_right);    if (_RopeRep::_S_leaf == __right->_M_tag &&        __right->_M_size._M_data + __slen <= _S_copy_max) {      _RopeRep* __new_right = _S_destr_leaf_concat_char_iter(__right, __s, __slen);      if (__right == __new_right) {        // _STLP_ASSERT(__new_right->_M_ref_count == 2)        // __new_right->_M_ref_count = 1;        __new_right->_M_decr();      } else {        // _STLP_ASSERT(__new_right->_M_ref_count >= 1)        __right->_M_unref_nonnil();      }      // _STLP_ASSERT(__r->_M_ref_count == 1)      // __r->_M_ref_count = 2;    // One more than before.      __r->_M_incr();      __STATIC_CAST(_RopeConcatenation*, __r)->_M_right = __new_right;      // E.Musser : moved below      //    __r->_M_size._M_data = __orig_size + __slen;      if (0 != __r->_M_c_string) {        __r->_M_free_c_string();        __r->_M_c_string = 0;      }      __r->_M_size._M_data = __orig_size + __slen;      return __r;    }  }  _RopeRep* __right =    _S_RopeLeaf_from_unowned_char_ptr(__s, __slen, __r->get_allocator());  __r->_M_ref_nonnil();  _STLP_TRY {    __result = _S_tree_concat(__r, __right);  }  _STLP_UNWIND(_S_unref(__r); _S_unref(__right))    // _STLP_ASSERT(1 == __result->_M_ref_count)  return __result;}template <class _CharT, class _Alloc>__RopeRep__*rope<_CharT,_Alloc>::_S_concat_rep(_RopeRep* __left, _RopeRep* __right) {  if (0 == __left) {    _S_ref(__right);    return __right;  }  if (0 == __right) {    __left->_M_ref_nonnil();    return __left;  }  if (_RopeRep::_S_leaf == __right->_M_tag) {    if (_RopeRep::_S_leaf == __left->_M_tag) {      if (__right->_M_size._M_data + __left->_M_size._M_data <= _S_copy_max) {        return _S_leaf_concat_char_iter(__STATIC_CAST(_RopeLeaf*, __left),                                        __STATIC_CAST(_RopeLeaf*, __right)->_M_data,                                        __right->_M_size._M_data);      }    } else if (_RopeRep::_S_concat == __left->_M_tag &&               _RopeRep::_S_leaf == __STATIC_CAST(_RopeConcatenation*, __left)->_M_right->_M_tag) {      _RopeLeaf* __leftright =        __STATIC_CAST(_RopeLeaf*, __STATIC_CAST(_RopeConcatenation*, __left)->_M_right);      if (__leftright->_M_size._M_data + __right->_M_size._M_data <= _S_copy_max) {        _RopeRep* __leftleft = __STATIC_CAST(_RopeConcatenation*, __left)->_M_left;        _RopeRep* __rest = _S_leaf_concat_char_iter(__leftright,                                                    __STATIC_CAST(_RopeLeaf*, __right)->_M_data,                                                    __right->_M_size._M_data);        __leftleft->_M_ref_nonnil();        _STLP_TRY {          return _S_tree_concat(__leftleft, __rest);        }        _STLP_UNWIND(_S_unref(__leftleft); _S_unref(__rest))      }    }  }  __left->_M_ref_nonnil();  __right->_M_ref_nonnil();  _STLP_TRY {    return _S_tree_concat(__left, __right);  }  _STLP_UNWIND(_S_unref(__left); _S_unref(__right))  _STLP_RET_AFTER_THROW(0)}template <class _CharT, class _Alloc>__RopeRep__*rope<_CharT,_Alloc>::_S_substring(_RopeRep* __base,                                  size_t __start, size_t __endp1) {  if (0 == __base) return 0;  size_t __len = __base->_M_size._M_data;  size_t __adj_endp1;  const size_t __lazy_threshold = 128;  if (__endp1 >= __len) {    if (0 == __start) {      __base->_M_ref_nonnil();      return __base;    } else {      __adj_endp1 = __len;    }  } else {    __adj_endp1 = __endp1;  }  switch(__base->_M_tag) {  case _RopeRep::_S_concat:  {    _RopeConcatenation* __c = __STATIC_CAST(_RopeConcatenation*, __base);    _RopeRep* __left = __c->_M_left;    _RopeRep* __right = __c->_M_right;    size_t __left_len = __left->_M_size._M_data;    _RopeRep* __result;    if (__adj_endp1 <= __left_len) {      return _S_substring(__left, __start, __endp1);    } else if (__start >= __left_len) {      return _S_substring(__right, __start - __left_len,                          __adj_endp1 - __left_len);    }    _Self_destruct_ptr __left_result(_S_substring(__left, __start, __left_len));    _Self_destruct_ptr __right_result(_S_substring(__right, 0, __endp1 - __left_len));    _STLP_MPWFIX_TRY    //*TY 06/01/2000 - mpw forgets to call dtor on __left_result and __right_result without this try block    __result = _S_concat_rep(__left_result, __right_result);    // _STLP_ASSERT(1 == __result->_M_ref_count)    return __result;    _STLP_MPWFIX_CATCH    //*TY 06/01/2000 -  }  case _RopeRep::_S_leaf:  {    _RopeLeaf* __l = __STATIC_CAST(_RopeLeaf*, __base);    _RopeLeaf* __result;    size_t __result_len;    if (__start >= __adj_endp1) return 0;    __result_len = __adj_endp1 - __start;    if (__result_len > __lazy_threshold) goto lazy;    const _CharT* __section = __l->_M_data + __start;    // We should sometimes create substring node instead.    __result = _S_RopeLeaf_from_unowned_char_ptr(__section, __result_len,                                                 __base->get_allocator());    return __result;  }  case _RopeRep::_S_substringfn:  // Avoid introducing multiple layers of substring nodes.  {    _RopeSubstring* __old = __STATIC_CAST(_RopeSubstring*, __base);    size_t __result_len;    if (__start >= __adj_endp1) return 0;    __result_len = __adj_endp1 - __start;    if (__result_len > __lazy_threshold) {      _RopeSubstring* __result = _S_new_RopeSubstring(__old->_M_base,                                                      __start + __old->_M_start,                                                      __adj_endp1 - __start,                                                      __base->get_allocator());      return __result;    } // *** else fall through: ***  }  case _RopeRep::_S_function:  {    _RopeFunction* __f = __STATIC_CAST(_RopeFunction*, __base);    if (__start >= __adj_endp1) return 0;    size_t __result_len = __adj_endp1 - __start;    if (__result_len > __lazy_threshold) goto lazy;    _CharT* __section = __base->_M_size.allocate(_S_rounded_up_size(__result_len));    _STLP_TRY {      (*(__f->_M_fn))(__start, __result_len, __section);    }    _STLP_UNWIND(_RopeRep::_S_free_string(__section,                                          __result_len, __base->get_allocator()))    _S_construct_null(__section + __result_len);    return _S_new_RopeLeaf(__section, __result_len,

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?