stl_rope.h
上传用户:kellyonhid
上传日期:2013-10-12
资源大小:932k
文件大小:92k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. /*
  2.  * Copyright (c) 1997
  3.  * Silicon Graphics Computer Systems, Inc.
  4.  *
  5.  * Permission to use, copy, modify, distribute and sell this software
  6.  * and its documentation for any purpose is hereby granted without fee,
  7.  * provided that the above copyright notice appear in all copies and
  8.  * that both that copyright notice and this permission notice appear
  9.  * in supporting documentation.  Silicon Graphics makes no
  10.  * representations about the suitability of this software for any
  11.  * purpose.  It is provided "as is" without express or implied warranty.
  12.  */
  13. /* NOTE: This is an internal header file, included by other STL headers.
  14.  *   You should not attempt to use it directly.
  15.  */
  16. // rope<_CharT,_Alloc> is a sequence of _CharT.
  17. // Ropes appear to be mutable, but update operations
  18. // really copy enough of the data structure to leave the original
  19. // valid.  Thus ropes can be logically copied by just copying
  20. // a pointer value.
  21. #ifndef __SGI_STL_INTERNAL_ROPE_H
  22. # define __SGI_STL_INTERNAL_ROPE_H
  23. # ifdef __GC
  24. #   define __GC_CONST const
  25. # else
  26. #   define __GC_CONST   // constant except for deallocation
  27. # endif
  28. # ifdef __STL_SGI_THREADS
  29. #    include <mutex.h>
  30. # endif
  31. __STL_BEGIN_NAMESPACE
  32. #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
  33. #pragma set woff 1174
  34. #endif
  35. // The _S_eos function is used for those functions that
  36. // convert to/from C-like strings to detect the end of the string.
  37. // The end-of-C-string character.
  38. // This is what the draft standard says it should be.
  39. template <class _CharT>
  40. inline _CharT _S_eos(_CharT*) { return _CharT(); }
  41. // Test for basic character types.
  42. // For basic character types leaves having a trailing eos.
  43. template <class _CharT>
  44. inline bool _S_is_basic_char_type(_CharT*) { return false; }
  45. template <class _CharT>
  46. inline bool _S_is_one_byte_char_type(_CharT*) { return false; }
  47. inline bool _S_is_basic_char_type(char*) { return true; }
  48. inline bool _S_is_one_byte_char_type(char*) { return true; }
  49. inline bool _S_is_basic_char_type(wchar_t*) { return true; }
  50. // Store an eos iff _CharT is a basic character type.
  51. // Do not reference _S_eos if it isn't.
  52. template <class _CharT>
  53. inline void _S_cond_store_eos(_CharT&) {}
  54. inline void _S_cond_store_eos(char& __c) { __c = 0; }
  55. inline void _S_cond_store_eos(wchar_t& __c) { __c = 0; }
  56. // char_producers are logically functions that generate a section of
  57. // a string.  These can be convereted to ropes.  The resulting rope
  58. // invokes the char_producer on demand.  This allows, for example,
  59. // files to be viewed as ropes without reading the entire file.
  60. template <class _CharT>
  61. class char_producer {
  62.     public:
  63.         virtual ~char_producer() {};
  64.         virtual void operator()(size_t __start_pos, size_t __len, 
  65.                                 _CharT* __buffer) = 0;
  66.         // Buffer should really be an arbitrary output iterator.
  67.         // That way we could flatten directly into an ostream, etc.
  68.         // This is thoroughly impossible, since iterator types don't
  69.         // have runtime descriptions.
  70. };
  71. // Sequence buffers:
  72. //
  73. // Sequence must provide an append operation that appends an
  74. // array to the sequence.  Sequence buffers are useful only if
  75. // appending an entire array is cheaper than appending element by element.
  76. // This is true for many string representations.
  77. // This should  perhaps inherit from ostream<sequence::value_type>
  78. // and be implemented correspondingly, so that they can be used
  79. // for formatted.  For the sake of portability, we don't do this yet.
  80. //
  81. // For now, sequence buffers behave as output iterators.  But they also
  82. // behave a little like basic_ostringstream<sequence::value_type> and a
  83. // little like containers.
  84. template<class _Sequence, size_t _Buf_sz = 100
  85. #   if defined(__sgi) && !defined(__GNUC__)
  86. #        define __TYPEDEF_WORKAROUND
  87.          ,class _V = typename _Sequence::value_type
  88. #   endif
  89.         >
  90. // The 3rd parameter works around a common compiler bug.
  91. class sequence_buffer : public output_iterator {
  92.     public:
  93. #       ifndef __TYPEDEF_WORKAROUND
  94.             typedef typename _Sequence::value_type value_type;
  95. #       else
  96.             typedef _V value_type;
  97. #       endif
  98.     protected:
  99.         _Sequence* _M_prefix;
  100.         value_type _M_buffer[_Buf_sz];
  101.         size_t     _M_buf_count;
  102.     public:
  103.         void flush() {
  104.             _M_prefix->append(_M_buffer, _M_buffer + _M_buf_count);
  105.             _M_buf_count = 0;
  106.         }
  107.         ~sequence_buffer() { flush(); }
  108.         sequence_buffer() : _M_prefix(0), _M_buf_count(0) {}
  109.         sequence_buffer(const sequence_buffer& __x) {
  110.             _M_prefix = __x._M_prefix;
  111.             _M_buf_count = __x._M_buf_count;
  112.             copy(__x._M_buffer, __x._M_buffer + __x._M_buf_count, _M_buffer);
  113.         }
  114.         sequence_buffer(sequence_buffer& __x) {
  115.             __x.flush();
  116.             _M_prefix = __x._M_prefix;
  117.             _M_buf_count = 0;
  118.         }
  119.         sequence_buffer(_Sequence& __s) : _M_prefix(&__s), _M_buf_count(0) {}
  120.         sequence_buffer& operator= (sequence_buffer& __x) {
  121.             __x.flush();
  122.             _M_prefix = __x._M_prefix;
  123.             _M_buf_count = 0;
  124.             return *this;
  125.         }
  126.         sequence_buffer& operator= (const sequence_buffer& __x) {
  127.             _M_prefix = __x._M_prefix;
  128.             _M_buf_count = __x._M_buf_count;
  129.             copy(__x._M_buffer, __x._M_buffer + __x._M_buf_count, _M_buffer);
  130.             return *this;
  131.         }
  132.         void push_back(value_type __x)
  133.         {
  134.             if (_M_buf_count < _Buf_sz) {
  135.                 _M_buffer[_M_buf_count] = __x;
  136.                 ++_M_buf_count;
  137.             } else {
  138.                 flush();
  139.                 _M_buffer[0] = __x;
  140.                 _M_buf_count = 1;
  141.             }
  142.         }
  143.         void append(value_type* __s, size_t __len)
  144.         {
  145.             if (__len + _M_buf_count <= _Buf_sz) {
  146.                 size_t __i = _M_buf_count;
  147.                 size_t __j = 0;
  148.                 for (; __j < __len; __i++, __j++) {
  149.                     _M_buffer[__i] = __s[__j];
  150.                 }
  151.                 _M_buf_count += __len;
  152.             } else if (0 == _M_buf_count) {
  153.                 _M_prefix->append(__s, __s + __len);
  154.             } else {
  155.                 flush();
  156.                 append(__s, __len);
  157.             }
  158.         }
  159.         sequence_buffer& write(value_type* __s, size_t __len)
  160.         {
  161.             append(__s, __len);
  162.             return *this;
  163.         }
  164.         sequence_buffer& put(value_type __x)
  165.         {
  166.             push_back(__x);
  167.             return *this;
  168.         }
  169.         sequence_buffer& operator=(const value_type& __rhs)
  170.         {
  171.             push_back(__rhs);
  172.             return *this;
  173.         }
  174.         sequence_buffer& operator*() { return *this; }
  175.         sequence_buffer& operator++() { return *this; }
  176.         sequence_buffer& operator++(int) { return *this; }
  177. };
  178. // The following should be treated as private, at least for now.
  179. template<class _CharT>
  180. class _Rope_char_consumer {
  181.     public:
  182.         // If we had member templates, these should not be virtual.
  183.         // For now we need to use run-time parametrization where
  184.         // compile-time would do.  _Hence this should all be private
  185.         // for now.
  186.         // The symmetry with char_producer is accidental and temporary.
  187.         virtual ~_Rope_char_consumer() {};
  188.         virtual bool operator()(const _CharT* __buffer, size_t __len) = 0;
  189. };
  190. //
  191. // What follows should really be local to rope.  Unfortunately,
  192. // that doesn't work, since it makes it impossible to define generic
  193. // equality on rope iterators.  According to the draft standard, the
  194. // template parameters for such an equality operator cannot be inferred
  195. // from the occurence of a member class as a parameter.
  196. // (SGI compilers in fact allow this, but the __result wouldn't be
  197. // portable.)
  198. // Similarly, some of the static member functions are member functions
  199. // only to avoid polluting the global namespace, and to circumvent
  200. // restrictions on type inference for template functions.
  201. //
  202. template<class _CharT, class _Alloc=__STL_DEFAULT_ALLOCATOR(_CharT)> class rope;
  203. template<class _CharT, class _Alloc> struct _Rope_RopeConcatenation;
  204. template<class _CharT, class _Alloc> struct _Rope_RopeLeaf;
  205. template<class _CharT, class _Alloc> struct _Rope_RopeFunction;
  206. template<class _CharT, class _Alloc> struct _Rope_RopeSubstring;
  207. template<class _CharT, class _Alloc> class _Rope_iterator;
  208. template<class _CharT, class _Alloc> class _Rope_const_iterator;
  209. template<class _CharT, class _Alloc> class _Rope_char_ref_proxy;
  210. template<class _CharT, class _Alloc> class _Rope_char_ptr_proxy;
  211. //
  212. // The internal data structure for representing a rope.  This is
  213. // private to the implementation.  A rope is really just a pointer
  214. // to one of these.
  215. //
  216. // A few basic functions for manipulating this data structure
  217. // are members of _RopeRep.  Most of the more complex algorithms
  218. // are implemented as rope members.
  219. //
  220. // Some of the static member functions of _RopeRep have identically
  221. // named functions in rope that simply invoke the _RopeRep versions.
  222. //
  223. // A macro to introduce various allocation and deallocation functions
  224. // These need to be defined differently depending on whether or not
  225. // we are using standard conforming allocators, and whether the allocator
  226. // instances have real state.  Thus this macro is invoked repeatedly
  227. // with different definitions of __ROPE_DEFINE_ALLOC.
  228. // __ROPE_DEFINE_ALLOC(type,name) defines 
  229. //   type * name_allocate(size_t) and
  230. //   void name_deallocate(tipe *, size_t)
  231. // Both functions may or may not be static.
  232. #define __ROPE_DEFINE_ALLOCS(__a) 
  233.         __ROPE_DEFINE_ALLOC(_CharT,_Data) /* character data */ 
  234.         typedef _Rope_RopeConcatenation<_CharT,__a> __C; 
  235.         __ROPE_DEFINE_ALLOC(__C,_C) 
  236.         typedef _Rope_RopeLeaf<_CharT,__a> __L; 
  237.         __ROPE_DEFINE_ALLOC(__L,_L) 
  238.         typedef _Rope_RopeFunction<_CharT,__a> __F; 
  239.         __ROPE_DEFINE_ALLOC(__F,_F) 
  240.         typedef _Rope_RopeSubstring<_CharT,__a> __S; 
  241.         __ROPE_DEFINE_ALLOC(__S,_S)
  242. //  Internal rope nodes potentially store a copy of the allocator
  243. //  instance used to allocate them.  This is mostly redundant.
  244. //  But the alternative would be to pass allocator instances around
  245. //  in some form to nearly all internal functions, since any pointer
  246. //  assignment may result in a zero reference count and thus require
  247. //  deallocation.
  248. //  The _Rope_rep_base class encapsulates
  249. //  the differences between SGI-style allocators and standard-conforming
  250. //  allocators.
  251. #ifdef __STL_USE_STD_ALLOCATORS
  252. #define __STATIC_IF_SGI_ALLOC  /* not static */
  253. // Base class for ordinary allocators.
  254. template <class _CharT, class _Allocator, bool _IsStatic>
  255. class _Rope_rep_alloc_base {
  256. public:
  257.   typedef typename _Alloc_traits<_CharT,_Allocator>::allocator_type
  258.           allocator_type;
  259.   allocator_type get_allocator() const { return _M_data_allocator; }
  260.   _Rope_rep_alloc_base(size_t __size, const allocator_type& __a)
  261.         : _M_size(__size), _M_data_allocator(__a) {}
  262.   size_t _M_size;       // This is here only to avoid wasting space
  263.                 // for an otherwise empty base class.
  264.   
  265. protected:
  266.     allocator_type _M_data_allocator;
  267. # define __ROPE_DEFINE_ALLOC(_T, __name) 
  268.         typedef typename 
  269.           _Alloc_traits<_T,_Allocator>::allocator_type __name##Allocator; 
  270.         /*static*/ _T * __name##_allocate(size_t __n) 
  271.           { return __name##Allocator(_M_data_allocator).allocate(__n); } 
  272.         void __name##_deallocate(_T* __p, size_t __n) 
  273.           { __name##Allocator(_M_data_allocator).deallocate(__p, __n); }
  274.   __ROPE_DEFINE_ALLOCS(_Allocator);
  275. # undef __ROPE_DEFINE_ALLOC
  276. };
  277. // Specialization for allocators that have the property that we don't
  278. //  actually have to store an allocator object.  
  279. template <class _CharT, class _Allocator>
  280. class _Rope_rep_alloc_base<_CharT,_Allocator,true> {
  281. public:
  282.   typedef typename _Alloc_traits<_CharT,_Allocator>::allocator_type
  283.           allocator_type;
  284.   allocator_type get_allocator() const { return allocator_type(); }
  285.   _Rope_rep_alloc_base(size_t __size, const allocator_type&)
  286.                 : _M_size(__size) {}
  287.   size_t _M_size;
  288.   
  289. protected:
  290. # define __ROPE_DEFINE_ALLOC(_T, __name) 
  291.         typedef typename 
  292.           _Alloc_traits<_T,_Allocator>::_Alloc_type __name##Alloc; 
  293.         typedef typename 
  294.           _Alloc_traits<_T,_Allocator>::allocator_type __name##Allocator; 
  295.         static _T* __name##_allocate(size_t __n) 
  296.                 { return __name##Alloc::allocate(__n); } 
  297.         void __name##_deallocate(_T *__p, size_t __n) 
  298.                 { __name##Alloc::deallocate(__p, __n); }
  299.   __ROPE_DEFINE_ALLOCS(_Allocator);
  300. # undef __ROPE_DEFINE_ALLOC
  301. };
  302. template <class _CharT, class _Alloc>
  303. struct _Rope_rep_base
  304.   : public _Rope_rep_alloc_base<_CharT,_Alloc,
  305.                                 _Alloc_traits<_CharT,_Alloc>::_S_instanceless>
  306. {
  307.   typedef _Rope_rep_alloc_base<_CharT,_Alloc,
  308.                                _Alloc_traits<_CharT,_Alloc>::_S_instanceless>
  309.           _Base;
  310.   typedef typename _Base::allocator_type allocator_type;
  311.   _Rope_rep_base(size_t __size, const allocator_type& __a)
  312.     : _Base(__size, __a) {}
  313. };    
  314. #else /* !__STL_USE_STD_ALLOCATORS */
  315. #define __STATIC_IF_SGI_ALLOC static
  316. template <class _CharT, class _Alloc> 
  317. class _Rope_rep_base {
  318. public:
  319.   typedef _Alloc allocator_type;
  320.   static allocator_type get_allocator() { return allocator_type(); }
  321.   _Rope_rep_base(size_t __size, const allocator_type&) : _M_size(__size) {}
  322.   size_t _M_size;
  323. protected:
  324. # define __ROPE_DEFINE_ALLOC(_T, __name) 
  325.         typedef simple_alloc<_T, _Alloc> __name##Alloc; 
  326.         static _T* __name##_allocate(size_t __n) 
  327.                 { return __name##Alloc::allocate(__n); } 
  328.         static void __name##_deallocate(_T* __p, size_t __n) 
  329.                 { __name##Alloc::deallocate(__p, __n); }
  330.   __ROPE_DEFINE_ALLOCS(_Alloc);
  331. # undef __ROPE_DEFINE_ALLOC
  332. };
  333. #endif /* __STL_USE_STD_ALLOCATORS */
  334. template<class _CharT, class _Alloc>
  335. struct _Rope_RopeRep : public _Rope_rep_base<_CharT,_Alloc> {
  336.     public:
  337.     enum { _S_max_rope_depth = 45 };
  338.     enum _Tag {_S_leaf, _S_concat, _S_substringfn, _S_function};
  339.     _Tag _M_tag:8;
  340.     bool _M_is_balanced:8;
  341.     unsigned char _M_depth;
  342.     __GC_CONST _CharT* _M_c_string;
  343.                         /* Flattened version of string, if needed.  */
  344.                         /* typically 0.                             */
  345.                         /* If it's not 0, then the memory is owned  */
  346.                         /* by this node.                            */
  347.                         /* In the case of a leaf, this may point to */
  348.                         /* the same memory as the data field.       */
  349.     typedef _Rope_rep_base<_CharT,_Alloc>::allocator_type allocator_type;
  350.     _Rope_RopeRep(_Tag __t, int __d, bool __b, size_t __size,
  351.                   allocator_type __a)
  352.         : _M_tag(__t), _M_depth(__d), _M_is_balanced(__b), _M_c_string(0),
  353.           _Rope_rep_base<_CharT,_Alloc>(__size, __a)
  354.     {
  355. #       ifndef __GC
  356.             _M_refcount = 1;
  357.             _M_init_refcount_lock();
  358. #       endif
  359.     }
  360. #   ifndef __GC
  361. #       if defined(__STL_WIN32THREADS)
  362.             long _M_refcount;   // InterlockedIncrement wants a long *
  363. #       else
  364.             size_t _M_refcount;
  365. #       endif
  366.         // We count references from rope instances
  367.         // and references from other rope nodes.  We
  368.         // do not count const_iterator references.
  369.         // Iterator references are counted so that rope modifications
  370.         // can be detected after the fact.
  371.         // Generally function results are counted, i.__e.
  372.         // a pointer returned by a function is included at the
  373.         // point at which the pointer is returned.
  374.         // The recipient should decrement the count if the
  375.         // __result is not needed.
  376.         // Generally function arguments are not reflected
  377.         // in the reference count.  The callee should increment
  378.         // the count before saving the argument someplace that
  379.         // will outlive the call.
  380. #   endif
  381. #   ifndef __GC
  382. #       ifdef __STL_SGI_THREADS
  383.             // Reference counting with multiple threads and no
  384.             // hardware or thread package support is pretty awful.
  385.             // Mutexes are normally too expensive.
  386.             // We'll assume a COMPARE_AND_SWAP(destp, __old, new)
  387.             // operation, which might be cheaper.
  388. #           if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64))
  389. #               define __add_and_fetch(l,v) add_then_test((unsigned long*)l,v)
  390. #           endif
  391.             void _M_init_refcount_lock() {}
  392.             void _M_incr_refcount ()
  393.             {
  394.                 __add_and_fetch(&_M_refcount, 1);
  395.             }
  396.             size_t _M_decr_refcount ()
  397.             {
  398.                 return __add_and_fetch(&_M_refcount, (size_t)(-1));
  399.             }
  400. #       elif defined(__STL_WIN32THREADS)
  401.             void _M_init_refcount_lock() {}
  402.             void _M_incr_refcount ()
  403.             {
  404.                 InterlockedIncrement(&_M_refcount);
  405.             }
  406.             size_t _M_decr_refcount ()
  407.             {
  408.                 return InterlockedDecrement(&_M_refcount);
  409.             }
  410. #       elif defined(_PTHREADS)
  411.             // This should be portable, but performance is expected
  412.             // to be quite awful.  This really needs platform specific
  413.             // code.
  414.             pthread_mutex_t _M_refcount_lock;
  415.             void _M_init_refcount_lock() {
  416.                 pthread_mutex_init(&_M_refcount_lock, 0);
  417.             }
  418.             void _M_incr_refcount ()
  419.             {   
  420.                 pthread_mutex_lock(&_M_refcount_lock);
  421.                 ++_M_refcount;
  422.                 pthread_mutex_unlock(&_M_refcount_lock);
  423.             }
  424.             size_t _M_decr_refcount ()
  425.             {   
  426.                 size_t __result;
  427.                 pthread_mutex_lock(&_M_refcount_lock);
  428.                 __result = --_M_refcount;
  429.                 pthread_mutex_unlock(&_M_refcount_lock);
  430.                 return __result;
  431.             }
  432. #       else
  433.             void _M_init_refcount_lock() {}
  434.             void _M_incr_refcount ()
  435.             {
  436.                 ++_M_refcount;
  437.             }
  438.             size_t _M_decr_refcount ()
  439.             {
  440.                 --_M_refcount;
  441.                 return _M_refcount;
  442.             }
  443. #       endif
  444. #   else
  445.         void _M_incr_refcount () {}
  446. #   endif
  447. #   ifdef __STL_USE_STD_ALLOCATORS
  448.         static void _S_free_string(__GC_CONST _CharT*, size_t __len,
  449.                                    allocator_type __a);
  450. #       define __STL_FREE_STRING(__s, __l, __a) _S_free_string(__s, __l, __a);
  451. #   else
  452.         static void _S_free_string(__GC_CONST _CharT*, size_t __len);
  453. #       define __STL_FREE_STRING(__s, __l, __a) _S_free_string(__s, __l);
  454. #   endif
  455.                         // Deallocate data section of a leaf.
  456.                         // This shouldn't be a member function.
  457.                         // But its hard to do anything else at the
  458.                         // moment, because it's templatized w.r.t.
  459.                         // an allocator.
  460.                         // Does nothing if __GC is defined.
  461. #   ifndef __GC
  462.           void _M_free_c_string();
  463.           void _M_free_tree();
  464.                         // Deallocate t. Assumes t is not 0.
  465.           void _M_unref_nonnil()
  466.           {
  467.               if (0 == _M_decr_refcount()) _M_free_tree();
  468.           }
  469.           void _M_ref_nonnil()
  470.           {
  471.               _M_incr_refcount();
  472.           }
  473.           static void _S_unref(_Rope_RopeRep* __t)
  474.           {
  475.               if (0 != __t) {
  476.                   __t->_M_unref_nonnil();
  477.               }
  478.           }
  479.           static void _S_ref(_Rope_RopeRep* __t)
  480.           {
  481.               if (0 != __t) __t->_M_incr_refcount();
  482.           }
  483.           static void _S_free_if_unref(_Rope_RopeRep* __t)
  484.           {
  485.               if (0 != __t && 0 == __t->_M_refcount) __t->_M_free_tree();
  486.           }
  487. #   else /* __GC */
  488.           void _M_unref_nonnil() {}
  489.           void _M_ref_nonnil() {}
  490.           static void _S_unref(_Rope_RopeRep*) {}
  491.           static void _S_ref(_Rope_RopeRep*) {}
  492.           static void _S_free_if_unref(_Rope_RopeRep*) {}
  493. #   endif
  494. };
  495. template<class _CharT, class _Alloc>
  496. struct _Rope_RopeLeaf : public _Rope_RopeRep<_CharT,_Alloc> {
  497.   public:
  498.     // Apparently needed by VC++
  499.     // The data fields of leaves are allocated with some
  500.     // extra space, to accomodate future growth and for basic
  501.     // character types, to hold a trailing eos character.
  502.     enum { _S_alloc_granularity = 8 };
  503.     static size_t _S_rounded_up_size(size_t __n) {
  504.         size_t __size_with_eos;
  505.              
  506.         if (_S_is_basic_char_type((_CharT*)0)) {
  507.             __size_with_eos = __n + 1;
  508.         } else {
  509.             __size_with_eos = __n;
  510.         }
  511. #       ifdef __GC
  512.            return __size_with_eos;
  513. #       else
  514.            // Allow slop for in-place expansion.
  515.            return (__size_with_eos + _S_alloc_granularity-1)
  516.                         &~ (_S_alloc_granularity-1);
  517. #       endif
  518.     }
  519.     __GC_CONST _CharT* _M_data; /* Not necessarily 0 terminated. */
  520.                                 /* The allocated size is         */
  521.                                 /* _S_rounded_up_size(size), except */
  522.                                 /* in the GC case, in which it   */
  523.                                 /* doesn't matter.               */
  524.     typedef _Rope_rep_base<_CharT,_Alloc>::allocator_type allocator_type;
  525.     _Rope_RopeLeaf(__GC_CONST _CharT* __d, size_t __size, allocator_type __a)
  526.         : _M_data(__d)
  527.         , _Rope_RopeRep<_CharT,_Alloc>(_S_leaf, 0, true, __size, __a)
  528.         {
  529.         __stl_assert(__size > 0);
  530.         if (_S_is_basic_char_type((_CharT *)0)) {
  531.             // already eos terminated.
  532.             _M_c_string = __d;
  533.         }
  534.     }
  535.         // The constructor assumes that d has been allocated with
  536.         // the proper allocator and the properly padded size.
  537.         // In contrast, the destructor deallocates the data:
  538. # ifndef __GC
  539.     ~_Rope_RopeLeaf() {
  540.         if (_M_data != _M_c_string) {
  541.             _M_free_c_string();
  542.         }
  543.         __STL_FREE_STRING(_M_data, _M_size, get_allocator());
  544.     }
  545. # endif
  546. };
  547. template<class _CharT, class _Alloc>
  548. struct _Rope_RopeConcatenation : public _Rope_RopeRep<_CharT,_Alloc> {
  549.   public:
  550.     _Rope_RopeRep<_CharT,_Alloc>* _M_left;
  551.     _Rope_RopeRep<_CharT,_Alloc>* _M_right;
  552.     typedef _Rope_rep_base<_CharT,_Alloc>::allocator_type allocator_type;
  553.     _Rope_RopeConcatenation(_Rope_RopeRep<_CharT,_Alloc>* __l,
  554.                              _Rope_RopeRep<_CharT,_Alloc>* __r,
  555.                              allocator_type __a)
  556.       : _M_left(__l), _M_right(__r)
  557.       , _Rope_RopeRep<_CharT,_Alloc>(
  558.           _S_concat, max(__l->_M_depth, __r->_M_depth) + 1, false,
  559.           __l->_M_size + __r->_M_size, __a)
  560.       {}
  561. # ifndef __GC
  562.     ~_Rope_RopeConcatenation() {
  563.         _M_free_c_string();
  564.         _M_left->_M_unref_nonnil();
  565.         _M_right->_M_unref_nonnil();
  566.     }
  567. # endif
  568. };
  569. template<class _CharT, class _Alloc>
  570. struct _Rope_RopeFunction : public _Rope_RopeRep<_CharT,_Alloc> {
  571.   public:
  572.     char_producer<_CharT>* _M_fn;
  573. #   ifndef __GC
  574.       bool _M_delete_when_done; // Char_producer is owned by the
  575.                                 // rope and should be explicitly
  576.                                 // deleted when the rope becomes
  577.                                 // inaccessible.
  578. #   else
  579.       // In the GC case, we either register the rope for
  580.       // finalization, or not.  Thus the field is unnecessary;
  581.       // the information is stored in the collector data structures.
  582.       // We do need a finalization procedure to be invoked by the
  583.       // collector.
  584.       static void _S_fn_finalization_proc(void * __tree, void *) {
  585.         delete ((_Rope_RopeFunction *)__tree) -> _M_fn;
  586.       }
  587. #   endif
  588.     typedef _Rope_rep_base<_CharT,_Alloc>::allocator_type allocator_type;
  589.     _Rope_RopeFunction(char_producer<_CharT>* __f, size_t __size,
  590.                         bool __d, allocator_type __a)
  591.       : _M_fn(__f)
  592. #       ifndef __GC
  593.       , _M_delete_when_done(__d)
  594. #       endif
  595.       , _Rope_RopeRep<_CharT,_Alloc>(_S_function, 0, true, __size, __a) {
  596.         __stl_assert(__size > 0);
  597. #       ifdef __GC
  598.             if (__d) {
  599.                 GC_REGISTER_FINALIZER(
  600.                   this, _Rope_RopeFunction::_S_fn_finalization_proc, 0, 0, 0);
  601.             }
  602. #       endif
  603.     }
  604. # ifndef __GC
  605.     ~_Rope_RopeFunction() {
  606.           _M_free_c_string();
  607.           if (_M_delete_when_done) {
  608.               delete _M_fn;
  609.           }
  610.     }
  611. # endif
  612. };
  613. // Substring results are usually represented using just
  614. // concatenation nodes.  But in the case of very long flat ropes
  615. // or ropes with a functional representation that isn't practical.
  616. // In that case, we represent the __result as a special case of
  617. // RopeFunction, whose char_producer points back to the rope itself.
  618. // In all cases except repeated substring operations and
  619. // deallocation, we treat the __result as a RopeFunction.
  620. template<class _CharT, class _Alloc>
  621. struct _Rope_RopeSubstring : public _Rope_RopeFunction<_CharT,_Alloc>,
  622.                              public char_producer<_CharT> {
  623.   public:
  624.     // XXX this whole class should be rewritten.
  625.     _Rope_RopeRep<_CharT,_Alloc>* _M_base;      // not 0
  626.     size_t _M_start;
  627.     virtual void operator()(size_t __start_pos, size_t __req_len,
  628.                             _CharT* __buffer) {
  629.         switch(_M_base->_M_tag) {
  630.             case _S_function:
  631.             case _S_substringfn:
  632.               {
  633.                 char_producer<_CharT>* __fn =
  634.                         ((_Rope_RopeFunction<_CharT,_Alloc>*)_M_base)->_M_fn;
  635.                 __stl_assert(__start_pos + __req_len <= _M_size);
  636.                 __stl_assert(_M_start + _M_size <= _M_base->_M_size);
  637.                 (*__fn)(__start_pos + _M_start, __req_len, __buffer);
  638.               }
  639.               break;
  640.             case _S_leaf:
  641.               {
  642.                 __GC_CONST _CharT* __s =
  643.                         ((_Rope_RopeLeaf<_CharT,_Alloc>*)_M_base)->_M_data;
  644.                 uninitialized_copy_n(__s + __start_pos + _M_start, __req_len,
  645.                                      __buffer);
  646.               }
  647.               break;
  648.             default:
  649.               __stl_assert(false);
  650.         }
  651.     }
  652.     typedef _Rope_rep_base<_CharT,_Alloc>::allocator_type allocator_type;
  653.     _Rope_RopeSubstring(_Rope_RopeRep<_CharT,_Alloc>* __b, size_t __s,
  654.                           size_t __l, allocator_type __a)
  655.       : _M_base(__b)
  656.       , _M_start(__s)
  657.       , _Rope_RopeFunction<_CharT,_Alloc>(this, __l, false, __a) 
  658.     {
  659.         __stl_assert(__l > 0);
  660.         __stl_assert(__s + __l <= __b->_M_size);
  661. #       ifndef __GC
  662.             _M_base->_M_ref_nonnil();
  663. #       endif
  664.         _M_tag = _S_substringfn;
  665.     }
  666.     virtual ~_Rope_RopeSubstring()
  667.       { 
  668. #       ifndef __GC
  669.           _M_base->_M_unref_nonnil();
  670.           _M_free_c_string();
  671. #       endif
  672.       }
  673. };
  674. // Self-destructing pointers to Rope_rep.
  675. // These are not conventional smart pointers.  Their
  676. // only purpose in life is to ensure that unref is called
  677. // on the pointer either at normal exit or if an exception
  678. // is raised.  It is the caller's responsibility to
  679. // adjust reference counts when these pointers are initialized
  680. // or assigned to.  (This convention significantly reduces
  681. // the number of potentially expensive reference count
  682. // updates.)
  683. #ifndef __GC
  684.   template<class _CharT, class _Alloc>
  685.   struct _Rope_self_destruct_ptr {
  686.     _Rope_RopeRep<_CharT,_Alloc>* _M_ptr;
  687.     ~_Rope_self_destruct_ptr() 
  688.       { _Rope_RopeRep<_CharT,_Alloc>::_S_unref(_M_ptr); }
  689. #   ifdef __STL_USE_EXCEPTIONS
  690.         _Rope_self_destruct_ptr() : _M_ptr(0) {};
  691. #   else
  692.         _Rope_self_destruct_ptr() {};
  693. #   endif
  694.     _Rope_self_destruct_ptr(_Rope_RopeRep<_CharT,_Alloc>* __p) : _M_ptr(__p) {}
  695.     _Rope_RopeRep<_CharT,_Alloc>& operator*() { return *_M_ptr; }
  696.     _Rope_RopeRep<_CharT,_Alloc>* operator->() { return _M_ptr; }
  697.     operator _Rope_RopeRep<_CharT,_Alloc>*() { return _M_ptr; }
  698.     _Rope_self_destruct_ptr& operator= (_Rope_RopeRep<_CharT,_Alloc>* __x)
  699.         { _M_ptr = __x; return *this; }
  700.   };
  701. #endif
  702. // Dereferencing a nonconst iterator has to return something
  703. // that behaves almost like a reference.  It's not possible to
  704. // return an actual reference since assignment requires extra
  705. // work.  And we would get into the same problems as with the
  706. // CD2 version of basic_string.
  707. template<class _CharT, class _Alloc>
  708. class _Rope_char_ref_proxy {
  709.     friend class rope<_CharT,_Alloc>;
  710.     friend class _Rope_iterator<_CharT,_Alloc>;
  711.     friend class _Rope_char_ptr_proxy<_CharT,_Alloc>;
  712. #   ifdef __GC
  713.         typedef _Rope_RopeRep<_CharT,_Alloc>* _Self_destruct_ptr;
  714. #   else
  715.         typedef _Rope_self_destruct_ptr<_CharT,_Alloc> _Self_destruct_ptr;
  716. #   endif
  717.     typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep;
  718.     typedef rope<_CharT,_Alloc> _My_rope;
  719.     size_t _M_pos;
  720.     _CharT _M_current;
  721.     bool _M_current_valid;
  722.     _My_rope* _M_root;     // The whole rope.
  723.   public:
  724.     _Rope_char_ref_proxy(_My_rope* __r, size_t __p) :
  725.         _M_pos(__p), _M_root(__r), _M_current_valid(false) {}
  726.     _Rope_char_ref_proxy(const _Rope_char_ref_proxy& __x) :
  727.         _M_pos(__x._M_pos), _M_root(__x._M_root), _M_current_valid(false) {}
  728.         // Don't preserve cache if the reference can outlive the
  729.         // expression.  We claim that's not possible without calling
  730.         // a copy constructor or generating reference to a proxy
  731.         // reference.  We declare the latter to have undefined semantics.
  732.     _Rope_char_ref_proxy(_My_rope* __r, size_t __p,
  733.                     _CharT __c) :
  734.         _M_pos(__p), _M_root(__r), _M_current(__c), _M_current_valid(true) {}
  735.     inline operator _CharT () const;
  736.     _Rope_char_ref_proxy& operator= (_CharT __c);
  737.     _Rope_char_ptr_proxy<_CharT,_Alloc> operator& () const;
  738.     _Rope_char_ref_proxy& operator= (const _Rope_char_ref_proxy& __c) {
  739.         return operator=((_CharT)__c); 
  740.     }
  741. };
  742. #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
  743.     template<class _CharT, class __Alloc>
  744.     inline void swap(_Rope_char_ref_proxy <_CharT, __Alloc > __a,
  745.                      _Rope_char_ref_proxy <_CharT, __Alloc > __b) {
  746.         _CharT __tmp = __a;
  747.         __a = __b;
  748.         __b = __tmp;
  749.     }
  750. #else
  751. // There is no really acceptable way to handle this.  The default
  752. // definition of swap doesn't work for proxy references.
  753. // It can't really be made to work, even with ugly hacks, since
  754. // the only unusual operation it uses is the copy constructor, which
  755. // is needed for other purposes.  We provide a macro for
  756. // full specializations, and instantiate the most common case.
  757. # define _ROPE_SWAP_SPECIALIZATION(_CharT, __Alloc) 
  758.     inline void swap(_Rope_char_ref_proxy <_CharT, __Alloc > __a, 
  759.                      _Rope_char_ref_proxy <_CharT, __Alloc > __b) { 
  760.         _CharT __tmp = __a; 
  761.         __a = __b; 
  762.         __b = __tmp; 
  763.     }
  764. _ROPE_SWAP_SPECIALIZATION(char,__STL_DEFAULT_ALLOCATOR(char))
  765. #endif /* !__STL_FUNCTION_TMPL_PARTIAL_ORDER */
  766. template<class _CharT, class _Alloc>
  767. class _Rope_char_ptr_proxy {
  768.     // XXX this class should be rewritten.
  769.     friend class _Rope_char_ref_proxy<_CharT,_Alloc>;
  770.     size_t _M_pos;
  771.     rope<_CharT,_Alloc>* _M_root;     // The whole rope.
  772.   public:
  773.     _Rope_char_ptr_proxy(const _Rope_char_ref_proxy<_CharT,_Alloc>& __x) 
  774.       : _M_pos(__x._M_pos), _M_root(__x._M_root) {}
  775.     _Rope_char_ptr_proxy(const _Rope_char_ptr_proxy& __x)
  776.       : _M_pos(__x._M_pos), _M_root(__x._M_root) {}
  777.     _Rope_char_ptr_proxy() {}
  778.     _Rope_char_ptr_proxy(_CharT* __x) : _M_root(0), _M_pos(0) {
  779.         __stl_assert(0 == __x);
  780.     }
  781.     _Rope_char_ptr_proxy& 
  782.     operator= (const _Rope_char_ptr_proxy& __x) {
  783.         _M_pos = __x._M_pos;
  784.         _M_root = __x._M_root;
  785.         return *this;
  786.     }
  787.     friend bool operator==  __STL_NULL_TMPL_ARGS
  788.                 (const _Rope_char_ptr_proxy<_CharT,_Alloc>& __x,
  789.                  const _Rope_char_ptr_proxy<_CharT,_Alloc>& __y);
  790.     _Rope_char_ref_proxy<_CharT,_Alloc> operator*() const {
  791.         return _Rope_char_ref_proxy<_CharT,_Alloc>(_M_root, _M_pos);
  792.     }
  793. };
  794. // Rope iterators:
  795. // Unlike in the C version, we cache only part of the stack
  796. // for rope iterators, since they must be efficiently copyable.
  797. // When we run out of cache, we have to reconstruct the iterator
  798. // value.
  799. // Pointers from iterators are not included in reference counts.
  800. // Iterators are assumed to be thread private.  Ropes can
  801. // be shared.
  802. #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
  803. #pragma set woff 1375
  804. #endif
  805. template<class _CharT, class _Alloc>
  806. class _Rope_iterator_base
  807.   : public random_access_iterator<_CharT, ptrdiff_t> {
  808.     friend class rope<_CharT,_Alloc>;
  809.   public:
  810.     typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep;
  811.         // Borland doesnt want this to be protected.
  812.   protected:
  813.     enum { _S_path_cache_len = 4 }; // Must be <= 9.
  814.     enum { _S_iterator_buf_len = 15 };
  815.     size_t _M_current_pos;
  816.     _RopeRep* _M_root;     // The whole rope.
  817.     size_t _M_leaf_pos;    // Starting position for current leaf
  818.     __GC_CONST _CharT* _M_buf_start;
  819.                         // Buffer possibly
  820.                         // containing current char.
  821.     __GC_CONST _CharT* _M_buf_ptr;
  822.                         // Pointer to current char in buffer.
  823.                         // != 0 ==> buffer valid.
  824.     __GC_CONST _CharT* _M_buf_end;
  825.                         // One past __last valid char in buffer.
  826.     // What follows is the path cache.  We go out of our
  827.     // way to make this compact.
  828.     // Path_end contains the bottom section of the path from
  829.     // the root to the current leaf.
  830.     const _RopeRep* _M_path_end[_S_path_cache_len];
  831.     int _M_leaf_index;     // Last valid __pos in path_end;
  832.                         // _M_path_end[0] ... _M_path_end[leaf_index-1]
  833.                         // point to concatenation nodes.
  834.     unsigned char _M_path_directions;
  835.                           // (path_directions >> __i) & 1 is 1
  836.                           // iff we got from _M_path_end[leaf_index - __i - 1]
  837.                           // to _M_path_end[leaf_index - __i] by going to the
  838.                           // __right. Assumes path_cache_len <= 9.
  839.     _CharT _M_tmp_buf[_S_iterator_buf_len];
  840.                         // Short buffer for surrounding chars.
  841.                         // This is useful primarily for 
  842.                         // RopeFunctions.  We put the buffer
  843.                         // here to avoid locking in the
  844.                         // multithreaded case.
  845.     // The cached path is generally assumed to be valid
  846.     // only if the buffer is valid.
  847.     static void _S_setbuf(_Rope_iterator_base& __x);
  848.                                         // Set buffer contents given
  849.                                         // path cache.
  850.     static void _S_setcache(_Rope_iterator_base& __x);
  851.                                         // Set buffer contents and
  852.                                         // path cache.
  853.     static void _S_setcache_for_incr(_Rope_iterator_base& __x);
  854.                                         // As above, but assumes path
  855.                                         // cache is valid for previous posn.
  856.     _Rope_iterator_base() {}
  857.     _Rope_iterator_base(_RopeRep* __root, size_t __pos)
  858.       : _M_root(__root), _M_current_pos(__pos), _M_buf_ptr(0) {}
  859.     void _M_incr(size_t __n);
  860.     void _M_decr(size_t __n);
  861.   public:
  862.     size_t index() const { return _M_current_pos; }
  863.     _Rope_iterator_base(const _Rope_iterator_base& __x) {
  864.         if (0 != __x._M_buf_ptr) {
  865.             *this = __x;
  866.         } else {
  867.             _M_current_pos = __x._M_current_pos;
  868.             _M_root = __x._M_root;
  869.             _M_buf_ptr = 0;
  870.         }
  871.     }
  872. };
  873. template<class _CharT, class _Alloc> class _Rope_iterator;
  874. template<class _CharT, class _Alloc>
  875. class _Rope_const_iterator : public _Rope_iterator_base<_CharT,_Alloc> {
  876.     friend class rope<_CharT,_Alloc>;
  877.   protected:
  878.     _Rope_const_iterator(const _RopeRep* __root, size_t __pos):
  879.                    _Rope_iterator_base<_CharT,_Alloc>(
  880.                      const_cast<_RopeRep*>(__root), __pos)
  881.                    // Only nonconst iterators modify root ref count
  882.     {}
  883.   public:
  884.     typedef _CharT reference;   // Really a value.  Returning a reference
  885.                                 // Would be a mess, since it would have
  886.                                 // to be included in refcount.
  887.     typedef const _CharT* pointer;
  888.   public:
  889.     _Rope_const_iterator() {};
  890.     _Rope_const_iterator(const _Rope_const_iterator& __x) :
  891.                                 _Rope_iterator_base<_CharT,_Alloc>(__x) { }
  892.     _Rope_const_iterator(const _Rope_iterator<_CharT,_Alloc>& __x);
  893.     _Rope_const_iterator(const rope<_CharT,_Alloc>& __r, size_t __pos) :
  894.         _Rope_iterator_base<_CharT,_Alloc>(__r._M_tree_ptr, __pos) {}
  895.     _Rope_const_iterator& operator= (const _Rope_const_iterator& __x) {
  896.         if (0 != __x._M_buf_ptr) {
  897.             *(static_cast<_Rope_iterator_base<_CharT,_Alloc>*>(this)) = __x;
  898.         } else {
  899.             _M_current_pos = __x._M_current_pos;
  900.             _M_root = __x._M_root;
  901.             _M_buf_ptr = 0;
  902.         }
  903.         return(*this);
  904.     }
  905.     reference operator*() {
  906.         if (0 == _M_buf_ptr) _S_setcache(*this);
  907.         return *_M_buf_ptr;
  908.     }
  909.     _Rope_const_iterator& operator++() {
  910.         __GC_CONST _CharT* __next;
  911.         if (0 != _M_buf_ptr && (__next = _M_buf_ptr + 1) < _M_buf_end) {
  912.             _M_buf_ptr = __next;
  913.             ++_M_current_pos;
  914.         } else {
  915.             _M_incr(1);
  916.         }
  917.         return *this;
  918.     }
  919.     _Rope_const_iterator& operator+=(ptrdiff_t __n) {
  920.         if (__n >= 0) {
  921.             _M_incr(__n);
  922.         } else {
  923.             _M_decr(-__n);
  924.         }
  925.         return *this;
  926.     }
  927.     _Rope_const_iterator& operator--() {
  928.         _M_decr(1);
  929.         return *this;
  930.     }
  931.     _Rope_const_iterator& operator-=(ptrdiff_t __n) {
  932.         if (__n >= 0) {
  933.             _M_decr(__n);
  934.         } else {
  935.             _M_incr(-__n);
  936.         }
  937.         return *this;
  938.     }
  939.     _Rope_const_iterator operator++(int) {
  940.         size_t __old_pos = _M_current_pos;
  941.         _M_incr(1);
  942.         return _Rope_const_iterator<_CharT,_Alloc>(_M_root, __old_pos);
  943.         // This makes a subsequent dereference expensive.
  944.         // Perhaps we should instead copy the iterator
  945.         // if it has a valid cache?
  946.     }
  947.     _Rope_const_iterator operator--(int) {
  948.         size_t __old_pos = _M_current_pos;
  949.         _M_decr(1);
  950.         return _Rope_const_iterator<_CharT,_Alloc>(_M_root, __old_pos);
  951.     }
  952.     friend _Rope_const_iterator<_CharT,_Alloc> operator- __STL_NULL_TMPL_ARGS
  953.         (const _Rope_const_iterator<_CharT,_Alloc>& __x,
  954.          ptrdiff_t __n);
  955.     friend _Rope_const_iterator<_CharT,_Alloc> operator+ __STL_NULL_TMPL_ARGS
  956.         (const _Rope_const_iterator<_CharT,_Alloc>& __x,
  957.          ptrdiff_t __n);
  958.     friend _Rope_const_iterator<_CharT,_Alloc> operator+ __STL_NULL_TMPL_ARGS
  959.         (ptrdiff_t __n,
  960.          const _Rope_const_iterator<_CharT,_Alloc>& __x);
  961.     reference operator[](size_t __n) {
  962.         return rope<_CharT,_Alloc>::_S_fetch(_M_root, _M_current_pos + __n);
  963.     }
  964.     friend bool operator== __STL_NULL_TMPL_ARGS
  965.         (const _Rope_const_iterator<_CharT,_Alloc>& __x,
  966.          const _Rope_const_iterator<_CharT,_Alloc>& __y);
  967.     friend bool operator< __STL_NULL_TMPL_ARGS
  968.         (const _Rope_const_iterator<_CharT,_Alloc>& __x,
  969.          const _Rope_const_iterator<_CharT,_Alloc>& __y);
  970.     friend ptrdiff_t operator- __STL_NULL_TMPL_ARGS
  971.         (const _Rope_const_iterator<_CharT,_Alloc>& __x,
  972.          const _Rope_const_iterator<_CharT,_Alloc>& __y);
  973. };
  974. template<class _CharT, class _Alloc>
  975. class _Rope_iterator : public _Rope_iterator_base<_CharT,_Alloc> {
  976.     friend class rope<_CharT,_Alloc>;
  977.   protected:
  978.     rope<_CharT,_Alloc>* _M_root_rope;
  979.         // root is treated as a cached version of this,
  980.         // and is used to detect changes to the underlying
  981.         // rope.
  982.         // Root is included in the reference count.
  983.         // This is necessary so that we can detect changes reliably.
  984.         // Unfortunately, it requires careful bookkeeping for the
  985.         // nonGC case.
  986.     _Rope_iterator(rope<_CharT,_Alloc>* __r, size_t __pos)
  987.       : _Rope_iterator_base<_CharT,_Alloc>(__r->_M_tree_ptr, __pos),
  988.         _M_root_rope(__r) 
  989.       { _RopeRep::_S_ref(_M_root); }
  990.     void _M_check();
  991.   public:
  992.     typedef _Rope_char_ref_proxy<_CharT,_Alloc>  reference;
  993.     typedef _Rope_char_ref_proxy<_CharT,_Alloc>* pointer;
  994.   public:
  995.     rope<_CharT,_Alloc>& container() { return *_M_root_rope; }
  996.     _Rope_iterator() {
  997.         _M_root = 0;  // Needed for reference counting.
  998.     };
  999.     _Rope_iterator(const _Rope_iterator& __x) :
  1000.         _Rope_iterator_base<_CharT,_Alloc>(__x) {
  1001.         _M_root_rope = __x._M_root_rope;
  1002.         _RopeRep::_S_ref(_M_root);
  1003.     }
  1004.     _Rope_iterator(rope<_CharT,_Alloc>& __r, size_t __pos);
  1005.     ~_Rope_iterator() {
  1006.         _RopeRep::_S_unref(_M_root);
  1007.     }
  1008.     _Rope_iterator& operator= (const _Rope_iterator& __x) {
  1009.         _RopeRep* __old = _M_root;
  1010.         _RopeRep::_S_ref(__x._M_root);
  1011.         if (0 != __x._M_buf_ptr) {
  1012.             _M_root_rope = __x._M_root_rope;
  1013.             *(static_cast<_Rope_iterator_base<_CharT,_Alloc>*>(this)) = __x;
  1014.         } else {
  1015.             _M_current_pos = __x._M_current_pos;
  1016.             _M_root = __x._M_root;
  1017.             _M_root_rope = __x._M_root_rope;
  1018.             _M_buf_ptr = 0;
  1019.         }
  1020.         _RopeRep::_S_unref(__old);
  1021.         return(*this);
  1022.     }
  1023.     reference operator*() {
  1024.         _M_check();
  1025.         if (0 == _M_buf_ptr) {
  1026.             return _Rope_char_ref_proxy<_CharT,_Alloc>(
  1027.                _M_root_rope, _M_current_pos);
  1028.         } else {
  1029.             return _Rope_char_ref_proxy<_CharT,_Alloc>(
  1030.                _M_root_rope, _M_current_pos, *_M_buf_ptr);
  1031.         }
  1032.     }
  1033.     _Rope_iterator& operator++() {
  1034.         _M_incr(1);
  1035.         return *this;
  1036.     }
  1037.     _Rope_iterator& operator+=(difference_type __n) {
  1038.         if (__n >= 0) {
  1039.             _M_incr(__n);
  1040.         } else {
  1041.             _M_decr(-__n);
  1042.         }
  1043.         return *this;
  1044.     }
  1045.     _Rope_iterator& operator--() {
  1046.         _M_decr(1);
  1047.         return *this;
  1048.     }
  1049.     _Rope_iterator& operator-=(difference_type __n) {
  1050.         if (__n >= 0) {
  1051.             _M_decr(__n);
  1052.         } else {
  1053.             _M_incr(-__n);
  1054.         }
  1055.         return *this;
  1056.     }
  1057.     _Rope_iterator operator++(int) {
  1058.         size_t __old_pos = _M_current_pos;
  1059.         _M_incr(1);
  1060.         return _Rope_iterator<_CharT,_Alloc>(_M_root_rope, __old_pos);
  1061.     }
  1062.     _Rope_iterator operator--(int) {
  1063.         size_t __old_pos = _M_current_pos;
  1064.         _M_decr(1);
  1065.         return _Rope_iterator<_CharT,_Alloc>(_M_root_rope, __old_pos);
  1066.     }
  1067.     reference operator[](ptrdiff_t __n) {
  1068.         return _Rope_char_ref_proxy<_CharT,_Alloc>(
  1069.           _M_root_rope, _M_current_pos + __n);
  1070.     }
  1071.     friend bool operator== __STL_NULL_TMPL_ARGS
  1072.         (const _Rope_iterator<_CharT,_Alloc>& __x,
  1073.          const _Rope_iterator<_CharT,_Alloc>& __y);
  1074.     friend bool operator< __STL_NULL_TMPL_ARGS
  1075.         (const _Rope_iterator<_CharT,_Alloc>& __x,
  1076.          const _Rope_iterator<_CharT,_Alloc>& __y);
  1077.     friend ptrdiff_t operator- __STL_NULL_TMPL_ARGS
  1078.         (const _Rope_iterator<_CharT,_Alloc>& __x,
  1079.          const _Rope_iterator<_CharT,_Alloc>& __y);
  1080.     friend _Rope_iterator<_CharT,_Alloc> operator- __STL_NULL_TMPL_ARGS
  1081.         (const _Rope_iterator<_CharT,_Alloc>& __x,
  1082.          ptrdiff_t __n);
  1083.     friend _Rope_iterator<_CharT,_Alloc> operator+ __STL_NULL_TMPL_ARGS
  1084.         (const _Rope_iterator<_CharT,_Alloc>& __x,
  1085.          ptrdiff_t __n);
  1086.     friend _Rope_iterator<_CharT,_Alloc> operator+ __STL_NULL_TMPL_ARGS
  1087.         (ptrdiff_t __n,
  1088.          const _Rope_iterator<_CharT,_Alloc>& __x);
  1089. };
  1090. #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
  1091. #pragma reset woff 1375
  1092. #endif
  1093. //  The rope base class encapsulates
  1094. //  the differences between SGI-style allocators and standard-conforming
  1095. //  allocators.
  1096. #ifdef __STL_USE_STD_ALLOCATORS
  1097. // Base class for ordinary allocators.
  1098. template <class _CharT, class _Allocator, bool _IsStatic>
  1099. class _Rope_alloc_base {
  1100. public:
  1101.   typedef _Rope_RopeRep<_CharT,_Allocator> _RopeRep;
  1102.   typedef typename _Alloc_traits<_CharT,_Allocator>::allocator_type
  1103.           allocator_type;
  1104.   allocator_type get_allocator() const { return _M_data_allocator; }
  1105.   _Rope_alloc_base(_RopeRep *__t, const allocator_type& __a)
  1106.         : _M_tree_ptr(__t), _M_data_allocator(__a) {}
  1107.   _Rope_alloc_base(const allocator_type& __a)
  1108.         : _M_data_allocator(__a) {}
  1109.   
  1110. protected:
  1111.   // The only data members of a rope:
  1112.     allocator_type _M_data_allocator;
  1113.     _RopeRep* _M_tree_ptr;
  1114. # define __ROPE_DEFINE_ALLOC(_T, __name) 
  1115.         typedef typename 
  1116.           _Alloc_traits<_T,_Allocator>::allocator_type __name##Allocator; 
  1117.         _T* __name##_allocate(size_t __n) const 
  1118.           { return __name##Allocator(_M_data_allocator).allocate(__n); } 
  1119.         void __name##_deallocate(_T *__p, size_t __n) const 
  1120.                 { __name##Allocator(_M_data_allocator).deallocate(__p, __n); }
  1121.   __ROPE_DEFINE_ALLOCS(_Allocator)
  1122. # undef __ROPE_DEFINE_ALLOC
  1123. };
  1124. // Specialization for allocators that have the property that we don't
  1125. //  actually have to store an allocator object.  
  1126. template <class _CharT, class _Allocator>
  1127. class _Rope_alloc_base<_CharT,_Allocator,true> {
  1128. public:
  1129.   typedef _Rope_RopeRep<_CharT,_Allocator> _RopeRep;
  1130.   typedef typename _Alloc_traits<_CharT,_Allocator>::allocator_type
  1131.           allocator_type;
  1132.   allocator_type get_allocator() const { return allocator_type(); }
  1133.   _Rope_alloc_base(_RopeRep *__t, const allocator_type&)
  1134.                 : _M_tree_ptr(__t) {}
  1135.   _Rope_alloc_base(const allocator_type&) {}
  1136.   
  1137. protected:
  1138.   // The only data member of a rope:
  1139.     _RopeRep *_M_tree_ptr;
  1140. # define __ROPE_DEFINE_ALLOC(_T, __name) 
  1141.         typedef typename 
  1142.           _Alloc_traits<_T,_Allocator>::_Alloc_type __name##Alloc; 
  1143.         typedef typename 
  1144.           _Alloc_traits<_T,_Allocator>::allocator_type __name##Allocator; 
  1145.         static _T* __name##_allocate(size_t __n) 
  1146.           { return __name##Alloc::allocate(__n); } 
  1147.         static void __name##_deallocate(_T *__p, size_t __n) 
  1148.           { __name##Alloc::deallocate(__p, __n); }
  1149.   __ROPE_DEFINE_ALLOCS(_Allocator)
  1150. # undef __ROPE_DEFINE_ALLOC
  1151. };
  1152. template <class _CharT, class _Alloc>
  1153. struct _Rope_base 
  1154.   : public _Rope_alloc_base<_CharT,_Alloc,
  1155.                             _Alloc_traits<_CharT,_Alloc>::_S_instanceless>
  1156. {
  1157.   typedef _Rope_alloc_base<_CharT,_Alloc,
  1158.                             _Alloc_traits<_CharT,_Alloc>::_S_instanceless>
  1159.           _Base;
  1160.   typedef typename _Base::allocator_type allocator_type;
  1161.   _Rope_base(_RopeRep* __t, const allocator_type& __a) : _Base(__t, __a) {}
  1162.   _Rope_base(const allocator_type& __a) : _Base(__a) {}
  1163. };    
  1164. #else /* !__STL_USE_STD_ALLOCATORS */
  1165. template <class _CharT, class _Alloc> 
  1166. class _Rope_base {
  1167. public:
  1168.   typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep;
  1169.   typedef _Alloc allocator_type;
  1170.   static allocator_type get_allocator() { return allocator_type(); }
  1171.   _Rope_base(_RopeRep * __t, const allocator_type&) : _M_tree_ptr(__t) {}
  1172.   _Rope_base(const allocator_type&) {}
  1173. protected:
  1174.   // The only data member of a rope:
  1175.     _RopeRep* _M_tree_ptr;
  1176. # define __ROPE_DEFINE_ALLOC(_T, __name) 
  1177.         typedef simple_alloc<_T, _Alloc> __name##Alloc; 
  1178.         static _T* __name##_allocate(size_t __n) 
  1179.                 { return __name##Alloc::allocate(__n); } 
  1180.         static void __name##_deallocate(_T *__p, size_t __n) 
  1181.                 { __name##Alloc::deallocate(__p, __n); }
  1182.   __ROPE_DEFINE_ALLOCS(_Alloc)
  1183. # undef __ROPE_DEFINE_ALLOC
  1184. };
  1185. #endif /* __STL_USE_STD_ALLOCATORS */
  1186. template <class _CharT, class _Alloc>
  1187. class rope : public _Rope_base<_CharT,_Alloc> {
  1188.     public:
  1189.         typedef _CharT value_type;
  1190.         typedef ptrdiff_t difference_type;
  1191.         typedef size_t size_type;
  1192.         typedef _CharT const_reference;
  1193.         typedef const _CharT* const_pointer;
  1194.         typedef _Rope_iterator<_CharT,_Alloc> iterator;
  1195.         typedef _Rope_const_iterator<_CharT,_Alloc> const_iterator;
  1196.         typedef _Rope_char_ref_proxy<_CharT,_Alloc> reference;
  1197.         typedef _Rope_char_ptr_proxy<_CharT,_Alloc> pointer;
  1198.         friend class _Rope_iterator<_CharT,_Alloc>;
  1199.         friend class _Rope_const_iterator<_CharT,_Alloc>;
  1200.         friend struct _Rope_RopeRep<_CharT,_Alloc>;
  1201.         friend class _Rope_iterator_base<_CharT,_Alloc>;
  1202.         friend class _Rope_char_ptr_proxy<_CharT,_Alloc>;
  1203.         friend class _Rope_char_ref_proxy<_CharT,_Alloc>;
  1204.         friend struct _Rope_RopeSubstring<_CharT,_Alloc>;
  1205.     protected:
  1206.         typedef _Rope_base<_CharT,_Alloc> _Base;
  1207.         typedef typename _Base::allocator_type allocator_type;
  1208. #       ifdef __STL_USE_NAMESPACES
  1209.           using _Base::_M_tree_ptr;
  1210. #       endif
  1211.         typedef __GC_CONST _CharT* _Cstrptr;
  1212. #       ifdef __STL_SGI_THREADS
  1213.             static _Cstrptr _S_atomic_swap(_Cstrptr* __p, _Cstrptr __q) {
  1214. #               if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64))
  1215.                     return (_Cstrptr) test_and_set((unsigned long*)__p,
  1216.                                                    (unsigned long)__q);
  1217. #               else
  1218.                     return (_Cstrptr) __test_and_set((unsigned long*)__p,
  1219.                                                      (unsigned long)__q);
  1220. #               endif
  1221.             }
  1222. #       elif defined(__STL_WIN32THREADS)
  1223.             static _Cstrptr _S_atomic_swap(_Cstrptr* __p, _Cstrptr __q) {
  1224.                 return (_Cstrptr) InterlockedExchange(
  1225.                   (LPLONG)__p, (LONG)__q);
  1226.             }
  1227. #       elif defined(_PTHREADS)
  1228.             // This should be portable, but performance is expected
  1229.             // to be quite awful.  This really needs platform specific
  1230.             // code.
  1231.             static pthread_mutex_t _S_swap_lock;
  1232.             static _Cstrptr _S_atomic_swap(_Cstrptr* __p, _Cstrptr __q) {
  1233.                 pthread_mutex_lock(&_S_swap_lock);
  1234.                 _Cstrptr __result = *__p;
  1235.                 *__p = __q;
  1236.                 pthread_mutex_unlock(&_S_swap_lock);
  1237.                 return __result;
  1238.             }
  1239. #       else
  1240.             static _Cstrptr _S_atomic_swap(_Cstrptr* __p, _Cstrptr __q) {
  1241.                 _Cstrptr __result = *__p;
  1242.                 *__p = __q;
  1243.                 return __result;
  1244.             }
  1245. #       endif
  1246.         static _CharT _S_empty_c_str[1];
  1247.         static bool _S_is0(_CharT __c) { return __c == _S_eos((_CharT*)0); }
  1248.         enum { _S_copy_max = 23 };
  1249.                 // For strings shorter than _S_copy_max, we copy to
  1250.                 // concatenate.
  1251.         typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep;
  1252.         typedef _Rope_RopeConcatenation<_CharT,_Alloc> _RopeConcatenation;
  1253.         typedef _Rope_RopeLeaf<_CharT,_Alloc> _RopeLeaf;
  1254.         typedef _Rope_RopeFunction<_CharT,_Alloc> _RopeFunction;
  1255.         typedef _Rope_RopeSubstring<_CharT,_Alloc> _RopeSubstring;
  1256.         // Retrieve a character at the indicated position.
  1257.         static _CharT _S_fetch(_RopeRep* __r, size_type __pos);
  1258. #       ifndef __GC
  1259.             // Obtain a pointer to the character at the indicated position.
  1260.             // The pointer can be used to change the character.
  1261.             // If such a pointer cannot be produced, as is frequently the
  1262.             // case, 0 is returned instead.
  1263.             // (Returns nonzero only if all nodes in the path have a refcount
  1264.             // of 1.)
  1265.             static _CharT* _S_fetch_ptr(_RopeRep* __r, size_type __pos);
  1266. #       endif
  1267.         static bool _S_apply_to_pieces(
  1268.                                 // should be template parameter
  1269.                                 _Rope_char_consumer<_CharT>& __c,
  1270.                                 const _RopeRep* __r,
  1271.                                 size_t __begin, size_t __end);
  1272.                                 // begin and end are assumed to be in range.
  1273. #       ifndef __GC
  1274.           static void _S_unref(_RopeRep* __t)
  1275.           {
  1276.               _RopeRep::_S_unref(__t);
  1277.           }
  1278.           static void _S_ref(_RopeRep* __t)
  1279.           {
  1280.               _RopeRep::_S_ref(__t);
  1281.           }
  1282. #       else /* __GC */
  1283.           static void _S_unref(_RopeRep*) {}
  1284.           static void _S_ref(_RopeRep*) {}
  1285. #       endif
  1286. #       ifdef __GC
  1287.             typedef _Rope_RopeRep<_CharT,_Alloc>* _Self_destruct_ptr;
  1288. #       else
  1289.             typedef _Rope_self_destruct_ptr<_CharT,_Alloc> _Self_destruct_ptr;
  1290. #       endif
  1291.         // _Result is counted in refcount.
  1292.         static _RopeRep* _S_substring(_RopeRep* __base,
  1293.                                     size_t __start, size_t __endp1);
  1294.         static _RopeRep* _S_concat_char_iter(_RopeRep* __r,
  1295.                                           const _CharT* __iter, size_t __slen);
  1296.                 // Concatenate rope and char ptr, copying __s.
  1297.                 // Should really take an arbitrary iterator.
  1298.                 // Result is counted in refcount.
  1299.         static _RopeRep* _S_destr_concat_char_iter(_RopeRep* __r,
  1300.                                           const _CharT* __iter, size_t __slen)
  1301.                 // As above, but one reference to __r is about to be
  1302.                 // destroyed.  Thus the pieces may be recycled if all
  1303.                 // relevent reference counts are 1.
  1304. #           ifdef __GC
  1305.                 // We can't really do anything since refcounts are unavailable.
  1306.                 { return _S_concat_char_iter(__r, __iter, __slen); }
  1307. #           else
  1308.                 ;
  1309. #           endif
  1310.         static _RopeRep* _S_concat(_RopeRep* __left, _RopeRep* __right);
  1311.                 // General concatenation on _RopeRep.  _Result
  1312.                 // has refcount of 1.  Adjusts argument refcounts.
  1313.    public:
  1314.         void apply_to_pieces( size_t __begin, size_t __end,
  1315.                               _Rope_char_consumer<_CharT>& __c) const {
  1316.             _S_apply_to_pieces(__c, _M_tree_ptr, __begin, __end);
  1317.         }
  1318.    protected:
  1319.         static size_t _S_rounded_up_size(size_t __n) {
  1320.             return _RopeLeaf::_S_rounded_up_size(__n);
  1321.         }
  1322.         static size_t _S_allocated_capacity(size_t __n) {
  1323.             if (_S_is_basic_char_type((_CharT*)0)) {
  1324.                 return _S_rounded_up_size(__n) - 1;
  1325.             } else {
  1326.                 return _S_rounded_up_size(__n);
  1327.             }
  1328.         }
  1329.                 
  1330.         // Allocate and construct a RopeLeaf using the supplied allocator
  1331.         // Takes ownership of s instead of copying.
  1332.         static _RopeLeaf* _S_new_RopeLeaf(__GC_CONST _CharT *__s,
  1333.                                           size_t __size, allocator_type __a)
  1334.         {
  1335. #           ifdef __STL_USE_STD_ALLOCATORS
  1336.               _RopeLeaf* __space = _LAllocator(__a).allocate(1);
  1337. #           else
  1338.               _RopeLeaf* __space = _L_allocate(1);
  1339. #           endif
  1340.             return new(__space) _RopeLeaf(__s, __size, __a);
  1341.         }
  1342.         static _RopeConcatenation* _S_new_RopeConcatenation(
  1343.                         _RopeRep* __left, _RopeRep* __right,
  1344.                         allocator_type __a)
  1345.         {
  1346. #           ifdef __STL_USE_STD_ALLOCATORS
  1347.               _RopeConcatenation* __space = _CAllocator(__a).allocate(1);
  1348. #           else
  1349.               _RopeConcatenation* __space = _C_allocate(1);
  1350. #           endif
  1351.             return new(__space) _RopeConcatenation(__left, __right, __a);
  1352.         }
  1353.         static _RopeFunction* _S_new_RopeFunction(char_producer<_CharT>* __f,
  1354.                 size_t __size, bool __d, allocator_type __a)
  1355.         {
  1356. #           ifdef __STL_USE_STD_ALLOCATORS
  1357.               _RopeFunction* __space = _FAllocator(__a).allocate(1);
  1358. #           else
  1359.               _RopeFunction* __space = _F_allocate(1);
  1360. #           endif
  1361.             return new(__space) _RopeFunction(__f, __size, __d, __a);
  1362.         }
  1363.         static _RopeSubstring* _S_new_RopeSubstring(
  1364.                 _Rope_RopeRep<_CharT,_Alloc>* __b, size_t __s,
  1365.                 size_t __l, allocator_type __a)
  1366.         {
  1367. #           ifdef __STL_USE_STD_ALLOCATORS
  1368.               _RopeSubstring* __space = _SAllocator(__a).allocate(1);
  1369. #           else
  1370.               _RopeSubstring* __space = _S_allocate(1);
  1371. #           endif
  1372.             return new(__space) _RopeSubstring(__b, __s, __l, __a);
  1373.         }
  1374. #       ifdef __STL_USE_STD_ALLOCATORS
  1375.           static
  1376.           _RopeLeaf* _S_RopeLeaf_from_unowned_char_ptr(const _CharT *__s,
  1377.                        size_t __size, allocator_type __a)
  1378. #         define __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __size, __a) 
  1379.                 _S_RopeLeaf_from_unowned_char_ptr(__s, __size, __a)     
  1380. #       else
  1381.           static
  1382.           _RopeLeaf* _S_RopeLeaf_from_unowned_char_ptr2(const _CharT* __s,
  1383.                                                         size_t __size)
  1384. #         define __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __size, __a) 
  1385.                _S_RopeLeaf_from_unowned_char_ptr2(__s, __size)
  1386. #       endif
  1387.         {
  1388.             if (0 == __size) return 0;
  1389. #           ifdef __STL_USE_STD_ALLOCATORS
  1390.               _CharT* __buf = __a.allocate(_S_rounded_up_size(__size));
  1391. #           else
  1392.               _CharT* __buf = _Data_allocate(_S_rounded_up_size(__size));
  1393.               allocator_type __a = allocator_type();
  1394. #           endif
  1395.             uninitialized_copy_n(__s, __size, __buf);
  1396.             _S_cond_store_eos(__buf[__size]);
  1397.             __STL_TRY {
  1398.               return _S_new_RopeLeaf(__buf, __size, __a);
  1399.             }
  1400.             __STL_UNWIND(_RopeRep::__STL_FREE_STRING(__buf, __size, __a))
  1401.         }
  1402.             
  1403.         // Concatenation of nonempty strings.
  1404.         // Always builds a concatenation node.
  1405.         // Rebalances if the result is too deep.
  1406.         // Result has refcount 1.
  1407.         // Does not increment left and right ref counts even though
  1408.         // they are referenced.
  1409.         static _RopeRep*
  1410.         _S_tree_concat(_RopeRep* __left, _RopeRep* __right);
  1411.         // Concatenation helper functions
  1412.         static _RopeLeaf*
  1413.         _S_leaf_concat_char_iter(_RopeLeaf* __r,
  1414.                                  const _CharT* __iter, size_t __slen);
  1415.                 // Concatenate by copying leaf.
  1416.                 // should take an arbitrary iterator
  1417.                 // result has refcount 1.
  1418. #       ifndef __GC
  1419.           static _RopeLeaf* _S_destr_leaf_concat_char_iter
  1420.                         (_RopeLeaf* __r, const _CharT* __iter, size_t __slen);
  1421.           // A version that potentially clobbers __r if __r->_M_refcount == 1.
  1422. #       endif
  1423.         // A helper function for exponentiating strings.
  1424.         // This uses a nonstandard refcount convention.
  1425.         // The result has refcount 0.
  1426.         struct _Concat_fn
  1427.                 : public binary_function<rope<_CharT,_Alloc>,
  1428.                                          rope<_CharT,_Alloc>,
  1429.                                          rope<_CharT,_Alloc> > {
  1430.                 rope operator() (const rope& __x, const rope& __y) {
  1431.                     return __x + __y;
  1432.                 }
  1433.         };
  1434.         // Needed by the call to "power" used to build ropes
  1435.         // consisting of n copies of a character.
  1436.         friend rope identity_element(_Concat_fn) 
  1437.         { return rope<_CharT,_Alloc>(); }
  1438.         static size_t _S_char_ptr_len(const _CharT* __s);
  1439.                         // slightly generalized strlen
  1440.         rope(_RopeRep* __t, const allocator_type& __a = allocator_type())
  1441.           : _Base(__t,__a) { }
  1442.         // Copy __r to the _CharT buffer.
  1443.         // Returns __buffer + __r->_M_size.
  1444.         // Assumes that buffer is uninitialized.
  1445.         static _CharT* _S_flatten(_RopeRep* __r, _CharT* __buffer);
  1446.         // Again, with explicit starting position and length.
  1447.         // Assumes that buffer is uninitialized.
  1448.         static _CharT* _S_flatten(_RopeRep* __r,
  1449.                                   size_t __start, size_t __len,
  1450.                                   _CharT* __buffer);
  1451.         static const unsigned long 
  1452.           _S_min_len[_RopeRep::_S_max_rope_depth + 1];
  1453.         static bool _S_is_balanced(_RopeRep* __r)
  1454.                 { return (__r->_M_size >= _S_min_len[__r->_M_depth]); }
  1455.         static bool _S_is_almost_balanced(_RopeRep* __r)
  1456.                 { return (__r->_M_depth == 0 ||
  1457.                           __r->_M_size >= _S_min_len[__r->_M_depth - 1]); }
  1458.         static bool _S_is_roughly_balanced(_RopeRep* __r)
  1459.                 { return (__r->_M_depth <= 1 ||
  1460.                           __r->_M_size >= _S_min_len[__r->_M_depth - 2]); }
  1461.         // Assumes the result is not empty.
  1462.         static _RopeRep* _S_concat_and_set_balanced(_RopeRep* __left,
  1463.                                                      _RopeRep* __right)
  1464.         {
  1465.             _RopeRep* __result = _S_concat(__left, __right);
  1466.             if (_S_is_balanced(__result)) __result->_M_is_balanced = true;
  1467.             return __result;
  1468.         }
  1469.         // The basic rebalancing operation.  _Logically copies the
  1470.         // rope.  The __result has refcount of 1.  _The client will
  1471.         // usually decrement the reference count of __r.
  1472.         // The __result isd within height 2 of balanced by the above
  1473.         // definition.
  1474.         static _RopeRep* _S_balance(_RopeRep* __r);
  1475.         // Add all unbalanced subtrees to the forest of balanceed trees.
  1476.         // Used only by balance.
  1477.         static void _S_add_to_forest(_RopeRep*__r, _RopeRep** __forest);
  1478.         
  1479.         // Add __r to forest, assuming __r is already balanced.
  1480.         static void _S_add_leaf_to_forest(_RopeRep* __r, _RopeRep** __forest);
  1481.         // Print to stdout, exposing structure
  1482.         static void _S_dump(_RopeRep* __r, int __indent = 0);
  1483.         // Return -1, 0, or 1 if __x < __y, __x == __y, or __x > __y resp.
  1484.         static int _S_compare(const _RopeRep* __x, const _RopeRep* __y);
  1485.    public:
  1486.         bool empty() const { return 0 == _M_tree_ptr; }
  1487.         // Comparison member function.  _This is public only for those
  1488.         // clients that need a ternary comparison.  Others
  1489.         // should use the comparison operators below.
  1490.         int compare(const rope& __y) const {
  1491.             return _S_compare(_M_tree_ptr, __y._M_tree_ptr);
  1492.         }
  1493.         rope(const _CharT* __s, const allocator_type& __a = allocator_type())
  1494.         : _Base(__STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, _S_char_ptr_len(__s),
  1495.                                                  __a),__a)
  1496.         { }
  1497.         rope(const _CharT* __s, size_t __len,
  1498.              const allocator_type& __a = allocator_type())
  1499.         : _Base(__STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __len, __a), __a)
  1500.         { }
  1501.         // Should perhaps be templatized with respect to the iterator type
  1502.         // and use Sequence_buffer.  (It should perhaps use sequence_buffer
  1503.         // even now.)
  1504.         rope(const _CharT *__s, const _CharT *__e,
  1505.              const allocator_type& __a = allocator_type())
  1506.         : _Base(__STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __e - __s, __a), __a)
  1507.         { }
  1508.         rope(const const_iterator& __s, const const_iterator& __e,
  1509.              const allocator_type& __a = allocator_type())
  1510.         : _Base(_S_substring(__s._M_root, __s._M_current_pos,
  1511.                              __e._M_current_pos), __a)
  1512.         { }
  1513.         rope(const iterator& __s, const iterator& __e,
  1514.              const allocator_type& __a = allocator_type())
  1515.         : _Base(_S_substring(__s._M_root, __s._M_current_pos,
  1516.                              __e._M_current_pos), __a)
  1517.         { }
  1518.         rope(_CharT __c, const allocator_type& __a = allocator_type())
  1519.         : _Base(__a)
  1520.         {
  1521.             _CharT* __buf = _Data_allocate(_S_rounded_up_size(1));
  1522.             construct(__buf, __c);
  1523.             __STL_TRY {
  1524.                 _M_tree_ptr = _S_new_RopeLeaf(__buf, 1, __a);
  1525.             }
  1526.             __STL_UNWIND(_RopeRep::__STL_FREE_STRING(__buf, 1, __a))
  1527.         }
  1528.         rope(size_t __n, _CharT __c,
  1529.              const allocator_type& __a = allocator_type());
  1530.         rope(const allocator_type& __a = allocator_type())
  1531.         : _Base(0, __a) {}
  1532.         // Construct a rope from a function that can compute its members
  1533.         rope(char_producer<_CharT> *__fn, size_t __len, bool __delete_fn,
  1534.              const allocator_type& __a = allocator_type())
  1535.             : _Base(__a)
  1536.         {
  1537.             _M_tree_ptr = (0 == __len) ?
  1538.                0 : _S_new_RopeFunction(__fn, __len, __delete_fn, __a);
  1539.         }
  1540.         rope(const rope& __x, const allocator_type& __a = allocator_type())
  1541.         : _Base(__x._M_tree_ptr, __a)
  1542.         {
  1543.             _S_ref(_M_tree_ptr);
  1544.         }
  1545.         ~rope()
  1546.         {
  1547.             _S_unref(_M_tree_ptr);
  1548.         }
  1549.         rope& operator=(const rope& __x)
  1550.         {
  1551.             _RopeRep* __old = _M_tree_ptr;
  1552. #           ifdef __STL_USE_STD_ALLOCATORS
  1553.               __stl_assert(get_allocator() == __x.get_allocator());
  1554. #           endif
  1555.             _M_tree_ptr = __x._M_tree_ptr;
  1556.             _S_ref(_M_tree_ptr);
  1557.             _S_unref(__old);
  1558.             return(*this);
  1559.         }
  1560.         void push_back(_CharT __x)
  1561.         {
  1562.             _RopeRep* __old = _M_tree_ptr;
  1563.             _M_tree_ptr = _S_concat_char_iter(_M_tree_ptr, &__x, 1);
  1564.             _S_unref(__old);
  1565.         }
  1566.         void pop_back()
  1567.         {
  1568.             _RopeRep* __old = _M_tree_ptr;
  1569.             _M_tree_ptr = 
  1570.               _S_substring(_M_tree_ptr, 0, _M_tree_ptr->_M_size - 1);
  1571.             _S_unref(__old);
  1572.         }
  1573.         _CharT back() const
  1574.         {
  1575.             return _S_fetch(_M_tree_ptr, _M_tree_ptr->_M_size - 1);
  1576.         }
  1577.         void push_front(_CharT __x)
  1578.         {
  1579.             _RopeRep* __old = _M_tree_ptr;
  1580.             _RopeRep* __left =
  1581.               __STL_ROPE_FROM_UNOWNED_CHAR_PTR(&__x, 1, get_allocator());
  1582.             __STL_TRY {
  1583.               _M_tree_ptr = _S_concat(__left, _M_tree_ptr);
  1584.               _S_unref(__old);
  1585.               _S_unref(__left);
  1586.             }
  1587.             __STL_UNWIND(_S_unref(__left))
  1588.         }
  1589.         void pop_front()
  1590.         {
  1591.             _RopeRep* __old = _M_tree_ptr;
  1592.             _M_tree_ptr = _S_substring(_M_tree_ptr, 1, _M_tree_ptr->_M_size);
  1593.             _S_unref(__old);
  1594.         }
  1595.         _CharT front() const
  1596.         {
  1597.             return _S_fetch(_M_tree_ptr, 0);
  1598.         }
  1599.         void balance()
  1600.         {
  1601.             _RopeRep* __old = _M_tree_ptr;
  1602.             _M_tree_ptr = _S_balance(_M_tree_ptr);
  1603.             _S_unref(__old);
  1604.         }
  1605.         void copy(_CharT* __buffer) const {
  1606.             destroy(__buffer, __buffer + size());
  1607.             _S_flatten(_M_tree_ptr, __buffer);
  1608.         }
  1609.         // This is the copy function from the standard, but
  1610.         // with the arguments reordered to make it consistent with the
  1611.         // rest of the interface.
  1612.         // Note that this guaranteed not to compile if the draft standard
  1613.         // order is assumed.
  1614.         size_type copy(size_type __pos, size_type __n, _CharT* __buffer) const 
  1615.         {
  1616.             size_t __size = size();
  1617.             size_t __len = (__pos + __n > __size? __size - __pos : __n);
  1618.             destroy(__buffer, __buffer + __len);
  1619.             _S_flatten(_M_tree_ptr, __pos, __len, __buffer);
  1620.             return __len;
  1621.         }
  1622.         // Print to stdout, exposing structure.  May be useful for
  1623.         // performance debugging.
  1624.         void dump() {
  1625.             _S_dump(_M_tree_ptr);
  1626.         }
  1627.         // Convert to 0 terminated string in new allocated memory.
  1628.         // Embedded 0s in the input do not terminate the copy.
  1629.         const _CharT* c_str() const;
  1630.         // As above, but lso use the flattened representation as the
  1631.         // the new rope representation.
  1632.         const _CharT* replace_with_c_str();
  1633.         // Reclaim memory for the c_str generated flattened string.
  1634.         // Intentionally undocumented, since it's hard to say when this
  1635.         // is safe for multiple threads.
  1636.         void delete_c_str () {
  1637.             if (0 == _M_tree_ptr) return;
  1638.             if (_RopeRep::_S_leaf == _M_tree_ptr->_M_tag && 
  1639.                 ((_RopeLeaf*)_M_tree_ptr)->_M_data == 
  1640.                       _M_tree_ptr->_M_c_string) {
  1641.                 // Representation shared
  1642.                 return;
  1643.             }
  1644. #           ifndef __GC
  1645.               _M_tree_ptr->_M_free_c_string();
  1646. #           endif
  1647.             _M_tree_ptr->_M_c_string = 0;
  1648.         }
  1649.         _CharT operator[] (size_type __pos) const {
  1650.             return _S_fetch(_M_tree_ptr, __pos);
  1651.         }
  1652.         _CharT at(size_type __pos) const {
  1653.            // if (__pos >= size()) throw out_of_range;  // XXX
  1654.            return (*this)[__pos];
  1655.         }
  1656.         const_iterator begin() const {
  1657.             return(const_iterator(_M_tree_ptr, 0));
  1658.         }
  1659.         // An easy way to get a const iterator from a non-const container.
  1660.         const_iterator const_begin() const {
  1661.             return(const_iterator(_M_tree_ptr, 0));
  1662.         }
  1663.         const_iterator end() const {
  1664.             return(const_iterator(_M_tree_ptr, size()));
  1665.         }
  1666.         const_iterator const_end() const {
  1667.             return(const_iterator(_M_tree_ptr, size()));
  1668.         }
  1669.         size_type size() const { 
  1670.             return(0 == _M_tree_ptr? 0 : _M_tree_ptr->_M_size);
  1671.         }
  1672.         size_type length() const {
  1673.             return size();
  1674.         }
  1675.         size_type max_size() const {
  1676.             return _S_min_len[_RopeRep::_S_max_rope_depth-1] - 1;
  1677.             //  Guarantees that the result can be sufficirntly
  1678.             //  balanced.  Longer ropes will probably still work,
  1679.             //  but it's harder to make guarantees.
  1680.         }
  1681. #     ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
  1682.         typedef reverse_iterator<const_iterator> const_reverse_iterator;
  1683. #     else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  1684.         typedef reverse_iterator<const_iterator, value_type, const_reference,
  1685.                                  difference_type>  const_reverse_iterator;
  1686. #     endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 
  1687.         const_reverse_iterator rbegin() const {
  1688.             return const_reverse_iterator(end());
  1689.         }
  1690.         const_reverse_iterator const_rbegin() const {
  1691.             return const_reverse_iterator(end());
  1692.         }
  1693.         const_reverse_iterator rend() const {
  1694.             return const_reverse_iterator(begin());
  1695.         }
  1696.         const_reverse_iterator const_rend() const {
  1697.             return const_reverse_iterator(begin());
  1698.         }
  1699.         friend rope<_CharT,_Alloc>
  1700.         operator+ __STL_NULL_TMPL_ARGS (const rope<_CharT,_Alloc>& __left,
  1701.                                         const rope<_CharT,_Alloc>& __right);
  1702.         
  1703.         friend rope<_CharT,_Alloc>
  1704.         operator+ __STL_NULL_TMPL_ARGS (const rope<_CharT,_Alloc>& __left,
  1705.                                         const _CharT* __right);
  1706.         
  1707.         friend rope<_CharT,_Alloc>
  1708.         operator+ __STL_NULL_TMPL_ARGS (const rope<_CharT,_Alloc>& __left,
  1709.                                         _CharT __right);
  1710.         
  1711.         // The symmetric cases are intentionally omitted, since they're presumed
  1712.         // to be less common, and we don't handle them as well.
  1713.         // The following should really be templatized.
  1714.         // The first argument should be an input iterator or
  1715.         // forward iterator with value_type _CharT.
  1716.         rope& append(const _CharT* __iter, size_t __n) {
  1717.             _RopeRep* __result = 
  1718.               _S_destr_concat_char_iter(_M_tree_ptr, __iter, __n);
  1719.             _S_unref(_M_tree_ptr);
  1720.             _M_tree_ptr = __result;
  1721.             return *this;
  1722.         }
  1723.         rope& append(const _CharT* __c_string) {
  1724.             size_t __len = _S_char_ptr_len(__c_string);
  1725.             append(__c_string, __len);
  1726.             return(*this);
  1727.         }
  1728.         rope& append(const _CharT* __s, const _CharT* __e) {
  1729.             _RopeRep* __result =
  1730.                 _S_destr_concat_char_iter(_M_tree_ptr, __s, __e - __s);
  1731.             _S_unref(_M_tree_ptr);
  1732.             _M_tree_ptr = __result;
  1733.             return *this;
  1734.         }
  1735.         rope& append(const_iterator __s, const_iterator __e) {
  1736.             __stl_assert(__s._M_root == __e._M_root);
  1737. #           ifdef __STL_USE_STD_ALLOCATORS
  1738.                 __stl_assert(get_allocator() == __s._M_root->get_allocator());
  1739. #           endif
  1740.             _Self_destruct_ptr __appendee(_S_substring(
  1741.               __s._M_root, __s._M_current_pos, __e._M_current_pos));
  1742.             _RopeRep* __result = 
  1743.               _S_concat(_M_tree_ptr, (_RopeRep*)__appendee);
  1744.             _S_unref(_M_tree_ptr);
  1745.             _M_tree_ptr = __result;
  1746.             return *this;
  1747.         }
  1748.         rope& append(_CharT __c) {
  1749.             _RopeRep* __result = 
  1750.               _S_destr_concat_char_iter(_M_tree_ptr, &__c, 1);
  1751.             _S_unref(_M_tree_ptr);
  1752.             _M_tree_ptr = __result;
  1753.             return *this;
  1754.         }
  1755.         rope& append() { return append(_CharT()); }  // XXX why?
  1756.         rope& append(const rope& __y) {
  1757. #           ifdef __STL_USE_STD_ALLOCATORS
  1758.               __stl_assert(__y.get_allocator() == get_allocator());
  1759. #           endif
  1760.             _RopeRep* __result = _S_concat(_M_tree_ptr, __y._M_tree_ptr);
  1761.             _S_unref(_M_tree_ptr);
  1762.             _M_tree_ptr = __result;
  1763.             return *this;
  1764.         }
  1765.         rope& append(size_t __n, _CharT __c) {
  1766.             rope<_CharT,_Alloc> __last(__n, __c);
  1767.             return append(__last);
  1768.         }
  1769.         void swap(rope& __b) {
  1770. #           ifdef __STL_USE_STD_ALLOCATORS
  1771.                 __stl_assert(get_allocator() == __b.get_allocator());
  1772. #           endif
  1773.             _RopeRep* __tmp = _M_tree_ptr;
  1774.             _M_tree_ptr = __b._M_tree_ptr;
  1775.             __b._M_tree_ptr = __tmp;
  1776.         }
  1777.     protected:
  1778.         // Result is included in refcount.
  1779.         static _RopeRep* replace(_RopeRep* __old, size_t __pos1,
  1780.                                   size_t __pos2, _RopeRep* __r) {
  1781.             if (0 == __old) { _S_ref(__r); return __r; }
  1782.             _Self_destruct_ptr __left(
  1783.               _S_substring(__old, 0, __pos1));
  1784.             _Self_destruct_ptr __right(
  1785.               _S_substring(__old, __pos2, __old->_M_size));
  1786.             _RopeRep* __result;
  1787. #           ifdef __STL_USE_STD_ALLOCATORS
  1788.                 __stl_assert(__old->get_allocator() == __r->get_allocator());
  1789. #           endif
  1790.             if (0 == __r) {
  1791.                 __result = _S_concat(__left, __right);
  1792.             } else {
  1793.                 _Self_destruct_ptr __left_result(_S_concat(__left, __r));
  1794.                 __result = _S_concat(__left_result, __right);
  1795.             }
  1796.             return __result;
  1797.         }
  1798.     public:
  1799.         void insert(size_t __p, const rope& __r) {
  1800.             _RopeRep* __result = 
  1801.               replace(_M_tree_ptr, __p, __p, __r._M_tree_ptr);
  1802. #           ifdef __STL_USE_STD_ALLOCATORS
  1803.                 __stl_assert(get_allocator() == __r.get_allocator());
  1804. #           endif
  1805.             _S_unref(_M_tree_ptr);
  1806.             _M_tree_ptr = __result;
  1807.         }
  1808.         void insert(size_t __p, size_t __n, _CharT __c) {
  1809.             rope<_CharT,_Alloc> __r(__n,__c);
  1810.             insert(__p, __r);
  1811.         }
  1812.         void insert(size_t __p, const _CharT* __i, size_t __n) {
  1813.             _Self_destruct_ptr __left(_S_substring(_M_tree_ptr, 0, __p));
  1814.             _Self_destruct_ptr __right(_S_substring(_M_tree_ptr, __p, size()));
  1815.             _Self_destruct_ptr __left_result(
  1816.               _S_concat_char_iter(__left, __i, __n));
  1817.             _RopeRep* __result = _S_concat(__left_result, __right);
  1818.             _S_unref(_M_tree_ptr);
  1819.             _M_tree_ptr = __result;
  1820.         }
  1821.         void insert(size_t __p, const _CharT* __c_string) {
  1822.             insert(__p, __c_string, _S_char_ptr_len(__c_string));
  1823.         }
  1824.         void insert(size_t __p, _CharT __c) {
  1825.             insert(__p, &__c, 1);
  1826.         }
  1827.         void insert(size_t __p) {
  1828.             _CharT __c = _CharT();
  1829.             insert(__p, &__c, 1);
  1830.         }
  1831.         void insert(size_t __p, const _CharT* __i, const _CharT* __j) {
  1832.             rope __r(__i, __j);
  1833.             insert(__p, __r);
  1834.         }
  1835.         void insert(size_t __p, const const_iterator& __i,
  1836.                               const const_iterator& __j) {
  1837.             rope __r(__i, __j);
  1838.             insert(__p, __r);
  1839.         }
  1840.         void insert(size_t __p, const iterator& __i,
  1841.                               const iterator& __j) {
  1842.             rope __r(__i, __j);
  1843.             insert(__p, __r);
  1844.         }
  1845.         // (position, length) versions of replace operations:
  1846.         void replace(size_t __p, size_t __n, const rope& __r) {
  1847.             _RopeRep* __result = 
  1848.               replace(_M_tree_ptr, __p, __p + __n, __r._M_tree_ptr);
  1849.             _S_unref(_M_tree_ptr);
  1850.             _M_tree_ptr = __result;
  1851.         }
  1852.         void replace(size_t __p, size_t __n, 
  1853.                      const _CharT* __i, size_t __i_len) {
  1854.             rope __r(__i, __i_len);
  1855.             replace(__p, __n, __r);
  1856.         }
  1857.         void replace(size_t __p, size_t __n, _CharT __c) {
  1858.             rope __r(__c);
  1859.             replace(__p, __n, __r);
  1860.         }
  1861.         void replace(size_t __p, size_t __n, const _CharT* __c_string) {
  1862.             rope __r(__c_string);
  1863.             replace(__p, __n, __r);
  1864.         }
  1865.         void replace(size_t __p, size_t __n, 
  1866.                      const _CharT* __i, const _CharT* __j) {
  1867.             rope __r(__i, __j);
  1868.             replace(__p, __n, __r);
  1869.         }
  1870.         void replace(size_t __p, size_t __n,
  1871.                      const const_iterator& __i, const const_iterator& __j) {
  1872.             rope __r(__i, __j);
  1873.             replace(__p, __n, __r);
  1874.         }
  1875.         void replace(size_t __p, size_t __n,
  1876.                      const iterator& __i, const iterator& __j) {
  1877.             rope __r(__i, __j);
  1878.             replace(__p, __n, __r);
  1879.         }
  1880.         // Single character variants:
  1881.         void replace(size_t __p, _CharT __c) {
  1882.             iterator __i(this, __p);
  1883.             *__i = __c;
  1884.         }
  1885.         void replace(size_t __p, const rope& __r) {
  1886.             replace(__p, 1, __r);
  1887.         }
  1888.         void replace(size_t __p, const _CharT* __i, size_t __i_len) {
  1889.             replace(__p, 1, __i, __i_len);
  1890.         }
  1891.         void replace(size_t __p, const _CharT* __c_string) {
  1892.             replace(__p, 1, __c_string);
  1893.         }
  1894.         void replace(size_t __p, const _CharT* __i, const _CharT* __j) {
  1895.             replace(__p, 1, __i, __j);
  1896.         }
  1897.         void replace(size_t __p, const const_iterator& __i,
  1898.                                const const_iterator& __j) {
  1899.             replace(__p, 1, __i, __j);
  1900.         }
  1901.         void replace(size_t __p, const iterator& __i,
  1902.                                const iterator& __j) {
  1903.             replace(__p, 1, __i, __j);
  1904.         }
  1905.         // Erase, (position, size) variant.
  1906.         void erase(size_t __p, size_t __n) {
  1907.             _RopeRep* __result = replace(_M_tree_ptr, __p, __p + __n, 0);
  1908.             _S_unref(_M_tree_ptr);
  1909.             _M_tree_ptr = __result;
  1910.         }
  1911.         // Erase, single character
  1912.         void erase(size_t __p) {
  1913.             erase(__p, __p + 1);
  1914.         }
  1915.         // Insert, iterator variants.  
  1916.         iterator insert(const iterator& __p, const rope& __r)
  1917.                 { insert(__p.index(), __r); return __p; }
  1918.         iterator insert(const iterator& __p, size_t __n, _CharT __c)
  1919.                 { insert(__p.index(), __n, __c); return __p; }
  1920.         iterator insert(const iterator& __p, _CharT __c) 
  1921.                 { insert(__p.index(), __c); return __p; }
  1922.         iterator insert(const iterator& __p ) 
  1923.                 { insert(__p.index()); return __p; }
  1924.         iterator insert(const iterator& __p, const _CharT* c_string) 
  1925.                 { insert(__p.index(), c_string); return __p; }
  1926.         iterator insert(const iterator& __p, const _CharT* __i, size_t __n)
  1927.                 { insert(__p.index(), __i, __n); return __p; }
  1928.         iterator insert(const iterator& __p, const _CharT* __i, 
  1929.                         const _CharT* __j)
  1930.                 { insert(__p.index(), __i, __j);  return __p; }
  1931.         iterator insert(const iterator& __p,
  1932.                         const const_iterator& __i, const const_iterator& __j)
  1933.                 { insert(__p.index(), __i, __j); return __p; }
  1934.         iterator insert(const iterator& __p,
  1935.                         const iterator& __i, const iterator& __j)
  1936.                 { insert(__p.index(), __i, __j); return __p; }
  1937.         // Replace, range variants.
  1938.         void replace(const iterator& __p, const iterator& __q,
  1939.                      const rope& __r)
  1940.                 { replace(__p.index(), __q.index() - __p.index(), __r); }
  1941.         void replace(const iterator& __p, const iterator& __q, _CharT __c)
  1942.                 { replace(__p.index(), __q.index() - __p.index(), __c); }
  1943.         void replace(const iterator& __p, const iterator& __q,
  1944.                      const _CharT* __c_string)
  1945.                 { replace(__p.index(), __q.index() - __p.index(), __c_string); }
  1946.         void replace(const iterator& __p, const iterator& __q,
  1947.                      const _CharT* __i, size_t __n)
  1948.                 { replace(__p.index(), __q.index() - __p.index(), __i, __n); }
  1949.         void replace(const iterator& __p, const iterator& __q,
  1950.                      const _CharT* __i, const _CharT* __j)
  1951.                 { replace(__p.index(), __q.index() - __p.index(), __i, __j); }
  1952.         void replace(const iterator& __p, const iterator& __q,
  1953.                      const const_iterator& __i, const const_iterator& __j)
  1954.                 { replace(__p.index(), __q.index() - __p.index(), __i, __j); }
  1955.         void replace(const iterator& __p, const iterator& __q,
  1956.                      const iterator& __i, const iterator& __j)
  1957.                 { replace(__p.index(), __q.index() - __p.index(), __i, __j); }
  1958.         // Replace, iterator variants.
  1959.         void replace(const iterator& __p, const rope& __r)
  1960.                 { replace(__p.index(), __r); }
  1961.         void replace(const iterator& __p, _CharT __c)
  1962.                 { replace(__p.index(), __c); }
  1963.         void replace(const iterator& __p, const _CharT* __c_string)
  1964.                 { replace(__p.index(), __c_string); }
  1965.         void replace(const iterator& __p, const _CharT* __i, size_t __n)
  1966.                 { replace(__p.index(), __i, __n); }
  1967.         void replace(const iterator& __p, const _CharT* __i, const _CharT* __j)
  1968.                 { replace(__p.index(), __i, __j); }
  1969.         void replace(const iterator& __p, const_iterator __i, 
  1970.                      const_iterator __j)
  1971.                 { replace(__p.index(), __i, __j); }
  1972.         void replace(const iterator& __p, iterator __i, iterator __j)
  1973.                 { replace(__p.index(), __i, __j); }
  1974.         // Iterator and range variants of erase
  1975.         iterator erase(const iterator& __p, const iterator& __q) {
  1976.             size_t __p_index = __p.index();
  1977.             erase(__p_index, __q.index() - __p_index);
  1978.             return iterator(this, __p_index);
  1979.         }
  1980.         iterator erase(const iterator& __p) {
  1981.             size_t __p_index = __p.index();
  1982.             erase(__p_index, 1);
  1983.             return iterator(this, __p_index);
  1984.         }
  1985.         rope substr(size_t __start, size_t __len = 1) const {
  1986.             return rope<_CharT,_Alloc>(
  1987.                         _S_substring(_M_tree_ptr, __start, __start + __len));
  1988.         }
  1989.         rope substr(iterator __start, iterator __end) const {
  1990.             return rope<_CharT,_Alloc>(
  1991.                 _S_substring(_M_tree_ptr, __start.index(), __end.index()));
  1992.         }
  1993.         
  1994.         rope substr(iterator __start) const {
  1995.             size_t __pos = __start.index();
  1996.             return rope<_CharT,_Alloc>(
  1997.                         _S_substring(_M_tree_ptr, __pos, __pos + 1));
  1998.         }
  1999.         
  2000.         rope substr(const_iterator __start, const_iterator __end) const {
  2001.             // This might eventually take advantage of the cache in the
  2002.             // iterator.
  2003.             return rope<_CharT,_Alloc>(
  2004.               _S_substring(_M_tree_ptr, __start.index(), __end.index()));
  2005.         }
  2006.         rope<_CharT,_Alloc> substr(const_iterator __start) {
  2007.             size_t __pos = __start.index();
  2008.             return rope<_CharT,_Alloc>(
  2009.               _S_substring(_M_tree_ptr, __pos, __pos + 1));
  2010.         }
  2011.         static const size_type npos;
  2012.         size_type find(_CharT __c, size_type __pos = 0) const;
  2013.         size_type find(_CharT* __s, size_type __pos = 0) const {
  2014.             size_type __result_pos;
  2015.             const_iterator __result = search(const_begin() + __pos, const_end(),
  2016.                                            __s, __s + _S_char_ptr_len(__s));
  2017.             __result_pos = __result.index();
  2018. #           ifndef __STL_OLD_ROPE_SEMANTICS
  2019.                 if (__result_pos == size()) __result_pos = npos;
  2020. #           endif
  2021.             return __result_pos;
  2022.         }
  2023.         iterator mutable_begin() {
  2024.             return(iterator(this, 0));
  2025.         }
  2026.         iterator mutable_end() {
  2027.             return(iterator(this, size()));
  2028.         }
  2029. #     ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
  2030.         typedef reverse_iterator<iterator> reverse_iterator;
  2031. #     else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  2032.         typedef reverse_iterator<iterator, value_type, reference,
  2033.                                  difference_type>  reverse_iterator;
  2034. #     endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 
  2035.         reverse_iterator mutable_rbegin() {
  2036.             return reverse_iterator(mutable_end());
  2037.         }
  2038.         reverse_iterator mutable_rend() {
  2039.             return reverse_iterator(mutable_begin());
  2040.         }
  2041.         reference mutable_reference_at(size_type __pos) {
  2042.             return reference(this, __pos);
  2043.         }
  2044. #       ifdef __STD_STUFF
  2045.             reference operator[] (size_type __pos) {
  2046.                 return _char_ref_proxy(this, __pos);
  2047.             }
  2048.             reference at(size_type __pos) {
  2049.                 // if (__pos >= size()) throw out_of_range;  // XXX
  2050.                 return (*this)[__pos];
  2051.             }
  2052.             void resize(size_type __n, _CharT __c) {}
  2053.             void resize(size_type __n) {}
  2054.             void reserve(size_type __res_arg = 0) {}
  2055.             size_type capacity() const {
  2056.                 return max_size();
  2057.             }
  2058.           // Stuff below this line is dangerous because it's error prone.
  2059.           // I would really like to get rid of it.
  2060.             // copy function with funny arg ordering.
  2061.               size_type copy(_CharT* __buffer, size_type __n, 
  2062.                              size_type __pos = 0) const {
  2063.                 return copy(__pos, __n, __buffer);
  2064.               }
  2065.             iterator end() { return mutable_end(); }
  2066.             iterator begin() { return mutable_begin(); }
  2067.             reverse_iterator rend() { return mutable_rend(); }
  2068.             reverse_iterator rbegin() { return mutable_rbegin(); }
  2069. #       else
  2070.             const_iterator end() { return const_end(); }
  2071.             const_iterator begin() { return const_begin(); }
  2072.             const_reverse_iterator rend() { return const_rend(); }
  2073.   
  2074.             const_reverse_iterator rbegin() { return const_rbegin(); }
  2075. #       endif
  2076.         
  2077. };
  2078. template <class _CharT, class _Alloc>
  2079. const rope<_CharT, _Alloc>::size_type rope<_CharT, _Alloc>::npos = -1;
  2080. template <class _CharT, class _Alloc>
  2081. inline bool operator== (const _Rope_const_iterator<_CharT,_Alloc>& __x,
  2082.                         const _Rope_const_iterator<_CharT,_Alloc>& __y) {
  2083.   return (__x._M_current_pos == __y._M_current_pos && 
  2084.           __x._M_root == __y._M_root);
  2085. }
  2086. template <class _CharT, class _Alloc>
  2087. inline bool operator< (const _Rope_const_iterator<_CharT,_Alloc>& __x,
  2088.                        const _Rope_const_iterator<_CharT,_Alloc>& __y) {
  2089.   return (__x._M_current_pos < __y._M_current_pos);
  2090. }
  2091. template <class _CharT, class _Alloc>
  2092. inline ptrdiff_t operator-(const _Rope_const_iterator<_CharT,_Alloc>& __x,
  2093.                            const _Rope_const_iterator<_CharT,_Alloc>& __y) {
  2094.   return (ptrdiff_t)__x._M_current_pos - (ptrdiff_t)__y._M_current_pos;
  2095. }
  2096. template <class _CharT, class _Alloc>
  2097. inline _Rope_const_iterator<_CharT,_Alloc>
  2098. operator-(const _Rope_const_iterator<_CharT,_Alloc>& __x, ptrdiff_t __n) {
  2099.   return _Rope_const_iterator<_CharT,_Alloc>(
  2100.             __x._M_root, __x._M_current_pos - __n);
  2101. }
  2102. template <class _CharT, class _Alloc>
  2103. inline _Rope_const_iterator<_CharT,_Alloc>
  2104. operator+(const _Rope_const_iterator<_CharT,_Alloc>& __x, ptrdiff_t __n) {
  2105.   return _Rope_const_iterator<_CharT,_Alloc>(
  2106.            __x._M_root, __x._M_current_pos + __n);
  2107. }
  2108. template <class _CharT, class _Alloc>
  2109. inline _Rope_const_iterator<_CharT,_Alloc>
  2110. operator+(ptrdiff_t __n, const _Rope_const_iterator<_CharT,_Alloc>& __x) {
  2111.   return _Rope_const_iterator<_CharT,_Alloc>(
  2112.            __x._M_root, __x._M_current_pos + __n);
  2113. }
  2114. template <class _CharT, class _Alloc>
  2115. inline bool operator== (const _Rope_iterator<_CharT,_Alloc>& __x,
  2116.                         const _Rope_iterator<_CharT,_Alloc>& __y) {
  2117.   return (__x._M_current_pos == __y._M_current_pos && 
  2118.           __x._M_root_rope == __y._M_root_rope);
  2119. }
  2120. template <class _CharT, class _Alloc>
  2121. inline bool operator< (const _Rope_iterator<_CharT,_Alloc>& __x,
  2122.                        const _Rope_iterator<_CharT,_Alloc>& __y) {
  2123.   return (__x._M_current_pos < __y._M_current_pos);
  2124. }
  2125. template <class _CharT, class _Alloc>
  2126. inline ptrdiff_t operator-(const _Rope_iterator<_CharT,_Alloc>& __x,
  2127.                            const _Rope_iterator<_CharT,_Alloc>& __y) {
  2128.   return (ptrdiff_t)__x._M_current_pos - (ptrdiff_t)__y._M_current_pos;
  2129. }
  2130. template <class _CharT, class _Alloc>
  2131. inline _Rope_iterator<_CharT,_Alloc>
  2132. operator-(const _Rope_iterator<_CharT,_Alloc>& __x,
  2133.           ptrdiff_t __n) {
  2134.   return _Rope_iterator<_CharT,_Alloc>(
  2135.     __x._M_root_rope, __x._M_current_pos - __n);
  2136. }
  2137. template <class _CharT, class _Alloc>
  2138. inline _Rope_iterator<_CharT,_Alloc>
  2139. operator+(const _Rope_iterator<_CharT,_Alloc>& __x,
  2140.           ptrdiff_t __n) {
  2141.   return _Rope_iterator<_CharT,_Alloc>(
  2142.     __x._M_root_rope, __x._M_current_pos + __n);
  2143. }
  2144. template <class _CharT, class _Alloc>
  2145. inline _Rope_iterator<_CharT,_Alloc>
  2146. operator+(ptrdiff_t __n, const _Rope_iterator<_CharT,_Alloc>& __x) {
  2147.   return _Rope_iterator<_CharT,_Alloc>(
  2148.     __x._M_root_rope, __x._M_current_pos + __n);
  2149. }
  2150. template <class _CharT, class _Alloc>
  2151. inline
  2152. rope<_CharT,_Alloc>
  2153. operator+ (const rope<_CharT,_Alloc>& __left,
  2154.            const rope<_CharT,_Alloc>& __right)
  2155. {
  2156. #   ifdef __STL_USE_STD_ALLOCATORS
  2157.         __stl_assert(__left.get_allocator() == __right.get_allocator());
  2158. #   endif
  2159.     return rope<_CharT,_Alloc>(
  2160.       rope<_CharT,_Alloc>::_S_concat(__left._M_tree_ptr, __right._M_tree_ptr));
  2161.     // Inlining this should make it possible to keep __left and
  2162.     // __right in registers.
  2163. }
  2164. template <class _CharT, class _Alloc>
  2165. inline
  2166. rope<_CharT,_Alloc>&
  2167. operator+= (rope<_CharT,_Alloc>& __left, 
  2168.       const rope<_CharT,_Alloc>& __right)
  2169. {
  2170.     __left.append(__right);
  2171.     return __left;
  2172. }
  2173. template <class _CharT, class _Alloc>
  2174. inline
  2175. rope<_CharT,_Alloc>
  2176. operator+ (const rope<_CharT,_Alloc>& __left,
  2177.            const _CharT* __right) {
  2178.     size_t __rlen = rope<_CharT,_Alloc>::_S_char_ptr_len(__right);
  2179.     return rope<_CharT,_Alloc>(
  2180.       rope<_CharT,_Alloc>::_S_concat_char_iter(
  2181.         __left._M_tree_ptr, __right, __rlen)); 
  2182. }
  2183. template <class _CharT, class _Alloc>
  2184. inline
  2185. rope<_CharT,_Alloc>&
  2186. operator+= (rope<_CharT,_Alloc>& __left,
  2187.             const _CharT* __right) {
  2188.     __left.append(__right);
  2189.     return __left;
  2190. }
  2191. template <class _CharT, class _Alloc>
  2192. inline
  2193. rope<_CharT,_Alloc>
  2194. operator+ (const rope<_CharT,_Alloc>& __left, _CharT __right) {
  2195.     return rope<_CharT,_Alloc>(
  2196.       rope<_CharT,_Alloc>::_S_concat_char_iter(
  2197.         __left._M_tree_ptr, &__right, 1));
  2198. }
  2199. template <class _CharT, class _Alloc>
  2200. inline
  2201. rope<_CharT,_Alloc>&
  2202. operator+= (rope<_CharT,_Alloc>& __left, _CharT __right) {
  2203.     __left.append(__right);
  2204.     return __left;
  2205. }
  2206. template <class _CharT, class _Alloc>
  2207. bool
  2208. operator< (const rope<_CharT,_Alloc>& __left, 
  2209.            const rope<_CharT,_Alloc>& __right) {
  2210.     return __left.compare(__right) < 0;
  2211. }
  2212.         
  2213. template <class _CharT, class _Alloc>
  2214. bool
  2215. operator== (const rope<_CharT,_Alloc>& __left, 
  2216.             const rope<_CharT,_Alloc>& __right) {
  2217.     return __left.compare(__right) == 0;
  2218. }
  2219. template <class _CharT, class _Alloc>
  2220. inline bool operator== (const _Rope_char_ptr_proxy<_CharT,_Alloc>& __x,
  2221.                         const _Rope_char_ptr_proxy<_CharT,_Alloc>& __y) {
  2222.         return (__x._M_pos == __y._M_pos && __x._M_root == __y._M_root);
  2223. }
  2224. template<class _CharT, class _Alloc>
  2225. ostream& operator<< (ostream& __o, const rope<_CharT,_Alloc>& __r);        
  2226.         
  2227. typedef rope<char> crope;
  2228. typedef rope<wchar_t> wrope;
  2229. inline crope::reference __mutable_reference_at(crope& __c, size_t __i)
  2230. {
  2231.     return __c.mutable_reference_at(__i);
  2232. }
  2233. inline wrope::reference __mutable_reference_at(wrope& __c, size_t __i)
  2234. {
  2235.     return __c.mutable_reference_at(__i);
  2236. }
  2237. #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
  2238. template <class _CharT, class _Alloc>
  2239. inline void swap(rope<_CharT,_Alloc>& __x, rope<_CharT,_Alloc>& __y) {
  2240.   __x.swap(__y);
  2241. }
  2242. #else
  2243. inline void swap(crope __x, crope __y) { __x.swap(__y); }
  2244. inline void swap(wrope __x, wrope __y) { __x.swap(__y); }
  2245. #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
  2246. // Hash functions should probably be revisited later:
  2247. __STL_TEMPLATE_NULL struct hash<crope>
  2248. {
  2249.   size_t operator()(const crope& __str) const
  2250.   {
  2251.     size_t __size = __str.size();
  2252.     if (0 == __size) return 0;
  2253.     return 13*__str[0] + 5*__str[__size - 1] + __size;
  2254.   }
  2255. };
  2256. __STL_TEMPLATE_NULL struct hash<wrope>
  2257. {
  2258.   size_t operator()(const wrope& __str) const
  2259.   {
  2260.     size_t __size = __str.size();
  2261.     if (0 == __size) return 0;
  2262.     return 13*__str[0] + 5*__str[__size - 1] + __size;
  2263.   }
  2264. };
  2265. #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
  2266. #pragma reset woff 1174
  2267. #endif
  2268. __STL_END_NAMESPACE
  2269. # include <ropeimpl.h>
  2270. # endif /* __SGI_STL_INTERNAL_ROPE_H */
  2271. // Local Variables:
  2272. // mode:C++
  2273. // End: