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