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