_rope.c

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

C
1,408
字号
template <class _CharT, class _Alloc>voidrope<_CharT,_Alloc>::_S_add_to_forest(_RopeRep* __r, _RopeRep** __forest){    if (__r -> _M_is_balanced) {      _S_add_leaf_to_forest(__r, __forest);      return;    }    _STLP_ASSERT(__r->_M_tag == _RopeRep::_S_concat)    {      _RopeConcatenation* __c = (_RopeConcatenation*)__r;      _S_add_to_forest(__c->_M_left, __forest);      _S_add_to_forest(__c->_M_right, __forest);    }}template <class _CharT, class _Alloc>voidrope<_CharT,_Alloc>::_S_add_leaf_to_forest(_RopeRep* __r, _RopeRep** __forest){    _RopeRep* __insertee;       // included in refcount    _RopeRep* __too_tiny = 0;      // included in refcount    int __i;          // forest[0..__i-1] is empty    size_t __s = __r->_M_size._M_data;    for (__i = 0; __s >= _S_min_len[__i+1]/* not this bucket */; ++__i) {  if (0 != __forest[__i]) {        _Self_destruct_ptr __old(__too_tiny);      __too_tiny = _S_concat_and_set_balanced(__forest[__i], __too_tiny);      __forest[__i]->_M_unref_nonnil();      __forest[__i] = 0;  }    }    {    _Self_destruct_ptr __old(__too_tiny);  __insertee = _S_concat_and_set_balanced(__too_tiny, __r);    }    // Too_tiny dead, and no longer included in refcount.    // Insertee is live and included.    _STLP_ASSERT(_S_is_almost_balanced(__insertee))    _STLP_ASSERT(__insertee->_M_depth <= __r->_M_depth + 1)    for (;; ++__i) {      if (0 != __forest[__i]) {        _Self_destruct_ptr __old(__insertee);      __insertee = _S_concat_and_set_balanced(__forest[__i], __insertee);      __forest[__i]->_M_unref_nonnil();      __forest[__i] = 0;      _STLP_ASSERT(_S_is_almost_balanced(__insertee))  }  _STLP_ASSERT(_S_min_len[__i] <= __insertee->_M_size._M_data)  _STLP_ASSERT(__forest[__i] == 0)  if (__i == _RopeRep::_S_max_rope_depth ||        __insertee->_M_size._M_data < _S_min_len[__i+1]) {      __forest[__i] = __insertee;      // refcount is OK since __insertee is now dead.      return;  }    }}template <class _CharT, class _Alloc>_CharTrope<_CharT,_Alloc>::_S_fetch(_RopeRep* __r, size_type __i){    _CharT* __cstr = __r->_M_c_string;    _STLP_ASSERT(__i < __r->_M_size._M_data)    if (0 != __cstr) return __cstr[__i];    for(;;) {      switch(__r->_M_tag) {  case _RopeRep::_S_concat:      {    _RopeConcatenation* __c = (_RopeConcatenation*)__r;    _RopeRep* __left = __c->_M_left;    size_t __left_len = __left->_M_size._M_data;    if (__i >= __left_len) {        __i -= __left_len;        __r = __c->_M_right;    } else {        __r = __left;    }      }      break;  case _RopeRep::_S_leaf:      {    _RopeLeaf* __l = (_RopeLeaf*)__r;    return __l->_M_data[__i];      }  case _RopeRep::_S_function:  case _RopeRep::_S_substringfn:      {    _RopeFunction* __f = (_RopeFunction*)__r;    _CharT __result;    (*(__f->_M_fn))(__i, 1, &__result);    return __result;      }      }    }#if defined(_STLP_NEED_UNREACHABLE_RETURN)    return 0;#endif}// Return a uniquely referenced character slot for the given// position, or 0 if that's not possible.template <class _CharT, class _Alloc>_CharT*rope<_CharT,_Alloc>::_S_fetch_ptr(_RopeRep* __r, size_type __i){    _RopeRep* __clrstack[_RopeRep::_S_max_rope_depth];    size_t __csptr = 0;    for(;;) {      // if (__r->_M_ref_count > 1) return 0;      if ( __r->_M_incr() > 2 ) {        __r->_M_decr();        return 0;      }      switch(__r->_M_tag) {  case _RopeRep::_S_concat:      {    _RopeConcatenation* __c = (_RopeConcatenation*)__r;    _RopeRep* __left = __c->_M_left;    size_t __left_len = __left->_M_size._M_data;    if (__c->_M_c_string != 0) __clrstack[__csptr++] = __c;    if (__i >= __left_len) {        __i -= __left_len;        __r = __c->_M_right;    } else {        __r = __left;    }      }      break;  case _RopeRep::_S_leaf:      {    _RopeLeaf* __l = (_RopeLeaf*)__r;    if (__l->_M_c_string != __l->_M_data && __l->_M_c_string != 0)        __clrstack[__csptr++] = __l;    while (__csptr > 0) {        -- __csptr;        _RopeRep* __d = __clrstack[__csptr];        __d->_M_free_c_string();        __d->_M_c_string = 0;    }    return __l->_M_data + __i;      }  case _RopeRep::_S_function:  case _RopeRep::_S_substringfn:      return 0;      }    }#if defined(_STLP_NEED_UNREACHABLE_RETURN)    return 0;#endif}// The following could be implemented trivially using// lexicographical_compare_3way.// We do a little more work to avoid dealing with rope iterators for// flat strings.template <class _CharT, class _Alloc>intrope<_CharT,_Alloc>::_S_compare (const _RopeRep* __left,                                 const _RopeRep* __right) {  size_t __left_len;  size_t __right_len;  if (0 == __right) return 0 != __left;  if (0 == __left) return -1;  __left_len = __left->_M_size._M_data;  __right_len = __right->_M_size._M_data;  if (_RopeRep::_S_leaf == __left->_M_tag) {    const _RopeLeaf* __l = __STATIC_CAST(const _RopeLeaf*, __left);    if (_RopeRep::_S_leaf == __right->_M_tag) {      const _RopeLeaf* __r = __STATIC_CAST(const _RopeLeaf*, __right);      return _STLP_PRIV __lexicographical_compare_3way(__l->_M_data, __l->_M_data + __left_len,                                                       __r->_M_data, __r->_M_data + __right_len);    }    else {      const_iterator __rstart(__right, 0);      const_iterator __rend(__right, __right_len);      return _STLP_PRIV __lexicographical_compare_3way(__l->_M_data, __l->_M_data + __left_len,                                                       __rstart, __rend);    }  }  else {    const_iterator __lstart(__left, 0);    const_iterator __lend(__left, __left_len);    if (_RopeRep::_S_leaf == __right->_M_tag) {      const _RopeLeaf* __r = __STATIC_CAST(const _RopeLeaf*, __right);      return _STLP_PRIV __lexicographical_compare_3way(__lstart, __lend,                                                       __r->_M_data, __r->_M_data + __right_len);    }    else {      const_iterator __rstart(__right, 0);      const_iterator __rend(__right, __right_len);      return _STLP_PRIV __lexicographical_compare_3way(__lstart, __lend, __rstart, __rend);    }  }}// Assignment to reference proxies.template <class _CharT, class _Alloc>_Rope_char_ref_proxy<_CharT, _Alloc>&_Rope_char_ref_proxy<_CharT, _Alloc>::operator= (_CharT __c) {    _RopeRep* __old = _M_root->_M_tree_ptr._M_data;  // First check for the case in which everything is uniquely  // referenced.  In that case we can do this destructively.  _CharT* __ptr = _My_rope::_S_fetch_ptr(__old, _M_pos);  if (0 != __ptr) {      *__ptr = __c;      return *this;  }    _Self_destruct_ptr __left(      _My_rope::_S_substring(__old, 0, _M_pos));    _Self_destruct_ptr __right(      _My_rope::_S_substring(__old, _M_pos+1, __old->_M_size._M_data));    _Self_destruct_ptr __result_left(      _My_rope::_S_destr_concat_char_iter(__left, &__c, 1));    // _STLP_ASSERT(__left == __result_left || 1 == __result_left->_M_ref_count)    _RopeRep* __result =      _My_rope::_S_concat_rep(__result_left, __right);    // _STLP_ASSERT(1 <= __result->_M_ref_count)    _RopeRep::_S_unref(__old);    _M_root->_M_tree_ptr._M_data = __result;    return *this;}template <class _CharT, class _Alloc>_Rope_char_ptr_proxy<_CharT, _Alloc>_Rope_char_ref_proxy<_CharT, _Alloc>::operator& () const {    return _Rope_char_ptr_proxy<_CharT, _Alloc>(*this);}template<class _CharT, class _Alloc>_CharT rope<_CharT,_Alloc>::_S_empty_c_str[1] = { _CharT() };// # endif#if !defined (_STLP_STATIC_CONST_INIT_BUG) && !defined (_STLP_NO_STATIC_CONST_DEFINITION)template <class _CharT, class _Alloc>const size_t rope<_CharT, _Alloc>::npos;#endiftemplate<class _CharT, class _Alloc>const _CharT* rope<_CharT,_Alloc>::c_str() const {  if (0 == _M_tree_ptr._M_data) {    // Possibly redundant, but probably fast.    _S_empty_c_str[0] = _STLP_DEFAULT_CONSTRUCTED(_CharT);    return _S_empty_c_str;  }  _CharT* __old_c_string = _M_tree_ptr._M_data->_M_c_string;  if (0 != __old_c_string) return __old_c_string;  size_t __s = size();  _CharT* __result = _STLP_CREATE_ALLOCATOR(allocator_type,(const allocator_type&)_M_tree_ptr, _CharT).allocate(__s + 1);  _S_flatten(_M_tree_ptr._M_data, __result);  _S_construct_null(__result + __s);  __old_c_string = __STATIC_CAST(_CharT*, _Atomic_swap_ptr(__REINTERPRET_CAST(void* _STLP_VOLATILE*, &(_M_tree_ptr._M_data->_M_c_string)),                                                           __result));  if (0 != __old_c_string) {    // It must have been added in the interim.  Hence it had to have been    // separately allocated.  Deallocate the old copy, since we just    // replaced it.    _STLP_STD::_Destroy_Range(__old_c_string, __old_c_string + __s + 1);    _STLP_CREATE_ALLOCATOR(allocator_type,(const allocator_type&)_M_tree_ptr, _CharT).deallocate(__old_c_string, __s + 1);  }  return __result;}template<class _CharT, class _Alloc>const _CharT* rope<_CharT,_Alloc>::replace_with_c_str() {  if (0 == _M_tree_ptr._M_data) {    _S_empty_c_str[0] = _STLP_DEFAULT_CONSTRUCTED(_CharT);    return _S_empty_c_str;  }  _CharT* __old_c_string = _M_tree_ptr._M_data->_M_c_string;  if (_RopeRep::_S_leaf == _M_tree_ptr._M_data->_M_tag && 0 != __old_c_string) {    return __old_c_string;  }  size_t __s = size();  _CharT* __result = _M_tree_ptr.allocate(_S_rounded_up_size(__s));  _S_flatten(_M_tree_ptr._M_data, __result);  _S_construct_null(__result + __s);  _M_tree_ptr._M_data->_M_unref_nonnil();  _M_tree_ptr._M_data = _S_new_RopeLeaf(__result, __s, _M_tree_ptr);  return __result;}// Algorithm specializations.  More should be added.#if (!defined (_STLP_MSVC) || (_STLP_MSVC >= 1310)) && !defined (__DMC__)// I couldn't get this to work with VC++template<class _CharT,class _Alloc>void _Rope_rotate(_Rope_iterator<_CharT,_Alloc> __first,                  _Rope_iterator<_CharT,_Alloc> __middle,                  _Rope_iterator<_CharT,_Alloc> __last) {  _STLP_ASSERT(__first.container() == __middle.container() &&               __middle.container() == __last.container())  rope<_CharT,_Alloc>& __r(__first.container());  rope<_CharT,_Alloc> __prefix = __r.substr(0, __first.index());  rope<_CharT,_Alloc> __suffix =    __r.substr(__last.index(), __r.size() - __last.index());  rope<_CharT,_Alloc> __part1 =    __r.substr(__middle.index(), __last.index() - __middle.index());  rope<_CharT,_Alloc> __part2 =    __r.substr(__first.index(), __middle.index() - __first.index());  __r = __prefix;  __r += __part1;  __r += __part2;  __r += __suffix;}# if 0// Probably not useful for several reasons:// - for SGIs 7.1 compiler and probably some others,//   this forces lots of rope<wchar_t, ...> instantiations, creating a//   code bloat and compile time problem.  (Fixed in 7.2.)// - wchar_t is 4 bytes wide on most UNIX platforms, making it unattractive//   for unicode strings.  Unsigned short may be a better character//   type.inline void rotate(    _Rope_iterator<wchar_t, allocator<char> > __first,                _Rope_iterator<wchar_t, allocator<char> > __middle,                _Rope_iterator<wchar_t, allocator<char> > __last) {    _Rope_rotate(__first, __middle, __last);}# endif#endif /* _STLP_MSVC */#   undef __RopeLeaf__#   undef __RopeRep__#   undef __RopeLeaf#   undef __RopeRep#   undef size_type_STLP_END_NAMESPACE# endif /* ROPEIMPL_H */// Local Variables:// mode:C++// End:

⌨️ 快捷键说明

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