OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libstdc++-v3/] [include/] [ext/] [rope] - Blame information for rev 17

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.