⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 _rope.h

📁 symbian 上的stl_port进过编译的。
💻 H
📖 第 1 页 / 共 5 页
字号:

  // Obtain a pointer to the character at the indicated position.
  // The pointer can be used to change the character.
  // If such a pointer cannot be produced, as is frequently the
  // case, 0 is returned instead.
  // (Returns nonzero only if all nodes in the path have a refcount
  // of 1.)
  static _CharT* _S_fetch_ptr(_RopeRep* __r, size_type __pos);

  static void _S_unref(_RopeRep* __t) {
    _RopeRep::_S_unref(__t);
  }
  static void _S_ref(_RopeRep* __t) {
    _RopeRep::_S_ref(__t);
  }

  typedef _Rope_self_destruct_ptr<_CharT,_Alloc> _Self_destruct_ptr;

  // _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 {
      _STLP_PLACEMENT_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 _STLP_PLACEMENT_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 _STLP_PLACEMENT_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 _STLP_PLACEMENT_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(__GCCE__) && !defined(__WINSCW__) && (!defined (__GNUC__) || (__GNUC__ < 3))
  friend _Concat_fn;
#else
  friend struct _STLP_PRIV _Rope_Concat_fn<_CharT,_Alloc>;
#endif

public:
  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);
  }

  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;
  }

  ~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;

⌨️ 快捷键说明

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