ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

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

Generated on Sun May 27 2012 04:29:22 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.