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