📄 stl_rope.h
字号:
# endif static _RopeRep* _S_concat(_RopeRep* __left, _RopeRep* __right); // General concatenation on _RopeRep. _Result // has refcount of 1. Adjusts argument refcounts. public: void apply_to_pieces( size_t __begin, size_t __end, _Rope_char_consumer<_CharT>& __c) const { _S_apply_to_pieces(__c, _M_tree_ptr, __begin, __end); } protected: static size_t _S_rounded_up_size(size_t __n) { return _RopeLeaf::_S_rounded_up_size(__n); } static size_t _S_allocated_capacity(size_t __n) { if (_S_is_basic_char_type((_CharT*)0)) { return _S_rounded_up_size(__n) - 1; } else { return _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(__GC_CONST _CharT *__s, size_t __size, allocator_type __a) {# ifdef __STL_USE_STD_ALLOCATORS _RopeLeaf* __space = _LAllocator(__a).allocate(1);# else _RopeLeaf* __space = _L_allocate(1);# endif return new(__space) _RopeLeaf(__s, __size, __a); } static _RopeConcatenation* _S_new_RopeConcatenation( _RopeRep* __left, _RopeRep* __right, allocator_type __a) {# ifdef __STL_USE_STD_ALLOCATORS _RopeConcatenation* __space = _CAllocator(__a).allocate(1);# else _RopeConcatenation* __space = _C_allocate(1);# endif return new(__space) _RopeConcatenation(__left, __right, __a); } static _RopeFunction* _S_new_RopeFunction(char_producer<_CharT>* __f, size_t __size, bool __d, allocator_type __a) {# ifdef __STL_USE_STD_ALLOCATORS _RopeFunction* __space = _FAllocator(__a).allocate(1);# else _RopeFunction* __space = _F_allocate(1);# endif return new(__space) _RopeFunction(__f, __size, __d, __a); } static _RopeSubstring* _S_new_RopeSubstring( _Rope_RopeRep<_CharT,_Alloc>* __b, size_t __s, size_t __l, allocator_type __a) {# ifdef __STL_USE_STD_ALLOCATORS _RopeSubstring* __space = _SAllocator(__a).allocate(1);# else _RopeSubstring* __space = _S_allocate(1);# endif return new(__space) _RopeSubstring(__b, __s, __l, __a); }# ifdef __STL_USE_STD_ALLOCATORS static _RopeLeaf* _S_RopeLeaf_from_unowned_char_ptr(const _CharT *__s, size_t __size, allocator_type __a)# define __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __size, __a) \ _S_RopeLeaf_from_unowned_char_ptr(__s, __size, __a) # else static _RopeLeaf* _S_RopeLeaf_from_unowned_char_ptr2(const _CharT* __s, size_t __size)# define __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __size, __a) \ _S_RopeLeaf_from_unowned_char_ptr2(__s, __size)# endif { if (0 == __size) return 0;# ifdef __STL_USE_STD_ALLOCATORS _CharT* __buf = __a.allocate(_S_rounded_up_size(__size));# else _CharT* __buf = _Data_allocate(_S_rounded_up_size(__size)); allocator_type __a = allocator_type();# endif uninitialized_copy_n(__s, __size, __buf); _S_cond_store_eos(__buf[__size]); __STL_TRY { return _S_new_RopeLeaf(__buf, __size, __a); } __STL_UNWIND(_RopeRep::__STL_FREE_STRING(__buf, __size, __a)) } // 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.# ifndef __GC 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.# endif private: static size_t _S_char_ptr_len(const _CharT* __s); // slightly generalized strlen rope(_RopeRep* __t, const allocator_type& __a = allocator_type()) : _Base(__t,__a) { } // Copy __r to the _CharT buffer. // Returns __buffer + __r->_M_size. // 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); static const unsigned long _S_min_len[_RopeRep::_S_max_rope_depth + 1]; static bool _S_is_balanced(_RopeRep* __r) { return (__r->_M_size >= _S_min_len[__r->_M_depth]); } static bool _S_is_almost_balanced(_RopeRep* __r) { return (__r->_M_depth == 0 || __r->_M_size >= _S_min_len[__r->_M_depth - 1]); } static bool _S_is_roughly_balanced(_RopeRep* __r) { return (__r->_M_depth <= 1 || __r->_M_size >= _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(__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); // Print to stdout, exposing structure static void _S_dump(_RopeRep* __r, int __indent = 0); // Return -1, 0, or 1 if __x < __y, __x == __y, or __x > __y resp. static int _S_compare(const _RopeRep* __x, const _RopeRep* __y); public: bool empty() const { return 0 == _M_tree_ptr; } // 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 rope& __y) const { return _S_compare(_M_tree_ptr, __y._M_tree_ptr); } rope(const _CharT* __s, const allocator_type& __a = allocator_type()) : _Base(__STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, _S_char_ptr_len(__s), __a),__a) { } rope(const _CharT* __s, size_t __len, const allocator_type& __a = allocator_type()) : _Base(__STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __len, __a), __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()) : _Base(__STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __e - __s, __a), __a) { } rope(const const_iterator& __s, const const_iterator& __e, const allocator_type& __a = allocator_type()) : _Base(_S_substring(__s._M_root, __s._M_current_pos, __e._M_current_pos), __a) { } rope(const iterator& __s, const iterator& __e, const allocator_type& __a = allocator_type()) : _Base(_S_substring(__s._M_root, __s._M_current_pos, __e._M_current_pos), __a) { } rope(_CharT __c, const allocator_type& __a = allocator_type()) : _Base(__a) { _CharT* __buf = _Data_allocate(_S_rounded_up_size(1)); construct(__buf, __c); __STL_TRY { _M_tree_ptr = _S_new_RopeLeaf(__buf, 1, __a); } __STL_UNWIND(_RopeRep::__STL_FREE_STRING(__buf, 1, __a)) } rope(size_t __n, _CharT __c, const allocator_type& __a = allocator_type()); rope(const allocator_type& __a = allocator_type()) : _Base(0, __a) {} // 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()) : _Base(__a) { _M_tree_ptr = (0 == __len) ? 0 : _S_new_RopeFunction(__fn, __len, __delete_fn, __a); } rope(const rope& __x, const allocator_type& __a = allocator_type()) : _Base(__x._M_tree_ptr, __a) { _S_ref(_M_tree_ptr); } ~rope() { _S_unref(_M_tree_ptr); } rope& operator=(const rope& __x) { _RopeRep* __old = _M_tree_ptr;# ifdef __STL_USE_STD_ALLOCATORS __stl_assert(get_allocator() == __x.get_allocator());# endif _M_tree_ptr = __x._M_tree_ptr; _S_ref(_M_tree_ptr); _S_unref(__old); return(*this); } void clear() { _S_unref(_M_tree_ptr); _M_tree_ptr = 0; } void push_back(_CharT __x) { _RopeRep* __old = _M_tree_ptr; _M_tree_ptr = _S_destr_concat_char_iter(_M_tree_ptr, &__x, 1); _S_unref(__old); } void pop_back() { _RopeRep* __old = _M_tree_ptr; _M_tree_ptr = _S_substring(_M_tree_ptr, 0, _M_tree_ptr->_M_size - 1); _S_unref(__old); } _CharT back() const { return _S_fetch(_M_tree_ptr, _M_tree_ptr->_M_size - 1); } void push_front(_CharT __x) { _RopeRep* __old = _M_tree_ptr; _RopeRep* __left = __STL_ROPE_FROM_UNOWNED_CHAR_PTR(&__x, 1, get_allocator()); __STL_TRY { _M_tree_ptr = _S_concat(__left, _M_tree_ptr); _S_unref(__old); _S_unref(__left); } __STL_UNWIND(_S_unref(__left)) } void pop_front() { _RopeRep* __old = _M_tree_ptr; _M_tree_ptr = _S_substring(_M_tree_ptr, 1, _M_tree_ptr->_M_size); _S_unref(__old); } _CharT front() const { return _S_fetch(_M_tree_ptr, 0); } void balance() { _RopeRep* __old = _M_tree_ptr; _M_tree_ptr = _S_balance(_M_tree_ptr); _S_unref(__old); } void copy(_CharT* __buffer) const { destroy(__buffer, __buffer + size()); _S_flatten(_M_tree_ptr, __buffer); } // This is the copy function from the standard, but // with the arguments reordered to make it consistent with the // rest of the interface. // Note that this guara
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -