home *** CD-ROM | disk | FTP | other *** search
/ Programmer Plus 2007 / Programmer-Plus-2007.iso / Programming / Compilers / digital marsC compier / dm / stl / stl_rope.h < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-08  |  97.5 KB  |  2,715 lines

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