Index: gcc/libstdc++-v3/include/ext/rope |
diff --git a/gcc/libstdc++-v3/include/ext/rope b/gcc/libstdc++-v3/include/ext/rope |
deleted file mode 100644 |
index 462c8f5db2ba629c30ac8e29811d9f7e95d11eaf..0000000000000000000000000000000000000000 |
--- a/gcc/libstdc++-v3/include/ext/rope |
+++ /dev/null |
@@ -1,2958 +0,0 @@ |
-// SGI's rope class -*- C++ -*- |
- |
-// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 |
-// Free Software Foundation, Inc. |
-// |
-// This file is part of the GNU ISO C++ Library. This library is free |
-// software; you can redistribute it and/or modify it under the |
-// terms of the GNU General Public License as published by the |
-// Free Software Foundation; either version 3, or (at your option) |
-// any later version. |
- |
-// This library is distributed in the hope that it will be useful, |
-// but WITHOUT ANY WARRANTY; without even the implied warranty of |
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
-// GNU General Public License for more details. |
- |
-// Under Section 7 of GPL version 3, you are granted additional |
-// permissions described in the GCC Runtime Library Exception, version |
-// 3.1, as published by the Free Software Foundation. |
- |
-// You should have received a copy of the GNU General Public License and |
-// a copy of the GCC Runtime Library Exception along with this program; |
-// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see |
-// <http://www.gnu.org/licenses/>. |
- |
-/* |
- * Copyright (c) 1997 |
- * Silicon Graphics Computer Systems, Inc. |
- * |
- * Permission to use, copy, modify, distribute and sell this software |
- * and its documentation for any purpose is hereby granted without fee, |
- * provided that the above copyright notice appear in all copies and |
- * that both that copyright notice and this permission notice appear |
- * in supporting documentation. Silicon Graphics makes no |
- * representations about the suitability of this software for any |
- * purpose. It is provided "as is" without express or implied warranty. |
- */ |
- |
-/** @file ext/rope |
- * This file is a GNU extension to the Standard C++ Library (possibly |
- * containing extensions from the HP/SGI STL subset). |
- */ |
- |
-#ifndef _ROPE |
-#define _ROPE 1 |
- |
-#include <algorithm> |
-#include <iosfwd> |
-#include <bits/stl_construct.h> |
-#include <bits/stl_uninitialized.h> |
-#include <bits/stl_function.h> |
-#include <bits/stl_numeric.h> |
-#include <bits/allocator.h> |
-#include <bits/gthr.h> |
-#include <tr1/functional> |
- |
-# ifdef __GC |
-# define __GC_CONST const |
-# else |
-# define __GC_CONST // constant except for deallocation |
-# endif |
- |
-#include <ext/memory> // For uninitialized_copy_n |
- |
-_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) |
- |
- namespace __detail |
- { |
- enum { _S_max_rope_depth = 45 }; |
- enum _Tag {_S_leaf, _S_concat, _S_substringfn, _S_function}; |
- } // namespace __detail |
- |
- using std::size_t; |
- using std::ptrdiff_t; |
- using std::allocator; |
- using std::_Destroy; |
- |
- // See libstdc++/36832. |
- template<typename _ForwardIterator, typename _Allocator> |
- void |
- _Destroy_const(_ForwardIterator __first, |
- _ForwardIterator __last, _Allocator __alloc) |
- { |
- for (; __first != __last; ++__first) |
- __alloc.destroy(&*__first); |
- } |
- |
- template<typename _ForwardIterator, typename _Tp> |
- inline void |
- _Destroy_const(_ForwardIterator __first, |
- _ForwardIterator __last, allocator<_Tp>) |
- { _Destroy(__first, __last); } |
- |
- // The _S_eos function is used for those functions that |
- // convert to/from C-like strings to detect the end of the string. |
- |
- // The end-of-C-string character. |
- // This is what the draft standard says it should be. |
- template <class _CharT> |
- inline _CharT |
- _S_eos(_CharT*) |
- { return _CharT(); } |
- |
- // Test for basic character types. |
- // For basic character types leaves having a trailing eos. |
- template <class _CharT> |
- inline bool |
- _S_is_basic_char_type(_CharT*) |
- { return false; } |
- |
- template <class _CharT> |
- inline bool |
- _S_is_one_byte_char_type(_CharT*) |
- { return false; } |
- |
- inline bool |
- _S_is_basic_char_type(char*) |
- { return true; } |
- |
- inline bool |
- _S_is_one_byte_char_type(char*) |
- { return true; } |
- |
- inline bool |
- _S_is_basic_char_type(wchar_t*) |
- { return true; } |
- |
- // Store an eos iff _CharT is a basic character type. |
- // Do not reference _S_eos if it isn't. |
- template <class _CharT> |
- inline void |
- _S_cond_store_eos(_CharT&) { } |
- |
- inline void |
- _S_cond_store_eos(char& __c) |
- { __c = 0; } |
- |
- inline void |
- _S_cond_store_eos(wchar_t& __c) |
- { __c = 0; } |
- |
- // char_producers are logically functions that generate a section of |
- // a string. These can be converted to ropes. The resulting rope |
- // invokes the char_producer on demand. This allows, for example, |
- // files to be viewed as ropes without reading the entire file. |
- template <class _CharT> |
- class char_producer |
- { |
- public: |
- virtual ~char_producer() { }; |
- |
- virtual void |
- operator()(size_t __start_pos, size_t __len, |
- _CharT* __buffer) = 0; |
- // Buffer should really be an arbitrary output iterator. |
- // That way we could flatten directly into an ostream, etc. |
- // This is thoroughly impossible, since iterator types don't |
- // have runtime descriptions. |
- }; |
- |
- // Sequence buffers: |
- // |
- // Sequence must provide an append operation that appends an |
- // array to the sequence. Sequence buffers are useful only if |
- // appending an entire array is cheaper than appending element by element. |
- // This is true for many string representations. |
- // This should perhaps inherit from ostream<sequence::value_type> |
- // and be implemented correspondingly, so that they can be used |
- // for formatted. For the sake of portability, we don't do this yet. |
- // |
- // For now, sequence buffers behave as output iterators. But they also |
- // behave a little like basic_ostringstream<sequence::value_type> and a |
- // little like containers. |
- |
- template<class _Sequence, size_t _Buf_sz = 100> |
- class sequence_buffer |
- : public std::iterator<std::output_iterator_tag, void, void, void, void> |
- { |
- public: |
- typedef typename _Sequence::value_type value_type; |
- protected: |
- _Sequence* _M_prefix; |
- value_type _M_buffer[_Buf_sz]; |
- size_t _M_buf_count; |
- public: |
- |
- void |
- flush() |
- { |
- _M_prefix->append(_M_buffer, _M_buffer + _M_buf_count); |
- _M_buf_count = 0; |
- } |
- |
- ~sequence_buffer() |
- { flush(); } |
- |
- sequence_buffer() |
- : _M_prefix(0), _M_buf_count(0) { } |
- |
- sequence_buffer(const sequence_buffer& __x) |
- { |
- _M_prefix = __x._M_prefix; |
- _M_buf_count = __x._M_buf_count; |
- std::copy(__x._M_buffer, __x._M_buffer + __x._M_buf_count, _M_buffer); |
- } |
- |
- sequence_buffer(sequence_buffer& __x) |
- { |
- __x.flush(); |
- _M_prefix = __x._M_prefix; |
- _M_buf_count = 0; |
- } |
- |
- sequence_buffer(_Sequence& __s) |
- : _M_prefix(&__s), _M_buf_count(0) { } |
- |
- sequence_buffer& |
- operator=(sequence_buffer& __x) |
- { |
- __x.flush(); |
- _M_prefix = __x._M_prefix; |
- _M_buf_count = 0; |
- return *this; |
- } |
- |
- sequence_buffer& |
- operator=(const sequence_buffer& __x) |
- { |
- _M_prefix = __x._M_prefix; |
- _M_buf_count = __x._M_buf_count; |
- std::copy(__x._M_buffer, __x._M_buffer + __x._M_buf_count, _M_buffer); |
- return *this; |
- } |
- |
- void |
- push_back(value_type __x) |
- { |
- if (_M_buf_count < _Buf_sz) |
- { |
- _M_buffer[_M_buf_count] = __x; |
- ++_M_buf_count; |
- } |
- else |
- { |
- flush(); |
- _M_buffer[0] = __x; |
- _M_buf_count = 1; |
- } |
- } |
- |
- void |
- append(value_type* __s, size_t __len) |
- { |
- if (__len + _M_buf_count <= _Buf_sz) |
- { |
- size_t __i = _M_buf_count; |
- for (size_t __j = 0; __j < __len; __i++, __j++) |
- _M_buffer[__i] = __s[__j]; |
- _M_buf_count += __len; |
- } |
- else if (0 == _M_buf_count) |
- _M_prefix->append(__s, __s + __len); |
- else |
- { |
- flush(); |
- append(__s, __len); |
- } |
- } |
- |
- sequence_buffer& |
- write(value_type* __s, size_t __len) |
- { |
- append(__s, __len); |
- return *this; |
- } |
- |
- sequence_buffer& |
- put(value_type __x) |
- { |
- push_back(__x); |
- return *this; |
- } |
- |
- sequence_buffer& |
- operator=(const value_type& __rhs) |
- { |
- push_back(__rhs); |
- return *this; |
- } |
- |
- sequence_buffer& |
- operator*() |
- { return *this; } |
- |
- sequence_buffer& |
- operator++() |
- { return *this; } |
- |
- sequence_buffer |
- operator++(int) |
- { return *this; } |
- }; |
- |
- // The following should be treated as private, at least for now. |
- template<class _CharT> |
- class _Rope_char_consumer |
- { |
- public: |
- // If we had member templates, these should not be virtual. |
- // For now we need to use run-time parametrization where |
- // compile-time would do. Hence this should all be private |
- // for now. |
- // The symmetry with char_producer is accidental and temporary. |
- virtual ~_Rope_char_consumer() { }; |
- |
- virtual bool |
- operator()(const _CharT* __buffer, size_t __len) = 0; |
- }; |
- |
- // First a lot of forward declarations. The standard seems to require |
- // much stricter "declaration before use" than many of the implementations |
- // that preceded it. |
- template<class _CharT, class _Alloc = allocator<_CharT> > |
- class rope; |
- |
- template<class _CharT, class _Alloc> |
- struct _Rope_RopeConcatenation; |
- |
- template<class _CharT, class _Alloc> |
- struct _Rope_RopeLeaf; |
- |
- template<class _CharT, class _Alloc> |
- struct _Rope_RopeFunction; |
- |
- template<class _CharT, class _Alloc> |
- struct _Rope_RopeSubstring; |
- |
- template<class _CharT, class _Alloc> |
- class _Rope_iterator; |
- |
- template<class _CharT, class _Alloc> |
- class _Rope_const_iterator; |
- |
- template<class _CharT, class _Alloc> |
- class _Rope_char_ref_proxy; |
- |
- template<class _CharT, class _Alloc> |
- class _Rope_char_ptr_proxy; |
- |
- template<class _CharT, class _Alloc> |
- bool |
- operator==(const _Rope_char_ptr_proxy<_CharT, _Alloc>& __x, |
- const _Rope_char_ptr_proxy<_CharT, _Alloc>& __y); |
- |
- template<class _CharT, class _Alloc> |
- _Rope_const_iterator<_CharT, _Alloc> |
- operator-(const _Rope_const_iterator<_CharT, _Alloc>& __x, |
- ptrdiff_t __n); |
- |
- template<class _CharT, class _Alloc> |
- _Rope_const_iterator<_CharT, _Alloc> |
- operator+(const _Rope_const_iterator<_CharT, _Alloc>& __x, |
- ptrdiff_t __n); |
- |
- template<class _CharT, class _Alloc> |
- _Rope_const_iterator<_CharT, _Alloc> |
- operator+(ptrdiff_t __n, |
- const _Rope_const_iterator<_CharT, _Alloc>& __x); |
- |
- template<class _CharT, class _Alloc> |
- bool |
- operator==(const _Rope_const_iterator<_CharT, _Alloc>& __x, |
- const _Rope_const_iterator<_CharT, _Alloc>& __y); |
- |
- template<class _CharT, class _Alloc> |
- bool |
- operator<(const _Rope_const_iterator<_CharT, _Alloc>& __x, |
- const _Rope_const_iterator<_CharT, _Alloc>& __y); |
- |
- template<class _CharT, class _Alloc> |
- ptrdiff_t |
- operator-(const _Rope_const_iterator<_CharT, _Alloc>& __x, |
- const _Rope_const_iterator<_CharT, _Alloc>& __y); |
- |
- template<class _CharT, class _Alloc> |
- _Rope_iterator<_CharT, _Alloc> |
- operator-(const _Rope_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n); |
- |
- template<class _CharT, class _Alloc> |
- _Rope_iterator<_CharT, _Alloc> |
- operator+(const _Rope_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n); |
- |
- template<class _CharT, class _Alloc> |
- _Rope_iterator<_CharT, _Alloc> |
- operator+(ptrdiff_t __n, const _Rope_iterator<_CharT, _Alloc>& __x); |
- |
- template<class _CharT, class _Alloc> |
- bool |
- operator==(const _Rope_iterator<_CharT, _Alloc>& __x, |
- const _Rope_iterator<_CharT, _Alloc>& __y); |
- |
- template<class _CharT, class _Alloc> |
- bool |
- operator<(const _Rope_iterator<_CharT, _Alloc>& __x, |
- const _Rope_iterator<_CharT, _Alloc>& __y); |
- |
- template<class _CharT, class _Alloc> |
- ptrdiff_t |
- operator-(const _Rope_iterator<_CharT, _Alloc>& __x, |
- const _Rope_iterator<_CharT, _Alloc>& __y); |
- |
- template<class _CharT, class _Alloc> |
- rope<_CharT, _Alloc> |
- operator+(const rope<_CharT, _Alloc>& __left, |
- const rope<_CharT, _Alloc>& __right); |
- |
- template<class _CharT, class _Alloc> |
- rope<_CharT, _Alloc> |
- operator+(const rope<_CharT, _Alloc>& __left, const _CharT* __right); |
- |
- template<class _CharT, class _Alloc> |
- rope<_CharT, _Alloc> |
- operator+(const rope<_CharT, _Alloc>& __left, _CharT __right); |
- |
- // Some helpers, so we can use power on ropes. |
- // See below for why this isn't local to the implementation. |
- |
- // This uses a nonstandard refcount convention. |
- // The result has refcount 0. |
- template<class _CharT, class _Alloc> |
- struct _Rope_Concat_fn |
- : public std::binary_function<rope<_CharT, _Alloc>, rope<_CharT, _Alloc>, |
- rope<_CharT, _Alloc> > |
- { |
- rope<_CharT, _Alloc> |
- operator()(const rope<_CharT, _Alloc>& __x, |
- const rope<_CharT, _Alloc>& __y) |
- { return __x + __y; } |
- }; |
- |
- template <class _CharT, class _Alloc> |
- inline rope<_CharT, _Alloc> |
- identity_element(_Rope_Concat_fn<_CharT, _Alloc>) |
- { return rope<_CharT, _Alloc>(); } |
- |
- // Class _Refcount_Base provides a type, _RC_t, a data member, |
- // _M_ref_count, and member functions _M_incr and _M_decr, which perform |
- // atomic preincrement/predecrement. The constructor initializes |
- // _M_ref_count. |
- struct _Refcount_Base |
- { |
- // The type _RC_t |
- typedef size_t _RC_t; |
- |
- // The data member _M_ref_count |
- volatile _RC_t _M_ref_count; |
- |
- // Constructor |
- __gthread_mutex_t _M_ref_count_lock; |
- |
- _Refcount_Base(_RC_t __n) : _M_ref_count(__n), _M_ref_count_lock() |
- { |
-#ifdef __GTHREAD_MUTEX_INIT |
- __gthread_mutex_t __tmp = __GTHREAD_MUTEX_INIT; |
- _M_ref_count_lock = __tmp; |
-#elif defined(__GTHREAD_MUTEX_INIT_FUNCTION) |
- __GTHREAD_MUTEX_INIT_FUNCTION (&_M_ref_count_lock); |
-#else |
-#error __GTHREAD_MUTEX_INIT or __GTHREAD_MUTEX_INIT_FUNCTION should be defined by gthr.h abstraction layer, report problem to libstdc++@gcc.gnu.org. |
-#endif |
- } |
- |
- void |
- _M_incr() |
- { |
- __gthread_mutex_lock(&_M_ref_count_lock); |
- ++_M_ref_count; |
- __gthread_mutex_unlock(&_M_ref_count_lock); |
- } |
- |
- _RC_t |
- _M_decr() |
- { |
- __gthread_mutex_lock(&_M_ref_count_lock); |
- volatile _RC_t __tmp = --_M_ref_count; |
- __gthread_mutex_unlock(&_M_ref_count_lock); |
- return __tmp; |
- } |
- }; |
- |
- // |
- // What follows should really be local to rope. Unfortunately, |
- // that doesn't work, since it makes it impossible to define generic |
- // equality on rope iterators. According to the draft standard, the |
- // template parameters for such an equality operator cannot be inferred |
- // from the occurrence of a member class as a parameter. |
- // (SGI compilers in fact allow this, but the __result wouldn't be |
- // portable.) |
- // Similarly, some of the static member functions are member functions |
- // only to avoid polluting the global namespace, and to circumvent |
- // restrictions on type inference for template functions. |
- // |
- |
- // |
- // The internal data structure for representing a rope. This is |
- // private to the implementation. A rope is really just a pointer |
- // to one of these. |
- // |
- // A few basic functions for manipulating this data structure |
- // are members of _RopeRep. Most of the more complex algorithms |
- // are implemented as rope members. |
- // |
- // Some of the static member functions of _RopeRep have identically |
- // named functions in rope that simply invoke the _RopeRep versions. |
- |
-#define __ROPE_DEFINE_ALLOCS(__a) \ |
- __ROPE_DEFINE_ALLOC(_CharT,_Data) /* character data */ \ |
- typedef _Rope_RopeConcatenation<_CharT,__a> __C; \ |
- __ROPE_DEFINE_ALLOC(__C,_C) \ |
- typedef _Rope_RopeLeaf<_CharT,__a> __L; \ |
- __ROPE_DEFINE_ALLOC(__L,_L) \ |
- typedef _Rope_RopeFunction<_CharT,__a> __F; \ |
- __ROPE_DEFINE_ALLOC(__F,_F) \ |
- typedef _Rope_RopeSubstring<_CharT,__a> __S; \ |
- __ROPE_DEFINE_ALLOC(__S,_S) |
- |
- // Internal rope nodes potentially store a copy of the allocator |
- // instance used to allocate them. This is mostly redundant. |
- // But the alternative would be to pass allocator instances around |
- // in some form to nearly all internal functions, since any pointer |
- // assignment may result in a zero reference count and thus require |
- // deallocation. |
- |
-#define __STATIC_IF_SGI_ALLOC /* not static */ |
- |
- template <class _CharT, class _Alloc> |
- struct _Rope_rep_base |
- : public _Alloc |
- { |
- typedef _Alloc allocator_type; |
- |
- allocator_type |
- get_allocator() const |
- { return *static_cast<const _Alloc*>(this); } |
- |
- allocator_type& |
- _M_get_allocator() |
- { return *static_cast<_Alloc*>(this); } |
- |
- const allocator_type& |
- _M_get_allocator() const |
- { return *static_cast<const _Alloc*>(this); } |
- |
- _Rope_rep_base(size_t __size, const allocator_type&) |
- : _M_size(__size) { } |
- |
- size_t _M_size; |
- |
-# define __ROPE_DEFINE_ALLOC(_Tp, __name) \ |
- typedef typename \ |
- _Alloc::template rebind<_Tp>::other __name##Alloc; \ |
- static _Tp* __name##_allocate(size_t __n) \ |
- { return __name##Alloc().allocate(__n); } \ |
- static void __name##_deallocate(_Tp *__p, size_t __n) \ |
- { __name##Alloc().deallocate(__p, __n); } |
- __ROPE_DEFINE_ALLOCS(_Alloc) |
-# undef __ROPE_DEFINE_ALLOC |
- }; |
- |
- template<class _CharT, class _Alloc> |
- struct _Rope_RopeRep |
- : public _Rope_rep_base<_CharT, _Alloc> |
-# ifndef __GC |
- , _Refcount_Base |
-# endif |
- { |
- public: |
- __detail::_Tag _M_tag:8; |
- bool _M_is_balanced:8; |
- unsigned char _M_depth; |
- __GC_CONST _CharT* _M_c_string; |
- __gthread_mutex_t _M_c_string_lock; |
- /* Flattened version of string, if needed. */ |
- /* typically 0. */ |
- /* If it's not 0, then the memory is owned */ |
- /* by this node. */ |
- /* In the case of a leaf, this may point to */ |
- /* the same memory as the data field. */ |
- typedef typename _Rope_rep_base<_CharT, _Alloc>::allocator_type |
- allocator_type; |
- |
- using _Rope_rep_base<_CharT, _Alloc>::get_allocator; |
- using _Rope_rep_base<_CharT, _Alloc>::_M_get_allocator; |
- |
- _Rope_RopeRep(__detail::_Tag __t, int __d, bool __b, size_t __size, |
- const allocator_type& __a) |
- : _Rope_rep_base<_CharT, _Alloc>(__size, __a), |
-#ifndef __GC |
- _Refcount_Base(1), |
-#endif |
- _M_tag(__t), _M_is_balanced(__b), _M_depth(__d), _M_c_string(0) |
-#ifdef __GTHREAD_MUTEX_INIT |
- { |
- // Do not copy a POSIX/gthr mutex once in use. However, bits are bits. |
- __gthread_mutex_t __tmp = __GTHREAD_MUTEX_INIT; |
- _M_c_string_lock = __tmp; |
- } |
-#else |
- { __GTHREAD_MUTEX_INIT_FUNCTION (&_M_c_string_lock); } |
-#endif |
-#ifdef __GC |
- void |
- _M_incr () { } |
-#endif |
- static void |
- _S_free_string(__GC_CONST _CharT*, size_t __len, |
- allocator_type& __a); |
-#define __STL_FREE_STRING(__s, __l, __a) _S_free_string(__s, __l, __a); |
- // Deallocate data section of a leaf. |
- // This shouldn't be a member function. |
- // But its hard to do anything else at the |
- // moment, because it's templatized w.r.t. |
- // an allocator. |
- // Does nothing if __GC is defined. |
-#ifndef __GC |
- void _M_free_c_string(); |
- void _M_free_tree(); |
- // Deallocate t. Assumes t is not 0. |
- void |
- _M_unref_nonnil() |
- { |
- if (0 == _M_decr()) |
- _M_free_tree(); |
- } |
- |
- void |
- _M_ref_nonnil() |
- { _M_incr(); } |
- |
- static void |
- _S_unref(_Rope_RopeRep* __t) |
- { |
- if (0 != __t) |
- __t->_M_unref_nonnil(); |
- } |
- |
- static void |
- _S_ref(_Rope_RopeRep* __t) |
- { |
- if (0 != __t) |
- __t->_M_incr(); |
- } |
- |
- static void |
- _S_free_if_unref(_Rope_RopeRep* __t) |
- { |
- if (0 != __t && 0 == __t->_M_ref_count) |
- __t->_M_free_tree(); |
- } |
-# else /* __GC */ |
- void _M_unref_nonnil() { } |
- void _M_ref_nonnil() { } |
- static void _S_unref(_Rope_RopeRep*) { } |
- static void _S_ref(_Rope_RopeRep*) { } |
- static void _S_free_if_unref(_Rope_RopeRep*) { } |
-# endif |
-protected: |
- _Rope_RopeRep& |
- operator=(const _Rope_RopeRep&); |
- |
- _Rope_RopeRep(const _Rope_RopeRep&); |
- }; |
- |
- template<class _CharT, class _Alloc> |
- struct _Rope_RopeLeaf |
- : public _Rope_RopeRep<_CharT, _Alloc> |
- { |
- public: |
- // Apparently needed by VC++ |
- // The data fields of leaves are allocated with some |
- // extra space, to accommodate future growth and for basic |
- // character types, to hold a trailing eos character. |
- enum { _S_alloc_granularity = 8 }; |
- |
- static size_t |
- _S_rounded_up_size(size_t __n) |
- { |
- size_t __size_with_eos; |
- |
- if (_S_is_basic_char_type((_CharT*)0)) |
- __size_with_eos = __n + 1; |
- else |
- __size_with_eos = __n; |
-#ifdef __GC |
- return __size_with_eos; |
-#else |
- // Allow slop for in-place expansion. |
- return ((__size_with_eos + size_t(_S_alloc_granularity) - 1) |
- &~ (size_t(_S_alloc_granularity) - 1)); |
-#endif |
- } |
- __GC_CONST _CharT* _M_data; /* Not necessarily 0 terminated. */ |
- /* The allocated size is */ |
- /* _S_rounded_up_size(size), except */ |
- /* in the GC case, in which it */ |
- /* doesn't matter. */ |
- typedef typename _Rope_rep_base<_CharT,_Alloc>::allocator_type |
- allocator_type; |
- |
- _Rope_RopeLeaf(__GC_CONST _CharT* __d, size_t __size, |
- const allocator_type& __a) |
- : _Rope_RopeRep<_CharT, _Alloc>(__detail::_S_leaf, 0, true, |
- __size, __a), _M_data(__d) |
- { |
- if (_S_is_basic_char_type((_CharT *)0)) |
- { |
- // already eos terminated. |
- this->_M_c_string = __d; |
- } |
- } |
- // The constructor assumes that d has been allocated with |
- // the proper allocator and the properly padded size. |
- // In contrast, the destructor deallocates the data: |
-#ifndef __GC |
- ~_Rope_RopeLeaf() throw() |
- { |
- if (_M_data != this->_M_c_string) |
- this->_M_free_c_string(); |
- |
- __STL_FREE_STRING(_M_data, this->_M_size, this->_M_get_allocator()); |
- } |
-#endif |
-protected: |
- _Rope_RopeLeaf& |
- operator=(const _Rope_RopeLeaf&); |
- |
- _Rope_RopeLeaf(const _Rope_RopeLeaf&); |
- }; |
- |
- template<class _CharT, class _Alloc> |
- struct _Rope_RopeConcatenation |
- : public _Rope_RopeRep<_CharT, _Alloc> |
- { |
- public: |
- _Rope_RopeRep<_CharT, _Alloc>* _M_left; |
- _Rope_RopeRep<_CharT, _Alloc>* _M_right; |
- |
- typedef typename _Rope_rep_base<_CharT, _Alloc>::allocator_type |
- allocator_type; |
- |
- _Rope_RopeConcatenation(_Rope_RopeRep<_CharT, _Alloc>* __l, |
- _Rope_RopeRep<_CharT, _Alloc>* __r, |
- const allocator_type& __a) |
- : _Rope_RopeRep<_CharT, _Alloc>(__detail::_S_concat, |
- std::max(__l->_M_depth, |
- __r->_M_depth) + 1, |
- false, |
- __l->_M_size + __r->_M_size, __a), |
- _M_left(__l), _M_right(__r) |
- { } |
-#ifndef __GC |
- ~_Rope_RopeConcatenation() throw() |
- { |
- this->_M_free_c_string(); |
- _M_left->_M_unref_nonnil(); |
- _M_right->_M_unref_nonnil(); |
- } |
-#endif |
-protected: |
- _Rope_RopeConcatenation& |
- operator=(const _Rope_RopeConcatenation&); |
- |
- _Rope_RopeConcatenation(const _Rope_RopeConcatenation&); |
- }; |
- |
- template<class _CharT, class _Alloc> |
- struct _Rope_RopeFunction |
- : public _Rope_RopeRep<_CharT, _Alloc> |
- { |
- public: |
- char_producer<_CharT>* _M_fn; |
-#ifndef __GC |
- bool _M_delete_when_done; // Char_producer is owned by the |
- // rope and should be explicitly |
- // deleted when the rope becomes |
- // inaccessible. |
-#else |
- // In the GC case, we either register the rope for |
- // finalization, or not. Thus the field is unnecessary; |
- // the information is stored in the collector data structures. |
- // We do need a finalization procedure to be invoked by the |
- // collector. |
- static void |
- _S_fn_finalization_proc(void * __tree, void *) |
- { delete ((_Rope_RopeFunction *)__tree) -> _M_fn; } |
-#endif |
- typedef typename _Rope_rep_base<_CharT, _Alloc>::allocator_type |
- allocator_type; |
- |
- _Rope_RopeFunction(char_producer<_CharT>* __f, size_t __size, |
- bool __d, const allocator_type& __a) |
- : _Rope_RopeRep<_CharT, _Alloc>(__detail::_S_function, 0, true, __size, __a) |
- , _M_fn(__f) |
-#ifndef __GC |
- , _M_delete_when_done(__d) |
-#endif |
- { |
-#ifdef __GC |
- if (__d) |
- { |
- GC_REGISTER_FINALIZER(this, _Rope_RopeFunction:: |
- _S_fn_finalization_proc, 0, 0, 0); |
- } |
-#endif |
- } |
-#ifndef __GC |
- ~_Rope_RopeFunction() throw() |
- { |
- this->_M_free_c_string(); |
- if (_M_delete_when_done) |
- delete _M_fn; |
- } |
-# endif |
- protected: |
- _Rope_RopeFunction& |
- operator=(const _Rope_RopeFunction&); |
- |
- _Rope_RopeFunction(const _Rope_RopeFunction&); |
- }; |
- // Substring results are usually represented using just |
- // concatenation nodes. But in the case of very long flat ropes |
- // or ropes with a functional representation that isn't practical. |
- // In that case, we represent the __result as a special case of |
- // RopeFunction, whose char_producer points back to the rope itself. |
- // In all cases except repeated substring operations and |
- // deallocation, we treat the __result as a RopeFunction. |
- template<class _CharT, class _Alloc> |
- struct _Rope_RopeSubstring |
- : public _Rope_RopeFunction<_CharT, _Alloc>, |
- public char_producer<_CharT> |
- { |
- public: |
- // XXX this whole class should be rewritten. |
- _Rope_RopeRep<_CharT,_Alloc>* _M_base; // not 0 |
- size_t _M_start; |
- |
- virtual void |
- operator()(size_t __start_pos, size_t __req_len, |
- _CharT* __buffer) |
- { |
- switch(_M_base->_M_tag) |
- { |
- case __detail::_S_function: |
- case __detail::_S_substringfn: |
- { |
- char_producer<_CharT>* __fn = |
- ((_Rope_RopeFunction<_CharT,_Alloc>*)_M_base)->_M_fn; |
- (*__fn)(__start_pos + _M_start, __req_len, __buffer); |
- } |
- break; |
- case __detail::_S_leaf: |
- { |
- __GC_CONST _CharT* __s = |
- ((_Rope_RopeLeaf<_CharT,_Alloc>*)_M_base)->_M_data; |
- uninitialized_copy_n(__s + __start_pos + _M_start, __req_len, |
- __buffer); |
- } |
- break; |
- default: |
- break; |
- } |
- } |
- |
- typedef typename _Rope_rep_base<_CharT, _Alloc>::allocator_type |
- allocator_type; |
- |
- _Rope_RopeSubstring(_Rope_RopeRep<_CharT, _Alloc>* __b, size_t __s, |
- size_t __l, const allocator_type& __a) |
- : _Rope_RopeFunction<_CharT, _Alloc>(this, __l, false, __a), |
- char_producer<_CharT>(), _M_base(__b), _M_start(__s) |
- { |
-#ifndef __GC |
- _M_base->_M_ref_nonnil(); |
-#endif |
- this->_M_tag = __detail::_S_substringfn; |
- } |
- virtual ~_Rope_RopeSubstring() throw() |
- { |
-#ifndef __GC |
- _M_base->_M_unref_nonnil(); |
- // _M_free_c_string(); -- done by parent class |
-#endif |
- } |
- }; |
- |
- // Self-destructing pointers to Rope_rep. |
- // These are not conventional smart pointers. Their |
- // only purpose in life is to ensure that unref is called |
- // on the pointer either at normal exit or if an exception |
- // is raised. It is the caller's responsibility to |
- // adjust reference counts when these pointers are initialized |
- // or assigned to. (This convention significantly reduces |
- // the number of potentially expensive reference count |
- // updates.) |
-#ifndef __GC |
- template<class _CharT, class _Alloc> |
- struct _Rope_self_destruct_ptr |
- { |
- _Rope_RopeRep<_CharT, _Alloc>* _M_ptr; |
- |
- ~_Rope_self_destruct_ptr() |
- { _Rope_RopeRep<_CharT, _Alloc>::_S_unref(_M_ptr); } |
-#ifdef __EXCEPTIONS |
- _Rope_self_destruct_ptr() : _M_ptr(0) { }; |
-#else |
- _Rope_self_destruct_ptr() { }; |
-#endif |
- _Rope_self_destruct_ptr(_Rope_RopeRep<_CharT, _Alloc>* __p) |
- : _M_ptr(__p) { } |
- |
- _Rope_RopeRep<_CharT, _Alloc>& |
- operator*() |
- { return *_M_ptr; } |
- |
- _Rope_RopeRep<_CharT, _Alloc>* |
- operator->() |
- { return _M_ptr; } |
- |
- operator _Rope_RopeRep<_CharT, _Alloc>*() |
- { return _M_ptr; } |
- |
- _Rope_self_destruct_ptr& |
- operator=(_Rope_RopeRep<_CharT, _Alloc>* __x) |
- { _M_ptr = __x; return *this; } |
- }; |
-#endif |
- |
- // Dereferencing a nonconst iterator has to return something |
- // that behaves almost like a reference. It's not possible to |
- // return an actual reference since assignment requires extra |
- // work. And we would get into the same problems as with the |
- // CD2 version of basic_string. |
- template<class _CharT, class _Alloc> |
- class _Rope_char_ref_proxy |
- { |
- friend class rope<_CharT, _Alloc>; |
- friend class _Rope_iterator<_CharT, _Alloc>; |
- friend class _Rope_char_ptr_proxy<_CharT, _Alloc>; |
-#ifdef __GC |
- typedef _Rope_RopeRep<_CharT, _Alloc>* _Self_destruct_ptr; |
-#else |
- typedef _Rope_self_destruct_ptr<_CharT, _Alloc> _Self_destruct_ptr; |
-#endif |
- typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep; |
- typedef rope<_CharT, _Alloc> _My_rope; |
- size_t _M_pos; |
- _CharT _M_current; |
- bool _M_current_valid; |
- _My_rope* _M_root; // The whole rope. |
- public: |
- _Rope_char_ref_proxy(_My_rope* __r, size_t __p) |
- : _M_pos(__p), _M_current(), _M_current_valid(false), _M_root(__r) { } |
- |
- _Rope_char_ref_proxy(const _Rope_char_ref_proxy& __x) |
- : _M_pos(__x._M_pos), _M_current(__x._M_current), |
- _M_current_valid(false), _M_root(__x._M_root) { } |
- |
- // Don't preserve cache if the reference can outlive the |
- // expression. We claim that's not possible without calling |
- // a copy constructor or generating reference to a proxy |
- // reference. We declare the latter to have undefined semantics. |
- _Rope_char_ref_proxy(_My_rope* __r, size_t __p, _CharT __c) |
- : _M_pos(__p), _M_current(__c), _M_current_valid(true), _M_root(__r) { } |
- |
- inline operator _CharT () const; |
- |
- _Rope_char_ref_proxy& |
- operator=(_CharT __c); |
- |
- _Rope_char_ptr_proxy<_CharT, _Alloc> operator&() const; |
- |
- _Rope_char_ref_proxy& |
- operator=(const _Rope_char_ref_proxy& __c) |
- { return operator=((_CharT)__c); } |
- }; |
- |
- template<class _CharT, class __Alloc> |
- inline void |
- swap(_Rope_char_ref_proxy <_CharT, __Alloc > __a, |
- _Rope_char_ref_proxy <_CharT, __Alloc > __b) |
- { |
- _CharT __tmp = __a; |
- __a = __b; |
- __b = __tmp; |
- } |
- |
- template<class _CharT, class _Alloc> |
- class _Rope_char_ptr_proxy |
- { |
- // XXX this class should be rewritten. |
- friend class _Rope_char_ref_proxy<_CharT, _Alloc>; |
- size_t _M_pos; |
- rope<_CharT,_Alloc>* _M_root; // The whole rope. |
- public: |
- _Rope_char_ptr_proxy(const _Rope_char_ref_proxy<_CharT,_Alloc>& __x) |
- : _M_pos(__x._M_pos), _M_root(__x._M_root) { } |
- |
- _Rope_char_ptr_proxy(const _Rope_char_ptr_proxy& __x) |
- : _M_pos(__x._M_pos), _M_root(__x._M_root) { } |
- |
- _Rope_char_ptr_proxy() { } |
- |
- _Rope_char_ptr_proxy(_CharT* __x) |
- : _M_root(0), _M_pos(0) { } |
- |
- _Rope_char_ptr_proxy& |
- operator=(const _Rope_char_ptr_proxy& __x) |
- { |
- _M_pos = __x._M_pos; |
- _M_root = __x._M_root; |
- return *this; |
- } |
- |
- template<class _CharT2, class _Alloc2> |
- friend bool |
- operator==(const _Rope_char_ptr_proxy<_CharT2, _Alloc2>& __x, |
- const _Rope_char_ptr_proxy<_CharT2, _Alloc2>& __y); |
- |
- _Rope_char_ref_proxy<_CharT, _Alloc> operator*() const |
- { return _Rope_char_ref_proxy<_CharT, _Alloc>(_M_root, _M_pos); } |
- }; |
- |
- // Rope iterators: |
- // Unlike in the C version, we cache only part of the stack |
- // for rope iterators, since they must be efficiently copyable. |
- // When we run out of cache, we have to reconstruct the iterator |
- // value. |
- // Pointers from iterators are not included in reference counts. |
- // Iterators are assumed to be thread private. Ropes can |
- // be shared. |
- |
- template<class _CharT, class _Alloc> |
- class _Rope_iterator_base |
- : public std::iterator<std::random_access_iterator_tag, _CharT> |
- { |
- friend class rope<_CharT, _Alloc>; |
- public: |
- typedef _Alloc _allocator_type; // used in _Rope_rotate, VC++ workaround |
- typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep; |
- // Borland doesn't want this to be protected. |
- protected: |
- enum { _S_path_cache_len = 4 }; // Must be <= 9. |
- enum { _S_iterator_buf_len = 15 }; |
- size_t _M_current_pos; |
- _RopeRep* _M_root; // The whole rope. |
- size_t _M_leaf_pos; // Starting position for current leaf |
- __GC_CONST _CharT* _M_buf_start; |
- // Buffer possibly |
- // containing current char. |
- __GC_CONST _CharT* _M_buf_ptr; |
- // Pointer to current char in buffer. |
- // != 0 ==> buffer valid. |
- __GC_CONST _CharT* _M_buf_end; |
- // One past __last valid char in buffer. |
- // 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. |
- const _RopeRep* _M_path_end[_S_path_cache_len]; |
- int _M_leaf_index; // Last valid __pos in path_end; |
- // _M_path_end[0] ... _M_path_end[leaf_index-1] |
- // point to concatenation nodes. |
- unsigned char _M_path_directions; |
- // (path_directions >> __i) & 1 is 1 |
- // iff 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. |
- _CharT _M_tmp_buf[_S_iterator_buf_len]; |
- // 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. |
- static void _S_setbuf(_Rope_iterator_base& __x); |
- // Set buffer contents given |
- // path cache. |
- static void _S_setcache(_Rope_iterator_base& __x); |
- // Set buffer contents and |
- // path cache. |
- static void _S_setcache_for_incr(_Rope_iterator_base& __x); |
- // As above, but assumes path |
- // cache is valid for previous posn. |
- _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; } |
- |
- _Rope_iterator_base(const _Rope_iterator_base& __x) |
- { |
- if (0 != __x._M_buf_ptr) |
- *this = __x; |
- else |
- { |
- _M_current_pos = __x._M_current_pos; |
- _M_root = __x._M_root; |
- _M_buf_ptr = 0; |
- } |
- } |
- }; |
- |
- 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>; |
- protected: |
- typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep; |
- // The one from the base class may not be directly visible. |
- _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; |
- |
- public: |
- _Rope_const_iterator() { }; |
- |
- _Rope_const_iterator(const _Rope_const_iterator& __x) |
- : _Rope_iterator_base<_CharT,_Alloc>(__x) { } |
- |
- _Rope_const_iterator(const _Rope_iterator<_CharT,_Alloc>& __x); |
- |
- _Rope_const_iterator(const rope<_CharT, _Alloc>& __r, size_t __pos) |
- : _Rope_iterator_base<_CharT,_Alloc>(__r._M_tree_ptr, __pos) { } |
- |
- _Rope_const_iterator& |
- operator=(const _Rope_const_iterator& __x) |
- { |
- if (0 != __x._M_buf_ptr) |
- *(static_cast<_Rope_iterator_base<_CharT, _Alloc>*>(this)) = __x; |
- else |
- { |
- this->_M_current_pos = __x._M_current_pos; |
- this->_M_root = __x._M_root; |
- this->_M_buf_ptr = 0; |
- } |
- return(*this); |
- } |
- |
- reference |
- operator*() |
- { |
- if (0 == this->_M_buf_ptr) |
- _S_setcache(*this); |
- return *this->_M_buf_ptr; |
- } |
- |
- // Without this const version, Rope iterators do not meet the |
- // requirements of an Input Iterator. |
- reference |
- operator*() const |
- { |
- return *const_cast<_Rope_const_iterator&>(*this); |
- } |
- |
- _Rope_const_iterator& |
- operator++() |
- { |
- __GC_CONST _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; |
- } |
- |
- _Rope_const_iterator& |
- operator+=(ptrdiff_t __n) |
- { |
- if (__n >= 0) |
- this->_M_incr(__n); |
- else |
- this->_M_decr(-__n); |
- return *this; |
- } |
- |
- _Rope_const_iterator& |
- operator--() |
- { |
- this->_M_decr(1); |
- return *this; |
- } |
- |
- _Rope_const_iterator& |
- operator-=(ptrdiff_t __n) |
- { |
- if (__n >= 0) |
- this->_M_decr(__n); |
- else |
- this->_M_incr(-__n); |
- return *this; |
- } |
- |
- _Rope_const_iterator |
- 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? |
- } |
- |
- _Rope_const_iterator |
- 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); |
- } |
- |
- template<class _CharT2, class _Alloc2> |
- friend _Rope_const_iterator<_CharT2, _Alloc2> |
- operator-(const _Rope_const_iterator<_CharT2, _Alloc2>& __x, |
- ptrdiff_t __n); |
- |
- template<class _CharT2, class _Alloc2> |
- friend _Rope_const_iterator<_CharT2, _Alloc2> |
- operator+(const _Rope_const_iterator<_CharT2, _Alloc2>& __x, |
- ptrdiff_t __n); |
- |
- template<class _CharT2, class _Alloc2> |
- friend _Rope_const_iterator<_CharT2, _Alloc2> |
- operator+(ptrdiff_t __n, |
- const _Rope_const_iterator<_CharT2, _Alloc2>& __x); |
- |
- reference |
- operator[](size_t __n) |
- { return rope<_CharT, _Alloc>::_S_fetch(this->_M_root, |
- this->_M_current_pos + __n); } |
- |
- template<class _CharT2, class _Alloc2> |
- friend bool |
- operator==(const _Rope_const_iterator<_CharT2, _Alloc2>& __x, |
- const _Rope_const_iterator<_CharT2, _Alloc2>& __y); |
- |
- template<class _CharT2, class _Alloc2> |
- friend bool |
- operator<(const _Rope_const_iterator<_CharT2, _Alloc2>& __x, |
- const _Rope_const_iterator<_CharT2, _Alloc2>& __y); |
- |
- template<class _CharT2, class _Alloc2> |
- friend ptrdiff_t |
- operator-(const _Rope_const_iterator<_CharT2, _Alloc2>& __x, |
- const _Rope_const_iterator<_CharT2, _Alloc2>& __y); |
- }; |
- |
- template<class _CharT, class _Alloc> |
- class _Rope_iterator |
- : public _Rope_iterator_base<_CharT, _Alloc> |
- { |
- friend class rope<_CharT, _Alloc>; |
- protected: |
- typedef typename _Rope_iterator_base<_CharT, _Alloc>::_RopeRep _RopeRep; |
- 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) |
- : _Rope_iterator_base<_CharT, _Alloc>(__r->_M_tree_ptr, __pos), |
- _M_root_rope(__r) |
- { _RopeRep::_S_ref(this->_M_root); |
- if (!(__r -> empty())) |
- _S_setcache(*this); |
- } |
- |
- void _M_check(); |
- public: |
- typedef _Rope_char_ref_proxy<_CharT, _Alloc> reference; |
- typedef _Rope_char_ref_proxy<_CharT, _Alloc>* pointer; |
- |
- rope<_CharT, _Alloc>& |
- container() |
- { return *_M_root_rope; } |
- |
- _Rope_iterator() |
- { |
- this->_M_root = 0; // Needed for reference counting. |
- }; |
- |
- _Rope_iterator(const _Rope_iterator& __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); |
- |
- ~_Rope_iterator() |
- { _RopeRep::_S_unref(this->_M_root); } |
- |
- _Rope_iterator& |
- operator=(const _Rope_iterator& __x) |
- { |
- _RopeRep* __old = this->_M_root; |
- |
- _RopeRep::_S_ref(__x._M_root); |
- if (0 != __x._M_buf_ptr) |
- { |
- _M_root_rope = __x._M_root_rope; |
- *(static_cast<_Rope_iterator_base<_CharT, _Alloc>*>(this)) = __x; |
- } |
- else |
- { |
- this->_M_current_pos = __x._M_current_pos; |
- this->_M_root = __x._M_root; |
- _M_root_rope = __x._M_root_rope; |
- this->_M_buf_ptr = 0; |
- } |
- _RopeRep::_S_unref(__old); |
- return(*this); |
- } |
- |
- reference |
- operator*() |
- { |
- _M_check(); |
- if (0 == this->_M_buf_ptr) |
- return _Rope_char_ref_proxy<_CharT, _Alloc>(_M_root_rope, |
- this->_M_current_pos); |
- else |
- return _Rope_char_ref_proxy<_CharT, _Alloc>(_M_root_rope, |
- this->_M_current_pos, |
- *this->_M_buf_ptr); |
- } |
- |
- // See above comment. |
- reference |
- operator*() const |
- { |
- return *const_cast<_Rope_iterator&>(*this); |
- } |
- |
- _Rope_iterator& |
- operator++() |
- { |
- this->_M_incr(1); |
- return *this; |
- } |
- |
- _Rope_iterator& |
- operator+=(ptrdiff_t __n) |
- { |
- if (__n >= 0) |
- this->_M_incr(__n); |
- else |
- this->_M_decr(-__n); |
- return *this; |
- } |
- |
- _Rope_iterator& |
- operator--() |
- { |
- this->_M_decr(1); |
- return *this; |
- } |
- |
- _Rope_iterator& |
- operator-=(ptrdiff_t __n) |
- { |
- if (__n >= 0) |
- this->_M_decr(__n); |
- else |
- this->_M_incr(-__n); |
- return *this; |
- } |
- |
- _Rope_iterator |
- operator++(int) |
- { |
- size_t __old_pos = this->_M_current_pos; |
- this->_M_incr(1); |
- return _Rope_iterator<_CharT,_Alloc>(_M_root_rope, __old_pos); |
- } |
- |
- _Rope_iterator |
- operator--(int) |
- { |
- size_t __old_pos = this->_M_current_pos; |
- this->_M_decr(1); |
- return _Rope_iterator<_CharT,_Alloc>(_M_root_rope, __old_pos); |
- } |
- |
- reference |
- operator[](ptrdiff_t __n) |
- { return _Rope_char_ref_proxy<_CharT, _Alloc>(_M_root_rope, |
- this->_M_current_pos |
- + __n); } |
- |
- template<class _CharT2, class _Alloc2> |
- friend bool |
- operator==(const _Rope_iterator<_CharT2, _Alloc2>& __x, |
- const _Rope_iterator<_CharT2, _Alloc2>& __y); |
- |
- template<class _CharT2, class _Alloc2> |
- friend bool |
- operator<(const _Rope_iterator<_CharT2, _Alloc2>& __x, |
- const _Rope_iterator<_CharT2, _Alloc2>& __y); |
- |
- template<class _CharT2, class _Alloc2> |
- friend ptrdiff_t |
- operator-(const _Rope_iterator<_CharT2, _Alloc2>& __x, |
- const _Rope_iterator<_CharT2, _Alloc2>& __y); |
- |
- template<class _CharT2, class _Alloc2> |
- friend _Rope_iterator<_CharT2, _Alloc2> |
- operator-(const _Rope_iterator<_CharT2, _Alloc2>& __x, ptrdiff_t __n); |
- |
- template<class _CharT2, class _Alloc2> |
- friend _Rope_iterator<_CharT2, _Alloc2> |
- operator+(const _Rope_iterator<_CharT2, _Alloc2>& __x, ptrdiff_t __n); |
- |
- template<class _CharT2, class _Alloc2> |
- friend _Rope_iterator<_CharT2, _Alloc2> |
- operator+(ptrdiff_t __n, const _Rope_iterator<_CharT2, _Alloc2>& __x); |
- }; |
- |
- |
- template <class _CharT, class _Alloc> |
- struct _Rope_base |
- : public _Alloc |
- { |
- typedef _Alloc allocator_type; |
- |
- allocator_type |
- get_allocator() const |
- { return *static_cast<const _Alloc*>(this); } |
- |
- allocator_type& |
- _M_get_allocator() |
- { return *static_cast<_Alloc*>(this); } |
- |
- const allocator_type& |
- _M_get_allocator() const |
- { return *static_cast<const _Alloc*>(this); } |
- |
- typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep; |
- // The one in _Base may not be visible due to template rules. |
- |
- _Rope_base(_RopeRep* __t, const allocator_type&) |
- : _M_tree_ptr(__t) { } |
- |
- _Rope_base(const allocator_type&) { } |
- |
- // The only data member of a rope: |
- _RopeRep *_M_tree_ptr; |
- |
-#define __ROPE_DEFINE_ALLOC(_Tp, __name) \ |
- typedef typename \ |
- _Alloc::template rebind<_Tp>::other __name##Alloc; \ |
- static _Tp* __name##_allocate(size_t __n) \ |
- { return __name##Alloc().allocate(__n); } \ |
- static void __name##_deallocate(_Tp *__p, size_t __n) \ |
- { __name##Alloc().deallocate(__p, __n); } |
- __ROPE_DEFINE_ALLOCS(_Alloc) |
-#undef __ROPE_DEFINE_ALLOC |
- |
- protected: |
- _Rope_base& |
- operator=(const _Rope_base&); |
- |
- _Rope_base(const _Rope_base&); |
- }; |
- |
- /** |
- * This is an SGI extension. |
- * @ingroup SGIextensions |
- * @doctodo |
- */ |
- template <class _CharT, class _Alloc> |
- class rope : public _Rope_base<_CharT, _Alloc> |
- { |
- 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>; |
- |
- protected: |
- typedef _Rope_base<_CharT, _Alloc> _Base; |
- typedef typename _Base::allocator_type allocator_type; |
- using _Base::_M_tree_ptr; |
- using _Base::get_allocator; |
- using _Base::_M_get_allocator; |
- typedef __GC_CONST _CharT* _Cstrptr; |
- |
- static _CharT _S_empty_c_str[1]; |
- |
- static bool |
- _S_is0(_CharT __c) |
- { return __c == _S_eos((_CharT*)0); } |
- |
- enum { _S_copy_max = 23 }; |
- // For strings shorter than _S_copy_max, we copy to |
- // concatenate. |
- |
- typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep; |
- 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); |
- |
-#ifndef __GC |
- // 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); |
-#endif |
- |
- static bool |
- _S_apply_to_pieces(// should be template parameter |
- _Rope_char_consumer<_CharT>& __c, |
- const _RopeRep* __r, |
- size_t __begin, size_t __end); |
- // begin and end are assumed to be in range. |
- |
-#ifndef __GC |
- static void |
- _S_unref(_RopeRep* __t) |
- { _RopeRep::_S_unref(__t); } |
- |
- static void |
- _S_ref(_RopeRep* __t) |
- { _RopeRep::_S_ref(__t); } |
- |
-#else /* __GC */ |
- static void _S_unref(_RopeRep*) { } |
- static void _S_ref(_RopeRep*) { } |
-#endif |
- |
-#ifdef __GC |
- typedef _Rope_RopeRep<_CharT, _Alloc>* _Self_destruct_ptr; |
-#else |
- typedef _Rope_self_destruct_ptr<_CharT, _Alloc> _Self_destruct_ptr; |
-#endif |
- |
- // _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 |
- // relevant reference counts are 1. |
-#ifdef __GC |
- // We can't really do anything since refcounts are unavailable. |
- { return _S_concat_char_iter(__r, __iter, __slen); } |
-#else |
- ; |
-#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, this->_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) |
- { |
- _RopeLeaf* __space = typename _Base::_LAlloc(__a).allocate(1); |
- return new(__space) _RopeLeaf(__s, __size, __a); |
- } |
- |
- static _RopeConcatenation* |
- _S_new_RopeConcatenation(_RopeRep* __left, _RopeRep* __right, |
- allocator_type& __a) |
- { |
- _RopeConcatenation* __space = typename _Base::_CAlloc(__a).allocate(1); |
- return new(__space) _RopeConcatenation(__left, __right, __a); |
- } |
- |
- static _RopeFunction* |
- _S_new_RopeFunction(char_producer<_CharT>* __f, |
- size_t __size, bool __d, allocator_type& __a) |
- { |
- _RopeFunction* __space = typename _Base::_FAlloc(__a).allocate(1); |
- 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) |
- { |
- _RopeSubstring* __space = typename _Base::_SAlloc(__a).allocate(1); |
- return new(__space) _RopeSubstring(__b, __s, __l, __a); |
- } |
- |
- 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) |
- { |
- if (0 == __size) |
- return 0; |
- _CharT* __buf = __a.allocate(_S_rounded_up_size(__size)); |
- |
- __uninitialized_copy_n_a(__s, __size, __buf, __a); |
- _S_cond_store_eos(__buf[__size]); |
- __try |
- { return _S_new_RopeLeaf(__buf, __size, __a); } |
- __catch(...) |
- { |
- _RopeRep::__STL_FREE_STRING(__buf, __size, __a); |
- __throw_exception_again; |
- } |
- } |
- |
- // 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[__detail::_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 balanced 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 == this->_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(this->_M_tree_ptr, __y._M_tree_ptr); } |
- |
- rope(const _CharT* __s, const allocator_type& __a = allocator_type()) |
- : _Base(__a) |
- { |
- this->_M_tree_ptr = |
- __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, _S_char_ptr_len(__s), |
- _M_get_allocator()); |
- } |
- |
- rope(const _CharT* __s, size_t __len, |
- const allocator_type& __a = allocator_type()) |
- : _Base(__a) |
- { |
- this->_M_tree_ptr = |
- __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __len, _M_get_allocator()); |
- } |
- |
- // 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(__a) |
- { |
- this->_M_tree_ptr = |
- __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __e - __s, _M_get_allocator()); |
- } |
- |
- 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 = this->_Data_allocate(_S_rounded_up_size(1)); |
- |
- _M_get_allocator().construct(__buf, __c); |
- __try |
- { |
- this->_M_tree_ptr = _S_new_RopeLeaf(__buf, 1, |
- _M_get_allocator()); |
- } |
- __catch(...) |
- { |
- _RopeRep::__STL_FREE_STRING(__buf, 1, _M_get_allocator()); |
- __throw_exception_again; |
- } |
- } |
- |
- 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) |
- { |
- this->_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(this->_M_tree_ptr); } |
- |
- ~rope() throw() |
- { _S_unref(this->_M_tree_ptr); } |
- |
- rope& |
- operator=(const rope& __x) |
- { |
- _RopeRep* __old = this->_M_tree_ptr; |
- this->_M_tree_ptr = __x._M_tree_ptr; |
- _S_ref(this->_M_tree_ptr); |
- _S_unref(__old); |
- return *this; |
- } |
- |
- void |
- clear() |
- { |
- _S_unref(this->_M_tree_ptr); |
- this->_M_tree_ptr = 0; |
- } |
- |
- void |
- push_back(_CharT __x) |
- { |
- _RopeRep* __old = this->_M_tree_ptr; |
- this->_M_tree_ptr |
- = _S_destr_concat_char_iter(this->_M_tree_ptr, &__x, 1); |
- _S_unref(__old); |
- } |
- |
- void |
- pop_back() |
- { |
- _RopeRep* __old = this->_M_tree_ptr; |
- this->_M_tree_ptr = _S_substring(this->_M_tree_ptr, |
- 0, this->_M_tree_ptr->_M_size - 1); |
- _S_unref(__old); |
- } |
- |
- _CharT |
- back() const |
- { return _S_fetch(this->_M_tree_ptr, this->_M_tree_ptr->_M_size - 1); } |
- |
- void |
- push_front(_CharT __x) |
- { |
- _RopeRep* __old = this->_M_tree_ptr; |
- _RopeRep* __left = |
- __STL_ROPE_FROM_UNOWNED_CHAR_PTR(&__x, 1, _M_get_allocator()); |
- __try |
- { |
- this->_M_tree_ptr = _S_concat(__left, this->_M_tree_ptr); |
- _S_unref(__old); |
- _S_unref(__left); |
- } |
- __catch(...) |
- { |
- _S_unref(__left); |
- __throw_exception_again; |
- } |
- } |
- |
- void |
- pop_front() |
- { |
- _RopeRep* __old = this->_M_tree_ptr; |
- this->_M_tree_ptr |
- = _S_substring(this->_M_tree_ptr, 1, this->_M_tree_ptr->_M_size); |
- _S_unref(__old); |
- } |
- |
- _CharT |
- front() const |
- { return _S_fetch(this->_M_tree_ptr, 0); } |
- |
- void |
- balance() |
- { |
- _RopeRep* __old = this->_M_tree_ptr; |
- this->_M_tree_ptr = _S_balance(this->_M_tree_ptr); |
- _S_unref(__old); |
- } |
- |
- void |
- copy(_CharT* __buffer) const |
- { |
- _Destroy_const(__buffer, __buffer + size(), _M_get_allocator()); |
- _S_flatten(this->_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 guaranteed not to compile if the draft standard |
- // order is assumed. |
- size_type |
- copy(size_type __pos, size_type __n, _CharT* __buffer) const |
- { |
- size_t __size = size(); |
- size_t __len = (__pos + __n > __size? __size - __pos : __n); |
- |
- _Destroy_const(__buffer, __buffer + __len, _M_get_allocator()); |
- _S_flatten(this->_M_tree_ptr, __pos, __len, __buffer); |
- return __len; |
- } |
- |
- // Print to stdout, exposing structure. May be useful for |
- // performance debugging. |
- void |
- dump() |
- { _S_dump(this->_M_tree_ptr); } |
- |
- // Convert to 0 terminated string in new allocated memory. |
- // Embedded 0s in the input do not terminate the copy. |
- const _CharT* c_str() const; |
- |
- // As above, but also use the flattened representation as |
- // the new rope representation. |
- const _CharT* replace_with_c_str(); |
- |
- // Reclaim memory for the c_str generated flattened string. |
- // Intentionally undocumented, since it's hard to say when this |
- // is safe for multiple threads. |
- void |
- delete_c_str () |
- { |
- if (0 == this->_M_tree_ptr) |
- return; |
- if (__detail::_S_leaf == this->_M_tree_ptr->_M_tag && |
- ((_RopeLeaf*)this->_M_tree_ptr)->_M_data == |
- this->_M_tree_ptr->_M_c_string) |
- { |
- // Representation shared |
- return; |
- } |
-#ifndef __GC |
- this->_M_tree_ptr->_M_free_c_string(); |
-#endif |
- this->_M_tree_ptr->_M_c_string = 0; |
- } |
- |
- _CharT |
- operator[] (size_type __pos) const |
- { return _S_fetch(this->_M_tree_ptr, __pos); } |
- |
- _CharT |
- at(size_type __pos) const |
- { |
- // if (__pos >= size()) throw out_of_range; // XXX |
- return (*this)[__pos]; |
- } |
- |
- const_iterator |
- begin() const |
- { return(const_iterator(this->_M_tree_ptr, 0)); } |
- |
- // An easy way to get a const iterator from a non-const container. |
- const_iterator |
- const_begin() const |
- { return(const_iterator(this->_M_tree_ptr, 0)); } |
- |
- const_iterator |
- end() const |
- { return(const_iterator(this->_M_tree_ptr, size())); } |
- |
- const_iterator |
- const_end() const |
- { return(const_iterator(this->_M_tree_ptr, size())); } |
- |
- size_type |
- size() const |
- { return(0 == this->_M_tree_ptr? 0 : this->_M_tree_ptr->_M_size); } |
- |
- size_type |
- length() const |
- { return size(); } |
- |
- size_type |
- max_size() const |
- { |
- return _S_min_len[int(__detail::_S_max_rope_depth) - 1] - 1; |
- // Guarantees that the result can be sufficiently |
- // balanced. Longer ropes will probably still work, |
- // but it's harder to make guarantees. |
- } |
- |
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator; |
- |
- const_reverse_iterator |
- rbegin() const |
- { return const_reverse_iterator(end()); } |
- |
- const_reverse_iterator |
- const_rbegin() const |
- { return const_reverse_iterator(end()); } |
- |
- const_reverse_iterator |
- rend() const |
- { return const_reverse_iterator(begin()); } |
- |
- const_reverse_iterator |
- const_rend() const |
- { return const_reverse_iterator(begin()); } |
- |
- template<class _CharT2, class _Alloc2> |
- friend rope<_CharT2, _Alloc2> |
- operator+(const rope<_CharT2, _Alloc2>& __left, |
- const rope<_CharT2, _Alloc2>& __right); |
- |
- template<class _CharT2, class _Alloc2> |
- friend rope<_CharT2, _Alloc2> |
- operator+(const rope<_CharT2, _Alloc2>& __left, const _CharT2* __right); |
- |
- template<class _CharT2, class _Alloc2> |
- friend rope<_CharT2, _Alloc2> |
- operator+(const rope<_CharT2, _Alloc2>& __left, _CharT2 __right); |
- |
- // The symmetric cases are intentionally omitted, since they're |
- // presumed to be less common, and we don't handle them as well. |
- |
- // The following should really be templatized. The first |
- // argument should be an input iterator or forward iterator with |
- // value_type _CharT. |
- rope& |
- append(const _CharT* __iter, size_t __n) |
- { |
- _RopeRep* __result = |
- _S_destr_concat_char_iter(this->_M_tree_ptr, __iter, __n); |
- _S_unref(this->_M_tree_ptr); |
- this->_M_tree_ptr = __result; |
- return *this; |
- } |
- |
- rope& |
- append(const _CharT* __c_string) |
- { |
- size_t __len = _S_char_ptr_len(__c_string); |
- append(__c_string, __len); |
- return(*this); |
- } |
- |
- rope& |
- append(const _CharT* __s, const _CharT* __e) |
- { |
- _RopeRep* __result = |
- _S_destr_concat_char_iter(this->_M_tree_ptr, __s, __e - __s); |
- _S_unref(this->_M_tree_ptr); |
- this->_M_tree_ptr = __result; |
- return *this; |
- } |
- |
- rope& |
- append(const_iterator __s, const_iterator __e) |
- { |
- _Self_destruct_ptr __appendee(_S_substring(__s._M_root, |
- __s._M_current_pos, |
- __e._M_current_pos)); |
- _RopeRep* __result = _S_concat(this->_M_tree_ptr, |
- (_RopeRep*)__appendee); |
- _S_unref(this->_M_tree_ptr); |
- this->_M_tree_ptr = __result; |
- return *this; |
- } |
- |
- rope& |
- append(_CharT __c) |
- { |
- _RopeRep* __result = |
- _S_destr_concat_char_iter(this->_M_tree_ptr, &__c, 1); |
- _S_unref(this->_M_tree_ptr); |
- this->_M_tree_ptr = __result; |
- return *this; |
- } |
- |
- rope& |
- append() |
- { return append(_CharT()); } // XXX why? |
- |
- rope& |
- append(const rope& __y) |
- { |
- _RopeRep* __result = _S_concat(this->_M_tree_ptr, __y._M_tree_ptr); |
- _S_unref(this->_M_tree_ptr); |
- this->_M_tree_ptr = __result; |
- return *this; |
- } |
- |
- rope& |
- append(size_t __n, _CharT __c) |
- { |
- rope<_CharT,_Alloc> __last(__n, __c); |
- return append(__last); |
- } |
- |
- void |
- swap(rope& __b) |
- { |
- _RopeRep* __tmp = this->_M_tree_ptr; |
- this->_M_tree_ptr = __b._M_tree_ptr; |
- __b._M_tree_ptr = __tmp; |
- } |
- |
- protected: |
- // Result is included in refcount. |
- static _RopeRep* |
- replace(_RopeRep* __old, size_t __pos1, |
- size_t __pos2, _RopeRep* __r) |
- { |
- if (0 == __old) |
- { |
- _S_ref(__r); |
- return __r; |
- } |
- _Self_destruct_ptr __left(_S_substring(__old, 0, __pos1)); |
- _Self_destruct_ptr __right(_S_substring(__old, __pos2, __old->_M_size)); |
- _RopeRep* __result; |
- |
- if (0 == __r) |
- __result = _S_concat(__left, __right); |
- else |
- { |
- _Self_destruct_ptr __left_result(_S_concat(__left, __r)); |
- __result = _S_concat(__left_result, __right); |
- } |
- return __result; |
- } |
- |
- public: |
- void |
- insert(size_t __p, const rope& __r) |
- { |
- _RopeRep* __result = |
- replace(this->_M_tree_ptr, __p, __p, __r._M_tree_ptr); |
- _S_unref(this->_M_tree_ptr); |
- this->_M_tree_ptr = __result; |
- } |
- |
- void |
- insert(size_t __p, size_t __n, _CharT __c) |
- { |
- rope<_CharT,_Alloc> __r(__n,__c); |
- insert(__p, __r); |
- } |
- |
- void |
- insert(size_t __p, const _CharT* __i, size_t __n) |
- { |
- _Self_destruct_ptr __left(_S_substring(this->_M_tree_ptr, 0, __p)); |
- _Self_destruct_ptr __right(_S_substring(this->_M_tree_ptr, |
- __p, size())); |
- _Self_destruct_ptr __left_result(_S_concat_char_iter(__left, __i, __n)); |
- // _S_ destr_concat_char_iter should be safe here. |
- // But as it stands it's probably not a win, since __left |
- // is likely to have additional references. |
- _RopeRep* __result = _S_concat(__left_result, __right); |
- _S_unref(this->_M_tree_ptr); |
- this->_M_tree_ptr = __result; |
- } |
- |
- void |
- insert(size_t __p, const _CharT* __c_string) |
- { insert(__p, __c_string, _S_char_ptr_len(__c_string)); } |
- |
- void |
- insert(size_t __p, _CharT __c) |
- { insert(__p, &__c, 1); } |
- |
- void |
- insert(size_t __p) |
- { |
- _CharT __c = _CharT(); |
- insert(__p, &__c, 1); |
- } |
- |
- void |
- insert(size_t __p, const _CharT* __i, const _CharT* __j) |
- { |
- rope __r(__i, __j); |
- insert(__p, __r); |
- } |
- |
- void |
- insert(size_t __p, const const_iterator& __i, |
- const const_iterator& __j) |
- { |
- rope __r(__i, __j); |
- insert(__p, __r); |
- } |
- |
- void |
- insert(size_t __p, const iterator& __i, |
- const iterator& __j) |
- { |
- rope __r(__i, __j); |
- insert(__p, __r); |
- } |
- |
- // (position, length) versions of replace operations: |
- |
- void |
- replace(size_t __p, size_t __n, const rope& __r) |
- { |
- _RopeRep* __result = |
- replace(this->_M_tree_ptr, __p, __p + __n, __r._M_tree_ptr); |
- _S_unref(this->_M_tree_ptr); |
- this->_M_tree_ptr = __result; |
- } |
- |
- void |
- replace(size_t __p, size_t __n, |
- const _CharT* __i, size_t __i_len) |
- { |
- rope __r(__i, __i_len); |
- replace(__p, __n, __r); |
- } |
- |
- void |
- replace(size_t __p, size_t __n, _CharT __c) |
- { |
- rope __r(__c); |
- replace(__p, __n, __r); |
- } |
- |
- void |
- replace(size_t __p, size_t __n, const _CharT* __c_string) |
- { |
- rope __r(__c_string); |
- replace(__p, __n, __r); |
- } |
- |
- void |
- replace(size_t __p, size_t __n, |
- const _CharT* __i, const _CharT* __j) |
- { |
- rope __r(__i, __j); |
- replace(__p, __n, __r); |
- } |
- |
- void |
- replace(size_t __p, size_t __n, |
- const const_iterator& __i, const const_iterator& __j) |
- { |
- rope __r(__i, __j); |
- replace(__p, __n, __r); |
- } |
- |
- void |
- replace(size_t __p, size_t __n, |
- const iterator& __i, const iterator& __j) |
- { |
- rope __r(__i, __j); |
- replace(__p, __n, __r); |
- } |
- |
- // Single character variants: |
- void |
- replace(size_t __p, _CharT __c) |
- { |
- iterator __i(this, __p); |
- *__i = __c; |
- } |
- |
- void |
- replace(size_t __p, const rope& __r) |
- { replace(__p, 1, __r); } |
- |
- void |
- replace(size_t __p, const _CharT* __i, size_t __i_len) |
- { replace(__p, 1, __i, __i_len); } |
- |
- void |
- replace(size_t __p, const _CharT* __c_string) |
- { replace(__p, 1, __c_string); } |
- |
- void |
- replace(size_t __p, const _CharT* __i, const _CharT* __j) |
- { replace(__p, 1, __i, __j); } |
- |
- void |
- replace(size_t __p, const const_iterator& __i, |
- const const_iterator& __j) |
- { replace(__p, 1, __i, __j); } |
- |
- void |
- replace(size_t __p, const iterator& __i, |
- const iterator& __j) |
- { replace(__p, 1, __i, __j); } |
- |
- // Erase, (position, size) variant. |
- void |
- erase(size_t __p, size_t __n) |
- { |
- _RopeRep* __result = replace(this->_M_tree_ptr, __p, |
- __p + __n, 0); |
- _S_unref(this->_M_tree_ptr); |
- this->_M_tree_ptr = __result; |
- } |
- |
- // Erase, single character |
- void |
- erase(size_t __p) |
- { erase(__p, __p + 1); } |
- |
- // Insert, iterator variants. |
- iterator |
- insert(const iterator& __p, const rope& __r) |
- { |
- insert(__p.index(), __r); |
- return __p; |
- } |
- |
- iterator |
- insert(const iterator& __p, size_t __n, _CharT __c) |
- { |
- insert(__p.index(), __n, __c); |
- return __p; |
- } |
- |
- iterator insert(const iterator& __p, _CharT __c) |
- { |
- insert(__p.index(), __c); |
- return __p; |
- } |
- |
- iterator |
- insert(const iterator& __p ) |
- { |
- insert(__p.index()); |
- return __p; |
- } |
- |
- iterator |
- insert(const iterator& __p, const _CharT* c_string) |
- { |
- insert(__p.index(), c_string); |
- return __p; |
- } |
- |
- iterator |
- insert(const iterator& __p, const _CharT* __i, size_t __n) |
- { |
- insert(__p.index(), __i, __n); |
- return __p; |
- } |
- |
- iterator |
- insert(const iterator& __p, const _CharT* __i, |
- const _CharT* __j) |
- { |
- insert(__p.index(), __i, __j); |
- return __p; |
- } |
- |
- iterator |
- insert(const iterator& __p, |
- const const_iterator& __i, const const_iterator& __j) |
- { |
- insert(__p.index(), __i, __j); |
- return __p; |
- } |
- |
- iterator |
- insert(const iterator& __p, |
- const iterator& __i, const iterator& __j) |
- { |
- insert(__p.index(), __i, __j); |
- return __p; |
- } |
- |
- // Replace, range variants. |
- void |
- replace(const iterator& __p, const iterator& __q, const rope& __r) |
- { replace(__p.index(), __q.index() - __p.index(), __r); } |
- |
- void |
- replace(const iterator& __p, const iterator& __q, _CharT __c) |
- { replace(__p.index(), __q.index() - __p.index(), __c); } |
- |
- void |
- replace(const iterator& __p, const iterator& __q, |
- const _CharT* __c_string) |
- { replace(__p.index(), __q.index() - __p.index(), __c_string); } |
- |
- void |
- replace(const iterator& __p, const iterator& __q, |
- const _CharT* __i, size_t __n) |
- { replace(__p.index(), __q.index() - __p.index(), __i, __n); } |
- |
- void |
- replace(const iterator& __p, const iterator& __q, |
- const _CharT* __i, const _CharT* __j) |
- { replace(__p.index(), __q.index() - __p.index(), __i, __j); } |
- |
- void |
- replace(const iterator& __p, const iterator& __q, |
- const const_iterator& __i, const const_iterator& __j) |
- { replace(__p.index(), __q.index() - __p.index(), __i, __j); } |
- |
- void |
- replace(const iterator& __p, const iterator& __q, |
- const iterator& __i, const iterator& __j) |
- { replace(__p.index(), __q.index() - __p.index(), __i, __j); } |
- |
- // Replace, iterator variants. |
- void |
- replace(const iterator& __p, const rope& __r) |
- { replace(__p.index(), __r); } |
- |
- void |
- replace(const iterator& __p, _CharT __c) |
- { replace(__p.index(), __c); } |
- |
- void |
- replace(const iterator& __p, const _CharT* __c_string) |
- { replace(__p.index(), __c_string); } |
- |
- void |
- replace(const iterator& __p, const _CharT* __i, size_t __n) |
- { replace(__p.index(), __i, __n); } |
- |
- void |
- replace(const iterator& __p, const _CharT* __i, const _CharT* __j) |
- { replace(__p.index(), __i, __j); } |
- |
- void |
- replace(const iterator& __p, const_iterator __i, const_iterator __j) |
- { replace(__p.index(), __i, __j); } |
- |
- void |
- replace(const iterator& __p, iterator __i, iterator __j) |
- { replace(__p.index(), __i, __j); } |
- |
- // Iterator and range variants of erase |
- iterator |
- erase(const iterator& __p, const iterator& __q) |
- { |
- size_t __p_index = __p.index(); |
- erase(__p_index, __q.index() - __p_index); |
- return iterator(this, __p_index); |
- } |
- |
- iterator |
- erase(const iterator& __p) |
- { |
- size_t __p_index = __p.index(); |
- erase(__p_index, 1); |
- return iterator(this, __p_index); |
- } |
- |
- rope |
- substr(size_t __start, size_t __len = 1) const |
- { |
- return rope<_CharT, _Alloc>(_S_substring(this->_M_tree_ptr, |
- __start, |
- __start + __len)); |
- } |
- |
- rope |
- substr(iterator __start, iterator __end) const |
- { |
- return rope<_CharT, _Alloc>(_S_substring(this->_M_tree_ptr, |
- __start.index(), |
- __end.index())); |
- } |
- |
- rope |
- substr(iterator __start) const |
- { |
- size_t __pos = __start.index(); |
- return rope<_CharT, _Alloc>(_S_substring(this->_M_tree_ptr, |
- __pos, __pos + 1)); |
- } |
- |
- rope |
- substr(const_iterator __start, const_iterator __end) const |
- { |
- // This might eventually take advantage of the cache in the |
- // iterator. |
- return rope<_CharT, _Alloc>(_S_substring(this->_M_tree_ptr, |
- __start.index(), |
- __end.index())); |
- } |
- |
- rope<_CharT, _Alloc> |
- substr(const_iterator __start) |
- { |
- size_t __pos = __start.index(); |
- return rope<_CharT, _Alloc>(_S_substring(this->_M_tree_ptr, |
- __pos, __pos + 1)); |
- } |
- |
- static const size_type npos; |
- |
- size_type find(_CharT __c, size_type __pos = 0) const; |
- |
- size_type |
- find(const _CharT* __s, size_type __pos = 0) const |
- { |
- size_type __result_pos; |
- const_iterator __result = |
- std::search(const_begin() + __pos, const_end(), |
- __s, __s + _S_char_ptr_len(__s)); |
- __result_pos = __result.index(); |
-#ifndef __STL_OLD_ROPE_SEMANTICS |
- if (__result_pos == size()) |
- __result_pos = npos; |
-#endif |
- return __result_pos; |
- } |
- |
- iterator |
- mutable_begin() |
- { return(iterator(this, 0)); } |
- |
- iterator |
- mutable_end() |
- { return(iterator(this, size())); } |
- |
- typedef std::reverse_iterator<iterator> reverse_iterator; |
- |
- reverse_iterator |
- mutable_rbegin() |
- { return reverse_iterator(mutable_end()); } |
- |
- reverse_iterator |
- mutable_rend() |
- { return reverse_iterator(mutable_begin()); } |
- |
- reference |
- mutable_reference_at(size_type __pos) |
- { return reference(this, __pos); } |
- |
-#ifdef __STD_STUFF |
- reference |
- operator[] (size_type __pos) |
- { return _char_ref_proxy(this, __pos); } |
- |
- reference |
- at(size_type __pos) |
- { |
- // if (__pos >= size()) throw out_of_range; // XXX |
- return (*this)[__pos]; |
- } |
- |
- void resize(size_type __n, _CharT __c) { } |
- void resize(size_type __n) { } |
- void reserve(size_type __res_arg = 0) { } |
- |
- size_type |
- capacity() const |
- { return max_size(); } |
- |
- // Stuff below this line is dangerous because it's error prone. |
- // I would really like to get rid of it. |
- // copy function with funny arg ordering. |
- size_type |
- copy(_CharT* __buffer, size_type __n, |
- size_type __pos = 0) const |
- { return copy(__pos, __n, __buffer); } |
- |
- iterator |
- end() |
- { return mutable_end(); } |
- |
- iterator |
- begin() |
- { return mutable_begin(); } |
- |
- reverse_iterator |
- rend() |
- { return mutable_rend(); } |
- |
- reverse_iterator |
- rbegin() |
- { return mutable_rbegin(); } |
- |
-#else |
- const_iterator |
- end() |
- { return const_end(); } |
- |
- const_iterator |
- begin() |
- { return const_begin(); } |
- |
- const_reverse_iterator |
- rend() |
- { return const_rend(); } |
- |
- const_reverse_iterator |
- rbegin() |
- { return const_rbegin(); } |
- |
-#endif |
- }; |
- |
- template <class _CharT, class _Alloc> |
- const typename rope<_CharT, _Alloc>::size_type |
- rope<_CharT, _Alloc>::npos = (size_type)(-1); |
- |
- template <class _CharT, class _Alloc> |
- inline bool operator==(const _Rope_const_iterator<_CharT, _Alloc>& __x, |
- const _Rope_const_iterator<_CharT, _Alloc>& __y) |
- { return (__x._M_current_pos == __y._M_current_pos |
- && __x._M_root == __y._M_root); } |
- |
- template <class _CharT, class _Alloc> |
- inline bool operator<(const _Rope_const_iterator<_CharT, _Alloc>& __x, |
- const _Rope_const_iterator<_CharT, _Alloc>& __y) |
- { return (__x._M_current_pos < __y._M_current_pos); } |
- |
- template <class _CharT, class _Alloc> |
- inline bool operator!=(const _Rope_const_iterator<_CharT, _Alloc>& __x, |
- const _Rope_const_iterator<_CharT, _Alloc>& __y) |
- { return !(__x == __y); } |
- |
- template <class _CharT, class _Alloc> |
- inline bool operator>(const _Rope_const_iterator<_CharT, _Alloc>& __x, |
- const _Rope_const_iterator<_CharT, _Alloc>& __y) |
- { return __y < __x; } |
- |
- template <class _CharT, class _Alloc> |
- inline bool |
- operator<=(const _Rope_const_iterator<_CharT, _Alloc>& __x, |
- const _Rope_const_iterator<_CharT, _Alloc>& __y) |
- { return !(__y < __x); } |
- |
- template <class _CharT, class _Alloc> |
- inline bool |
- operator>=(const _Rope_const_iterator<_CharT, _Alloc>& __x, |
- const _Rope_const_iterator<_CharT, _Alloc>& __y) |
- { return !(__x < __y); } |
- |
- template <class _CharT, class _Alloc> |
- inline ptrdiff_t |
- operator-(const _Rope_const_iterator<_CharT, _Alloc>& __x, |
- const _Rope_const_iterator<_CharT, _Alloc>& __y) |
- { return (ptrdiff_t)__x._M_current_pos - (ptrdiff_t)__y._M_current_pos; } |
- |
- template <class _CharT, class _Alloc> |
- inline _Rope_const_iterator<_CharT, _Alloc> |
- operator-(const _Rope_const_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n) |
- { return _Rope_const_iterator<_CharT, _Alloc>(__x._M_root, |
- __x._M_current_pos - __n); } |
- |
- template <class _CharT, class _Alloc> |
- inline _Rope_const_iterator<_CharT, _Alloc> |
- operator+(const _Rope_const_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n) |
- { return _Rope_const_iterator<_CharT, _Alloc>(__x._M_root, |
- __x._M_current_pos + __n); } |
- |
- template <class _CharT, class _Alloc> |
- inline _Rope_const_iterator<_CharT, _Alloc> |
- operator+(ptrdiff_t __n, const _Rope_const_iterator<_CharT, _Alloc>& __x) |
- { return _Rope_const_iterator<_CharT, _Alloc>(__x._M_root, |
- __x._M_current_pos + __n); } |
- |
- template <class _CharT, class _Alloc> |
- inline bool |
- operator==(const _Rope_iterator<_CharT, _Alloc>& __x, |
- const _Rope_iterator<_CharT, _Alloc>& __y) |
- {return (__x._M_current_pos == __y._M_current_pos |
- && __x._M_root_rope == __y._M_root_rope); } |
- |
- template <class _CharT, class _Alloc> |
- inline bool |
- operator<(const _Rope_iterator<_CharT, _Alloc>& __x, |
- const _Rope_iterator<_CharT, _Alloc>& __y) |
- { return (__x._M_current_pos < __y._M_current_pos); } |
- |
- template <class _CharT, class _Alloc> |
- inline bool |
- operator!=(const _Rope_iterator<_CharT, _Alloc>& __x, |
- const _Rope_iterator<_CharT, _Alloc>& __y) |
- { return !(__x == __y); } |
- |
- template <class _CharT, class _Alloc> |
- inline bool |
- operator>(const _Rope_iterator<_CharT, _Alloc>& __x, |
- const _Rope_iterator<_CharT, _Alloc>& __y) |
- { return __y < __x; } |
- |
- template <class _CharT, class _Alloc> |
- inline bool |
- operator<=(const _Rope_iterator<_CharT, _Alloc>& __x, |
- const _Rope_iterator<_CharT, _Alloc>& __y) |
- { return !(__y < __x); } |
- |
- template <class _CharT, class _Alloc> |
- inline bool |
- operator>=(const _Rope_iterator<_CharT, _Alloc>& __x, |
- const _Rope_iterator<_CharT, _Alloc>& __y) |
- { return !(__x < __y); } |
- |
- template <class _CharT, class _Alloc> |
- inline ptrdiff_t |
- operator-(const _Rope_iterator<_CharT, _Alloc>& __x, |
- const _Rope_iterator<_CharT, _Alloc>& __y) |
- { return ((ptrdiff_t)__x._M_current_pos |
- - (ptrdiff_t)__y._M_current_pos); } |
- |
- template <class _CharT, class _Alloc> |
- inline _Rope_iterator<_CharT, _Alloc> |
- operator-(const _Rope_iterator<_CharT, _Alloc>& __x, |
- ptrdiff_t __n) |
- { return _Rope_iterator<_CharT, _Alloc>(__x._M_root_rope, |
- __x._M_current_pos - __n); } |
- |
- template <class _CharT, class _Alloc> |
- inline _Rope_iterator<_CharT, _Alloc> |
- operator+(const _Rope_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n) |
- { return _Rope_iterator<_CharT, _Alloc>(__x._M_root_rope, |
- __x._M_current_pos + __n); } |
- |
- template <class _CharT, class _Alloc> |
- inline _Rope_iterator<_CharT, _Alloc> |
- operator+(ptrdiff_t __n, const _Rope_iterator<_CharT, _Alloc>& __x) |
- { return _Rope_iterator<_CharT, _Alloc>(__x._M_root_rope, |
- __x._M_current_pos + __n); } |
- |
- template <class _CharT, class _Alloc> |
- inline rope<_CharT, _Alloc> |
- operator+(const rope<_CharT, _Alloc>& __left, |
- const rope<_CharT, _Alloc>& __right) |
- { |
- // Inlining this should make it possible to keep __left and |
- // __right in registers. |
- typedef rope<_CharT, _Alloc> rope_type; |
- return rope_type(rope_type::_S_concat(__left._M_tree_ptr, |
- __right._M_tree_ptr)); |
- } |
- |
- template <class _CharT, class _Alloc> |
- inline rope<_CharT, _Alloc>& |
- operator+=(rope<_CharT, _Alloc>& __left, |
- const rope<_CharT, _Alloc>& __right) |
- { |
- __left.append(__right); |
- return __left; |
- } |
- |
- template <class _CharT, class _Alloc> |
- inline rope<_CharT, _Alloc> |
- operator+(const rope<_CharT, _Alloc>& __left, |
- const _CharT* __right) |
- { |
- typedef rope<_CharT, _Alloc> rope_type; |
- size_t __rlen = rope_type::_S_char_ptr_len(__right); |
- return rope_type(rope_type::_S_concat_char_iter(__left._M_tree_ptr, |
- __right, __rlen)); |
- } |
- |
- template <class _CharT, class _Alloc> |
- inline rope<_CharT, _Alloc>& |
- operator+=(rope<_CharT, _Alloc>& __left, |
- const _CharT* __right) |
- { |
- __left.append(__right); |
- return __left; |
- } |
- |
- template <class _CharT, class _Alloc> |
- inline rope<_CharT, _Alloc> |
- operator+(const rope<_CharT, _Alloc>& __left, _CharT __right) |
- { |
- typedef rope<_CharT, _Alloc> rope_type; |
- return rope_type(rope_type::_S_concat_char_iter(__left._M_tree_ptr, |
- &__right, 1)); |
- } |
- |
- template <class _CharT, class _Alloc> |
- inline rope<_CharT, _Alloc>& |
- operator+=(rope<_CharT, _Alloc>& __left, _CharT __right) |
- { |
- __left.append(__right); |
- return __left; |
- } |
- |
- template <class _CharT, class _Alloc> |
- bool |
- operator<(const rope<_CharT, _Alloc>& __left, |
- const rope<_CharT, _Alloc>& __right) |
- { return __left.compare(__right) < 0; } |
- |
- template <class _CharT, class _Alloc> |
- bool |
- operator==(const rope<_CharT, _Alloc>& __left, |
- const rope<_CharT, _Alloc>& __right) |
- { return __left.compare(__right) == 0; } |
- |
- template <class _CharT, class _Alloc> |
- inline bool |
- operator==(const _Rope_char_ptr_proxy<_CharT, _Alloc>& __x, |
- const _Rope_char_ptr_proxy<_CharT, _Alloc>& __y) |
- { return (__x._M_pos == __y._M_pos && __x._M_root == __y._M_root); } |
- |
- template <class _CharT, class _Alloc> |
- inline bool |
- operator!=(const rope<_CharT, _Alloc>& __x, |
- const rope<_CharT, _Alloc>& __y) |
- { return !(__x == __y); } |
- |
- template <class _CharT, class _Alloc> |
- inline bool |
- operator>(const rope<_CharT, _Alloc>& __x, |
- const rope<_CharT, _Alloc>& __y) |
- { return __y < __x; } |
- |
- template <class _CharT, class _Alloc> |
- inline bool |
- operator<=(const rope<_CharT, _Alloc>& __x, |
- const rope<_CharT, _Alloc>& __y) |
- { return !(__y < __x); } |
- |
- template <class _CharT, class _Alloc> |
- inline bool |
- operator>=(const rope<_CharT, _Alloc>& __x, |
- const rope<_CharT, _Alloc>& __y) |
- { return !(__x < __y); } |
- |
- template <class _CharT, class _Alloc> |
- inline bool |
- operator!=(const _Rope_char_ptr_proxy<_CharT, _Alloc>& __x, |
- const _Rope_char_ptr_proxy<_CharT, _Alloc>& __y) |
- { return !(__x == __y); } |
- |
- template<class _CharT, class _Traits, class _Alloc> |
- std::basic_ostream<_CharT, _Traits>& |
- operator<<(std::basic_ostream<_CharT, _Traits>& __o, |
- const rope<_CharT, _Alloc>& __r); |
- |
- typedef rope<char> crope; |
- typedef rope<wchar_t> wrope; |
- |
- inline crope::reference |
- __mutable_reference_at(crope& __c, size_t __i) |
- { return __c.mutable_reference_at(__i); } |
- |
- inline wrope::reference |
- __mutable_reference_at(wrope& __c, size_t __i) |
- { return __c.mutable_reference_at(__i); } |
- |
- template <class _CharT, class _Alloc> |
- inline void |
- swap(rope<_CharT, _Alloc>& __x, rope<_CharT, _Alloc>& __y) |
- { __x.swap(__y); } |
- |
-_GLIBCXX_END_NAMESPACE |
- |
- |
-namespace std |
-{ |
-namespace tr1 |
-{ |
- template<> |
- struct hash<__gnu_cxx::crope> |
- { |
- size_t |
- operator()(const __gnu_cxx::crope& __str) const |
- { |
- size_t __size = __str.size(); |
- if (0 == __size) |
- return 0; |
- return 13 * __str[0] + 5 * __str[__size - 1] + __size; |
- } |
- }; |
- |
- |
- template<> |
- struct hash<__gnu_cxx::wrope> |
- { |
- size_t |
- operator()(const __gnu_cxx::wrope& __str) const |
- { |
- size_t __size = __str.size(); |
- if (0 == __size) |
- return 0; |
- return 13 * __str[0] + 5 * __str[__size - 1] + __size; |
- } |
- }; |
-} // namespace tr1 |
-} // namespace std |
- |
-# include <ext/ropeimpl.h> |
- |
-#endif |