_rope.h
来自「stl的源码」· C头文件 代码 · 共 1,929 行 · 第 1/5 页
H
1,929 行
// _Result is counted in refcount. static _RopeRep* _S_substring(_RopeRep* __base, size_t __start, size_t __endp1); static _RopeRep* _S_concat_char_iter(_RopeRep* __r, const _CharT* __iter, size_t __slen); // Concatenate rope and char ptr, copying __s. // Should really take an arbitrary iterator. // Result is counted in refcount. static _RopeRep* _S_destr_concat_char_iter(_RopeRep* __r, const _CharT* __iter, size_t __slen); // As above, but one reference to __r is about to be // destroyed. Thus the pieces may be recycled if all // relevent reference counts are 1. // General concatenation on _RopeRep. _Result // has refcount of 1. Adjusts argument refcounts. static _RopeRep* _S_concat_rep(_RopeRep* __left, _RopeRep* __right);public:#if defined (_STLP_MEMBER_TEMPLATES) template <class _CharConsumer>#else typedef _Rope_char_consumer<_CharT> _CharConsumer;#endif void apply_to_pieces(size_t __begin, size_t __end, _CharConsumer& __c) const { _S_apply_to_pieces(__c, _M_tree_ptr._M_data, __begin, __end); }protected: static size_t _S_rounded_up_size(size_t __n) { return _RopeRep::_S_rounded_up_size(__n); } // Allocate and construct a RopeLeaf using the supplied allocator // Takes ownership of s instead of copying. static _RopeLeaf* _S_new_RopeLeaf(_CharT *__s, size_t _p_size, allocator_type __a) { _RopeLeaf* __space = _STLP_CREATE_ALLOCATOR(allocator_type, __a, _RopeLeaf).allocate(1); _STLP_TRY { new(__space) _RopeLeaf(__s, _p_size, __a); } _STLP_UNWIND(_STLP_CREATE_ALLOCATOR(allocator_type,__a, _RopeLeaf).deallocate(__space, 1)) return __space; } static _RopeConcatenation* _S_new_RopeConcatenation(_RopeRep* __left, _RopeRep* __right, allocator_type __a) { _RopeConcatenation* __space = _STLP_CREATE_ALLOCATOR(allocator_type, __a, _RopeConcatenation).allocate(1); return new(__space) _RopeConcatenation(__left, __right, __a); } static _RopeFunction* _S_new_RopeFunction(char_producer<_CharT>* __f, size_t _p_size, bool __d, allocator_type __a) { _RopeFunction* __space = _STLP_CREATE_ALLOCATOR(allocator_type, __a, _RopeFunction).allocate(1); return new(__space) _RopeFunction(__f, _p_size, __d, __a); } static _RopeSubstring* _S_new_RopeSubstring(_Rope_RopeRep<_CharT,_Alloc>* __b, size_t __s, size_t __l, allocator_type __a) { _RopeSubstring* __space = _STLP_CREATE_ALLOCATOR(allocator_type, __a, _RopeSubstring).allocate(1); return new(__space) _RopeSubstring(__b, __s, __l, __a); } static _RopeLeaf* _S_RopeLeaf_from_unowned_char_ptr(const _CharT *__s, size_t _p_size, allocator_type __a) { if (0 == _p_size) return 0; _CharT* __buf = _STLP_CREATE_ALLOCATOR(allocator_type,__a, _CharT).allocate(_S_rounded_up_size(_p_size)); _STLP_PRIV __ucopy_n(__s, _p_size, __buf); _S_construct_null(__buf + _p_size); _STLP_TRY { return _S_new_RopeLeaf(__buf, _p_size, __a); } _STLP_UNWIND(_RopeRep::_S_free_string(__buf, _p_size, __a)) _STLP_RET_AFTER_THROW(0) } // Concatenation of nonempty strings. // Always builds a concatenation node. // Rebalances if the result is too deep. // Result has refcount 1. // Does not increment left and right ref counts even though // they are referenced. static _RopeRep* _S_tree_concat(_RopeRep* __left, _RopeRep* __right); // Concatenation helper functions static _RopeLeaf* _S_leaf_concat_char_iter(_RopeLeaf* __r, const _CharT* __iter, size_t __slen); // Concatenate by copying leaf. // should take an arbitrary iterator // result has refcount 1. static _RopeLeaf* _S_destr_leaf_concat_char_iter (_RopeLeaf* __r, const _CharT* __iter, size_t __slen); // A version that potentially clobbers __r if __r->_M_ref_count == 1. // A helper function for exponentiating strings. // This uses a nonstandard refcount convention. // The result has refcount 0. typedef _STLP_PRIV _Rope_Concat_fn<_CharT,_Alloc> _Concat_fn;#if !defined (__GNUC__) || (__GNUC__ < 3) friend _Concat_fn;#else friend struct _STLP_PRIV _Rope_Concat_fn<_CharT,_Alloc>;#endifpublic: static size_t _S_char_ptr_len(const _CharT* __s) { return char_traits<_CharT>::length(__s); }public: /* for operators */ rope(_RopeRep* __t, const allocator_type& __a = allocator_type()) : _M_tree_ptr(__a, __t) { }private: // Copy __r to the _CharT buffer. // Returns __buffer + __r->_M_size._M_data. // Assumes that buffer is uninitialized. static _CharT* _S_flatten(_RopeRep* __r, _CharT* __buffer); // Again, with explicit starting position and length. // Assumes that buffer is uninitialized. static _CharT* _S_flatten(_RopeRep* __r, size_t __start, size_t __len, _CharT* __buffer); // fbp : HP aCC prohibits access to protected min_len from within static methods ( ?? )public: static const unsigned long _S_min_len[__ROPE_DEPTH_SIZE];protected: static bool _S_is_balanced(_RopeRep* __r) { return (__r->_M_size._M_data >= _S_min_len[__r->_M_depth]); } static bool _S_is_almost_balanced(_RopeRep* __r) { return (__r->_M_depth == 0 || __r->_M_size._M_data >= _S_min_len[__r->_M_depth - 1]); } static bool _S_is_roughly_balanced(_RopeRep* __r) { return (__r->_M_depth <= 1 || __r->_M_size._M_data >= _S_min_len[__r->_M_depth - 2]); } // Assumes the result is not empty. static _RopeRep* _S_concat_and_set_balanced(_RopeRep* __left, _RopeRep* __right) { _RopeRep* __result = _S_concat_rep(__left, __right); if (_S_is_balanced(__result)) __result->_M_is_balanced = true; return __result; } // The basic rebalancing operation. Logically copies the // rope. The result has refcount of 1. The client will // usually decrement the reference count of __r. // The result is within height 2 of balanced by the above // definition. static _RopeRep* _S_balance(_RopeRep* __r); // Add all unbalanced subtrees to the forest of balanceed trees. // Used only by balance. static void _S_add_to_forest(_RopeRep*__r, _RopeRep** __forest); // Add __r to forest, assuming __r is already balanced. static void _S_add_leaf_to_forest(_RopeRep* __r, _RopeRep** __forest);#ifdef _STLP_DEBUG // Print to stdout, exposing structure static void _S_dump(_RopeRep* __r, int __indent = 0);#endif // Return -1, 0, or 1 if __x < __y, __x == __y, or __x > __y resp. static int _S_compare(const _RopeRep* __x, const _RopeRep* __y); void _STLP_FUNCTION_THROWS _M_throw_out_of_range() const; void _M_reset(_RopeRep* __r) { //if (__r != _M_tree_ptr._M_data) { _S_unref(_M_tree_ptr._M_data); _M_tree_ptr._M_data = __r; //} }public: bool empty() const { return 0 == _M_tree_ptr._M_data; } // Comparison member function. This is public only for those // clients that need a ternary comparison. Others // should use the comparison operators below. int compare(const _Self& __y) const { return _S_compare(_M_tree_ptr._M_data, __y._M_tree_ptr._M_data); } rope(const _CharT* __s, const allocator_type& __a = allocator_type()) : _M_tree_ptr(__a, _S_RopeLeaf_from_unowned_char_ptr(__s, _S_char_ptr_len(__s),__a)) {} rope(const _CharT* __s, size_t __len, const allocator_type& __a = allocator_type()) : _M_tree_ptr(__a, (_S_RopeLeaf_from_unowned_char_ptr(__s, __len, __a))) {} // Should perhaps be templatized with respect to the iterator type // and use Sequence_buffer. (It should perhaps use sequence_buffer // even now.) rope(const _CharT *__s, const _CharT *__e, const allocator_type& __a = allocator_type()) : _M_tree_ptr(__a, _S_RopeLeaf_from_unowned_char_ptr(__s, __e - __s, __a)) {} rope(const const_iterator& __s, const const_iterator& __e, const allocator_type& __a = allocator_type()) : _M_tree_ptr(__a, _S_substring(__s._M_root, __s._M_current_pos, __e._M_current_pos)) {} rope(const iterator& __s, const iterator& __e, const allocator_type& __a = allocator_type()) : _M_tree_ptr(__a, _S_substring(__s._M_root, __s._M_current_pos, __e._M_current_pos)) {} rope(_CharT __c, const allocator_type& __a = allocator_type()) : _M_tree_ptr(__a, (_RopeRep*)0) { _CharT* __buf = _M_tree_ptr.allocate(_S_rounded_up_size(1)); _Copy_Construct(__buf, __c); _S_construct_null(__buf + 1); _STLP_TRY { _M_tree_ptr._M_data = _S_new_RopeLeaf(__buf, 1, __a); } _STLP_UNWIND(_RopeRep::_S_free_string(__buf, 1, __a)) } rope(size_t __n, _CharT __c, const allocator_type& __a = allocator_type()): _M_tree_ptr(__a, (_RopeRep*)0) { if (0 == __n) return; rope<_CharT,_Alloc> __result;# define __exponentiate_threshold size_t(32) _RopeRep* __remainder; rope<_CharT,_Alloc> __remainder_rope; // gcc-2.7.2 bugs typedef _STLP_PRIV _Rope_Concat_fn<_CharT,_Alloc> _Concat_fn; size_t __exponent = __n / __exponentiate_threshold; size_t __rest = __n % __exponentiate_threshold; if (0 == __rest) { __remainder = 0; } else { _CharT* __rest_buffer = _M_tree_ptr.allocate(_S_rounded_up_size(__rest)); uninitialized_fill_n(__rest_buffer, __rest, __c); _S_construct_null(__rest_buffer + __rest); _STLP_TRY { __remainder = _S_new_RopeLeaf(__rest_buffer, __rest, __a); } _STLP_UNWIND(_RopeRep::_S_free_string(__rest_buffer, __rest, __a)) } __remainder_rope._M_tree_ptr._M_data = __remainder; if (__exponent != 0) { _CharT* __base_buffer = _M_tree_ptr.allocate(_S_rounded_up_size(__exponentiate_threshold)); _RopeLeaf* __base_leaf; rope<_CharT,_Alloc> __base_rope; uninitialized_fill_n(__base_buffer, __exponentiate_threshold, __c); _S_construct_null(__base_buffer + __exponentiate_threshold); _STLP_TRY { __base_leaf = _S_new_RopeLeaf(__base_buffer, __exponentiate_threshold, __a); } _STLP_UNWIND(_RopeRep::_S_free_string(__base_buffer, __exponentiate_threshold, __a)) __base_rope._M_tree_ptr._M_data = __base_leaf; if (1 == __exponent) { __result = __base_rope; // One each for base_rope and __result //_STLP_ASSERT(2 == __result._M_tree_ptr._M_data->_M_ref_count) } else { __result = _STLP_PRIV __power(__base_rope, __exponent, _Concat_fn()); } if (0 != __remainder) { __result += __remainder_rope; } } else { __result = __remainder_rope; } _M_tree_ptr._M_data = __result._M_tree_ptr._M_data; _M_tree_ptr._M_data->_M_ref_nonnil();# undef __exponentiate_threshold } rope(const allocator_type& __a = allocator_type()) : _M_tree_ptr(__a, (_RopeRep*)0) {} // Construct a rope from a function that can compute its members rope(char_producer<_CharT> *__fn, size_t __len, bool __delete_fn, const allocator_type& __a = allocator_type()) : _M_tree_ptr(__a, (_RopeRep*)0) { _M_tree_ptr._M_data = (0 == __len) ? 0 : _S_new_RopeFunction(__fn, __len, __delete_fn, __a); } rope(const _Self& __x) : _M_tree_ptr(__x._M_tree_ptr, __x._M_tree_ptr._M_data) { _S_ref(_M_tree_ptr._M_data); }#if !defined (_STLP_NO_MOVE_SEMANTIC) rope(__move_source<_Self> __src) : _M_tree_ptr(__src.get()._M_tree_ptr, __src.get()._M_tree_ptr._M_data) { __src.get()._M_tree_ptr._M_data = 0; }#endif ~rope() { _S_unref(_M_tree_ptr._M_data); } _Self& operator=(const _Self& __x) { _STLP_ASSERT(get_allocator() == __x.get_allocator()) _S_ref(__x._M_tree_ptr._M_data); _M_reset(__x._M_tree_ptr._M_data); return *this; } void clear() { _S_unref(_M_tree_ptr._M_data); _M_tree_ptr._M_data = 0; } void push_back(_CharT __x) { _M_reset(_S_destr_concat_char_iter(_M_tree_ptr._M_data, &__x, 1)); } void pop_back() { _RopeRep* __old = _M_tree_ptr._M_data; _M_tree_ptr._M_data = _S_substring(_M_tree_ptr._M_data, 0, _M_tree_ptr._M_data->_M_size._M_data - 1); _S_unref(__old); } _CharT back() const { return _S_fetch(_M_tree_ptr._M_data, _M_tree_ptr._M_data->_M_size._M_data - 1); } void push_front(_CharT __x) { _RopeRep* __old = _M_tree_ptr._M_data; _RopeRep* __left = _S_RopeLeaf_from_unowned_char_ptr(&__x, 1, _M_tree_ptr); _STLP_TRY { _M_tree_ptr._M_data = _S_concat_rep(__left, _M_tree_ptr._M_data); _S_unref(__old); _S_unref(__left); } _STLP_UNWIND(_S_unref(__left)) } void pop_front() { _RopeRep* __old = _M_tree_ptr._M_data; _M_tree_ptr._M_data = _S_substring(_M_tree_ptr._M_data, 1, _M_tree_ptr._M_data->_M_size._M_data); _S_unref(__old); } _CharT front() const { return _S_fetch(_M_tree_ptr._M_data, 0); } void balance() { _RopeRep* __old = _M_tree_ptr._M_data; _M_tree_ptr._M_data = _S_balance(_M_tree_ptr._M_data); _S_unref(__old); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?