📄 _rope.h
字号:
enum { _S_path_cache_len = 4 }; // Must be <= 9 because of _M_path_direction.
enum { _S_iterator_buf_len = 15 };
size_t _M_current_pos;
// The whole rope.
_RopeRep* _M_root;
// Starting position for current leaf
size_t _M_leaf_pos;
// Buffer possibly containing current char.
_CharT* _M_buf_start;
// Pointer to current char in buffer, != 0 ==> buffer valid.
_CharT* _M_buf_ptr;
// One past __last valid char in buffer.
_CharT* _M_buf_end;
// What follows is the path cache. We go out of our
// way to make this compact.
// Path_end contains the bottom section of the path from
// the root to the current leaf.
struct {
# if defined (__BORLANDC__) && (__BORLANDC__ < 0x560)
_RopeRep const*_M_data[4];
# else
_RopeRep const*_M_data[_S_path_cache_len];
# endif
} _M_path_end;
// Last valid __pos in path_end;
// _M_path_end[0] ... _M_path_end[_M_leaf_index-1]
// point to concatenation nodes.
int _M_leaf_index;
// (_M_path_directions >> __i) & 1 is 1
// if we got from _M_path_end[leaf_index - __i - 1]
// to _M_path_end[leaf_index - __i] by going to the
// __right. Assumes path_cache_len <= 9.
unsigned char _M_path_directions;
// Short buffer for surrounding chars.
// This is useful primarily for
// RopeFunctions. We put the buffer
// here to avoid locking in the
// multithreaded case.
// The cached path is generally assumed to be valid
// only if the buffer is valid.
struct {
# if defined (__BORLANDC__) && (__BORLANDC__ < 0x560)
_CharT _M_data[15];
# else
_CharT _M_data[_S_iterator_buf_len];
# endif
} _M_tmp_buf;
// Set buffer contents given path cache.
static void _S_setbuf(_Rope_iterator_base<_CharT, _Alloc>& __x);
// Set buffer contents and path cache.
static void _S_setcache(_Rope_iterator_base<_CharT, _Alloc>& __x);
// As above, but assumes path cache is valid for previous posn.
static void _S_setcache_for_incr(_Rope_iterator_base<_CharT, _Alloc>& __x);
_Rope_iterator_base() {}
_Rope_iterator_base(_RopeRep* __root, size_t __pos)
: _M_current_pos(__pos),_M_root(__root), _M_buf_ptr(0) {}
void _M_incr(size_t __n);
void _M_decr(size_t __n);
public:
size_t index() const { return _M_current_pos; }
private:
void _M_copy_buf(const _Self& __x) {
_M_tmp_buf = __x._M_tmp_buf;
if (__x._M_buf_start == __x._M_tmp_buf._M_data) {
_M_buf_start = _M_tmp_buf._M_data;
_M_buf_end = _M_buf_start + (__x._M_buf_end - __x._M_buf_start);
_M_buf_ptr = _M_buf_start + (__x._M_buf_ptr - __x._M_buf_start);
} else {
_M_buf_end = __x._M_buf_end;
}
}
public:
_Rope_iterator_base(const _Self& __x) :
_M_current_pos(__x._M_current_pos),
_M_root(__x._M_root),
_M_leaf_pos( __x._M_leaf_pos ),
_M_buf_start(__x._M_buf_start),
_M_buf_ptr(__x._M_buf_ptr),
_M_path_end(__x._M_path_end),
_M_leaf_index(__x._M_leaf_index),
_M_path_directions(__x._M_path_directions)
{
if (0 != __x._M_buf_ptr) {
_M_copy_buf(__x);
}
}
_Self& operator = (const _Self& __x)
{
_M_current_pos = __x._M_current_pos;
_M_root = __x._M_root;
_M_buf_start = __x._M_buf_start;
_M_buf_ptr = __x._M_buf_ptr;
_M_path_end = __x._M_path_end;
_M_leaf_index = __x._M_leaf_index;
_M_path_directions = __x._M_path_directions;
_M_leaf_pos = __x._M_leaf_pos;
if (0 != __x._M_buf_ptr) {
_M_copy_buf(__x);
}
return *this;
}
};
template<class _CharT, class _Alloc> class _Rope_iterator;
template<class _CharT, class _Alloc>
class _Rope_const_iterator : public _Rope_iterator_base<_CharT,_Alloc> {
friend class rope<_CharT,_Alloc>;
typedef _Rope_const_iterator<_CharT, _Alloc> _Self;
typedef _Rope_iterator_base<_CharT,_Alloc> _Base;
// protected:
public:
# ifndef _STLP_HAS_NO_NAMESPACES
typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep;
// The one from the base class may not be directly visible.
# endif
_Rope_const_iterator(const _RopeRep* __root, size_t __pos):
_Rope_iterator_base<_CharT,_Alloc>(__CONST_CAST(_RopeRep*,__root), __pos)
// Only nonconst iterators modify root ref count
{}
public:
typedef _CharT reference; // Really a value. Returning a reference
// Would be a mess, since it would have
// to be included in refcount.
typedef const _CharT* pointer;
typedef _CharT value_type;
typedef ptrdiff_t difference_type;
typedef random_access_iterator_tag iterator_category;
public:
_Rope_const_iterator() {}
_Rope_const_iterator(const _Self& __x) :
_Rope_iterator_base<_CharT,_Alloc>(__x) { }
_Rope_const_iterator(const _Rope_iterator<_CharT,_Alloc>& __x):
_Rope_iterator_base<_CharT,_Alloc>(__x) {}
_Rope_const_iterator(const rope<_CharT,_Alloc>& __r, size_t __pos) :
_Rope_iterator_base<_CharT,_Alloc>(__r._M_tree_ptr._M_data, __pos) {}
_Self& operator= (const _Self& __x) {
_Base::operator=(__x);
return *this;
}
reference operator*() {
if (0 == this->_M_buf_ptr)
#if !defined (__DMC__)
_S_setcache(*this);
#else
{ _Rope_iterator_base<_CharT, _Alloc>* __x = this; _S_setcache(*__x); }
#endif
return *(this->_M_buf_ptr);
}
_Self& operator++() {
_CharT* __next;
if (0 != this->_M_buf_ptr && (__next = this->_M_buf_ptr + 1) < this->_M_buf_end) {
this->_M_buf_ptr = __next;
++this->_M_current_pos;
} else {
this->_M_incr(1);
}
return *this;
}
_Self& operator+=(ptrdiff_t __n) {
if (__n >= 0) {
this->_M_incr(__n);
} else {
this->_M_decr(-__n);
}
return *this;
}
_Self& operator--() {
this->_M_decr(1);
return *this;
}
_Self& operator-=(ptrdiff_t __n) {
if (__n >= 0) {
this->_M_decr(__n);
} else {
this->_M_incr(-__n);
}
return *this;
}
_Self operator++(int) {
size_t __old_pos = this->_M_current_pos;
this->_M_incr(1);
return _Rope_const_iterator<_CharT,_Alloc>(this->_M_root, __old_pos);
// This makes a subsequent dereference expensive.
// Perhaps we should instead copy the iterator
// if it has a valid cache?
}
_Self operator--(int) {
size_t __old_pos = this->_M_current_pos;
this->_M_decr(1);
return _Rope_const_iterator<_CharT,_Alloc>(this->_M_root, __old_pos);
}
inline reference operator[](size_t __n);
};
template<class _CharT, class _Alloc>
class _Rope_iterator : public _Rope_iterator_base<_CharT,_Alloc> {
friend class rope<_CharT,_Alloc>;
typedef _Rope_iterator<_CharT, _Alloc> _Self;
typedef _Rope_iterator_base<_CharT,_Alloc> _Base;
typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep;
public:
rope<_CharT,_Alloc>* _M_root_rope;
// root is treated as a cached version of this,
// and is used to detect changes to the underlying
// rope.
// Root is included in the reference count.
// This is necessary so that we can detect changes reliably.
// Unfortunately, it requires careful bookkeeping for the
// nonGC case.
_Rope_iterator(rope<_CharT,_Alloc>* __r, size_t __pos);
void _M_check();
public:
typedef _Rope_char_ref_proxy<_CharT,_Alloc> reference;
typedef _Rope_char_ref_proxy<_CharT,_Alloc>* pointer;
typedef _CharT value_type;
typedef ptrdiff_t difference_type;
typedef random_access_iterator_tag iterator_category;
public:
~_Rope_iterator() { //*TY 5/6/00 - added dtor to balance reference count
_RopeRep::_S_unref(this->_M_root);
}
rope<_CharT,_Alloc>& container() { return *_M_root_rope; }
_Rope_iterator() {
this->_M_root = 0; // Needed for reference counting.
}
_Rope_iterator(const _Self& __x) :
_Rope_iterator_base<_CharT,_Alloc>(__x) {
_M_root_rope = __x._M_root_rope;
_RopeRep::_S_ref(this->_M_root);
}
_Rope_iterator(rope<_CharT,_Alloc>& __r, size_t __pos);
_Self& operator= (const _Self& __x) {
_RopeRep* __old = this->_M_root;
_RopeRep::_S_ref(__x._M_root);
_Base::operator=(__x);
_M_root_rope = __x._M_root_rope;
_RopeRep::_S_unref(__old);
return *this;
}
reference operator*() {
_M_check();
if (0 == this->_M_buf_ptr) {
return reference(_M_root_rope, this->_M_current_pos);
} else {
return reference(_M_root_rope, this->_M_current_pos, *(this->_M_buf_ptr));
}
}
_Self& operator++() {
this->_M_incr(1);
return *this;
}
_Self& operator+=(ptrdiff_t __n) {
if (__n >= 0) {
this->_M_incr(__n);
} else {
this->_M_decr(-__n);
}
return *this;
}
_Self& operator--() {
this->_M_decr(1);
return *this;
}
_Self& operator-=(ptrdiff_t __n) {
if (__n >= 0) {
this->_M_decr(__n);
} else {
this->_M_incr(-__n);
}
return *this;
}
_Self operator++(int) {
size_t __old_pos = this->_M_current_pos;
this->_M_incr(1);
return _Self(_M_root_rope, __old_pos);
}
_Self operator--(int) {
size_t __old_pos = this->_M_current_pos;
this->_M_decr(1);
return _Self(_M_root_rope, __old_pos);
}
reference operator[](ptrdiff_t __n) {
return reference(_M_root_rope, this->_M_current_pos + __n);
}
};
# ifdef _STLP_USE_OLD_HP_ITERATOR_QUERIES
template <class _CharT, class _Alloc>
inline random_access_iterator_tag
iterator_category(const _Rope_iterator<_CharT,_Alloc>&) { return random_access_iterator_tag();}
template <class _CharT, class _Alloc>
inline _CharT* value_type(const _Rope_iterator<_CharT,_Alloc>&) { return 0; }
template <class _CharT, class _Alloc>
inline ptrdiff_t* distance_type(const _Rope_iterator<_CharT,_Alloc>&) { return 0; }
template <class _CharT, class _Alloc>
inline random_access_iterator_tag
iterator_category(const _Rope_const_iterator<_CharT,_Alloc>&) { return random_access_iterator_tag(); }
template <class _CharT, class _Alloc>
inline _CharT* value_type(const _Rope_const_iterator<_CharT,_Alloc>&) { return 0; }
template <class _CharT, class _Alloc>
inline ptrdiff_t* distance_type(const _Rope_const_iterator<_CharT,_Alloc>&) { return 0; }
#endif /* _STLP_USE_OLD_HP_ITERATOR_QUERIES */
template <class _CharT, class _Alloc, class _CharConsumer>
bool _S_apply_to_pieces(_CharConsumer& __c,
_Rope_RopeRep<_CharT, _Alloc> *__r,
size_t __begin, size_t __end);
// begin and end are assumed to be in range.
template <class _CharT, class _Alloc>
class rope
#if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND)
: public __stlport_class<rope<_CharT, _Alloc> >
#endif
{
typedef rope<_CharT,_Alloc> _Self;
public:
typedef _CharT value_type;
typedef ptrdiff_t difference_type;
typedef size_t size_type;
typedef _CharT const_reference;
typedef const _CharT* const_pointer;
typedef _Rope_iterator<_CharT,_Alloc> iterator;
typedef _Rope_const_iterator<_CharT,_Alloc> const_iterator;
typedef _Rope_char_ref_proxy<_CharT,_Alloc> reference;
typedef _Rope_char_ptr_proxy<_CharT,_Alloc> pointer;
friend class _Rope_iterator<_CharT,_Alloc>;
friend class _Rope_const_iterator<_CharT,_Alloc>;
friend struct _Rope_RopeRep<_CharT,_Alloc>;
friend class _Rope_iterator_base<_CharT,_Alloc>;
friend class _Rope_char_ptr_proxy<_CharT,_Alloc>;
friend class _Rope_char_ref_proxy<_CharT,_Alloc>;
friend struct _Rope_RopeSubstring<_CharT,_Alloc>;
_STLP_DECLARE_RANDOM_ACCESS_REVERSE_ITERATORS;
protected:
typedef _CharT* _Cstrptr;
static _CharT _S_empty_c_str[1];
enum { _S_copy_max = 23 };
// For strings shorter than _S_copy_max, we copy to
// concatenate.
typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep;
typedef typename _RopeRep::_IsBasicCharType _IsBasicCharType;
public:
_STLP_FORCE_ALLOCATORS(_CharT, _Alloc)
typedef typename _Alloc_traits<_CharT,_Alloc>::allocator_type allocator_type;
public:
// The only data member of a rope:
_STLP_PRIV _STLP_alloc_proxy<_RopeRep*, _CharT, allocator_type> _M_tree_ptr;
public:
allocator_type get_allocator() const { return allocator_type(_M_tree_ptr); }
public:
typedef _Rope_RopeConcatenation<_CharT,_Alloc> _RopeConcatenation;
typedef _Rope_RopeLeaf<_CharT,_Alloc> _RopeLeaf;
typedef _Rope_RopeFunction<_CharT,_Alloc> _RopeFunction;
typedef _Rope_RopeSubstring<_CharT,_Alloc> _RopeSubstring;
// Retrieve a character at the indicated position.
static _CharT _S_fetch(_RopeRep* __r, size_type __pos);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -