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