_rope.h

00001 /*
00002  *
00003  * Copyright (c) 1996,1997
00004  * Silicon Graphics Computer Systems, Inc.
00005  *
00006  * Copyright (c) 1997
00007  * Moscow Center for SPARC Technology
00008  *
00009  * Copyright (c) 1999 
00010  * Boris Fomitchev
00011  *
00012  * This material is provided "as is", with absolutely no warranty expressed
00013  * or implied. Any use is at your own risk.
00014  *
00015  * Permission to use or copy this software for any purpose is hereby granted 
00016  * without fee, provided the above notices are retained on all copies.
00017  * Permission to modify the code and to distribute modified code is granted,
00018  * provided the above notices are retained, and a notice that the code was
00019  * modified is included with the above copyright notice.
00020  *
00021  */
00022 
00023 /* NOTE: This is an internal header file, included by other STL headers.
00024  *   You should not attempt to use it directly.
00025  */
00026 
00027 // rope<_CharT,_Alloc> is a sequence of _CharT.
00028 // Ropes appear to be mutable, but update operations
00029 // really copy enough of the data structure to leave the original
00030 // valid.  Thus ropes can be logically copied by just copying
00031 // a pointer value.
00032 
00033 #ifndef _STLP_INTERNAL_ROPE_H
00034 # define _STLP_INTERNAL_ROPE_H
00035 
00036 # ifndef _STLP_INTERNAL_ALGOBASE_H
00037 #  include <stl/_algobase.h>
00038 # endif
00039 
00040 # ifndef _STLP_IOSFWD
00041 #  include <iosfwd>
00042 # endif
00043 
00044 # ifndef _STLP_INTERNAL_ALLOC_H
00045 #  include <stl/_alloc.h>
00046 # endif
00047 
00048 # ifndef _STLP_INTERNAL_ITERATOR_H
00049 #  include <stl/_iterator.h>
00050 # endif
00051 
00052 # ifndef _STLP_INTERNAL_ALGO_H
00053 #  include <stl/_algo.h>
00054 # endif
00055 
00056 # ifndef _STLP_INTERNAL_FUNCTION_H
00057 #  include <stl/_function.h>
00058 # endif
00059 
00060 # ifndef _STLP_INTERNAL_NUMERIC_H
00061 #  include <stl/_numeric.h>
00062 # endif
00063 
00064 # ifndef _STLP_INTERNAL_HASH_FUN_H
00065 #  include <stl/_hash_fun.h>
00066 # endif
00067 
00068 # ifdef __GC
00069 #   define __GC_CONST const
00070 # else
00071 # include <stl/_threads.h>
00072 #   define __GC_CONST   // constant except for deallocation
00073 # endif
00074 # ifdef _STLP_SGI_THREADS
00075 #    include <mutex.h>
00076 # endif
00077 
00078 #ifdef _STLP_MEMBER_TEMPLATE_CLASSES 
00079 #  define _STLP_CREATE_ALLOCATOR(__atype,__a, _Tp) (_Alloc_traits<_Tp,__atype>::create_allocator(__a)) 
00080 #elif defined(__MRC__)||defined(__SC__) 
00081 #  define _STLP_CREATE_ALLOCATOR(__atype,__a, _Tp) __stl_alloc_create<_Tp,__atype>(__a,(_Tp*)0) 
00082 #else 
00083 #  define _STLP_CREATE_ALLOCATOR(__atype,__a, _Tp) __stl_alloc_create(__a,(_Tp*)0) 
00084 #endif 
00085 
00086 _STLP_BEGIN_NAMESPACE
00087 
00088 // First a lot of forward declarations.  The standard seems to require
00089 // much stricter "declaration before use" than many of the implementations
00090 // that preceded it.
00091 template<class _CharT, _STLP_DEFAULT_ALLOCATOR_SELECT(_CharT) > class rope;
00092 template<class _CharT, class _Alloc> struct _Rope_RopeConcatenation;
00093 template<class _CharT, class _Alloc> struct _Rope_RopeRep;
00094 template<class _CharT, class _Alloc> struct _Rope_RopeLeaf;
00095 template<class _CharT, class _Alloc> struct _Rope_RopeFunction;
00096 template<class _CharT, class _Alloc> struct _Rope_RopeSubstring;
00097 template<class _CharT, class _Alloc> class _Rope_iterator;
00098 template<class _CharT, class _Alloc> class _Rope_const_iterator;
00099 template<class _CharT, class _Alloc> class _Rope_char_ref_proxy;
00100 template<class _CharT, class _Alloc> class _Rope_char_ptr_proxy;
00101 
00102 // Some helpers, so we can use power on ropes.
00103 // See below for why this isn't local to the implementation.
00104 
00105 // This uses a nonstandard refcount convention.
00106 // The result has refcount 0.
00107 template<class _CharT, class _Alloc>
00108 struct _Rope_Concat_fn
00109   : public binary_function<rope<_CharT,_Alloc>, rope<_CharT,_Alloc>,
00110   rope<_CharT,_Alloc> > {
00111   rope<_CharT,_Alloc> operator() (const rope<_CharT,_Alloc>& __x,
00112                                   const rope<_CharT,_Alloc>& __y) {
00113     return __x + __y;
00114   }
00115 };
00116 
00117 template <class _CharT, class _Alloc>
00118 inline
00119 rope<_CharT,_Alloc>
00120 __identity_element(_Rope_Concat_fn<_CharT, _Alloc>)
00121 {
00122   return rope<_CharT,_Alloc>();
00123 }
00124 
00125 // The _S_eos function is used for those functions that
00126 // convert to/from C-like strings to detect the end of the string.
00127 
00128 // The end-of-C-string character.
00129 // This is what the draft standard says it should be.
00130 template <class _CharT>
00131 inline _CharT _S_eos(_CharT*) { return _CharT(); }
00132 
00133 // fbp : some compilers fail to zero-initialize builtins ;(
00134 inline const char _S_eos(const char*) { return 0; }
00135 # ifdef _STLP_HAS_WCHAR_T
00136 inline const wchar_t _S_eos(const wchar_t*) { return 0; }
00137 # endif
00138 
00139 // Test for basic character types.
00140 // For basic character types leaves having a trailing eos.
00141 template <class _CharT>
00142 inline bool _S_is_basic_char_type(_CharT*) { return false; }
00143 template <class _CharT>
00144 inline bool _S_is_one_byte_char_type(_CharT*) { return false; }
00145 
00146 inline bool _S_is_basic_char_type(char*) { return true; }
00147 inline bool _S_is_one_byte_char_type(char*) { return true; }
00148 # ifdef _STLP_HAS_WCHAR_T
00149 inline bool _S_is_basic_char_type(wchar_t*) { return true; }
00150 # endif
00151 
00152 // Store an eos iff _CharT is a basic character type.
00153 // Do not reference _S_eos if it isn't.
00154 template <class _CharT>
00155 inline void _S_cond_store_eos(_CharT&) {}
00156 
00157 inline void _S_cond_store_eos(char& __c) { __c = 0; }
00158 # ifdef _STLP_HAS_WCHAR_T
00159 inline void _S_cond_store_eos(wchar_t& __c) { __c = 0; }
00160 # endif
00161 
00162 // char_producers are logically functions that generate a section of
00163 // a string.  These can be convereted to ropes.  The resulting rope
00164 // invokes the char_producer on demand.  This allows, for example,
00165 // files to be viewed as ropes without reading the entire file.
00166 template <class _CharT>
00167 class char_producer {
00168 public:
00169   virtual ~char_producer() {};
00170   virtual void operator()(size_t __start_pos, size_t __len, 
00171                           _CharT* __buffer) = 0;
00172   // Buffer should really be an arbitrary output iterator.
00173   // That way we could flatten directly into an ostream, etc.
00174   // This is thoroughly impossible, since iterator types don't
00175   // have runtime descriptions.
00176 };
00177 
00178 // Sequence buffers:
00179 //
00180 // Sequence must provide an append operation that appends an
00181 // array to the sequence.  Sequence buffers are useful only if
00182 // appending an entire array is cheaper than appending element by element.
00183 // This is true for many string representations.
00184 // This should  perhaps inherit from ostream<sequence::value_type>
00185 // and be implemented correspondingly, so that they can be used
00186 // for formatted.  For the sake of portability, we don't do this yet.
00187 //
00188 // For now, sequence buffers behave as output iterators.  But they also
00189 // behave a little like basic_ostringstream<sequence::value_type> and a
00190 // little like containers.
00191 
00192 template<class _Sequence
00193 # if !(defined (_STLP_NON_TYPE_TMPL_PARAM_BUG) || \
00194        defined ( _STLP_NO_DEFAULT_NON_TYPE_PARAM ))
00195 , size_t _Buf_sz = 100
00196 #   if defined(__sgi) && !defined(__GNUC__)
00197 #        define __TYPEDEF_WORKAROUND
00198 ,class _V = typename _Sequence::value_type
00199 #   endif /* __sgi */
00200 # endif /* _STLP_NON_TYPE_TMPL_PARAM_BUG */
00201 >
00202 // The 3rd parameter works around a common compiler bug.
00203 class sequence_buffer : public iterator <output_iterator_tag, void, void, void, void> {
00204 public:
00205 #       ifndef __TYPEDEF_WORKAROUND
00206   typedef typename _Sequence::value_type value_type;
00207   typedef sequence_buffer<_Sequence
00208 # if !(defined (_STLP_NON_TYPE_TMPL_PARAM_BUG) || \
00209        defined ( _STLP_NO_DEFAULT_NON_TYPE_PARAM ))
00210   , _Buf_sz
00211   > _Self;
00212 # else /* _STLP_NON_TYPE_TMPL_PARAM_BUG */
00213   > _Self;
00214   enum { _Buf_sz = 100}; 
00215 # endif /* _STLP_NON_TYPE_TMPL_PARAM_BUG */
00216   // # endif
00217 #       else /* __TYPEDEF_WORKAROUND */
00218   typedef _V value_type;
00219   typedef sequence_buffer<_Sequence, _Buf_sz, _V> _Self;
00220 #       endif /* __TYPEDEF_WORKAROUND */
00221 protected:
00222   _Sequence* _M_prefix;
00223   value_type _M_buffer[_Buf_sz];
00224   size_t     _M_buf_count;
00225 public:
00226   void flush() {
00227     _M_prefix->append(_M_buffer, _M_buffer + _M_buf_count);
00228     _M_buf_count = 0;
00229   }
00230   ~sequence_buffer() { flush(); }
00231   sequence_buffer() : _M_prefix(0), _M_buf_count(0) {}
00232   sequence_buffer(const _Self& __x) {
00233     _M_prefix = __x._M_prefix;
00234     _M_buf_count = __x._M_buf_count;
00235     copy(__x._M_buffer, __x._M_buffer + __x._M_buf_count, _M_buffer);
00236   }
00237   sequence_buffer(_Self& __x) {
00238     __x.flush();
00239     _M_prefix = __x._M_prefix;
00240     _M_buf_count = 0;
00241   }
00242   sequence_buffer(_Sequence& __s) : _M_prefix(&__s), _M_buf_count(0) {}
00243   _Self& operator= (_Self& __x) {
00244     __x.flush();
00245     _M_prefix = __x._M_prefix;
00246     _M_buf_count = 0;
00247     return *this;
00248   }
00249   _Self& operator= (const _Self& __x) {
00250     _M_prefix = __x._M_prefix;
00251     _M_buf_count = __x._M_buf_count;
00252     copy(__x._M_buffer, __x._M_buffer + __x._M_buf_count, _M_buffer);
00253     return *this;
00254   }
00255   void push_back(value_type __x)
00256   {
00257     if (_M_buf_count < _Buf_sz) {
00258       _M_buffer[_M_buf_count] = __x;
00259       ++_M_buf_count;
00260     } else {
00261       flush();
00262       _M_buffer[0] = __x;
00263       _M_buf_count = 1;
00264     }
00265   }
00266   void append(value_type* __s, size_t __len)
00267   {
00268     if (__len + _M_buf_count <= _Buf_sz) {
00269       size_t __i = _M_buf_count;
00270       size_t __j = 0;
00271       for (; __j < __len; __i++, __j++) {
00272         _M_buffer[__i] = __s[__j];
00273       }
00274       _M_buf_count += __len;
00275     } else if (0 == _M_buf_count) {
00276       _M_prefix->append(__s, __s + __len);
00277     } else {
00278       flush();
00279       append(__s, __len);
00280     }
00281   }
00282   _Self& write(value_type* __s, size_t __len)
00283   {
00284     append(__s, __len);
00285     return *this;
00286   }
00287   _Self& put(value_type __x)
00288   {
00289     push_back(__x);
00290     return *this;
00291   }
00292   _Self& operator=(const value_type& __rhs)
00293   {
00294     push_back(__rhs);
00295     return *this;
00296   }
00297   _Self& operator*() { return *this; }
00298   _Self& operator++() { return *this; }
00299   _Self& operator++(int) { return *this; }
00300 };
00301 
00302 // The following should be treated as private, at least for now.
00303 template<class _CharT>
00304 class _Rope_char_consumer {
00305 public:
00306   // If we had member templates, these should not be virtual.
00307   // For now we need to use run-time parametrization where
00308   // compile-time would do.  _Hence this should all be private
00309   // for now.
00310   // The symmetry with char_producer is accidental and temporary.
00311   virtual ~_Rope_char_consumer() {};
00312   virtual bool operator()(const _CharT* __buffer, size_t __len) = 0;
00313 };
00314 
00315 //
00316 // What follows should really be local to rope.  Unfortunately,
00317 // that doesn't work, since it makes it impossible to define generic
00318 // equality on rope iterators.  According to the draft standard, the
00319 // template parameters for such an equality operator cannot be inferred
00320 // from the occurence of a member class as a parameter.
00321 // (SGI compilers in fact allow this, but the __result wouldn't be
00322 // portable.)
00323 // Similarly, some of the static member functions are member functions
00324 // only to avoid polluting the global namespace, and to circumvent
00325 // restrictions on type inference for template functions.
00326 //
00327 
00328 //
00329 // The internal data structure for representing a rope.  This is
00330 // private to the implementation.  A rope is really just a pointer
00331 // to one of these.
00332 //
00333 // A few basic functions for manipulating this data structure
00334 // are members of _RopeRep.  Most of the more complex algorithms
00335 // are implemented as rope members.
00336 //
00337 // Some of the static member functions of _RopeRep have identically
00338 // named functions in rope that simply invoke the _RopeRep versions.
00339 //
00340 // A macro to introduce various allocation and deallocation functions
00341 // These need to be defined differently depending on whether or not
00342 // we are using standard conforming allocators, and whether the allocator
00343 // instances have real state.  Thus this macro is invoked repeatedly
00344 // with different definitions of __ROPE_DEFINE_ALLOC.
00345 
00346 #if defined (_STLP_MEMBER_TEMPLATE_CLASSES)
00347 # define __ROPE_DEFINE_ALLOC(_Tp, __name, _M_proxy) \
00348         typedef typename \
00349           _Alloc_traits<_Tp,_Alloc>::allocator_type __name##Allocator;
00350 
00351 #define __ROPE_DEFINE_ALLOCS(__a, _M_proxy) \
00352         __ROPE_DEFINE_ALLOC(_CharT,_Data, _M_proxy) /* character data */ \
00353         typedef _Rope_RopeConcatenation<_CharT,__a> __C; \
00354         __ROPE_DEFINE_ALLOC(__C,_C, _M_proxy) \
00355         typedef _Rope_RopeLeaf<_CharT,__a> __L; \
00356         __ROPE_DEFINE_ALLOC(__L,_L, _M_proxy) \
00357         typedef _Rope_RopeFunction<_CharT,__a> __F; \
00358         __ROPE_DEFINE_ALLOC(__F,_F, _M_proxy) \
00359         typedef _Rope_RopeSubstring<_CharT,__a> __S; \
00360         __ROPE_DEFINE_ALLOC(__S,_S,_M_proxy)
00361 #else
00362 #define __ROPE_DEFINE_ALLOC(_Tp, __name, _M_proxy) 
00363 #define __ROPE_DEFINE_ALLOCS(__a, _M_proxy)
00364 #endif
00365 
00366 
00367 template<class _CharT, class _Alloc>
00368 struct _Rope_RopeRep
00369 # ifndef __GC
00370   : public _Refcount_Base
00371 # endif
00372 {
00373   typedef _Rope_RopeRep<_CharT, _Alloc> _Self;
00374 public:
00375 #  define __ROPE_MAX_DEPTH  45
00376 #  define __ROPE_DEPTH_SIZE 46
00377   enum { _S_max_rope_depth = __ROPE_MAX_DEPTH };
00378   enum _Tag {_S_leaf, _S_concat, _S_substringfn, _S_function};
00379   // Apparently needed by VC++
00380   // The data fields of leaves are allocated with some
00381   // extra space, to accomodate future growth and for basic
00382   // character types, to hold a trailing eos character.
00383   enum { _S_alloc_granularity = 8 };
00384 
00385   
00386   _Tag _M_tag:8;
00387   bool _M_is_balanced:8;
00388 
00389   _STLP_FORCE_ALLOCATORS(_CharT, _Alloc)
00390   typedef typename _Alloc_traits<_CharT,_Alloc>::allocator_type
00391   allocator_type;
00392   
00393   allocator_type get_allocator() const { return allocator_type(_M_size);  }
00394 
00395   unsigned char _M_depth;
00396   __GC_CONST _CharT* _M_c_string;
00397   _STLP_alloc_proxy<size_t, _CharT, allocator_type> _M_size;
00398 
00399 # ifdef _STLP_NO_ARROW_OPERATOR
00400   _Rope_RopeRep() : _Refcount_Base(1), _M_size(allocator_type(), 0) {}
00401 # endif
00402 
00403   /* Flattened version of string, if needed.  */
00404   /* typically 0.                             */
00405   /* If it's not 0, then the memory is owned  */
00406   /* by this node.                            */
00407   /* In the case of a leaf, this may point to */
00408   /* the same memory as the data field.       */
00409   _Rope_RopeRep(_Tag __t, int __d, bool __b, size_t _p_size,
00410                 allocator_type __a) :
00411 #         ifndef __GC
00412     _Refcount_Base(1),
00413 #         endif
00414     _M_tag(__t), _M_is_balanced(__b), _M_depth(__d), _M_c_string(0), _M_size(__a, _p_size)
00415   { }
00416 #   ifdef __GC
00417   void _M_incr () {}
00418 #   endif
00419 
00420   // fbp : moved from RopeLeaf
00421   static size_t _S_rounded_up_size(size_t __n) {
00422     size_t __size_with_eos;
00423     
00424     if (_S_is_basic_char_type((_CharT*)0)) {
00425       __size_with_eos = __n + 1;
00426     } else {
00427       __size_with_eos = __n;
00428     }
00429 #       ifdef __GC
00430     return __size_with_eos;
00431 #       else
00432     // Allow slop for in-place expansion.
00433     return (__size_with_eos + _S_alloc_granularity-1)
00434       &~ (_S_alloc_granularity-1);
00435 #       endif
00436   }
00437 
00438   static void _S_free_string(__GC_CONST _CharT* __s, size_t __len,
00439                              allocator_type __a) {
00440 
00441     if (!_S_is_basic_char_type((_CharT*)0)) {
00442       _Destroy(__s, __s + __len);
00443     }
00444     //  This has to be a static member, so this gets a bit messy
00445 #   ifdef _STLP_MEMBER_TEMPLATE_CLASSES
00446     __a.deallocate(__s, _S_rounded_up_size(__len));             //*ty 03/24/2001 - restored not to use __stl_alloc_rebind() since it is not defined under _STLP_MEMBER_TEMPLATE_CLASSES
00447 #   else
00448     __stl_alloc_rebind (__a, (_CharT*)0).deallocate(__s, _S_rounded_up_size(__len));
00449 #   endif
00450   }
00451   
00452   // Deallocate data section of a leaf.
00453   // This shouldn't be a member function.
00454   // But its hard to do anything else at the
00455   // moment, because it's templatized w.r.t.
00456   // an allocator.
00457   // Does nothing if __GC is defined.
00458 #   ifndef __GC
00459   void _M_free_c_string();
00460   void _M_free_tree();
00461   // Deallocate t. Assumes t is not 0.
00462   void _M_unref_nonnil()
00463   {
00464     _M_decr(); if (!_M_ref_count) _M_free_tree();
00465   }
00466   void _M_ref_nonnil()
00467   {
00468     _M_incr();
00469   }
00470   static void _S_unref(_Self* __t)
00471   {
00472     if (0 != __t) {
00473       __t->_M_unref_nonnil();
00474     }
00475   }
00476   static void _S_ref(_Self* __t)
00477   {
00478     if (0 != __t) __t->_M_incr();
00479   }
00480   static void _S_free_if_unref(_Self* __t)
00481   {
00482     if (0 != __t && 0 == __t->_M_ref_count) __t->_M_free_tree();
00483   }
00484 #   else /* __GC */
00485   void _M_unref_nonnil() {}
00486   void _M_ref_nonnil() {}
00487   static void _S_unref(_Self*) {}
00488   static void _S_ref(_Self*) {}
00489   static void _S_free_if_unref(_Self*) {}
00490 #   endif
00491 
00492   __ROPE_DEFINE_ALLOCS(_Alloc, _M_size)
00493     };
00494 
00495 template<class _CharT, class _Alloc>
00496 struct _Rope_RopeLeaf : public _Rope_RopeRep<_CharT,_Alloc> {
00497 public:
00498   __GC_CONST _CharT* _M_data; /* Not necessarily 0 terminated. */
00499                                 /* The allocated size is         */
00500                                 /* _S_rounded_up_size(size), except */
00501                                 /* in the GC case, in which it   */
00502                                 /* doesn't matter.               */
00503   _STLP_FORCE_ALLOCATORS(_CharT, _Alloc)
00504   typedef typename _Rope_RopeRep<_CharT,_Alloc>::allocator_type allocator_type;
00505   _Rope_RopeLeaf(__GC_CONST _CharT* __d, size_t _p_size, allocator_type __a)
00506     : _Rope_RopeRep<_CharT,_Alloc>(_Rope_RopeRep<_CharT,_Alloc>::_S_leaf, 0, true, _p_size, __a), 
00507     _M_data(__d)
00508   {
00509     _STLP_ASSERT(_p_size > 0)
00510     if (_S_is_basic_char_type((_CharT *)0)) {
00511       // already eos terminated.
00512       this->_M_c_string = __d;
00513     }
00514   }
00515 
00516 # ifdef _STLP_NO_ARROW_OPERATOR
00517   _Rope_RopeLeaf() {}
00518   _Rope_RopeLeaf(const _Rope_RopeLeaf<_CharT, _Alloc>& ) {}
00519 # endif
00520   
00521 // The constructor assumes that d has been allocated with
00522   // the proper allocator and the properly padded size.
00523   // In contrast, the destructor deallocates the data:
00524 # ifndef __GC
00525   ~_Rope_RopeLeaf() {
00526     if (_M_data != this->_M_c_string) {
00527       this->_M_free_c_string();
00528     }
00529     _S_free_string(_M_data, this->_M_size._M_data, this->get_allocator());
00530   }
00531 # endif
00532 };
00533 
00534 template<class _CharT, class _Alloc>
00535 struct _Rope_RopeConcatenation : public _Rope_RopeRep<_CharT,_Alloc> {
00536 public:
00537   _Rope_RopeRep<_CharT,_Alloc>* _M_left;
00538   _Rope_RopeRep<_CharT,_Alloc>* _M_right;
00539   _STLP_FORCE_ALLOCATORS(_CharT, _Alloc)
00540   typedef typename _Rope_RopeRep<_CharT,_Alloc>::allocator_type allocator_type;
00541   _Rope_RopeConcatenation(_Rope_RopeRep<_CharT,_Alloc>* __l,
00542                           _Rope_RopeRep<_CharT,_Alloc>* __r,
00543                           allocator_type __a)
00544     :   _Rope_RopeRep<_CharT,_Alloc>(
00545                                      _Rope_RopeRep<_CharT,_Alloc>::_S_concat, 
00546                                      (max)(__l->_M_depth, __r->_M_depth) + 1, false,
00547                                      __l->_M_size._M_data + __r->_M_size._M_data, __a), _M_left(__l), _M_right(__r)
00548   {}
00549 # ifdef _STLP_NO_ARROW_OPERATOR
00550   _Rope_RopeConcatenation() {}
00551   _Rope_RopeConcatenation(const _Rope_RopeConcatenation<_CharT, _Alloc>&) {}
00552 # endif
00553 
00554 # ifndef __GC
00555   ~_Rope_RopeConcatenation() {
00556     this->_M_free_c_string();
00557     _M_left->_M_unref_nonnil();
00558     _M_right->_M_unref_nonnil();
00559   }
00560 # endif
00561 };
00562 
00563 template<class _CharT, class _Alloc>
00564 struct _Rope_RopeFunction : public _Rope_RopeRep<_CharT,_Alloc> {
00565 public:
00566   char_producer<_CharT>* _M_fn;
00567 #   ifndef __GC
00568   bool _M_delete_when_done; // Char_producer is owned by the
00569                                 // rope and should be explicitly
00570                                 // deleted when the rope becomes
00571                                 // inaccessible.
00572 #   else
00573   // In the GC case, we either register the rope for
00574   // finalization, or not.  Thus the field is unnecessary;
00575   // the information is stored in the collector data structures.
00576   // We do need a finalization procedure to be invoked by the
00577   // collector.
00578   static void _S_fn_finalization_proc(void * __tree, void *) {
00579     delete ((_Rope_RopeFunction *)__tree) -> _M_fn;
00580   }
00581 #   endif
00582   _STLP_FORCE_ALLOCATORS(_CharT, _Alloc)
00583   typedef typename _Rope_RopeRep<_CharT,_Alloc>::allocator_type allocator_type;
00584 # ifdef _STLP_NO_ARROW_OPERATOR
00585   _Rope_RopeFunction() {}
00586   _Rope_RopeFunction(const _Rope_RopeFunction<_CharT, _Alloc>& ) {}
00587 # endif
00588 
00589   _Rope_RopeFunction(char_producer<_CharT>* __f, size_t _p_size,
00590                      bool __d, allocator_type __a)
00591     :
00592     _Rope_RopeRep<_CharT,_Alloc>(_Rope_RopeRep<_CharT,_Alloc>::_S_function, 0, true, _p_size, __a),
00593     _M_fn(__f)
00594 #       ifndef __GC
00595     , _M_delete_when_done(__d)
00596 #       endif
00597   {
00598     _STLP_ASSERT(_p_size > 0)
00599 #       ifdef __GC
00600     if (__d) {
00601       GC_REGISTER_FINALIZER(
00602                             this, _Rope_RopeFunction::_S_fn_finalization_proc, 0, 0, 0);
00603     }
00604 #       endif
00605   }
00606 # ifndef __GC
00607   ~_Rope_RopeFunction() {
00608     this->_M_free_c_string();
00609     if (_M_delete_when_done) {
00610       delete _M_fn;
00611     }
00612   }
00613 # endif
00614 };
00615 // Substring results are usually represented using just
00616 // concatenation nodes.  But in the case of very long flat ropes
00617 // or ropes with a functional representation that isn't practical.
00618 // In that case, we represent the __result as a special case of
00619 // RopeFunction, whose char_producer points back to the rope itself.
00620 // In all cases except repeated substring operations and
00621 // deallocation, we treat the __result as a RopeFunction.
00622 template<class _CharT, class _Alloc>
00623 # if  ( defined (__IBMCPP__) && (__IBMCPP__ == 500) )  // JFA 10-Aug-2000 for some reason xlC cares about the order
00624 struct _Rope_RopeSubstring : public char_producer<_CharT> , public _Rope_RopeFunction<_CharT,_Alloc>
00625 # else
00626 struct _Rope_RopeSubstring : public _Rope_RopeFunction<_CharT,_Alloc>,
00627                              public char_producer<_CharT>
00628 # endif
00629 {
00630 public:
00631   // XXX this whole class should be rewritten.
00632   typedef _Rope_RopeRep<_CharT,_Alloc> _Base;
00633   _Rope_RopeRep<_CharT,_Alloc>* _M_base;      // not 0
00634   size_t _M_start;
00635   virtual void operator()(size_t __start_pos, size_t __req_len,
00636                           _CharT* __buffer) {
00637     switch(_M_base->_M_tag) {
00638     case _Base::_S_function:
00639     case _Base::_S_substringfn:
00640       {
00641         char_producer<_CharT>* __fn =
00642           ((_Rope_RopeFunction<_CharT,_Alloc>*)_M_base)->_M_fn;
00643         _STLP_ASSERT(__start_pos + __req_len <= this->_M_size._M_data)
00644         _STLP_ASSERT(_M_start + this->_M_size._M_data <= _M_base->_M_size._M_data)
00645         (*__fn)(__start_pos + _M_start, __req_len, __buffer);
00646       }
00647       break;
00648     case _Base::_S_leaf:
00649       {
00650         __GC_CONST _CharT* __s =
00651           ((_Rope_RopeLeaf<_CharT,_Alloc>*)_M_base)->_M_data;
00652         uninitialized_copy_n(__s + __start_pos + _M_start, __req_len,
00653                              __buffer);
00654       }
00655       break;
00656     default:
00657       _STLP_ASSERT(false)
00658         ;
00659     }
00660   }
00661 
00662   _STLP_FORCE_ALLOCATORS(_CharT, _Alloc)
00663   typedef typename _Rope_RopeRep<_CharT,_Alloc>::allocator_type allocator_type;
00664 
00665   _Rope_RopeSubstring(_Rope_RopeRep<_CharT,_Alloc>* __b, size_t __s,
00666                       size_t __l, allocator_type __a)
00667     : _Rope_RopeFunction<_CharT,_Alloc>(this, __l, false, __a),
00668         _M_base(__b),
00669     _M_start(__s)
00670        
00671   {
00672     _STLP_ASSERT(__l > 0)
00673     _STLP_ASSERT(__s + __l <= __b->_M_size._M_data)
00674 #       ifndef __GC
00675     _M_base->_M_ref_nonnil();
00676 #       endif
00677     this->_M_tag = _Base::_S_substringfn;
00678   }
00679   virtual ~_Rope_RopeSubstring()
00680   { 
00681 #       ifndef __GC
00682     _M_base->_M_unref_nonnil();
00683 #       endif
00684   }
00685 };
00686 
00687 // Self-destructing pointers to Rope_rep.
00688 // These are not conventional smart pointers.  Their
00689 // only purpose in life is to ensure that unref is called
00690 // on the pointer either at normal exit or if an exception
00691 // is raised.  It is the caller's responsibility to
00692 // adjust reference counts when these pointers are initialized
00693 // or assigned to.  (This convention significantly reduces
00694 // the number of potentially expensive reference count
00695 // updates.)
00696 #ifndef __GC
00697 template<class _CharT, class _Alloc>
00698 struct _Rope_self_destruct_ptr {
00699   _Rope_RopeRep<_CharT,_Alloc>* _M_ptr;
00700   ~_Rope_self_destruct_ptr() 
00701   { _Rope_RopeRep<_CharT,_Alloc>::_S_unref(_M_ptr); }
00702 #   ifdef _STLP_USE_EXCEPTIONS
00703   _Rope_self_destruct_ptr() : _M_ptr(0) {};
00704 #   else
00705   _Rope_self_destruct_ptr() {};
00706 #   endif
00707   _Rope_self_destruct_ptr(_Rope_RopeRep<_CharT,_Alloc>* __p) : _M_ptr(__p) {}
00708   _Rope_RopeRep<_CharT,_Alloc>& operator*() { return *_M_ptr; }
00709   _Rope_RopeRep<_CharT,_Alloc>* operator->() { return _M_ptr; }
00710   operator _Rope_RopeRep<_CharT,_Alloc>*() { return _M_ptr; }
00711   _Rope_self_destruct_ptr<_CharT, _Alloc>& 
00712   operator= (_Rope_RopeRep<_CharT,_Alloc>* __x)
00713   { _M_ptr = __x; return *this; }
00714 };
00715 #endif
00716 
00717 // Dereferencing a nonconst iterator has to return something
00718 // that behaves almost like a reference.  It's not possible to
00719 // return an actual reference since assignment requires extra
00720 // work.  And we would get into the same problems as with the
00721 // CD2 version of basic_string.
00722 template<class _CharT, class _Alloc>
00723 class _Rope_char_ref_proxy {
00724   typedef _Rope_char_ref_proxy<_CharT, _Alloc> _Self;
00725   friend class rope<_CharT,_Alloc>;
00726   friend class _Rope_iterator<_CharT,_Alloc>;
00727   friend class _Rope_char_ptr_proxy<_CharT,_Alloc>;
00728 #   ifdef __GC
00729   typedef _Rope_RopeRep<_CharT,_Alloc>* _Self_destruct_ptr;
00730 #   else
00731   typedef _Rope_self_destruct_ptr<_CharT,_Alloc> _Self_destruct_ptr;
00732 #   endif
00733   typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep;
00734   typedef rope<_CharT,_Alloc> _My_rope;
00735   size_t _M_pos;
00736   _CharT _M_current;
00737   bool _M_current_valid;
00738   _My_rope* _M_root;     // The whole rope.
00739 public:
00740   _Rope_char_ref_proxy(_My_rope* __r, size_t __p) :
00741     _M_pos(__p), _M_current_valid(false), _M_root(__r) {}
00742   _Rope_char_ref_proxy(const _Self& __x) :
00743     _M_pos(__x._M_pos), _M_current_valid(false), _M_root(__x._M_root) {}
00744   // Don't preserve cache if the reference can outlive the
00745   // expression.  We claim that's not possible without calling
00746   // a copy constructor or generating reference to a proxy
00747   // reference.  We declare the latter to have undefined semantics.
00748   _Rope_char_ref_proxy(_My_rope* __r, size_t __p,
00749                        _CharT __c) :
00750     _M_pos(__p), _M_current(__c), _M_current_valid(true), _M_root(__r) {}
00751   inline operator _CharT () const;
00752   _Self& operator= (_CharT __c);
00753   _Rope_char_ptr_proxy<_CharT, _Alloc> operator& () const;
00754   _Self& operator= (const _Self& __c) {
00755     return operator=((_CharT)__c); 
00756   }
00757 };
00758 
00759 #ifdef _STLP_FUNCTION_TMPL_PARTIAL_ORDER
00760 template<class _CharT, class __Alloc>
00761 inline void swap(_Rope_char_ref_proxy <_CharT, __Alloc > __a,
00762                  _Rope_char_ref_proxy <_CharT, __Alloc > __b) {
00763   _CharT __tmp = __a;
00764   __a = __b;
00765   __b = __tmp;
00766 }
00767 #else
00768 // There is no really acceptable way to handle this.  The default
00769 // definition of swap doesn't work for proxy references.
00770 // It can't really be made to work, even with ugly hacks, since
00771 // the only unusual operation it uses is the copy constructor, which
00772 // is needed for other purposes.  We provide a macro for
00773 // full specializations, and instantiate the most common case.
00774 # define _ROPE_SWAP_SPECIALIZATION(_CharT, __Alloc) \
00775     inline void swap(_Rope_char_ref_proxy <_CharT, __Alloc > __a, \
00776                      _Rope_char_ref_proxy <_CharT, __Alloc > __b) { \
00777         _CharT __tmp = __a; \
00778         __a = __b; \
00779         __b = __tmp; \
00780     }
00781 
00782 _ROPE_SWAP_SPECIALIZATION(char,_STLP_DEFAULT_ALLOCATOR(char) )
00783 
00784 #endif /* !_STLP_FUNCTION_TMPL_PARTIAL_ORDER */
00785 
00786   template<class _CharT, class _Alloc>
00787 class _Rope_char_ptr_proxy {
00788   // XXX this class should be rewritten.
00789 public:
00790   typedef _Rope_char_ptr_proxy<_CharT, _Alloc> _Self;
00791   friend class _Rope_char_ref_proxy<_CharT,_Alloc>;
00792   size_t _M_pos;
00793   rope<_CharT,_Alloc>* _M_root;     // The whole rope.
00794 
00795   _Rope_char_ptr_proxy(const _Rope_char_ref_proxy<_CharT,_Alloc>& __x) 
00796     : _M_pos(__x._M_pos), _M_root(__x._M_root) {}
00797   _Rope_char_ptr_proxy(const _Self& __x)
00798     : _M_pos(__x._M_pos), _M_root(__x._M_root) {}
00799   _Rope_char_ptr_proxy() {}
00800   _Rope_char_ptr_proxy(_CharT* __x) : _M_pos(0), _M_root(0) {
00801     _STLP_ASSERT(0 == __x)
00802   }
00803   _Self& 
00804   operator= (const _Self& __x) {
00805     _M_pos = __x._M_pos;
00806     _M_root = __x._M_root;
00807     return *this;
00808   }
00809 
00810   _Rope_char_ref_proxy<_CharT,_Alloc> operator*() const {
00811     return _Rope_char_ref_proxy<_CharT,_Alloc>(_M_root, _M_pos);
00812   }
00813 };
00814 
00815 
00816 // Rope iterators:
00817 // Unlike in the C version, we cache only part of the stack
00818 // for rope iterators, since they must be efficiently copyable.
00819 // When we run out of cache, we have to reconstruct the iterator
00820 // value.
00821 // Pointers from iterators are not included in reference counts.
00822 // Iterators are assumed to be thread private.  Ropes can
00823 // be shared.
00824 
00825 template<class _CharT, class _Alloc>
00826 class _Rope_iterator_base
00827 /*   : public random_access_iterator<_CharT, ptrdiff_t>  */
00828 {
00829   friend class rope<_CharT,_Alloc>;
00830   typedef _Rope_iterator_base<_CharT, _Alloc> _Self;
00831 public:
00832   typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep;
00833   // Borland doesnt want this to be protected.
00834   //  protected:
00835   enum { _S_path_cache_len = 4 }; // Must be <= 9.
00836   enum { _S_iterator_buf_len = 15 };
00837   size_t _M_current_pos;
00838   _RopeRep* _M_root;     // The whole rope.
00839   size_t _M_leaf_pos;    // Starting position for current leaf
00840   __GC_CONST _CharT* _M_buf_start;
00841   // Buffer possibly
00842   // containing current char.
00843   __GC_CONST _CharT* _M_buf_ptr;
00844   // Pointer to current char in buffer.
00845   // != 0 ==> buffer valid.
00846   __GC_CONST _CharT* _M_buf_end;
00847   // One past __last valid char in buffer.
00848   // What follows is the path cache.  We go out of our
00849   // way to make this compact.
00850   // Path_end contains the bottom section of the path from
00851   // the root to the current leaf.
00852   const _RopeRep* _M_path_end[_S_path_cache_len];
00853   int _M_leaf_index;     // Last valid __pos in path_end;
00854   // _M_path_end[0] ... _M_path_end[leaf_index-1]
00855   // point to concatenation nodes.
00856   unsigned char _M_path_directions;
00857   // (path_directions >> __i) & 1 is 1
00858   // iff we got from _M_path_end[leaf_index - __i - 1]
00859   // to _M_path_end[leaf_index - __i] by going to the
00860   // __right. Assumes path_cache_len <= 9.
00861   _CharT _M_tmp_buf[_S_iterator_buf_len];
00862   // Short buffer for surrounding chars.
00863   // This is useful primarily for 
00864   // RopeFunctions.  We put the buffer
00865   // here to avoid locking in the
00866   // multithreaded case.
00867   // The cached path is generally assumed to be valid
00868   // only if the buffer is valid.
00869   static void _S_setbuf(_Rope_iterator_base<_CharT, _Alloc>& __x);
00870   // Set buffer contents given
00871   // path cache.
00872   static void _S_setcache(_Rope_iterator_base<_CharT, _Alloc>& __x);
00873   // Set buffer contents and
00874   // path cache.
00875   static void _S_setcache_for_incr(_Rope_iterator_base<_CharT, _Alloc>& __x);
00876   // As above, but assumes path
00877   // cache is valid for previous posn.
00878   _Rope_iterator_base() {}
00879   _Rope_iterator_base(_RopeRep* __root, size_t __pos)
00880     : _M_current_pos(__pos),_M_root(__root),  _M_buf_ptr(0) {}
00881   void _M_incr(size_t __n);
00882   void _M_decr(size_t __n);
00883 public:
00884   size_t index() const { return _M_current_pos; }
00885   _Rope_iterator_base(const _Self& __x) {
00886     if (0 != __x._M_buf_ptr) {
00887       *this = __x;
00888     } else {
00889       _M_current_pos = __x._M_current_pos;
00890       _M_root = __x._M_root;
00891       _M_buf_ptr = 0;
00892     }
00893   }
00894 };
00895 
00896 template<class _CharT, class _Alloc> class _Rope_iterator;
00897 
00898 template<class _CharT, class _Alloc>
00899 class _Rope_const_iterator : public _Rope_iterator_base<_CharT,_Alloc> {
00900   friend class rope<_CharT,_Alloc>;
00901   typedef  _Rope_const_iterator<_CharT, _Alloc> _Self;
00902   typedef _Rope_iterator_base<_CharT,_Alloc> _Base;
00903   //  protected:
00904 public:
00905 #   ifndef _STLP_HAS_NO_NAMESPACES
00906   typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep;
00907   // The one from the base class may not be directly visible.
00908 #   endif
00909   _Rope_const_iterator(const _RopeRep* __root, size_t __pos):
00910     _Rope_iterator_base<_CharT,_Alloc>(
00911                                        __CONST_CAST(_RopeRep*,__root), __pos)
00912     // Only nonconst iterators modify root ref count
00913   {}
00914 public:
00915   typedef _CharT reference;   // Really a value.  Returning a reference
00916                                 // Would be a mess, since it would have
00917                                 // to be included in refcount.
00918   typedef const _CharT* pointer;
00919   typedef _CharT value_type;
00920   typedef ptrdiff_t difference_type;
00921   typedef random_access_iterator_tag iterator_category;
00922 
00923 public:
00924   _Rope_const_iterator() {};
00925   _Rope_const_iterator(const _Self& __x) :
00926     _Rope_iterator_base<_CharT,_Alloc>(__x) { }
00927   _Rope_const_iterator(const _Rope_iterator<_CharT,_Alloc>& __x): 
00928     _Rope_iterator_base<_CharT,_Alloc>(__x) {}
00929   _Rope_const_iterator(const rope<_CharT,_Alloc>& __r, size_t __pos) :
00930     _Rope_iterator_base<_CharT,_Alloc>(__r._M_tree_ptr._M_data, __pos) {}
00931   _Self& operator= (const _Self& __x) {
00932     if (0 != __x._M_buf_ptr) {
00933       *(__STATIC_CAST(_Base*,this)) = __x;
00934     } else {
00935       this->_M_current_pos = __x._M_current_pos;
00936       this->_M_root = __x._M_root;
00937       this->_M_buf_ptr = 0;
00938     }
00939     return(*this);
00940   }
00941   reference operator*() {
00942     if (0 == this->_M_buf_ptr) _S_setcache(*this);
00943     return *(this->_M_buf_ptr);
00944   }
00945   _Self& operator++() {
00946     __GC_CONST _CharT* __next;
00947     if (0 != this->_M_buf_ptr && (__next = this->_M_buf_ptr + 1) < this->_M_buf_end) {
00948       this->_M_buf_ptr = __next;
00949       ++this->_M_current_pos;
00950     } else {
00951       this->_M_incr(1);
00952     }
00953     return *this;
00954   }
00955   _Self& operator+=(ptrdiff_t __n) {
00956     if (__n >= 0) {
00957       this->_M_incr(__n);
00958     } else {
00959       this->_M_decr(-__n);
00960     }
00961     return *this;
00962   }
00963   _Self& operator--() {
00964     this->_M_decr(1);
00965     return *this;
00966   }
00967   _Self& operator-=(ptrdiff_t __n) {
00968     if (__n >= 0) {
00969       this->_M_decr(__n);
00970     } else {
00971       this->_M_incr(-__n);
00972     }
00973     return *this;
00974   }
00975   _Self operator++(int) {
00976     size_t __old_pos = this->_M_current_pos;
00977     this->_M_incr(1);
00978     return _Rope_const_iterator<_CharT,_Alloc>(this->_M_root, __old_pos);
00979     // This makes a subsequent dereference expensive.
00980     // Perhaps we should instead copy the iterator
00981     // if it has a valid cache?
00982   }
00983   _Self operator--(int) {
00984     size_t __old_pos = this->_M_current_pos;
00985     this->_M_decr(1);
00986     return _Rope_const_iterator<_CharT,_Alloc>(this->_M_root, __old_pos);
00987   }
00988   inline reference operator[](size_t __n);
00989 };
00990 
00991 template<class _CharT, class _Alloc>
00992 class _Rope_iterator : public _Rope_iterator_base<_CharT,_Alloc> {
00993   friend class rope<_CharT,_Alloc>;
00994   typedef _Rope_iterator<_CharT, _Alloc> _Self;
00995   typedef _Rope_iterator_base<_CharT,_Alloc> _Base;
00996   typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep;
00997   //  protected:
00998 public:
00999   rope<_CharT,_Alloc>* _M_root_rope;
01000   // root is treated as a cached version of this,
01001   // and is used to detect changes to the underlying
01002   // rope.
01003   // Root is included in the reference count.
01004   // This is necessary so that we can detect changes reliably.
01005   // Unfortunately, it requires careful bookkeeping for the
01006   // nonGC case.
01007   _Rope_iterator(rope<_CharT,_Alloc>* __r, size_t __pos);
01008   
01009   void _M_check();
01010 public:
01011   typedef _Rope_char_ref_proxy<_CharT,_Alloc>  reference;
01012   typedef _Rope_char_ref_proxy<_CharT,_Alloc>* pointer;
01013   typedef _CharT value_type;
01014   typedef ptrdiff_t difference_type;
01015   typedef random_access_iterator_tag iterator_category;
01016 public:
01017   ~_Rope_iterator()             //*TY 5/6/00 - added dtor to balance reference count
01018   {
01019     _RopeRep::_S_unref(this->_M_root);
01020   }
01021   
01022   rope<_CharT,_Alloc>& container() { return *_M_root_rope; }
01023   _Rope_iterator() {
01024     this->_M_root = 0;  // Needed for reference counting.
01025   };
01026   _Rope_iterator(const  _Self& __x) :
01027     _Rope_iterator_base<_CharT,_Alloc>(__x) {
01028     _M_root_rope = __x._M_root_rope;
01029     _RopeRep::_S_ref(this->_M_root);
01030   }
01031   _Rope_iterator(rope<_CharT,_Alloc>& __r, size_t __pos);
01032   _Self& operator= (const  _Self& __x) {
01033     _RopeRep* __old = this->_M_root;
01034     
01035     _RopeRep::_S_ref(__x._M_root);
01036     if (0 != __x._M_buf_ptr) {
01037       _M_root_rope = __x._M_root_rope;
01038       *(__STATIC_CAST(_Base*,this)) = __x;
01039     } else {
01040       this->_M_current_pos = __x._M_current_pos;
01041       this->_M_root = __x._M_root;
01042       _M_root_rope = __x._M_root_rope;
01043       this->_M_buf_ptr = 0;
01044     }
01045     _RopeRep::_S_unref(__old);
01046     return(*this);
01047   }
01048   reference operator*() {
01049     _M_check();
01050     if (0 == this->_M_buf_ptr) {
01051       return _Rope_char_ref_proxy<_CharT,_Alloc>(
01052                                                  _M_root_rope, this->_M_current_pos);
01053     } else {
01054       return _Rope_char_ref_proxy<_CharT,_Alloc>(
01055                                                  _M_root_rope, this->_M_current_pos, *(this->_M_buf_ptr));
01056     }
01057   }
01058   _Self& operator++() {
01059     this->_M_incr(1);
01060     return *this;
01061   }
01062   _Self& operator+=(ptrdiff_t __n) {
01063     if (__n >= 0) {
01064       this->_M_incr(__n);
01065     } else {
01066       this->_M_decr(-__n);
01067     }
01068     return *this;
01069   }
01070   _Self& operator--() {
01071     this->_M_decr(1);
01072     return *this;
01073   }
01074   _Self& operator-=(ptrdiff_t __n) {
01075     if (__n >= 0) {
01076       this->_M_decr(__n);
01077     } else {
01078       this->_M_incr(-__n);
01079     }
01080     return *this;
01081   }
01082   _Self operator++(int) {
01083     size_t __old_pos = this->_M_current_pos;
01084     this->_M_incr(1);
01085     return _Rope_iterator<_CharT,_Alloc>(_M_root_rope, __old_pos);
01086   }
01087   _Self operator--(int) {
01088     size_t __old_pos = this->_M_current_pos;
01089     this->_M_decr(1);
01090     return _Rope_iterator<_CharT,_Alloc>(_M_root_rope, __old_pos);
01091   }
01092   reference operator[](ptrdiff_t __n) {
01093     return _Rope_char_ref_proxy<_CharT,_Alloc>(
01094                                                _M_root_rope, this->_M_current_pos + __n);
01095   }
01096 };
01097 
01098 # ifdef _STLP_USE_OLD_HP_ITERATOR_QUERIES
01099 template <class _CharT, class _Alloc>
01100 inline random_access_iterator_tag
01101 iterator_category(const _Rope_iterator<_CharT,_Alloc>&) {  return random_access_iterator_tag();}
01102 template <class _CharT, class _Alloc>
01103 inline _CharT* value_type(const _Rope_iterator<_CharT,_Alloc>&) { return 0; }
01104 template <class _CharT, class _Alloc>
01105 inline ptrdiff_t* distance_type(const _Rope_iterator<_CharT,_Alloc>&) { return 0; }
01106 template <class _CharT, class _Alloc>
01107 inline random_access_iterator_tag
01108 iterator_category(const _Rope_const_iterator<_CharT,_Alloc>&) { return random_access_iterator_tag(); }
01109 template <class _CharT, class _Alloc>
01110 inline _CharT* value_type(const _Rope_const_iterator<_CharT,_Alloc>&) { return 0; }
01111 template <class _CharT, class _Alloc>
01112 inline ptrdiff_t* distance_type(const _Rope_const_iterator<_CharT,_Alloc>&) { return 0; }
01113 #endif
01114 
01115 template <class _CharT, class _Alloc>
01116 class rope {
01117   typedef rope<_CharT,_Alloc> _Self;
01118 public:
01119   typedef _CharT value_type;
01120   typedef ptrdiff_t difference_type;
01121   typedef size_t size_type;
01122   typedef _CharT const_reference;
01123   typedef const _CharT* const_pointer;
01124   typedef _Rope_iterator<_CharT,_Alloc> iterator;
01125   typedef _Rope_const_iterator<_CharT,_Alloc> const_iterator;
01126   typedef _Rope_char_ref_proxy<_CharT,_Alloc> reference;
01127   typedef _Rope_char_ptr_proxy<_CharT,_Alloc> pointer;
01128   
01129   friend class _Rope_iterator<_CharT,_Alloc>;
01130   friend class _Rope_const_iterator<_CharT,_Alloc>;
01131   friend struct _Rope_RopeRep<_CharT,_Alloc>;
01132   friend class _Rope_iterator_base<_CharT,_Alloc>;
01133   friend class _Rope_char_ptr_proxy<_CharT,_Alloc>;
01134   friend class _Rope_char_ref_proxy<_CharT,_Alloc>;
01135   friend struct _Rope_RopeSubstring<_CharT,_Alloc>;
01136 
01137   _STLP_DECLARE_RANDOM_ACCESS_REVERSE_ITERATORS;
01138   
01139 protected:
01140   typedef __GC_CONST _CharT* _Cstrptr;
01141   
01142   static _CharT _S_empty_c_str[1];
01143   
01144   static bool _S_is0(_CharT __c) { return __c == _S_eos((_CharT*)0); }
01145   enum { _S_copy_max = 23 };
01146   // For strings shorter than _S_copy_max, we copy to
01147   // concatenate.
01148   
01149 public:
01150   typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep;
01151   _STLP_FORCE_ALLOCATORS(_CharT, _Alloc)
01152   typedef typename _Alloc_traits<_CharT,_Alloc>::allocator_type  allocator_type;
01153   allocator_type get_allocator() const { return allocator_type(_M_tree_ptr); }
01154 public:
01155   // The only data member of a rope:
01156   _STLP_alloc_proxy<_RopeRep*, _CharT, allocator_type> _M_tree_ptr;
01157 
01158   typedef _Rope_RopeConcatenation<_CharT,_Alloc> _RopeConcatenation;
01159   typedef _Rope_RopeLeaf<_CharT,_Alloc> _RopeLeaf;
01160   typedef _Rope_RopeFunction<_CharT,_Alloc> _RopeFunction;
01161   typedef _Rope_RopeSubstring<_CharT,_Alloc> _RopeSubstring;
01162 
01163 
01164 
01165   // Retrieve a character at the indicated position.
01166   static _CharT _S_fetch(_RopeRep* __r, size_type __pos);
01167 
01168 #       ifndef __GC
01169   // Obtain a pointer to the character at the indicated position.
01170   // The pointer can be used to change the character.
01171   // If such a pointer cannot be produced, as is frequently the
01172   // case, 0 is returned instead.
01173   // (Returns nonzero only if all nodes in the path have a refcount
01174   // of 1.)
01175   static _CharT* _S_fetch_ptr(_RopeRep* __r, size_type __pos);
01176 #       endif
01177 
01178   static bool _S_apply_to_pieces(
01179                                 // should be template parameter
01180                                  _Rope_char_consumer<_CharT>& __c,
01181                                  const _RopeRep* __r,
01182                                  size_t __begin, size_t __end);
01183                                 // begin and end are assumed to be in range.
01184 
01185 #       ifndef __GC
01186   static void _S_unref(_RopeRep* __t)
01187   {
01188     _RopeRep::_S_unref(__t);
01189   }
01190   static void _S_ref(_RopeRep* __t)
01191   {
01192     _RopeRep::_S_ref(__t);
01193   }
01194 #       else /* __GC */
01195   static void _S_unref(_RopeRep*) {}
01196   static void _S_ref(_RopeRep*) {}
01197 #       endif
01198 
01199 
01200 #       ifdef __GC
01201   typedef _Rope_RopeRep<_CharT,_Alloc>* _Self_destruct_ptr;
01202 #       else
01203   typedef _Rope_self_destruct_ptr<_CharT,_Alloc> _Self_destruct_ptr;
01204 #       endif
01205 
01206   // _Result is counted in refcount.
01207   static _RopeRep* _S_substring(_RopeRep* __base,
01208                                 size_t __start, size_t __endp1);
01209 
01210   static _RopeRep* _S_concat_char_iter(_RopeRep* __r,
01211                                        const _CharT* __iter, size_t __slen);
01212   // Concatenate rope and char ptr, copying __s.
01213   // Should really take an arbitrary iterator.
01214   // Result is counted in refcount.
01215   static _RopeRep* _S_destr_concat_char_iter(_RopeRep* __r,
01216                                              const _CharT* __iter, size_t __slen)
01217     // As above, but one reference to __r is about to be
01218     // destroyed.  Thus the pieces may be recycled if all
01219     // relevent reference counts are 1.
01220 #           ifdef __GC
01221     // We can't really do anything since refcounts are unavailable.
01222   { return _S_concat_char_iter(__r, __iter, __slen); }
01223 #           else
01224   ;
01225 #           endif
01226 
01227   static _RopeRep* _S_concat_rep(_RopeRep* __left, _RopeRep* __right);
01228   // General concatenation on _RopeRep.  _Result
01229   // has refcount of 1.  Adjusts argument refcounts.
01230 
01231 public:
01232   void apply_to_pieces( size_t __begin, size_t __end,
01233                         _Rope_char_consumer<_CharT>& __c) const {
01234     _S_apply_to_pieces(__c, _M_tree_ptr._M_data, __begin, __end);
01235   }
01236 
01237 
01238 protected:
01239 
01240   static size_t _S_rounded_up_size(size_t __n) {
01241     return _RopeRep::_S_rounded_up_size(__n);
01242   }
01243 
01244   static size_t _S_allocated_capacity(size_t __n) {
01245     if (_S_is_basic_char_type((_CharT*)0)) {
01246       return _S_rounded_up_size(__n) - 1;
01247     } else {
01248       return _S_rounded_up_size(__n);
01249     }
01250   }
01251                 
01252   // Allocate and construct a RopeLeaf using the supplied allocator
01253   // Takes ownership of s instead of copying.
01254   static _RopeLeaf* _S_new_RopeLeaf(__GC_CONST _CharT *__s,
01255                                     size_t _p_size, allocator_type __a)
01256   {
01257    _RopeLeaf* __space = _STLP_CREATE_ALLOCATOR(allocator_type,__a, _RopeLeaf).allocate(1,(const void*)0);
01258     _STLP_TRY {
01259       _STLP_PLACEMENT_NEW(__space) _RopeLeaf(__s, _p_size, __a);
01260     }
01261    _STLP_UNWIND(_STLP_CREATE_ALLOCATOR(allocator_type,__a, 
01262                                    _RopeLeaf).deallocate(__space, 1))
01263           return __space;
01264   }
01265 
01266   static _RopeConcatenation* _S_new_RopeConcatenation(
01267                                                       _RopeRep* __left, _RopeRep* __right,
01268                                                       allocator_type __a)
01269   {
01270    _RopeConcatenation* __space = _STLP_CREATE_ALLOCATOR(allocator_type,__a,
01271                                                     _RopeConcatenation).allocate(1,(const void*)0);
01272     return _STLP_PLACEMENT_NEW(__space) _RopeConcatenation(__left, __right, __a);
01273   }
01274 
01275   static _RopeFunction* _S_new_RopeFunction(char_producer<_CharT>* __f,
01276                                             size_t _p_size, bool __d, allocator_type __a)
01277   {
01278    _RopeFunction* __space = _STLP_CREATE_ALLOCATOR(allocator_type,__a, 
01279                                                _RopeFunction).allocate(1,(const void*)0);
01280     return _STLP_PLACEMENT_NEW(__space) _RopeFunction(__f, _p_size, __d, __a);
01281   }
01282 
01283   static _RopeSubstring* _S_new_RopeSubstring(
01284                                               _Rope_RopeRep<_CharT,_Alloc>* __b, size_t __s,
01285                                               size_t __l, allocator_type __a)
01286   {
01287    _RopeSubstring* __space = _STLP_CREATE_ALLOCATOR(allocator_type,__a, 
01288                                                 _RopeSubstring).allocate(1,(const void*)0);
01289     return _STLP_PLACEMENT_NEW(__space) _RopeSubstring(__b, __s, __l, __a);
01290   }
01291 
01292 #         define _STLP_ROPE_FROM_UNOWNED_CHAR_PTR(__s, _p_size, __a) \
01293                 _S_RopeLeaf_from_unowned_char_ptr(__s, _p_size, __a)     
01294 
01295   static
01296   _RopeLeaf* _S_RopeLeaf_from_unowned_char_ptr(const _CharT *__s,
01297                                                size_t _p_size, allocator_type __a)
01298   {
01299     if (0 == _p_size) return 0;
01300 
01301    _CharT* __buf = _STLP_CREATE_ALLOCATOR(allocator_type,__a, _CharT).allocate(_S_rounded_up_size(_p_size));
01302 
01303     uninitialized_copy_n(__s, _p_size, __buf);
01304     _S_cond_store_eos(__buf[_p_size]);
01305 
01306     _STLP_TRY {
01307       return _S_new_RopeLeaf(__buf, _p_size, __a);
01308     }
01309     _STLP_UNWIND(_RopeRep::_S_free_string(__buf, _p_size, __a))
01310             
01311 # if defined (_STLP_THROW_RETURN_BUG)
01312       return 0;
01313 # endif
01314   }
01315             
01316 
01317   // Concatenation of nonempty strings.
01318   // Always builds a concatenation node.
01319   // Rebalances if the result is too deep.
01320   // Result has refcount 1.
01321   // Does not increment left and right ref counts even though
01322   // they are referenced.
01323   static _RopeRep*
01324   _S_tree_concat(_RopeRep* __left, _RopeRep* __right);
01325 
01326   // Concatenation helper functions
01327   static _RopeLeaf*
01328   _S_leaf_concat_char_iter(_RopeLeaf* __r,
01329                            const _CharT* __iter, size_t __slen);
01330   // Concatenate by copying leaf.
01331   // should take an arbitrary iterator
01332   // result has refcount 1.
01333 #       ifndef __GC
01334   static _RopeLeaf* _S_destr_leaf_concat_char_iter
01335   (_RopeLeaf* __r, const _CharT* __iter, size_t __slen);
01336   // A version that potentially clobbers __r if __r->_M_ref_count == 1.
01337 #       endif
01338 
01339 
01340   // A helper function for exponentiating strings.
01341   // This uses a nonstandard refcount convention.
01342   // The result has refcount 0.
01343   friend struct _Rope_Concat_fn<_CharT,_Alloc>;
01344   typedef _Rope_Concat_fn<_CharT,_Alloc> _Concat_fn;
01345 
01346 public:
01347   static size_t _S_char_ptr_len(const _CharT* __s) {
01348     const _CharT* __p = __s;
01349           
01350     while (!_S_is0(*__p)) { ++__p; }
01351     return (__p - __s);
01352   }
01353 
01354 public: /* for operators */
01355   rope(_RopeRep* __t, const allocator_type& __a = allocator_type())
01356     : _M_tree_ptr(__a, __t) { }
01357 private:
01358   // Copy __r to the _CharT buffer.
01359   // Returns __buffer + __r->_M_size._M_data.
01360   // Assumes that buffer is uninitialized.
01361   static _CharT* _S_flatten(_RopeRep* __r, _CharT* __buffer);
01362 
01363   // Again, with explicit starting position and length.
01364   // Assumes that buffer is uninitialized.
01365   static _CharT* _S_flatten(_RopeRep* __r,
01366                             size_t __start, size_t __len,
01367                             _CharT* __buffer);
01368 
01369   // fbp : HP aCC prohibits access to protected min_len from within static methods ( ?? )
01370 public:
01371   static const unsigned long _S_min_len[46];
01372 protected:
01373   static bool _S_is_balanced(_RopeRep* __r)
01374   { return (__r->_M_size._M_data >= _S_min_len[__r->_M_depth]); }
01375 
01376   static bool _S_is_almost_balanced(_RopeRep* __r)
01377   { return (__r->_M_depth == 0 ||
01378             __r->_M_size._M_data >= _S_min_len[__r->_M_depth - 1]); }
01379 
01380   static bool _S_is_roughly_balanced(_RopeRep* __r)
01381   { return (__r->_M_depth <= 1 ||
01382             __r->_M_size._M_data >= _S_min_len[__r->_M_depth - 2]); }
01383 
01384   // Assumes the result is not empty.
01385   static _RopeRep* _S_concat_and_set_balanced(_RopeRep* __left,
01386                                               _RopeRep* __right)
01387   {
01388     _RopeRep* __result = _S_concat_rep(__left, __right);
01389     if (_S_is_balanced(__result)) __result->_M_is_balanced = true;
01390     return __result;
01391   }
01392 
01393   // The basic rebalancing operation.  Logically copies the
01394   // rope.  The result has refcount of 1.  The client will
01395   // usually decrement the reference count of __r.
01396   // The result is within height 2 of balanced by the above
01397   // definition.
01398   static _RopeRep* _S_balance(_RopeRep* __r);
01399 
01400   // Add all unbalanced subtrees to the forest of balanceed trees.
01401   // Used only by balance.
01402   static void _S_add_to_forest(_RopeRep*__r, _RopeRep** __forest);
01403         
01404   // Add __r to forest, assuming __r is already balanced.
01405   static void _S_add_leaf_to_forest(_RopeRep* __r, _RopeRep** __forest);
01406 
01407   // Print to stdout, exposing structure
01408   static void _S_dump(_RopeRep* __r, int __indent = 0);
01409 
01410   // Return -1, 0, or 1 if __x < __y, __x == __y, or __x > __y resp.
01411   static int _S_compare(const _RopeRep* __x, const _RopeRep* __y);
01412 
01413 public:
01414   bool empty() const { return 0 == _M_tree_ptr._M_data; }
01415 
01416   // Comparison member function.  This is public only for those
01417   // clients that need a ternary comparison.  Others
01418   // should use the comparison operators below.
01419   int compare(const _Self& __y) const {
01420     return _S_compare(_M_tree_ptr._M_data, __y._M_tree_ptr._M_data);
01421   }
01422 
01423   rope(const _CharT* __s, const allocator_type& __a = allocator_type())
01424     : _M_tree_ptr(__a, _STLP_ROPE_FROM_UNOWNED_CHAR_PTR(__s, _S_char_ptr_len(__s),__a))
01425   { }
01426 
01427   rope(const _CharT* __s, size_t __len,
01428        const allocator_type& __a = allocator_type())
01429     : _M_tree_ptr(__a, (_STLP_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __len, __a)))
01430   { }
01431 
01432   // Should perhaps be templatized with respect to the iterator type
01433   // and use Sequence_buffer.  (It should perhaps use sequence_buffer
01434   // even now.)
01435   rope(const _CharT *__s, const _CharT *__e,
01436        const allocator_type& __a = allocator_type())
01437     : _M_tree_ptr(__a, _STLP_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __e - __s, __a))
01438   { }
01439 
01440   rope(const const_iterator& __s, const const_iterator& __e,
01441        const allocator_type& __a = allocator_type())
01442     : _M_tree_ptr(__a, _S_substring(__s._M_root, __s._M_current_pos,
01443                                     __e._M_current_pos))
01444   { }
01445 
01446   rope(const iterator& __s, const iterator& __e,
01447        const allocator_type& __a = allocator_type())
01448     : _M_tree_ptr(__a, _S_substring(__s._M_root, __s._M_current_pos,
01449                                     __e._M_current_pos))
01450   { }
01451 
01452   rope(_CharT __c, const allocator_type& __a = allocator_type())
01453     : _M_tree_ptr(__a, (_RopeRep*)0)
01454   {
01455     _CharT* __buf = _M_tree_ptr.allocate(_S_rounded_up_size(1));
01456 
01457     _Construct(__buf, __c);
01458     _STLP_TRY {
01459       _M_tree_ptr._M_data = _S_new_RopeLeaf(__buf, 1, __a);
01460     }
01461     _STLP_UNWIND(_RopeRep::_S_free_string(__buf, 1, __a))
01462       }
01463 
01464   rope(size_t __n, _CharT __c,     
01465        const allocator_type& __a = allocator_type()):
01466     _M_tree_ptr(__a, (_RopeRep*)0) {
01467     rope<_CharT,_Alloc> __result;
01468 # define  __exponentiate_threshold size_t(32)
01469     _RopeRep* __remainder;
01470     rope<_CharT,_Alloc> __remainder_rope;
01471             
01472     // gcc-2.7.2 bugs
01473     typedef _Rope_Concat_fn<_CharT,_Alloc> _Concat_fn;
01474             
01475     if (0 == __n)
01476       return;
01477             
01478     size_t __exponent = __n / __exponentiate_threshold;
01479     size_t __rest = __n % __exponentiate_threshold;
01480     if (0 == __rest) {
01481       __remainder = 0;
01482     } else {
01483       _CharT* __rest_buffer = _M_tree_ptr.allocate(_S_rounded_up_size(__rest));
01484       uninitialized_fill_n(__rest_buffer, __rest, __c);
01485       _S_cond_store_eos(__rest_buffer[__rest]);
01486       _STLP_TRY {
01487                 __remainder = _S_new_RopeLeaf(__rest_buffer, __rest, __a);
01488       }
01489       _STLP_UNWIND(_RopeRep::_S_free_string(__rest_buffer, __rest, __a))
01490                 }
01491     __remainder_rope._M_tree_ptr._M_data = __remainder;
01492     if (__exponent != 0) {
01493       _CharT* __base_buffer =
01494                 _M_tree_ptr.allocate(_S_rounded_up_size(__exponentiate_threshold));
01495       _RopeLeaf* __base_leaf;
01496       rope<_CharT,_Alloc> __base_rope;
01497       uninitialized_fill_n(__base_buffer, __exponentiate_threshold, __c);
01498       _S_cond_store_eos(__base_buffer[__exponentiate_threshold]);
01499       _STLP_TRY {
01500                 __base_leaf = _S_new_RopeLeaf(__base_buffer,
01501                                       __exponentiate_threshold, __a);
01502       }
01503       _STLP_UNWIND(_RopeRep::_S_free_string(__base_buffer, 
01504                                             __exponentiate_threshold, __a))
01505                 __base_rope._M_tree_ptr._M_data = __base_leaf;
01506       if (1 == __exponent) {
01507                 __result = __base_rope;
01508 #         ifndef __GC
01509                 _STLP_ASSERT(2 == __result._M_tree_ptr._M_data->_M_ref_count)
01510                 // One each for base_rope and __result
01511 #         endif
01512       } else {
01513                 __result = power(__base_rope, __exponent, _Concat_fn());
01514       }
01515       if (0 != __remainder) {
01516                 __result += __remainder_rope;
01517       }
01518     } else {
01519       __result = __remainder_rope;
01520     }
01521     _M_tree_ptr._M_data = __result._M_tree_ptr._M_data;
01522     _M_tree_ptr._M_data->_M_ref_nonnil();
01523 # undef __exponentiate_threshold
01524   }
01525 
01526   rope(const allocator_type& __a = allocator_type())
01527     : _M_tree_ptr(__a, (_RopeRep*)0) {}
01528 
01529   // Construct a rope from a function that can compute its members
01530   rope(char_producer<_CharT> *__fn, size_t __len, bool __delete_fn,
01531        const allocator_type& __a = allocator_type())
01532     : _M_tree_ptr(__a, (_RopeRep*)0)
01533   {
01534     _M_tree_ptr._M_data = (0 == __len) ?
01535       0 : _S_new_RopeFunction(__fn, __len, __delete_fn, __a);
01536   }
01537 
01538   rope(const _Self& __x)
01539     : _M_tree_ptr(__x.get_allocator(), __x._M_tree_ptr._M_data)
01540   {
01541     _S_ref(_M_tree_ptr._M_data);
01542   }
01543 
01544   ~rope()
01545   {
01546     _S_unref(_M_tree_ptr._M_data);
01547   }
01548 
01549   _Self& operator=(const _Self& __x)
01550   {
01551     _RopeRep* __old = _M_tree_ptr._M_data;
01552     _STLP_ASSERT(get_allocator() == __x.get_allocator())
01553     _M_tree_ptr._M_data = __x._M_tree_ptr._M_data;
01554     _S_ref(_M_tree_ptr._M_data);
01555     _S_unref(__old);
01556     return(*this);
01557   }
01558   void clear()
01559   {
01560     _S_unref(_M_tree_ptr._M_data);
01561     _M_tree_ptr._M_data = 0;
01562   }
01563   void push_back(_CharT __x)
01564   {
01565     _RopeRep* __old = _M_tree_ptr._M_data;
01566     _M_tree_ptr._M_data = _S_destr_concat_char_iter(_M_tree_ptr._M_data, &__x, 1);
01567     _S_unref(__old);
01568   }
01569 
01570   void pop_back()
01571   {
01572     _RopeRep* __old = _M_tree_ptr._M_data;
01573     _M_tree_ptr._M_data = 
01574       _S_substring(_M_tree_ptr._M_data, 0, _M_tree_ptr._M_data->_M_size._M_data - 1);
01575     _S_unref(__old);
01576   }
01577 
01578   _CharT back() const
01579   {
01580     return _S_fetch(_M_tree_ptr._M_data, _M_tree_ptr._M_data->_M_size._M_data - 1);
01581   }
01582 
01583   void push_front(_CharT __x)
01584   {
01585     _RopeRep* __old = _M_tree_ptr._M_data;
01586     _RopeRep* __left =
01587       _STLP_ROPE_FROM_UNOWNED_CHAR_PTR(&__x, 1, get_allocator());
01588     _STLP_TRY {
01589       _M_tree_ptr._M_data = _S_concat_rep(__left, _M_tree_ptr._M_data);
01590       _S_unref(__old);
01591       _S_unref(__left);
01592     }
01593     _STLP_UNWIND(_S_unref(__left))
01594       }
01595 
01596   void pop_front()
01597   {
01598     _RopeRep* __old = _M_tree_ptr._M_data;
01599     _M_tree_ptr._M_data = _S_substring(_M_tree_ptr._M_data, 1, _M_tree_ptr._M_data->_M_size._M_data);
01600     _S_unref(__old);
01601   }
01602 
01603   _CharT front() const
01604   {
01605     return _S_fetch(_M_tree_ptr._M_data, 0);
01606   }
01607 
01608   void balance()
01609   {
01610     _RopeRep* __old = _M_tree_ptr._M_data;
01611     _M_tree_ptr._M_data = _S_balance(_M_tree_ptr._M_data);
01612     _S_unref(__old);
01613   }
01614 
01615   void copy(_CharT* __buffer) const {
01616     _Destroy(__buffer, __buffer + size());
01617     _S_flatten(_M_tree_ptr._M_data, __buffer);
01618   }
01619 
01620   // This is the copy function from the standard, but
01621   // with the arguments reordered to make it consistent with the
01622   // rest of the interface.
01623   // Note that this guaranteed not to compile if the draft standard
01624   // order is assumed.
01625   size_type copy(size_type __pos, size_type __n, _CharT* __buffer) const 
01626   {
01627     size_t _p_size = size();
01628     size_t __len = (__pos + __n > _p_size? _p_size - __pos : __n);
01629 
01630     _Destroy(__buffer, __buffer + __len);
01631     _S_flatten(_M_tree_ptr._M_data, __pos, __len, __buffer);
01632     return __len;
01633   }
01634 
01635   // Print to stdout, exposing structure.  May be useful for
01636   // performance debugging.
01637   void dump() {
01638     _S_dump(_M_tree_ptr._M_data);
01639   }
01640 
01641   // Convert to 0 terminated string in new allocated memory.
01642   // Embedded 0s in the input do not terminate the copy.
01643   const _CharT* c_str() const;
01644 
01645   // As above, but lso use the flattened representation as the
01646   // the new rope representation.
01647   const _CharT* replace_with_c_str();
01648 
01649   // Reclaim memory for the c_str generated flattened string.
01650   // Intentionally undocumented, since it's hard to say when this
01651   // is safe for multiple threads.
01652   void delete_c_str () {
01653     if (0 == _M_tree_ptr._M_data) return;
01654     if (_RopeRep::_S_leaf == _M_tree_ptr._M_data->_M_tag && 
01655         ((_RopeLeaf*)_M_tree_ptr._M_data)->_M_data == 
01656         _M_tree_ptr._M_data->_M_c_string) {
01657       // Representation shared
01658       return;
01659     }
01660 #           ifndef __GC
01661     _M_tree_ptr._M_data->_M_free_c_string();
01662 #           endif
01663     _M_tree_ptr._M_data->_M_c_string = 0;
01664   }
01665 
01666   _CharT operator[] (size_type __pos) const {
01667     return _S_fetch(_M_tree_ptr._M_data, __pos);
01668   }
01669 
01670   _CharT at(size_type __pos) const {
01671     // if (__pos >= size()) throw out_of_range;  // XXX
01672     return (*this)[__pos];
01673   }
01674 
01675   const_iterator begin() const {
01676     return(const_iterator(_M_tree_ptr._M_data, 0));
01677   }
01678 
01679   // An easy way to get a const iterator from a non-const container.
01680   const_iterator const_begin() const {
01681     return(const_iterator(_M_tree_ptr._M_data, 0));
01682   }
01683 
01684   const_iterator end() const {
01685     return(const_iterator(_M_tree_ptr._M_data, size()));
01686   }
01687 
01688   const_iterator const_end() const {
01689     return(const_iterator(_M_tree_ptr._M_data, size()));
01690   }
01691 
01692   size_type size() const { 
01693     return(0 == _M_tree_ptr._M_data? 0 : _M_tree_ptr._M_data->_M_size._M_data);
01694   }
01695 
01696   size_type length() const {
01697     return size();
01698   }
01699 
01700   size_type max_size() const {
01701     return _S_min_len[__ROPE_MAX_DEPTH-1] - 1;
01702     //  Guarantees that the result can be sufficirntly
01703     //  balanced.  Longer ropes will probably still work,
01704     //  but it's harder to make guarantees.
01705   }
01706 
01707   const_reverse_iterator rbegin() const {
01708     return const_reverse_iterator(end());
01709   }
01710 
01711   const_reverse_iterator const_rbegin() const {
01712     return const_reverse_iterator(end());
01713   }
01714 
01715   const_reverse_iterator rend() const {
01716     return const_reverse_iterator(begin());
01717   }
01718 
01719   const_reverse_iterator const_rend() const {
01720     return const_reverse_iterator(begin());
01721   }
01722   // The symmetric cases are intentionally omitted, since they're presumed
01723   // to be less common, and we don't handle them as well.
01724 
01725   // The following should really be templatized.
01726   // The first argument should be an input iterator or
01727   // forward iterator with value_type _CharT.
01728   _Self& append(const _CharT* __iter, size_t __n) {
01729     _RopeRep* __result = 
01730       _S_destr_concat_char_iter(_M_tree_ptr._M_data, __iter, __n);
01731     _S_unref(_M_tree_ptr._M_data);
01732     _M_tree_ptr._M_data = __result;
01733     return *this;
01734   }
01735 
01736   _Self& append(const _CharT* __c_string) {
01737     size_t __len = _S_char_ptr_len(__c_string);
01738     append(__c_string, __len);
01739     return(*this);
01740   }
01741 
01742   _Self& append(const _CharT* __s, const _CharT* __e) {
01743     _RopeRep* __result =
01744       _S_destr_concat_char_iter(_M_tree_ptr._M_data, __s, __e - __s);
01745     _S_unref(_M_tree_ptr._M_data);
01746     _M_tree_ptr._M_data = __result;
01747     return *this;
01748   }
01749 
01750   _Self& append(const_iterator __s, const_iterator __e) {
01751     _STLP_ASSERT(__s._M_root == __e._M_root)
01752     _STLP_ASSERT(get_allocator() == __s._M_root->get_allocator())
01753     _Self_destruct_ptr __appendee(_S_substring(
01754                                                __s._M_root, __s._M_current_pos, __e._M_current_pos));
01755     _RopeRep* __result = 
01756       _S_concat_rep(_M_tree_ptr._M_data, (_RopeRep*)__appendee);
01757     _S_unref(_M_tree_ptr._M_data);
01758     _M_tree_ptr._M_data = __result;
01759     return *this;
01760   }
01761 
01762   _Self& append(_CharT __c) {
01763     _RopeRep* __result = 
01764       _S_destr_concat_char_iter(_M_tree_ptr._M_data, &__c, 1);
01765     _S_unref(_M_tree_ptr._M_data);
01766     _M_tree_ptr._M_data = __result;
01767     return *this;
01768   }
01769 
01770   _Self& append() { return append(_CharT()); }  // XXX why?
01771 
01772   _Self& append(const _Self& __y) {
01773     _STLP_ASSERT(__y.get_allocator() == get_allocator())
01774     _RopeRep* __result = _S_concat_rep(_M_tree_ptr._M_data, __y._M_tree_ptr._M_data);
01775     _S_unref(_M_tree_ptr._M_data);
01776     _M_tree_ptr._M_data = __result;
01777     return *this;
01778   }
01779 
01780   _Self& append(size_t __n, _CharT __c) {
01781     rope<_CharT,_Alloc> __last(__n, __c);
01782     return append(__last);
01783   }
01784 
01785   void swap(_Self& __b) {
01786     _STLP_ASSERT(get_allocator() == __b.get_allocator())
01787     _RopeRep* __tmp = _M_tree_ptr._M_data;
01788     _M_tree_ptr._M_data = __b._M_tree_ptr._M_data;
01789     __b._M_tree_ptr._M_data = __tmp;
01790   }
01791 
01792 
01793 protected:
01794   // Result is included in refcount.
01795   static _RopeRep* replace(_RopeRep* __old, size_t __pos1,
01796                            size_t __pos2, _RopeRep* __r) {
01797     if (0 == __old) { _S_ref(__r); return __r; }
01798     _Self_destruct_ptr __left(
01799                               _S_substring(__old, 0, __pos1));
01800     _Self_destruct_ptr __right(
01801                                _S_substring(__old, __pos2, __old->_M_size._M_data));
01802         _STLP_MPWFIX_TRY        //*TY 06/01/2000 - 
01803     _RopeRep* __result;
01804 
01805     if (0 == __r) {
01806       __result = _S_concat_rep(__left, __right);
01807     } else {
01808       _STLP_ASSERT(__old->get_allocator() == __r->get_allocator())
01809       _Self_destruct_ptr __left_result(_S_concat_rep(__left, __r));
01810       __result = _S_concat_rep(__left_result, __right);
01811     }
01812     return __result;
01813         _STLP_MPWFIX_CATCH      //*TY 06/01/2000 - 
01814   }
01815 
01816 public:
01817   void insert(size_t __p, const _Self& __r) {
01818     _RopeRep* __result = 
01819       replace(_M_tree_ptr._M_data, __p, __p, __r._M_tree_ptr._M_data);
01820     _STLP_ASSERT(get_allocator() == __r.get_allocator())
01821     _S_unref(_M_tree_ptr._M_data);
01822     _M_tree_ptr._M_data = __result;
01823   }
01824 
01825   void insert(size_t __p, size_t __n, _CharT __c) {
01826     rope<_CharT,_Alloc> __r(__n,__c);
01827     insert(__p, __r);
01828   }
01829 
01830   void insert(size_t __p, const _CharT* __i, size_t __n) {
01831     _Self_destruct_ptr __left(_S_substring(_M_tree_ptr._M_data, 0, __p));
01832     _Self_destruct_ptr __right(_S_substring(_M_tree_ptr._M_data, __p, size()));
01833     _Self_destruct_ptr __left_result(
01834                                      _S_concat_char_iter(__left, __i, __n));
01835     // _S_ destr_concat_char_iter should be safe here.
01836     // But as it stands it's probably not a win, since __left
01837     // is likely to have additional references.
01838     _RopeRep* __result = _S_concat_rep(__left_result, __right);
01839     _S_unref(_M_tree_ptr._M_data);
01840     _M_tree_ptr._M_data = __result;
01841   }
01842 
01843   void insert(size_t __p, const _CharT* __c_string) {
01844     insert(__p, __c_string, _S_char_ptr_len(__c_string));
01845   }
01846 
01847   void insert(size_t __p, _CharT __c) {
01848     insert(__p, &__c, 1);
01849   }
01850 
01851   void insert(size_t __p) {
01852     _CharT __c = _CharT();
01853     insert(__p, &__c, 1);
01854   }
01855 
01856   void insert(size_t __p, const _CharT* __i, const _CharT* __j) {
01857     _Self __r(__i, __j);
01858     insert(__p, __r);
01859   }
01860 
01861   void insert(size_t __p, const const_iterator& __i,
01862               const const_iterator& __j) {
01863     _Self __r(__i, __j);
01864     insert(__p, __r);
01865   }
01866 
01867   void insert(size_t __p, const iterator& __i,
01868               const iterator& __j) {
01869     _Self __r(__i, __j);
01870     insert(__p, __r);
01871   }
01872 
01873   // (position, length) versions of replace operations:
01874 
01875   void replace(size_t __p, size_t __n, const _Self& __r) {
01876     _RopeRep* __result = 
01877       replace(_M_tree_ptr._M_data, __p, __p + __n, __r._M_tree_ptr._M_data);
01878     _S_unref(_M_tree_ptr._M_data);
01879     _M_tree_ptr._M_data = __result;
01880   }
01881 
01882   void replace(size_t __p, size_t __n, 
01883                const _CharT* __i, size_t __i_len) {
01884     _Self __r(__i, __i_len);
01885     replace(__p, __n, __r);
01886   }
01887 
01888   void replace(size_t __p, size_t __n, _CharT __c) {
01889     _Self __r(__c);
01890     replace(__p, __n, __r);
01891   }
01892 
01893   void replace(size_t __p, size_t __n, const _CharT* __c_string) {
01894     _Self __r(__c_string);
01895     replace(__p, __n, __r);
01896   }
01897 
01898   void replace(size_t __p, size_t __n, 
01899                const _CharT* __i, const _CharT* __j) {
01900     _Self __r(__i, __j);
01901     replace(__p, __n, __r);
01902   }
01903 
01904   void replace(size_t __p, size_t __n,
01905                const const_iterator& __i, const const_iterator& __j) {
01906     _Self __r(__i, __j);
01907     replace(__p, __n, __r);
01908   }
01909 
01910   void replace(size_t __p, size_t __n,
01911                const iterator& __i, const iterator& __j) {
01912     _Self __r(__i, __j);
01913     replace(__p, __n, __r);
01914   }
01915 
01916   // Single character variants:
01917   void replace(size_t __p, _CharT __c) {
01918     iterator __i(this, __p);
01919     *__i = __c;
01920   }
01921 
01922   void replace(size_t __p, const _Self& __r) {
01923     replace(__p, 1, __r);
01924   }
01925 
01926   void replace(size_t __p, const _CharT* __i, size_t __i_len) {
01927     replace(__p, 1, __i, __i_len);
01928   }
01929 
01930   void replace(size_t __p, const _CharT* __c_string) {
01931     replace(__p, 1, __c_string);
01932   }
01933 
01934   void replace(size_t __p, const _CharT* __i, const _CharT* __j) {
01935     replace(__p, 1, __i, __j);
01936   }
01937 
01938   void replace(size_t __p, const const_iterator& __i,
01939                const const_iterator& __j) {
01940     replace(__p, 1, __i, __j);
01941   }
01942 
01943   void replace(size_t __p, const iterator& __i,
01944                const iterator& __j) {
01945     replace(__p, 1, __i, __j);
01946   }
01947 
01948   // Erase, (position, size) variant.
01949   void erase(size_t __p, size_t __n) {
01950     _RopeRep* __result = replace(_M_tree_ptr._M_data, __p, __p + __n, 0);
01951     _S_unref(_M_tree_ptr._M_data);
01952     _M_tree_ptr._M_data = __result;
01953   }
01954 
01955   // Erase, single character
01956   void erase(size_t __p) {
01957     erase(__p, __p + 1);
01958   }
01959 
01960   // Insert, iterator variants.  
01961   iterator insert(const iterator& __p, const _Self& __r)
01962   { insert(__p.index(), __r); return __p; }
01963   iterator insert(const iterator& __p, size_t __n, _CharT __c)
01964   { insert(__p.index(), __n, __c); return __p; }
01965   iterator insert(const iterator& __p, _CharT __c) 
01966   { insert(__p.index(), __c); return __p; }
01967   iterator insert(const iterator& __p ) 
01968   { insert(__p.index()); return __p; }
01969   iterator insert(const iterator& __p, const _CharT* c_string) 
01970   { insert(__p.index(), c_string); return __p; }
01971   iterator insert(const iterator& __p, const _CharT* __i, size_t __n)
01972   { insert(__p.index(), __i, __n); return __p; }
01973   iterator insert(const iterator& __p, const _CharT* __i, 
01974                   const _CharT* __j)
01975   { insert(__p.index(), __i, __j);  return __p; }
01976   iterator insert(const iterator& __p,
01977                   const const_iterator& __i, const const_iterator& __j)
01978   { insert(__p.index(), __i, __j); return __p; }
01979   iterator insert(const iterator& __p,
01980                   const iterator& __i, const iterator& __j)
01981   { insert(__p.index(), __i, __j); return __p; }
01982 
01983   // Replace, range variants.
01984   void replace(const iterator& __p, const iterator& __q,
01985                const _Self& __r)
01986   { replace(__p.index(), __q.index() - __p.index(), __r); }
01987   void replace(const iterator& __p, const iterator& __q, _CharT __c)
01988   { replace(__p.index(), __q.index() - __p.index(), __c); }
01989   void replace(const iterator& __p, const iterator& __q,
01990                const _CharT* __c_string)
01991   { replace(__p.index(), __q.index() - __p.index(), __c_string); }
01992   void replace(const iterator& __p, const iterator& __q,
01993                const _CharT* __i, size_t __n)
01994   { replace(__p.index(), __q.index() - __p.index(), __i, __n); }
01995   void replace(const iterator& __p, const iterator& __q,
01996                const _CharT* __i, const _CharT* __j)
01997   { replace(__p.index(), __q.index() - __p.index(), __i, __j); }
01998   void replace(const iterator& __p, const iterator& __q,
01999                const const_iterator& __i, const const_iterator& __j)
02000   { replace(__p.index(), __q.index() - __p.index(), __i, __j); }
02001   void replace(const iterator& __p, const iterator& __q,
02002                const iterator& __i, const iterator& __j)
02003   { replace(__p.index(), __q.index() - __p.index(), __i, __j); }
02004 
02005   // Replace, iterator variants.
02006   void replace(const iterator& __p, const _Self& __r)
02007   { replace(__p.index(), __r); }
02008   void replace(const iterator& __p, _CharT __c)
02009   { replace(__p.index(), __c); }
02010   void replace(const iterator& __p, const _CharT* __c_string)
02011   { replace(__p.index(), __c_string); }
02012   void replace(const iterator& __p, const _CharT* __i, size_t __n)
02013   { replace(__p.index(), __i, __n); }
02014   void replace(const iterator& __p, const _CharT* __i, const _CharT* __j)
02015   { replace(__p.index(), __i, __j); }
02016   void replace(const iterator& __p, const_iterator __i, 
02017                const_iterator __j)
02018   { replace(__p.index(), __i, __j); }
02019   void replace(const iterator& __p, iterator __i, iterator __j)
02020   { replace(__p.index(), __i, __j); }
02021 
02022   // Iterator and range variants of erase
02023   iterator erase(const iterator& __p, const iterator& __q) {
02024     size_t __p_index = __p.index();
02025     erase(__p_index, __q.index() - __p_index);
02026     return iterator(this, __p_index);
02027   }
02028   iterator erase(const iterator& __p) {
02029     size_t __p_index = __p.index();
02030     erase(__p_index, 1);
02031     return iterator(this, __p_index);
02032   }
02033 
02034   _Self substr(size_t __start, size_t __len = 1) const {
02035     return rope<_CharT,_Alloc>(
02036                                _S_substring(_M_tree_ptr._M_data, __start, __start + __len));
02037   }
02038 
02039   _Self substr(iterator __start, iterator __end) const {
02040     return rope<_CharT,_Alloc>(
02041                                _S_substring(_M_tree_ptr._M_data, __start.index(), __end.index()));
02042   }
02043         
02044   _Self substr(iterator __start) const {
02045     size_t __pos = __start.index();
02046     return rope<_CharT,_Alloc>(
02047                                _S_substring(_M_tree_ptr._M_data, __pos, __pos + 1));
02048   }
02049         
02050   _Self substr(const_iterator __start, const_iterator __end) const {
02051     // This might eventually take advantage of the cache in the
02052     // iterator.
02053     return rope<_CharT,_Alloc>(
02054                                _S_substring(_M_tree_ptr._M_data, __start.index(), __end.index()));
02055   }
02056 
02057   rope<_CharT,_Alloc> substr(const_iterator __start) {
02058     size_t __pos = __start.index();
02059     return rope<_CharT,_Alloc>(
02060                                _S_substring(_M_tree_ptr._M_data, __pos, __pos + 1));
02061   }
02062 
02063   enum { npos = -1 };
02064 
02065   //         static const size_type npos;
02066 
02067   size_type find(_CharT __c, size_type __pos = 0) const;
02068   size_type find(const _CharT* __s, size_type __pos = 0) const {
02069     size_type __result_pos;
02070     const_iterator __result = search(const_begin() + (ptrdiff_t)__pos, const_end(),
02071                                      __s, __s + _S_char_ptr_len(__s));
02072     __result_pos = __result.index();
02073 #           ifndef _STLP_OLD_ROPE_SEMANTICS
02074     if (__result_pos == size()) __result_pos = npos;
02075 #           endif
02076     return __result_pos;
02077   }
02078 
02079   iterator mutable_begin() {
02080     return(iterator(this, 0));
02081   }
02082 
02083   iterator mutable_end() {
02084     return(iterator(this, size()));
02085   }
02086 
02087   reverse_iterator mutable_rbegin() {
02088     return reverse_iterator(mutable_end());
02089   }
02090 
02091   reverse_iterator mutable_rend() {
02092     return reverse_iterator(mutable_begin());
02093   }
02094 
02095   reference mutable_reference_at(size_type __pos) {
02096     return reference(this, __pos);
02097   }
02098 
02099 #       ifdef __STD_STUFF
02100   reference operator[] (size_type __pos) {
02101     return reference(this, __pos);
02102   }
02103 
02104   reference at(size_type __pos) {
02105     // if (__pos >= size()) throw out_of_range;  // XXX
02106     return (*this)[__pos];
02107   }
02108 
02109   void resize(size_type, _CharT) {}
02110   void resize(size_type) {}
02111   void reserve(size_type = 0) {}
02112   size_type capacity() const {
02113     return max_size();
02114   }
02115 
02116   // Stuff below this line is dangerous because it's error prone.
02117   // I would really like to get rid of it.
02118   // copy function with funny arg ordering.
02119   size_type copy(_CharT* __buffer, size_type __n, 
02120                  size_type __pos = 0) const {
02121     return copy(__pos, __n, __buffer);
02122   }
02123 
02124   iterator end() { return mutable_end(); }
02125 
02126   iterator begin() { return mutable_begin(); }
02127 
02128   reverse_iterator rend() { return mutable_rend(); }
02129 
02130   reverse_iterator rbegin() { return mutable_rbegin(); }
02131 
02132 #       else
02133 
02134   const_iterator end() { return const_end(); }
02135 
02136   const_iterator begin() { return const_begin(); }
02137 
02138   const_reverse_iterator rend() { return const_rend(); }
02139   
02140   const_reverse_iterator rbegin() { return const_rbegin(); }
02141 
02142 #       endif
02143 
02144   __ROPE_DEFINE_ALLOCS(_Alloc, _M_tree_ptr)
02145     };
02146 
02147 # undef __ROPE_DEFINE_ALLOC
02148 # undef __ROPE_DEFINE_ALLOCS
02149 
02150 template <class _CharT, class _Alloc>
02151 inline _CharT 
02152 _Rope_const_iterator< _CharT, _Alloc>::operator[](size_t __n)
02153 {
02154   return rope<_CharT,_Alloc>::_S_fetch(this->_M_root, this->_M_current_pos + __n);
02155 }
02156 
02157 template <class _CharT, class _Alloc>
02158 inline bool operator== (const _Rope_const_iterator<_CharT,_Alloc>& __x,
02159                         const _Rope_const_iterator<_CharT,_Alloc>& __y) {
02160   return (__x._M_current_pos == __y._M_current_pos && 
02161           __x._M_root == __y._M_root);
02162 }
02163 
02164 template <class _CharT, class _Alloc>
02165 inline bool operator< (const _Rope_const_iterator<_CharT,_Alloc>& __x,
02166                        const _Rope_const_iterator<_CharT,_Alloc>& __y) {
02167   return (__x._M_current_pos < __y._M_current_pos);
02168 }
02169 
02170 #ifdef _STLP_USE_SEPARATE_RELOPS_NAMESPACE
02171 
02172 template <class _CharT, class _Alloc>
02173 inline bool operator!= (const _Rope_const_iterator<_CharT,_Alloc>& __x,
02174                         const _Rope_const_iterator<_CharT,_Alloc>& __y) {
02175   return !(__x == __y);
02176 }
02177 
02178 template <class _CharT, class _Alloc>
02179 inline bool operator> (const _Rope_const_iterator<_CharT,_Alloc>& __x,
02180                        const _Rope_const_iterator<_CharT,_Alloc>& __y) {
02181   return __y < __x;
02182 }
02183 
02184 template <class _CharT, class _Alloc>
02185 inline bool operator<= (const _Rope_const_iterator<_CharT,_Alloc>& __x,
02186                         const _Rope_const_iterator<_CharT,_Alloc>& __y) {
02187   return !(__y < __x);
02188 }
02189 
02190 template <class _CharT, class _Alloc>
02191 inline bool operator>= (const _Rope_const_iterator<_CharT,_Alloc>& __x,
02192                         const _Rope_const_iterator<_CharT,_Alloc>& __y) {
02193   return !(__x < __y);
02194 }
02195 
02196 #endif /* _STLP_USE_SEPARATE_RELOPS_NAMESPACE */
02197 
02198 template <class _CharT, class _Alloc>
02199 inline ptrdiff_t operator-(const _Rope_const_iterator<_CharT,_Alloc>& __x,
02200                            const _Rope_const_iterator<_CharT,_Alloc>& __y) {
02201   return (ptrdiff_t)__x._M_current_pos - (ptrdiff_t)__y._M_current_pos;
02202 }
02203 
02204 #if !defined( __MWERKS__ ) || __MWERKS__ >= 0x2000              // dwa 8/21/97  - "ambiguous access to overloaded function" bug.
02205 template <class _CharT, class _Alloc>
02206 inline _Rope_const_iterator<_CharT,_Alloc>
02207 operator-(const _Rope_const_iterator<_CharT,_Alloc>& __x, ptrdiff_t __n) {
02208   return _Rope_const_iterator<_CharT,_Alloc>(
02209                                              __x._M_root, __x._M_current_pos - __n);
02210 }
02211 # endif
02212 
02213 template <class _CharT, class _Alloc>
02214 inline _Rope_const_iterator<_CharT,_Alloc>
02215 operator+(const _Rope_const_iterator<_CharT,_Alloc>& __x, ptrdiff_t __n) {
02216   return _Rope_const_iterator<_CharT,_Alloc>(
02217                                              __x._M_root, __x._M_current_pos + __n);
02218 }
02219 
02220 template <class _CharT, class _Alloc>
02221 inline _Rope_const_iterator<_CharT,_Alloc>
02222 operator+(ptrdiff_t __n, const _Rope_const_iterator<_CharT,_Alloc>& __x) {
02223   return _Rope_const_iterator<_CharT,_Alloc>(
02224                                              __x._M_root, __x._M_current_pos + __n);
02225 }
02226 
02227 template <class _CharT, class _Alloc>
02228 inline bool operator== (const _Rope_iterator<_CharT,_Alloc>& __x,
02229                         const _Rope_iterator<_CharT,_Alloc>& __y) {
02230   return (__x._M_current_pos == __y._M_current_pos && 
02231           __x._M_root_rope == __y._M_root_rope);
02232 }
02233 
02234 template <class _CharT, class _Alloc>
02235 inline bool operator< (const _Rope_iterator<_CharT,_Alloc>& __x,
02236                        const _Rope_iterator<_CharT,_Alloc>& __y) {
02237   return (__x._M_current_pos < __y._M_current_pos);
02238 }
02239 
02240 #ifdef _STLP_USE_SEPARATE_RELOPS_NAMESPACE
02241 
02242 template <class _CharT, class _Alloc>
02243 inline bool operator!= (const _Rope_iterator<_CharT,_Alloc>& __x,
02244                         const _Rope_iterator<_CharT,_Alloc>& __y) {
02245   return !(__x == __y);
02246 }
02247 
02248 template <class _CharT, class _Alloc>
02249 inline bool operator> (const _Rope_iterator<_CharT,_Alloc>& __x,
02250                        const _Rope_iterator<_CharT,_Alloc>& __y) {
02251   return __y < __x;
02252 }
02253 
02254 template <class _CharT, class _Alloc>
02255 inline bool operator<= (const _Rope_iterator<_CharT,_Alloc>& __x,
02256                         const _Rope_iterator<_CharT,_Alloc>& __y) {
02257   return !(__y < __x);
02258 }
02259 
02260 template <class _CharT, class _Alloc>
02261 inline bool operator>= (const _Rope_iterator<_CharT,_Alloc>& __x,
02262                         const _Rope_iterator<_CharT,_Alloc>& __y) {
02263   return !(__x < __y);
02264 }
02265 
02266 #endif /* _STLP_USE_SEPARATE_RELOPS_NAMESPACE */
02267 
02268 template <class _CharT, class _Alloc>
02269 inline ptrdiff_t operator-(const _Rope_iterator<_CharT,_Alloc>& __x,
02270                            const _Rope_iterator<_CharT,_Alloc>& __y) {
02271   return (ptrdiff_t)__x._M_current_pos - (ptrdiff_t)__y._M_current_pos;
02272 }
02273 
02274 #if !defined( __MWERKS__ ) || __MWERKS__ >= 0x2000              // dwa 8/21/97  - "ambiguous access to overloaded function" bug.
02275 template <class _CharT, class _Alloc>
02276 inline _Rope_iterator<_CharT,_Alloc>
02277 operator-(const _Rope_iterator<_CharT,_Alloc>& __x,
02278           ptrdiff_t __n) {
02279   return _Rope_iterator<_CharT,_Alloc>(
02280                                        __x._M_root_rope, __x._M_current_pos - __n);
02281 }
02282 # endif
02283 
02284 template <class _CharT, class _Alloc>
02285 inline _Rope_iterator<_CharT,_Alloc>
02286 operator+(const _Rope_iterator<_CharT,_Alloc>& __x,
02287           ptrdiff_t __n) {
02288   return _Rope_iterator<_CharT,_Alloc>(
02289                                        __x._M_root_rope, __x._M_current_pos + __n);
02290 }
02291 
02292 template <class _CharT, class _Alloc>
02293 inline _Rope_iterator<_CharT,_Alloc>
02294 operator+(ptrdiff_t __n, const _Rope_iterator<_CharT,_Alloc>& __x) {
02295   return _Rope_iterator<_CharT,_Alloc>(
02296                                        __x._M_root_rope, __x._M_current_pos + __n);
02297 }
02298 
02299 template <class _CharT, class _Alloc>
02300 inline
02301 rope<_CharT,_Alloc>
02302 operator+ (const rope<_CharT,_Alloc>& __left,
02303            const rope<_CharT,_Alloc>& __right)
02304 {
02305   _STLP_ASSERT(__left.get_allocator() == __right.get_allocator())
02306   return rope<_CharT,_Alloc>(rope<_CharT,_Alloc>::_S_concat_rep(__left._M_tree_ptr._M_data, __right._M_tree_ptr._M_data));
02307   // Inlining this should make it possible to keep __left and
02308   // __right in registers.
02309 }
02310 
02311 template <class _CharT, class _Alloc>
02312 inline
02313 rope<_CharT,_Alloc>&
02314 operator+= (rope<_CharT,_Alloc>& __left, 
02315             const rope<_CharT,_Alloc>& __right)
02316 {
02317   __left.append(__right);
02318   return __left;
02319 }
02320 
02321 template <class _CharT, class _Alloc>
02322 inline
02323 rope<_CharT,_Alloc>
02324 operator+ (const rope<_CharT,_Alloc>& __left,
02325            const _CharT* __right) {
02326   size_t __rlen = rope<_CharT,_Alloc>::_S_char_ptr_len(__right);
02327   return rope<_CharT,_Alloc>(
02328                              rope<_CharT,_Alloc>::_S_concat_char_iter(
02329                                                                       __left._M_tree_ptr._M_data, __right, __rlen)); 
02330 }
02331 
02332 template <class _CharT, class _Alloc>
02333 inline
02334 rope<_CharT,_Alloc>&
02335 operator+= (rope<_CharT,_Alloc>& __left,
02336             const _CharT* __right) {
02337   __left.append(__right);
02338   return __left;
02339 }
02340 
02341 template <class _CharT, class _Alloc>
02342 inline
02343 rope<_CharT,_Alloc>
02344 operator+ (const rope<_CharT,_Alloc>& __left, _STLP_SIMPLE_TYPE(_CharT) __right) {
02345   return rope<_CharT,_Alloc>(
02346                              rope<_CharT,_Alloc>::_S_concat_char_iter(
02347                                                                       __left._M_tree_ptr._M_data, &__right, 1));
02348 }
02349 
02350 template <class _CharT, class _Alloc>
02351 inline
02352 rope<_CharT,_Alloc>&
02353 operator+= (rope<_CharT,_Alloc>& __left, _STLP_SIMPLE_TYPE(_CharT) __right) {
02354   __left.append(__right);
02355   return __left;
02356 }
02357 
02358 template <class _CharT, class _Alloc>
02359 inline bool
02360 operator< (const rope<_CharT,_Alloc>& __left, 
02361            const rope<_CharT,_Alloc>& __right) {
02362   return __left.compare(__right) < 0;
02363 }
02364         
02365 template <class _CharT, class _Alloc>
02366 inline bool
02367 operator== (const rope<_CharT,_Alloc>& __left, 
02368             const rope<_CharT,_Alloc>& __right) {
02369   return __left.compare(__right) == 0;
02370 }
02371 
02372 #ifdef _STLP_USE_SEPARATE_RELOPS_NAMESPACE
02373 
02374 template <class _CharT, class _Alloc>
02375 inline bool
02376 operator!= (const rope<_CharT,_Alloc>& __x, const rope<_CharT,_Alloc>& __y) {
02377   return !(__x == __y);
02378 }
02379 
02380 template <class _CharT, class _Alloc>
02381 inline bool
02382 operator> (const rope<_CharT,_Alloc>& __x, const rope<_CharT,_Alloc>& __y) {
02383   return __y < __x;
02384 }
02385 
02386 template <class _CharT, class _Alloc>
02387 inline bool
02388 operator<= (const rope<_CharT,_Alloc>& __x, const rope<_CharT,_Alloc>& __y) {
02389   return !(__y < __x);
02390 }
02391 
02392 template <class _CharT, class _Alloc>
02393 inline bool
02394 operator>= (const rope<_CharT,_Alloc>& __x, const rope<_CharT,_Alloc>& __y) {
02395   return !(__x < __y);
02396 }
02397 
02398 template <class _CharT, class _Alloc>
02399 inline bool operator!= (const _Rope_char_ptr_proxy<_CharT,_Alloc>& __x,
02400                         const _Rope_char_ptr_proxy<_CharT,_Alloc>& __y) {
02401   return !(__x == __y);
02402 }
02403 
02404 #endif /* _STLP_USE_SEPARATE_RELOPS_NAMESPACE */
02405 
02406 template <class _CharT, class _Alloc>
02407 inline bool operator== (const _Rope_char_ptr_proxy<_CharT,_Alloc>& __x,
02408                         const _Rope_char_ptr_proxy<_CharT,_Alloc>& __y) {
02409   return (__x._M_pos == __y._M_pos && __x._M_root == __y._M_root);
02410 }
02411 
02412 #ifdef _STLP_USE_NEW_IOSTREAMS
02413 template<class _CharT, class _Traits, class _Alloc>
02414 basic_ostream<_CharT, _Traits>& operator<< (
02415                                             basic_ostream<_CharT, _Traits>& __o,
02416                                             const rope<_CharT, _Alloc>& __r);
02417 #elif ! defined (_STLP_USE_NO_IOSTREAMS)
02418 template<class _CharT, class _Alloc>
02419 ostream& operator<< (ostream& __o, const rope<_CharT,_Alloc>& __r);        
02420 #endif
02421         
02422 typedef rope<char, _STLP_DEFAULT_ALLOCATOR(char) > crope;
02423 # ifdef _STLP_HAS_WCHAR_T
02424 typedef rope<wchar_t, _STLP_DEFAULT_ALLOCATOR(wchar_t) > wrope;
02425 # endif
02426 
02427 inline crope::reference __mutable_reference_at(crope& __c, size_t __i)
02428 {
02429   return __c.mutable_reference_at(__i);
02430 }
02431 
02432 # ifdef _STLP_HAS_WCHAR_T
02433 inline wrope::reference __mutable_reference_at(wrope& __c, size_t __i)
02434 {
02435   return __c.mutable_reference_at(__i);
02436 }
02437 # endif
02438 
02439 #ifdef _STLP_FUNCTION_TMPL_PARTIAL_ORDER
02440 
02441 template <class _CharT, class _Alloc>
02442 inline void swap(rope<_CharT,_Alloc>& __x, rope<_CharT,_Alloc>& __y) {
02443   __x.swap(__y);
02444 }
02445 #else
02446 
02447 inline void swap(crope __x, crope __y) { __x.swap(__y); }
02448 # ifdef _STLP_HAS_WCHAR_T       // dwa 8/21/97
02449 inline void swap(wrope __x, wrope __y) { __x.swap(__y); }
02450 # endif
02451 
02452 #endif /* _STLP_FUNCTION_TMPL_PARTIAL_ORDER */
02453 
02454 
02455 // Hash functions should probably be revisited later:
02456 _STLP_TEMPLATE_NULL struct hash<crope>
02457 {
02458   size_t operator()(const crope& __str) const
02459   {
02460     size_t _p_size = __str.size();
02461 
02462     if (0 == _p_size) return 0;
02463     return 13*__str[0] + 5*__str[_p_size - 1] + _p_size;
02464   }
02465 };
02466 
02467 # ifdef _STLP_HAS_WCHAR_T       // dwa 8/21/97
02468 _STLP_TEMPLATE_NULL struct hash<wrope>
02469 {
02470   size_t operator()(const wrope& __str) const
02471   {
02472     size_t _p_size = __str.size();
02473 
02474     if (0 == _p_size) return 0;
02475     return 13*__str[0] + 5*__str[_p_size - 1] + _p_size;
02476   }
02477 };
02478 #endif
02479 
02480 #ifndef _STLP_MSVC
02481 // I couldn't get this to work with VC++
02482 template<class _CharT,class _Alloc>
02483 void
02484 _Rope_rotate(_Rope_iterator<_CharT,_Alloc> __first,
02485              _Rope_iterator<_CharT,_Alloc> __middle,
02486              _Rope_iterator<_CharT,_Alloc> __last);
02487 
02488 #if !defined(__GNUC__)
02489 // Appears to confuse g++
02490 //DJO Symbian also be confused by this
02491 inline void rotate(_Rope_iterator<char,_STLP_DEFAULT_ALLOCATOR(char) > __first,
02492                    _Rope_iterator<char,_STLP_DEFAULT_ALLOCATOR(char) > __middle,
02493                    _Rope_iterator<char,_STLP_DEFAULT_ALLOCATOR(char) > __last) {
02494   _Rope_rotate(__first, __middle, __last);
02495 }
02496 #endif
02497 
02498 #endif
02499 
02500 template <class _CharT, class _Alloc>
02501 inline _Rope_char_ref_proxy<_CharT, _Alloc>::operator _CharT () const
02502 {
02503   if (_M_current_valid) {
02504         return _M_current;
02505   } else {
02506     return _My_rope::_S_fetch(_M_root->_M_tree_ptr._M_data, _M_pos);
02507   }
02508 }
02509 _STLP_END_NAMESPACE
02510 
02511 # if !defined (_STLP_LINK_TIME_INSTANTIATION)
02512 #  include <stl/_rope.c>
02513 # endif
02514 
02515 # endif /* _STLP_INTERNAL_ROPE_H */
02516 
02517 // Local Variables:
02518 // mode:C++
02519 // End:

Generated on Mon Jun 5 10:20:47 2006 for Intelligence.kdevelop by  doxygen 1.4.6