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

Subversion Repositories openrisc

[/] [openrisc/] [tags/] [gnu-src/] [gcc-4.5.1/] [gcc-4.5.1-or32-1.0rc3/] [libstdc++-v3/] [include/] [ext/] [rope] - Blame information for rev 595

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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