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

Subversion Repositories altor32

[/] [altor32/] [trunk/] [gcc-x64/] [or1knd-elf/] [or1knd-elf/] [include/] [c++/] [4.8.0/] [bits/] [stl_tree.h] - Blame information for rev 35

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 35 ultra_embe
// RB tree implementation -*- C++ -*-
2
 
3
// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
4
// 2009, 2010, 2011
5
// Free Software Foundation, Inc.
6
//
7
// This file is part of the GNU ISO C++ Library.  This library is free
8
// software; you can redistribute it and/or modify it under the
9
// terms of the GNU General Public License as published by the
10
// Free Software Foundation; either version 3, or (at your option)
11
// any later version.
12
 
13
// This library is distributed in the hope that it will be useful,
14
// but WITHOUT ANY WARRANTY; without even the implied warranty of
15
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
// GNU General Public License for more details.
17
 
18
// Under Section 7 of GPL version 3, you are granted additional
19
// permissions described in the GCC Runtime Library Exception, version
20
// 3.1, as published by the Free Software Foundation.
21
 
22
// You should have received a copy of the GNU General Public License and
23
// a copy of the GCC Runtime Library Exception along with this program;
24
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
25
// <http://www.gnu.org/licenses/>.
26
 
27
/*
28
 *
29
 * Copyright (c) 1996,1997
30
 * Silicon Graphics Computer Systems, Inc.
31
 *
32
 * Permission to use, copy, modify, distribute and sell this software
33
 * and its documentation for any purpose is hereby granted without fee,
34
 * provided that the above copyright notice appear in all copies and
35
 * that both that copyright notice and this permission notice appear
36
 * in supporting documentation.  Silicon Graphics makes no
37
 * representations about the suitability of this software for any
38
 * purpose.  It is provided "as is" without express or implied warranty.
39
 *
40
 *
41
 * Copyright (c) 1994
42
 * Hewlett-Packard Company
43
 *
44
 * Permission to use, copy, modify, distribute and sell this software
45
 * and its documentation for any purpose is hereby granted without fee,
46
 * provided that the above copyright notice appear in all copies and
47
 * that both that copyright notice and this permission notice appear
48
 * in supporting documentation.  Hewlett-Packard Company makes no
49
 * representations about the suitability of this software for any
50
 * purpose.  It is provided "as is" without express or implied warranty.
51
 *
52
 *
53
 */
54
 
55
/** @file bits/stl_tree.h
56
 *  This is an internal header file, included by other library headers.
57
 *  Do not attempt to use it directly. @headername{map,set}
58
 */
59
 
60
#ifndef _STL_TREE_H
61
#define _STL_TREE_H 1
62
 
63
#include <bits/stl_algobase.h>
64
#include <bits/allocator.h>
65
#include <bits/stl_function.h>
66
#include <bits/cpp_type_traits.h>
67
 
68
namespace std _GLIBCXX_VISIBILITY(default)
69
{
70
_GLIBCXX_BEGIN_NAMESPACE_VERSION
71
 
72
  // Red-black tree class, designed for use in implementing STL
73
  // associative containers (set, multiset, map, and multimap). The
74
  // insertion and deletion algorithms are based on those in Cormen,
75
  // Leiserson, and Rivest, Introduction to Algorithms (MIT Press,
76
  // 1990), except that
77
  //
78
  // (1) the header cell is maintained with links not only to the root
79
  // but also to the leftmost node of the tree, to enable constant
80
  // time begin(), and to the rightmost node of the tree, to enable
81
  // linear time performance when used with the generic set algorithms
82
  // (set_union, etc.)
83
  // 
84
  // (2) when a node being deleted has two children its successor node
85
  // is relinked into its place, rather than copied, so that the only
86
  // iterators invalidated are those referring to the deleted node.
87
 
88
  enum _Rb_tree_color { _S_red = false, _S_black = true };
89
 
90
  struct _Rb_tree_node_base
91
  {
92
    typedef _Rb_tree_node_base* _Base_ptr;
93
    typedef const _Rb_tree_node_base* _Const_Base_ptr;
94
 
95
    _Rb_tree_color      _M_color;
96
    _Base_ptr           _M_parent;
97
    _Base_ptr           _M_left;
98
    _Base_ptr           _M_right;
99
 
100
    static _Base_ptr
101
    _S_minimum(_Base_ptr __x)
102
    {
103
      while (__x->_M_left != 0) __x = __x->_M_left;
104
      return __x;
105
    }
106
 
107
    static _Const_Base_ptr
108
    _S_minimum(_Const_Base_ptr __x)
109
    {
110
      while (__x->_M_left != 0) __x = __x->_M_left;
111
      return __x;
112
    }
113
 
114
    static _Base_ptr
115
    _S_maximum(_Base_ptr __x)
116
    {
117
      while (__x->_M_right != 0) __x = __x->_M_right;
118
      return __x;
119
    }
120
 
121
    static _Const_Base_ptr
122
    _S_maximum(_Const_Base_ptr __x)
123
    {
124
      while (__x->_M_right != 0) __x = __x->_M_right;
125
      return __x;
126
    }
127
  };
128
 
129
  template<typename _Val>
130
    struct _Rb_tree_node : public _Rb_tree_node_base
131
    {
132
      typedef _Rb_tree_node<_Val>* _Link_type;
133
      _Val _M_value_field;
134
 
135
#if __cplusplus >= 201103L
136
      template<typename... _Args>
137
        _Rb_tree_node(_Args&&... __args)
138
        : _Rb_tree_node_base(),
139
          _M_value_field(std::forward<_Args>(__args)...) { }
140
#endif
141
    };
142
 
143
  _GLIBCXX_PURE _Rb_tree_node_base*
144
  _Rb_tree_increment(_Rb_tree_node_base* __x) throw ();
145
 
146
  _GLIBCXX_PURE const _Rb_tree_node_base*
147
  _Rb_tree_increment(const _Rb_tree_node_base* __x) throw ();
148
 
149
  _GLIBCXX_PURE _Rb_tree_node_base*
150
  _Rb_tree_decrement(_Rb_tree_node_base* __x) throw ();
151
 
152
  _GLIBCXX_PURE const _Rb_tree_node_base*
153
  _Rb_tree_decrement(const _Rb_tree_node_base* __x) throw ();
154
 
155
  template<typename _Tp>
156
    struct _Rb_tree_iterator
157
    {
158
      typedef _Tp  value_type;
159
      typedef _Tp& reference;
160
      typedef _Tp* pointer;
161
 
162
      typedef bidirectional_iterator_tag iterator_category;
163
      typedef ptrdiff_t                  difference_type;
164
 
165
      typedef _Rb_tree_iterator<_Tp>        _Self;
166
      typedef _Rb_tree_node_base::_Base_ptr _Base_ptr;
167
      typedef _Rb_tree_node<_Tp>*           _Link_type;
168
 
169
      _Rb_tree_iterator()
170
      : _M_node() { }
171
 
172
      explicit
173
      _Rb_tree_iterator(_Link_type __x)
174
      : _M_node(__x) { }
175
 
176
      reference
177
      operator*() const
178
      { return static_cast<_Link_type>(_M_node)->_M_value_field; }
179
 
180
      pointer
181
      operator->() const
182
      { return std::__addressof(static_cast<_Link_type>
183
                                (_M_node)->_M_value_field); }
184
 
185
      _Self&
186
      operator++()
187
      {
188
        _M_node = _Rb_tree_increment(_M_node);
189
        return *this;
190
      }
191
 
192
      _Self
193
      operator++(int)
194
      {
195
        _Self __tmp = *this;
196
        _M_node = _Rb_tree_increment(_M_node);
197
        return __tmp;
198
      }
199
 
200
      _Self&
201
      operator--()
202
      {
203
        _M_node = _Rb_tree_decrement(_M_node);
204
        return *this;
205
      }
206
 
207
      _Self
208
      operator--(int)
209
      {
210
        _Self __tmp = *this;
211
        _M_node = _Rb_tree_decrement(_M_node);
212
        return __tmp;
213
      }
214
 
215
      bool
216
      operator==(const _Self& __x) const
217
      { return _M_node == __x._M_node; }
218
 
219
      bool
220
      operator!=(const _Self& __x) const
221
      { return _M_node != __x._M_node; }
222
 
223
      _Base_ptr _M_node;
224
  };
225
 
226
  template<typename _Tp>
227
    struct _Rb_tree_const_iterator
228
    {
229
      typedef _Tp        value_type;
230
      typedef const _Tp& reference;
231
      typedef const _Tp* pointer;
232
 
233
      typedef _Rb_tree_iterator<_Tp> iterator;
234
 
235
      typedef bidirectional_iterator_tag iterator_category;
236
      typedef ptrdiff_t                  difference_type;
237
 
238
      typedef _Rb_tree_const_iterator<_Tp>        _Self;
239
      typedef _Rb_tree_node_base::_Const_Base_ptr _Base_ptr;
240
      typedef const _Rb_tree_node<_Tp>*           _Link_type;
241
 
242
      _Rb_tree_const_iterator()
243
      : _M_node() { }
244
 
245
      explicit
246
      _Rb_tree_const_iterator(_Link_type __x)
247
      : _M_node(__x) { }
248
 
249
      _Rb_tree_const_iterator(const iterator& __it)
250
      : _M_node(__it._M_node) { }
251
 
252
      iterator
253
      _M_const_cast() const
254
      { return iterator(static_cast<typename iterator::_Link_type>
255
                        (const_cast<typename iterator::_Base_ptr>(_M_node))); }
256
 
257
      reference
258
      operator*() const
259
      { return static_cast<_Link_type>(_M_node)->_M_value_field; }
260
 
261
      pointer
262
      operator->() const
263
      { return std::__addressof(static_cast<_Link_type>
264
                                (_M_node)->_M_value_field); }
265
 
266
      _Self&
267
      operator++()
268
      {
269
        _M_node = _Rb_tree_increment(_M_node);
270
        return *this;
271
      }
272
 
273
      _Self
274
      operator++(int)
275
      {
276
        _Self __tmp = *this;
277
        _M_node = _Rb_tree_increment(_M_node);
278
        return __tmp;
279
      }
280
 
281
      _Self&
282
      operator--()
283
      {
284
        _M_node = _Rb_tree_decrement(_M_node);
285
        return *this;
286
      }
287
 
288
      _Self
289
      operator--(int)
290
      {
291
        _Self __tmp = *this;
292
        _M_node = _Rb_tree_decrement(_M_node);
293
        return __tmp;
294
      }
295
 
296
      bool
297
      operator==(const _Self& __x) const
298
      { return _M_node == __x._M_node; }
299
 
300
      bool
301
      operator!=(const _Self& __x) const
302
      { return _M_node != __x._M_node; }
303
 
304
      _Base_ptr _M_node;
305
    };
306
 
307
  template<typename _Val>
308
    inline bool
309
    operator==(const _Rb_tree_iterator<_Val>& __x,
310
               const _Rb_tree_const_iterator<_Val>& __y)
311
    { return __x._M_node == __y._M_node; }
312
 
313
  template<typename _Val>
314
    inline bool
315
    operator!=(const _Rb_tree_iterator<_Val>& __x,
316
               const _Rb_tree_const_iterator<_Val>& __y)
317
    { return __x._M_node != __y._M_node; }
318
 
319
  void
320
  _Rb_tree_insert_and_rebalance(const bool __insert_left,
321
                                _Rb_tree_node_base* __x,
322
                                _Rb_tree_node_base* __p,
323
                                _Rb_tree_node_base& __header) throw ();
324
 
325
  _Rb_tree_node_base*
326
  _Rb_tree_rebalance_for_erase(_Rb_tree_node_base* const __z,
327
                               _Rb_tree_node_base& __header) throw ();
328
 
329
 
330
  template<typename _Key, typename _Val, typename _KeyOfValue,
331
           typename _Compare, typename _Alloc = allocator<_Val> >
332
    class _Rb_tree
333
    {
334
      typedef typename _Alloc::template rebind<_Rb_tree_node<_Val> >::other
335
              _Node_allocator;
336
 
337
    protected:
338
      typedef _Rb_tree_node_base* _Base_ptr;
339
      typedef const _Rb_tree_node_base* _Const_Base_ptr;
340
 
341
    public:
342
      typedef _Key key_type;
343
      typedef _Val value_type;
344
      typedef value_type* pointer;
345
      typedef const value_type* const_pointer;
346
      typedef value_type& reference;
347
      typedef const value_type& const_reference;
348
      typedef _Rb_tree_node<_Val>* _Link_type;
349
      typedef const _Rb_tree_node<_Val>* _Const_Link_type;
350
      typedef size_t size_type;
351
      typedef ptrdiff_t difference_type;
352
      typedef _Alloc allocator_type;
353
 
354
      _Node_allocator&
355
      _M_get_Node_allocator() _GLIBCXX_NOEXCEPT
356
      { return *static_cast<_Node_allocator*>(&this->_M_impl); }
357
 
358
      const _Node_allocator&
359
      _M_get_Node_allocator() const _GLIBCXX_NOEXCEPT
360
      { return *static_cast<const _Node_allocator*>(&this->_M_impl); }
361
 
362
      allocator_type
363
      get_allocator() const _GLIBCXX_NOEXCEPT
364
      { return allocator_type(_M_get_Node_allocator()); }
365
 
366
    protected:
367
      _Link_type
368
      _M_get_node()
369
      { return _M_impl._Node_allocator::allocate(1); }
370
 
371
      void
372
      _M_put_node(_Link_type __p)
373
      { _M_impl._Node_allocator::deallocate(__p, 1); }
374
 
375
#if __cplusplus < 201103L
376
      _Link_type
377
      _M_create_node(const value_type& __x)
378
      {
379
        _Link_type __tmp = _M_get_node();
380
        __try
381
          { get_allocator().construct
382
              (std::__addressof(__tmp->_M_value_field), __x); }
383
        __catch(...)
384
          {
385
            _M_put_node(__tmp);
386
            __throw_exception_again;
387
          }
388
        return __tmp;
389
      }
390
 
391
      void
392
      _M_destroy_node(_Link_type __p)
393
      {
394
        get_allocator().destroy(std::__addressof(__p->_M_value_field));
395
        _M_put_node(__p);
396
      }
397
#else
398
      template<typename... _Args>
399
        _Link_type
400
        _M_create_node(_Args&&... __args)
401
        {
402
          _Link_type __tmp = _M_get_node();
403
          __try
404
            {
405
              _M_get_Node_allocator().construct(__tmp,
406
                                             std::forward<_Args>(__args)...);
407
            }
408
          __catch(...)
409
            {
410
              _M_put_node(__tmp);
411
              __throw_exception_again;
412
            }
413
          return __tmp;
414
        }
415
 
416
      void
417
      _M_destroy_node(_Link_type __p)
418
      {
419
        _M_get_Node_allocator().destroy(__p);
420
        _M_put_node(__p);
421
      }
422
#endif
423
 
424
      _Link_type
425
      _M_clone_node(_Const_Link_type __x)
426
      {
427
        _Link_type __tmp = _M_create_node(__x->_M_value_field);
428
        __tmp->_M_color = __x->_M_color;
429
        __tmp->_M_left = 0;
430
        __tmp->_M_right = 0;
431
        return __tmp;
432
      }
433
 
434
    protected:
435
      template<typename _Key_compare,
436
               bool _Is_pod_comparator = __is_pod(_Key_compare)>
437
        struct _Rb_tree_impl : public _Node_allocator
438
        {
439
          _Key_compare          _M_key_compare;
440
          _Rb_tree_node_base    _M_header;
441
          size_type             _M_node_count; // Keeps track of size of tree.
442
 
443
          _Rb_tree_impl()
444
          : _Node_allocator(), _M_key_compare(), _M_header(),
445
            _M_node_count(0)
446
          { _M_initialize(); }
447
 
448
          _Rb_tree_impl(const _Key_compare& __comp, const _Node_allocator& __a)
449
          : _Node_allocator(__a), _M_key_compare(__comp), _M_header(),
450
            _M_node_count(0)
451
          { _M_initialize(); }
452
 
453
#if __cplusplus >= 201103L
454
          _Rb_tree_impl(const _Key_compare& __comp, _Node_allocator&& __a)
455
          : _Node_allocator(std::move(__a)), _M_key_compare(__comp),
456
            _M_header(), _M_node_count(0)
457
          { _M_initialize(); }
458
#endif
459
 
460
        private:
461
          void
462
          _M_initialize()
463
          {
464
            this->_M_header._M_color = _S_red;
465
            this->_M_header._M_parent = 0;
466
            this->_M_header._M_left = &this->_M_header;
467
            this->_M_header._M_right = &this->_M_header;
468
          }
469
        };
470
 
471
      _Rb_tree_impl<_Compare> _M_impl;
472
 
473
    protected:
474
      _Base_ptr&
475
      _M_root()
476
      { return this->_M_impl._M_header._M_parent; }
477
 
478
      _Const_Base_ptr
479
      _M_root() const
480
      { return this->_M_impl._M_header._M_parent; }
481
 
482
      _Base_ptr&
483
      _M_leftmost()
484
      { return this->_M_impl._M_header._M_left; }
485
 
486
      _Const_Base_ptr
487
      _M_leftmost() const
488
      { return this->_M_impl._M_header._M_left; }
489
 
490
      _Base_ptr&
491
      _M_rightmost()
492
      { return this->_M_impl._M_header._M_right; }
493
 
494
      _Const_Base_ptr
495
      _M_rightmost() const
496
      { return this->_M_impl._M_header._M_right; }
497
 
498
      _Link_type
499
      _M_begin()
500
      { return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); }
501
 
502
      _Const_Link_type
503
      _M_begin() const
504
      {
505
        return static_cast<_Const_Link_type>
506
          (this->_M_impl._M_header._M_parent);
507
      }
508
 
509
      _Link_type
510
      _M_end()
511
      { return static_cast<_Link_type>(&this->_M_impl._M_header); }
512
 
513
      _Const_Link_type
514
      _M_end() const
515
      { return static_cast<_Const_Link_type>(&this->_M_impl._M_header); }
516
 
517
      static const_reference
518
      _S_value(_Const_Link_type __x)
519
      { return __x->_M_value_field; }
520
 
521
      static const _Key&
522
      _S_key(_Const_Link_type __x)
523
      { return _KeyOfValue()(_S_value(__x)); }
524
 
525
      static _Link_type
526
      _S_left(_Base_ptr __x)
527
      { return static_cast<_Link_type>(__x->_M_left); }
528
 
529
      static _Const_Link_type
530
      _S_left(_Const_Base_ptr __x)
531
      { return static_cast<_Const_Link_type>(__x->_M_left); }
532
 
533
      static _Link_type
534
      _S_right(_Base_ptr __x)
535
      { return static_cast<_Link_type>(__x->_M_right); }
536
 
537
      static _Const_Link_type
538
      _S_right(_Const_Base_ptr __x)
539
      { return static_cast<_Const_Link_type>(__x->_M_right); }
540
 
541
      static const_reference
542
      _S_value(_Const_Base_ptr __x)
543
      { return static_cast<_Const_Link_type>(__x)->_M_value_field; }
544
 
545
      static const _Key&
546
      _S_key(_Const_Base_ptr __x)
547
      { return _KeyOfValue()(_S_value(__x)); }
548
 
549
      static _Base_ptr
550
      _S_minimum(_Base_ptr __x)
551
      { return _Rb_tree_node_base::_S_minimum(__x); }
552
 
553
      static _Const_Base_ptr
554
      _S_minimum(_Const_Base_ptr __x)
555
      { return _Rb_tree_node_base::_S_minimum(__x); }
556
 
557
      static _Base_ptr
558
      _S_maximum(_Base_ptr __x)
559
      { return _Rb_tree_node_base::_S_maximum(__x); }
560
 
561
      static _Const_Base_ptr
562
      _S_maximum(_Const_Base_ptr __x)
563
      { return _Rb_tree_node_base::_S_maximum(__x); }
564
 
565
    public:
566
      typedef _Rb_tree_iterator<value_type>       iterator;
567
      typedef _Rb_tree_const_iterator<value_type> const_iterator;
568
 
569
      typedef std::reverse_iterator<iterator>       reverse_iterator;
570
      typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
571
 
572
    private:
573
      pair<_Base_ptr, _Base_ptr>
574
      _M_get_insert_unique_pos(const key_type& __k);
575
 
576
      pair<_Base_ptr, _Base_ptr>
577
      _M_get_insert_equal_pos(const key_type& __k);
578
 
579
      pair<_Base_ptr, _Base_ptr>
580
      _M_get_insert_hint_unique_pos(const_iterator __pos,
581
                                    const key_type& __k);
582
 
583
      pair<_Base_ptr, _Base_ptr>
584
      _M_get_insert_hint_equal_pos(const_iterator __pos,
585
                                   const key_type& __k);
586
 
587
#if __cplusplus >= 201103L
588
      template<typename _Arg>
589
        iterator
590
        _M_insert_(_Base_ptr __x, _Base_ptr __y, _Arg&& __v);
591
 
592
      iterator
593
      _M_insert_node(_Base_ptr __x, _Base_ptr __y, _Link_type __z);
594
 
595
      template<typename _Arg>
596
        iterator
597
        _M_insert_lower(_Base_ptr __y, _Arg&& __v);
598
 
599
      template<typename _Arg>
600
        iterator
601
        _M_insert_equal_lower(_Arg&& __x);
602
 
603
      iterator
604
      _M_insert_lower_node(_Base_ptr __p, _Link_type __z);
605
 
606
      iterator
607
      _M_insert_equal_lower_node(_Link_type __z);
608
#else
609
      iterator
610
      _M_insert_(_Base_ptr __x, _Base_ptr __y,
611
                 const value_type& __v);
612
 
613
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
614
      // 233. Insertion hints in associative containers.
615
      iterator
616
      _M_insert_lower(_Base_ptr __y, const value_type& __v);
617
 
618
      iterator
619
      _M_insert_equal_lower(const value_type& __x);
620
#endif
621
 
622
      _Link_type
623
      _M_copy(_Const_Link_type __x, _Link_type __p);
624
 
625
      void
626
      _M_erase(_Link_type __x);
627
 
628
      iterator
629
      _M_lower_bound(_Link_type __x, _Link_type __y,
630
                     const _Key& __k);
631
 
632
      const_iterator
633
      _M_lower_bound(_Const_Link_type __x, _Const_Link_type __y,
634
                     const _Key& __k) const;
635
 
636
      iterator
637
      _M_upper_bound(_Link_type __x, _Link_type __y,
638
                     const _Key& __k);
639
 
640
      const_iterator
641
      _M_upper_bound(_Const_Link_type __x, _Const_Link_type __y,
642
                     const _Key& __k) const;
643
 
644
    public:
645
      // allocation/deallocation
646
      _Rb_tree() { }
647
 
648
      _Rb_tree(const _Compare& __comp,
649
               const allocator_type& __a = allocator_type())
650
      : _M_impl(__comp, _Node_allocator(__a)) { }
651
 
652
      _Rb_tree(const _Rb_tree& __x)
653
      : _M_impl(__x._M_impl._M_key_compare, __x._M_get_Node_allocator())
654
      {
655
        if (__x._M_root() != 0)
656
          {
657
            _M_root() = _M_copy(__x._M_begin(), _M_end());
658
            _M_leftmost() = _S_minimum(_M_root());
659
            _M_rightmost() = _S_maximum(_M_root());
660
            _M_impl._M_node_count = __x._M_impl._M_node_count;
661
          }
662
      }
663
 
664
#if __cplusplus >= 201103L
665
      _Rb_tree(_Rb_tree&& __x);
666
#endif
667
 
668
      ~_Rb_tree() _GLIBCXX_NOEXCEPT
669
      { _M_erase(_M_begin()); }
670
 
671
      _Rb_tree&
672
      operator=(const _Rb_tree& __x);
673
 
674
      // Accessors.
675
      _Compare
676
      key_comp() const
677
      { return _M_impl._M_key_compare; }
678
 
679
      iterator
680
      begin() _GLIBCXX_NOEXCEPT
681
      {
682
        return iterator(static_cast<_Link_type>
683
                        (this->_M_impl._M_header._M_left));
684
      }
685
 
686
      const_iterator
687
      begin() const _GLIBCXX_NOEXCEPT
688
      {
689
        return const_iterator(static_cast<_Const_Link_type>
690
                              (this->_M_impl._M_header._M_left));
691
      }
692
 
693
      iterator
694
      end() _GLIBCXX_NOEXCEPT
695
      { return iterator(static_cast<_Link_type>(&this->_M_impl._M_header)); }
696
 
697
      const_iterator
698
      end() const _GLIBCXX_NOEXCEPT
699
      {
700
        return const_iterator(static_cast<_Const_Link_type>
701
                              (&this->_M_impl._M_header));
702
      }
703
 
704
      reverse_iterator
705
      rbegin() _GLIBCXX_NOEXCEPT
706
      { return reverse_iterator(end()); }
707
 
708
      const_reverse_iterator
709
      rbegin() const _GLIBCXX_NOEXCEPT
710
      { return const_reverse_iterator(end()); }
711
 
712
      reverse_iterator
713
      rend() _GLIBCXX_NOEXCEPT
714
      { return reverse_iterator(begin()); }
715
 
716
      const_reverse_iterator
717
      rend() const _GLIBCXX_NOEXCEPT
718
      { return const_reverse_iterator(begin()); }
719
 
720
      bool
721
      empty() const _GLIBCXX_NOEXCEPT
722
      { return _M_impl._M_node_count == 0; }
723
 
724
      size_type
725
      size() const _GLIBCXX_NOEXCEPT
726
      { return _M_impl._M_node_count; }
727
 
728
      size_type
729
      max_size() const _GLIBCXX_NOEXCEPT
730
      { return _M_get_Node_allocator().max_size(); }
731
 
732
      void
733
      swap(_Rb_tree& __t);
734
 
735
      // Insert/erase.
736
#if __cplusplus >= 201103L
737
      template<typename _Arg>
738
        pair<iterator, bool>
739
        _M_insert_unique(_Arg&& __x);
740
 
741
      template<typename _Arg>
742
        iterator
743
        _M_insert_equal(_Arg&& __x);
744
 
745
      template<typename _Arg>
746
        iterator
747
        _M_insert_unique_(const_iterator __position, _Arg&& __x);
748
 
749
      template<typename _Arg>
750
        iterator
751
        _M_insert_equal_(const_iterator __position, _Arg&& __x);
752
 
753
      template<typename... _Args>
754
        pair<iterator, bool>
755
        _M_emplace_unique(_Args&&... __args);
756
 
757
      template<typename... _Args>
758
        iterator
759
        _M_emplace_equal(_Args&&... __args);
760
 
761
      template<typename... _Args>
762
        iterator
763
        _M_emplace_hint_unique(const_iterator __pos, _Args&&... __args);
764
 
765
      template<typename... _Args>
766
        iterator
767
        _M_emplace_hint_equal(const_iterator __pos, _Args&&... __args);
768
#else
769
      pair<iterator, bool>
770
      _M_insert_unique(const value_type& __x);
771
 
772
      iterator
773
      _M_insert_equal(const value_type& __x);
774
 
775
      iterator
776
      _M_insert_unique_(const_iterator __position, const value_type& __x);
777
 
778
      iterator
779
      _M_insert_equal_(const_iterator __position, const value_type& __x);
780
#endif
781
 
782
      template<typename _InputIterator>
783
        void
784
        _M_insert_unique(_InputIterator __first, _InputIterator __last);
785
 
786
      template<typename _InputIterator>
787
        void
788
        _M_insert_equal(_InputIterator __first, _InputIterator __last);
789
 
790
    private:
791
      void
792
      _M_erase_aux(const_iterator __position);
793
 
794
      void
795
      _M_erase_aux(const_iterator __first, const_iterator __last);
796
 
797
    public:
798
#if __cplusplus >= 201103L
799
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
800
      // DR 130. Associative erase should return an iterator.
801
      iterator
802
      erase(const_iterator __position)
803
      {
804
        const_iterator __result = __position;
805
        ++__result;
806
        _M_erase_aux(__position);
807
        return __result._M_const_cast();
808
      }
809
 
810
      // LWG 2059.
811
      iterator
812
      erase(iterator __position)
813
      {
814
        iterator __result = __position;
815
        ++__result;
816
        _M_erase_aux(__position);
817
        return __result;
818
      }
819
#else
820
      void
821
      erase(iterator __position)
822
      { _M_erase_aux(__position); }
823
 
824
      void
825
      erase(const_iterator __position)
826
      { _M_erase_aux(__position); }
827
#endif
828
      size_type
829
      erase(const key_type& __x);
830
 
831
#if __cplusplus >= 201103L
832
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
833
      // DR 130. Associative erase should return an iterator.
834
      iterator
835
      erase(const_iterator __first, const_iterator __last)
836
      {
837
        _M_erase_aux(__first, __last);
838
        return __last._M_const_cast();
839
      }
840
#else
841
      void
842
      erase(iterator __first, iterator __last)
843
      { _M_erase_aux(__first, __last); }
844
 
845
      void
846
      erase(const_iterator __first, const_iterator __last)
847
      { _M_erase_aux(__first, __last); }
848
#endif
849
      void
850
      erase(const key_type* __first, const key_type* __last);
851
 
852
      void
853
      clear() _GLIBCXX_NOEXCEPT
854
      {
855
        _M_erase(_M_begin());
856
        _M_leftmost() = _M_end();
857
        _M_root() = 0;
858
        _M_rightmost() = _M_end();
859
        _M_impl._M_node_count = 0;
860
      }
861
 
862
      // Set operations.
863
      iterator
864
      find(const key_type& __k);
865
 
866
      const_iterator
867
      find(const key_type& __k) const;
868
 
869
      size_type
870
      count(const key_type& __k) const;
871
 
872
      iterator
873
      lower_bound(const key_type& __k)
874
      { return _M_lower_bound(_M_begin(), _M_end(), __k); }
875
 
876
      const_iterator
877
      lower_bound(const key_type& __k) const
878
      { return _M_lower_bound(_M_begin(), _M_end(), __k); }
879
 
880
      iterator
881
      upper_bound(const key_type& __k)
882
      { return _M_upper_bound(_M_begin(), _M_end(), __k); }
883
 
884
      const_iterator
885
      upper_bound(const key_type& __k) const
886
      { return _M_upper_bound(_M_begin(), _M_end(), __k); }
887
 
888
      pair<iterator, iterator>
889
      equal_range(const key_type& __k);
890
 
891
      pair<const_iterator, const_iterator>
892
      equal_range(const key_type& __k) const;
893
 
894
      // Debugging.
895
      bool
896
      __rb_verify() const;
897
    };
898
 
899
  template<typename _Key, typename _Val, typename _KeyOfValue,
900
           typename _Compare, typename _Alloc>
901
    inline bool
902
    operator==(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
903
               const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
904
    {
905
      return __x.size() == __y.size()
906
             && std::equal(__x.begin(), __x.end(), __y.begin());
907
    }
908
 
909
  template<typename _Key, typename _Val, typename _KeyOfValue,
910
           typename _Compare, typename _Alloc>
911
    inline bool
912
    operator<(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
913
              const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
914
    {
915
      return std::lexicographical_compare(__x.begin(), __x.end(),
916
                                          __y.begin(), __y.end());
917
    }
918
 
919
  template<typename _Key, typename _Val, typename _KeyOfValue,
920
           typename _Compare, typename _Alloc>
921
    inline bool
922
    operator!=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
923
               const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
924
    { return !(__x == __y); }
925
 
926
  template<typename _Key, typename _Val, typename _KeyOfValue,
927
           typename _Compare, typename _Alloc>
928
    inline bool
929
    operator>(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
930
              const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
931
    { return __y < __x; }
932
 
933
  template<typename _Key, typename _Val, typename _KeyOfValue,
934
           typename _Compare, typename _Alloc>
935
    inline bool
936
    operator<=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
937
               const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
938
    { return !(__y < __x); }
939
 
940
  template<typename _Key, typename _Val, typename _KeyOfValue,
941
           typename _Compare, typename _Alloc>
942
    inline bool
943
    operator>=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
944
               const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
945
    { return !(__x < __y); }
946
 
947
  template<typename _Key, typename _Val, typename _KeyOfValue,
948
           typename _Compare, typename _Alloc>
949
    inline void
950
    swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
951
         _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
952
    { __x.swap(__y); }
953
 
954
#if __cplusplus >= 201103L
955
  template<typename _Key, typename _Val, typename _KeyOfValue,
956
           typename _Compare, typename _Alloc>
957
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
958
    _Rb_tree(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&& __x)
959
    : _M_impl(__x._M_impl._M_key_compare,
960
              std::move(__x._M_get_Node_allocator()))
961
    {
962
      if (__x._M_root() != 0)
963
        {
964
          _M_root() = __x._M_root();
965
          _M_leftmost() = __x._M_leftmost();
966
          _M_rightmost() = __x._M_rightmost();
967
          _M_root()->_M_parent = _M_end();
968
 
969
          __x._M_root() = 0;
970
          __x._M_leftmost() = __x._M_end();
971
          __x._M_rightmost() = __x._M_end();
972
 
973
          this->_M_impl._M_node_count = __x._M_impl._M_node_count;
974
          __x._M_impl._M_node_count = 0;
975
        }
976
    }
977
#endif
978
 
979
  template<typename _Key, typename _Val, typename _KeyOfValue,
980
           typename _Compare, typename _Alloc>
981
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&
982
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
983
    operator=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x)
984
    {
985
      if (this != &__x)
986
        {
987
          // Note that _Key may be a constant type.
988
          clear();
989
          _M_impl._M_key_compare = __x._M_impl._M_key_compare;
990
          if (__x._M_root() != 0)
991
            {
992
              _M_root() = _M_copy(__x._M_begin(), _M_end());
993
              _M_leftmost() = _S_minimum(_M_root());
994
              _M_rightmost() = _S_maximum(_M_root());
995
              _M_impl._M_node_count = __x._M_impl._M_node_count;
996
            }
997
        }
998
      return *this;
999
    }
1000
 
1001
  template<typename _Key, typename _Val, typename _KeyOfValue,
1002
           typename _Compare, typename _Alloc>
1003
#if __cplusplus >= 201103L
1004
    template<typename _Arg>
1005
#endif
1006
    typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1007
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1008
#if __cplusplus >= 201103L
1009
    _M_insert_(_Base_ptr __x, _Base_ptr __p, _Arg&& __v)
1010
#else
1011
    _M_insert_(_Base_ptr __x, _Base_ptr __p, const _Val& __v)
1012
#endif
1013
    {
1014
      bool __insert_left = (__x != 0 || __p == _M_end()
1015
                            || _M_impl._M_key_compare(_KeyOfValue()(__v),
1016
                                                      _S_key(__p)));
1017
 
1018
      _Link_type __z = _M_create_node(_GLIBCXX_FORWARD(_Arg, __v));
1019
 
1020
      _Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
1021
                                    this->_M_impl._M_header);
1022
      ++_M_impl._M_node_count;
1023
      return iterator(__z);
1024
    }
1025
 
1026
  template<typename _Key, typename _Val, typename _KeyOfValue,
1027
           typename _Compare, typename _Alloc>
1028
#if __cplusplus >= 201103L
1029
    template<typename _Arg>
1030
#endif
1031
    typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1032
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1033
#if __cplusplus >= 201103L
1034
    _M_insert_lower(_Base_ptr __p, _Arg&& __v)
1035
#else
1036
    _M_insert_lower(_Base_ptr __p, const _Val& __v)
1037
#endif
1038
    {
1039
      bool __insert_left = (__p == _M_end()
1040
                            || !_M_impl._M_key_compare(_S_key(__p),
1041
                                                       _KeyOfValue()(__v)));
1042
 
1043
      _Link_type __z = _M_create_node(_GLIBCXX_FORWARD(_Arg, __v));
1044
 
1045
      _Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
1046
                                    this->_M_impl._M_header);
1047
      ++_M_impl._M_node_count;
1048
      return iterator(__z);
1049
    }
1050
 
1051
  template<typename _Key, typename _Val, typename _KeyOfValue,
1052
           typename _Compare, typename _Alloc>
1053
#if __cplusplus >= 201103L
1054
    template<typename _Arg>
1055
#endif
1056
    typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1057
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1058
#if __cplusplus >= 201103L
1059
    _M_insert_equal_lower(_Arg&& __v)
1060
#else
1061
    _M_insert_equal_lower(const _Val& __v)
1062
#endif
1063
    {
1064
      _Link_type __x = _M_begin();
1065
      _Link_type __y = _M_end();
1066
      while (__x != 0)
1067
        {
1068
          __y = __x;
1069
          __x = !_M_impl._M_key_compare(_S_key(__x), _KeyOfValue()(__v)) ?
1070
                _S_left(__x) : _S_right(__x);
1071
        }
1072
      return _M_insert_lower(__y, _GLIBCXX_FORWARD(_Arg, __v));
1073
    }
1074
 
1075
  template<typename _Key, typename _Val, typename _KoV,
1076
           typename _Compare, typename _Alloc>
1077
    typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type
1078
    _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::
1079
    _M_copy(_Const_Link_type __x, _Link_type __p)
1080
    {
1081
      // Structural copy.  __x and __p must be non-null.
1082
      _Link_type __top = _M_clone_node(__x);
1083
      __top->_M_parent = __p;
1084
 
1085
      __try
1086
        {
1087
          if (__x->_M_right)
1088
            __top->_M_right = _M_copy(_S_right(__x), __top);
1089
          __p = __top;
1090
          __x = _S_left(__x);
1091
 
1092
          while (__x != 0)
1093
            {
1094
              _Link_type __y = _M_clone_node(__x);
1095
              __p->_M_left = __y;
1096
              __y->_M_parent = __p;
1097
              if (__x->_M_right)
1098
                __y->_M_right = _M_copy(_S_right(__x), __y);
1099
              __p = __y;
1100
              __x = _S_left(__x);
1101
            }
1102
        }
1103
      __catch(...)
1104
        {
1105
          _M_erase(__top);
1106
          __throw_exception_again;
1107
        }
1108
      return __top;
1109
    }
1110
 
1111
  template<typename _Key, typename _Val, typename _KeyOfValue,
1112
           typename _Compare, typename _Alloc>
1113
    void
1114
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1115
    _M_erase(_Link_type __x)
1116
    {
1117
      // Erase without rebalancing.
1118
      while (__x != 0)
1119
        {
1120
          _M_erase(_S_right(__x));
1121
          _Link_type __y = _S_left(__x);
1122
          _M_destroy_node(__x);
1123
          __x = __y;
1124
        }
1125
    }
1126
 
1127
  template<typename _Key, typename _Val, typename _KeyOfValue,
1128
           typename _Compare, typename _Alloc>
1129
    typename _Rb_tree<_Key, _Val, _KeyOfValue,
1130
                      _Compare, _Alloc>::iterator
1131
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1132
    _M_lower_bound(_Link_type __x, _Link_type __y,
1133
                   const _Key& __k)
1134
    {
1135
      while (__x != 0)
1136
        if (!_M_impl._M_key_compare(_S_key(__x), __k))
1137
          __y = __x, __x = _S_left(__x);
1138
        else
1139
          __x = _S_right(__x);
1140
      return iterator(__y);
1141
    }
1142
 
1143
  template<typename _Key, typename _Val, typename _KeyOfValue,
1144
           typename _Compare, typename _Alloc>
1145
    typename _Rb_tree<_Key, _Val, _KeyOfValue,
1146
                      _Compare, _Alloc>::const_iterator
1147
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1148
    _M_lower_bound(_Const_Link_type __x, _Const_Link_type __y,
1149
                   const _Key& __k) const
1150
    {
1151
      while (__x != 0)
1152
        if (!_M_impl._M_key_compare(_S_key(__x), __k))
1153
          __y = __x, __x = _S_left(__x);
1154
        else
1155
          __x = _S_right(__x);
1156
      return const_iterator(__y);
1157
    }
1158
 
1159
  template<typename _Key, typename _Val, typename _KeyOfValue,
1160
           typename _Compare, typename _Alloc>
1161
    typename _Rb_tree<_Key, _Val, _KeyOfValue,
1162
                      _Compare, _Alloc>::iterator
1163
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1164
    _M_upper_bound(_Link_type __x, _Link_type __y,
1165
                   const _Key& __k)
1166
    {
1167
      while (__x != 0)
1168
        if (_M_impl._M_key_compare(__k, _S_key(__x)))
1169
          __y = __x, __x = _S_left(__x);
1170
        else
1171
          __x = _S_right(__x);
1172
      return iterator(__y);
1173
    }
1174
 
1175
  template<typename _Key, typename _Val, typename _KeyOfValue,
1176
           typename _Compare, typename _Alloc>
1177
    typename _Rb_tree<_Key, _Val, _KeyOfValue,
1178
                      _Compare, _Alloc>::const_iterator
1179
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1180
    _M_upper_bound(_Const_Link_type __x, _Const_Link_type __y,
1181
                   const _Key& __k) const
1182
    {
1183
      while (__x != 0)
1184
        if (_M_impl._M_key_compare(__k, _S_key(__x)))
1185
          __y = __x, __x = _S_left(__x);
1186
        else
1187
          __x = _S_right(__x);
1188
      return const_iterator(__y);
1189
    }
1190
 
1191
  template<typename _Key, typename _Val, typename _KeyOfValue,
1192
           typename _Compare, typename _Alloc>
1193
    pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
1194
                           _Compare, _Alloc>::iterator,
1195
         typename _Rb_tree<_Key, _Val, _KeyOfValue,
1196
                           _Compare, _Alloc>::iterator>
1197
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1198
    equal_range(const _Key& __k)
1199
    {
1200
      _Link_type __x = _M_begin();
1201
      _Link_type __y = _M_end();
1202
      while (__x != 0)
1203
        {
1204
          if (_M_impl._M_key_compare(_S_key(__x), __k))
1205
            __x = _S_right(__x);
1206
          else if (_M_impl._M_key_compare(__k, _S_key(__x)))
1207
            __y = __x, __x = _S_left(__x);
1208
          else
1209
            {
1210
              _Link_type __xu(__x), __yu(__y);
1211
              __y = __x, __x = _S_left(__x);
1212
              __xu = _S_right(__xu);
1213
              return pair<iterator,
1214
                          iterator>(_M_lower_bound(__x, __y, __k),
1215
                                    _M_upper_bound(__xu, __yu, __k));
1216
            }
1217
        }
1218
      return pair<iterator, iterator>(iterator(__y),
1219
                                      iterator(__y));
1220
    }
1221
 
1222
  template<typename _Key, typename _Val, typename _KeyOfValue,
1223
           typename _Compare, typename _Alloc>
1224
    pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
1225
                           _Compare, _Alloc>::const_iterator,
1226
         typename _Rb_tree<_Key, _Val, _KeyOfValue,
1227
                           _Compare, _Alloc>::const_iterator>
1228
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1229
    equal_range(const _Key& __k) const
1230
    {
1231
      _Const_Link_type __x = _M_begin();
1232
      _Const_Link_type __y = _M_end();
1233
      while (__x != 0)
1234
        {
1235
          if (_M_impl._M_key_compare(_S_key(__x), __k))
1236
            __x = _S_right(__x);
1237
          else if (_M_impl._M_key_compare(__k, _S_key(__x)))
1238
            __y = __x, __x = _S_left(__x);
1239
          else
1240
            {
1241
              _Const_Link_type __xu(__x), __yu(__y);
1242
              __y = __x, __x = _S_left(__x);
1243
              __xu = _S_right(__xu);
1244
              return pair<const_iterator,
1245
                          const_iterator>(_M_lower_bound(__x, __y, __k),
1246
                                          _M_upper_bound(__xu, __yu, __k));
1247
            }
1248
        }
1249
      return pair<const_iterator, const_iterator>(const_iterator(__y),
1250
                                                  const_iterator(__y));
1251
    }
1252
 
1253
  template<typename _Key, typename _Val, typename _KeyOfValue,
1254
           typename _Compare, typename _Alloc>
1255
    void
1256
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1257
    swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __t)
1258
    {
1259
      if (_M_root() == 0)
1260
        {
1261
          if (__t._M_root() != 0)
1262
            {
1263
              _M_root() = __t._M_root();
1264
              _M_leftmost() = __t._M_leftmost();
1265
              _M_rightmost() = __t._M_rightmost();
1266
              _M_root()->_M_parent = _M_end();
1267
 
1268
              __t._M_root() = 0;
1269
              __t._M_leftmost() = __t._M_end();
1270
              __t._M_rightmost() = __t._M_end();
1271
            }
1272
        }
1273
      else if (__t._M_root() == 0)
1274
        {
1275
          __t._M_root() = _M_root();
1276
          __t._M_leftmost() = _M_leftmost();
1277
          __t._M_rightmost() = _M_rightmost();
1278
          __t._M_root()->_M_parent = __t._M_end();
1279
 
1280
          _M_root() = 0;
1281
          _M_leftmost() = _M_end();
1282
          _M_rightmost() = _M_end();
1283
        }
1284
      else
1285
        {
1286
          std::swap(_M_root(),__t._M_root());
1287
          std::swap(_M_leftmost(),__t._M_leftmost());
1288
          std::swap(_M_rightmost(),__t._M_rightmost());
1289
 
1290
          _M_root()->_M_parent = _M_end();
1291
          __t._M_root()->_M_parent = __t._M_end();
1292
        }
1293
      // No need to swap header's color as it does not change.
1294
      std::swap(this->_M_impl._M_node_count, __t._M_impl._M_node_count);
1295
      std::swap(this->_M_impl._M_key_compare, __t._M_impl._M_key_compare);
1296
 
1297
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
1298
      // 431. Swapping containers with unequal allocators.
1299
      std::__alloc_swap<_Node_allocator>::
1300
        _S_do_it(_M_get_Node_allocator(), __t._M_get_Node_allocator());
1301
    }
1302
 
1303
  template<typename _Key, typename _Val, typename _KeyOfValue,
1304
           typename _Compare, typename _Alloc>
1305
    pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
1306
                           _Compare, _Alloc>::_Base_ptr,
1307
         typename _Rb_tree<_Key, _Val, _KeyOfValue,
1308
                           _Compare, _Alloc>::_Base_ptr>
1309
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1310
    _M_get_insert_unique_pos(const key_type& __k)
1311
    {
1312
      typedef pair<_Base_ptr, _Base_ptr> _Res;
1313
      _Link_type __x = _M_begin();
1314
      _Link_type __y = _M_end();
1315
      bool __comp = true;
1316
      while (__x != 0)
1317
        {
1318
          __y = __x;
1319
          __comp = _M_impl._M_key_compare(__k, _S_key(__x));
1320
          __x = __comp ? _S_left(__x) : _S_right(__x);
1321
        }
1322
      iterator __j = iterator(__y);
1323
      if (__comp)
1324
        {
1325
          if (__j == begin())
1326
            return _Res(__x, __y);
1327
          else
1328
            --__j;
1329
        }
1330
      if (_M_impl._M_key_compare(_S_key(__j._M_node), __k))
1331
        return _Res(__x, __y);
1332
      return _Res(__j._M_node, 0);
1333
    }
1334
 
1335
  template<typename _Key, typename _Val, typename _KeyOfValue,
1336
           typename _Compare, typename _Alloc>
1337
    pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
1338
                           _Compare, _Alloc>::_Base_ptr,
1339
         typename _Rb_tree<_Key, _Val, _KeyOfValue,
1340
                           _Compare, _Alloc>::_Base_ptr>
1341
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1342
    _M_get_insert_equal_pos(const key_type& __k)
1343
    {
1344
      typedef pair<_Base_ptr, _Base_ptr> _Res;
1345
      _Link_type __x = _M_begin();
1346
      _Link_type __y = _M_end();
1347
      while (__x != 0)
1348
        {
1349
          __y = __x;
1350
          __x = _M_impl._M_key_compare(__k, _S_key(__x)) ?
1351
                _S_left(__x) : _S_right(__x);
1352
        }
1353
      return _Res(__x, __y);
1354
    }
1355
 
1356
  template<typename _Key, typename _Val, typename _KeyOfValue,
1357
           typename _Compare, typename _Alloc>
1358
#if __cplusplus >= 201103L
1359
    template<typename _Arg>
1360
#endif
1361
    pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
1362
                           _Compare, _Alloc>::iterator, bool>
1363
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1364
#if __cplusplus >= 201103L
1365
    _M_insert_unique(_Arg&& __v)
1366
#else
1367
    _M_insert_unique(const _Val& __v)
1368
#endif
1369
    {
1370
      typedef pair<iterator, bool> _Res;
1371
      pair<_Base_ptr, _Base_ptr> __res
1372
        = _M_get_insert_unique_pos(_KeyOfValue()(__v));
1373
 
1374
      if (__res.second)
1375
        return _Res(_M_insert_(__res.first, __res.second,
1376
                               _GLIBCXX_FORWARD(_Arg, __v)),
1377
                    true);
1378
 
1379
      return _Res(iterator(static_cast<_Link_type>(__res.first)), false);
1380
    }
1381
 
1382
  template<typename _Key, typename _Val, typename _KeyOfValue,
1383
           typename _Compare, typename _Alloc>
1384
#if __cplusplus >= 201103L
1385
    template<typename _Arg>
1386
#endif
1387
    typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1388
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1389
#if __cplusplus >= 201103L
1390
    _M_insert_equal(_Arg&& __v)
1391
#else
1392
    _M_insert_equal(const _Val& __v)
1393
#endif
1394
    {
1395
      pair<_Base_ptr, _Base_ptr> __res
1396
        = _M_get_insert_equal_pos(_KeyOfValue()(__v));
1397
      return _M_insert_(__res.first, __res.second, _GLIBCXX_FORWARD(_Arg, __v));
1398
    }
1399
 
1400
  template<typename _Key, typename _Val, typename _KeyOfValue,
1401
           typename _Compare, typename _Alloc>
1402
    pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
1403
                           _Compare, _Alloc>::_Base_ptr,
1404
         typename _Rb_tree<_Key, _Val, _KeyOfValue,
1405
                           _Compare, _Alloc>::_Base_ptr>
1406
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1407
    _M_get_insert_hint_unique_pos(const_iterator __position,
1408
                                  const key_type& __k)
1409
    {
1410
      iterator __pos = __position._M_const_cast();
1411
      typedef pair<_Base_ptr, _Base_ptr> _Res;
1412
 
1413
      // end()
1414
      if (__pos._M_node == _M_end())
1415
        {
1416
          if (size() > 0
1417
              && _M_impl._M_key_compare(_S_key(_M_rightmost()), __k))
1418
            return _Res(0, _M_rightmost());
1419
          else
1420
            return _M_get_insert_unique_pos(__k);
1421
        }
1422
      else if (_M_impl._M_key_compare(__k, _S_key(__pos._M_node)))
1423
        {
1424
          // First, try before...
1425
          iterator __before = __pos;
1426
          if (__pos._M_node == _M_leftmost()) // begin()
1427
            return _Res(_M_leftmost(), _M_leftmost());
1428
          else if (_M_impl._M_key_compare(_S_key((--__before)._M_node), __k))
1429
            {
1430
              if (_S_right(__before._M_node) == 0)
1431
                return _Res(0, __before._M_node);
1432
              else
1433
                return _Res(__pos._M_node, __pos._M_node);
1434
            }
1435
          else
1436
            return _M_get_insert_unique_pos(__k);
1437
        }
1438
      else if (_M_impl._M_key_compare(_S_key(__pos._M_node), __k))
1439
        {
1440
          // ... then try after.
1441
          iterator __after = __pos;
1442
          if (__pos._M_node == _M_rightmost())
1443
            return _Res(0, _M_rightmost());
1444
          else if (_M_impl._M_key_compare(__k, _S_key((++__after)._M_node)))
1445
            {
1446
              if (_S_right(__pos._M_node) == 0)
1447
                return _Res(0, __pos._M_node);
1448
              else
1449
                return _Res(__after._M_node, __after._M_node);
1450
            }
1451
          else
1452
            return _M_get_insert_unique_pos(__k);
1453
        }
1454
      else
1455
        // Equivalent keys.
1456
        return _Res(__pos._M_node, 0);
1457
    }
1458
 
1459
  template<typename _Key, typename _Val, typename _KeyOfValue,
1460
           typename _Compare, typename _Alloc>
1461
#if __cplusplus >= 201103L
1462
    template<typename _Arg>
1463
#endif
1464
    typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1465
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1466
#if __cplusplus >= 201103L
1467
    _M_insert_unique_(const_iterator __position, _Arg&& __v)
1468
#else
1469
    _M_insert_unique_(const_iterator __position, const _Val& __v)
1470
#endif
1471
    {
1472
      pair<_Base_ptr, _Base_ptr> __res
1473
        = _M_get_insert_hint_unique_pos(__position, _KeyOfValue()(__v));
1474
 
1475
      if (__res.second)
1476
        return _M_insert_(__res.first, __res.second,
1477
                          _GLIBCXX_FORWARD(_Arg, __v));
1478
      return iterator(static_cast<_Link_type>(__res.first));
1479
    }
1480
 
1481
  template<typename _Key, typename _Val, typename _KeyOfValue,
1482
           typename _Compare, typename _Alloc>
1483
    pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
1484
                           _Compare, _Alloc>::_Base_ptr,
1485
         typename _Rb_tree<_Key, _Val, _KeyOfValue,
1486
                           _Compare, _Alloc>::_Base_ptr>
1487
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1488
    _M_get_insert_hint_equal_pos(const_iterator __position, const key_type& __k)
1489
    {
1490
      iterator __pos = __position._M_const_cast();
1491
      typedef pair<_Base_ptr, _Base_ptr> _Res;
1492
 
1493
      // end()
1494
      if (__pos._M_node == _M_end())
1495
        {
1496
          if (size() > 0
1497
              && !_M_impl._M_key_compare(__k, _S_key(_M_rightmost())))
1498
            return _Res(0, _M_rightmost());
1499
          else
1500
            return _M_get_insert_equal_pos(__k);
1501
        }
1502
      else if (!_M_impl._M_key_compare(_S_key(__pos._M_node), __k))
1503
        {
1504
          // First, try before...
1505
          iterator __before = __pos;
1506
          if (__pos._M_node == _M_leftmost()) // begin()
1507
            return _Res(_M_leftmost(), _M_leftmost());
1508
          else if (!_M_impl._M_key_compare(__k, _S_key((--__before)._M_node)))
1509
            {
1510
              if (_S_right(__before._M_node) == 0)
1511
                return _Res(0, __before._M_node);
1512
              else
1513
                return _Res(__pos._M_node, __pos._M_node);
1514
            }
1515
          else
1516
            return _M_get_insert_equal_pos(__k);
1517
        }
1518
      else
1519
        {
1520
          // ... then try after.  
1521
          iterator __after = __pos;
1522
          if (__pos._M_node == _M_rightmost())
1523
            return _Res(0, _M_rightmost());
1524
          else if (!_M_impl._M_key_compare(_S_key((++__after)._M_node), __k))
1525
            {
1526
              if (_S_right(__pos._M_node) == 0)
1527
                return _Res(0, __pos._M_node);
1528
              else
1529
                return _Res(__after._M_node, __after._M_node);
1530
            }
1531
          else
1532
            return _Res(0, 0);
1533
        }
1534
    }
1535
 
1536
  template<typename _Key, typename _Val, typename _KeyOfValue,
1537
           typename _Compare, typename _Alloc>
1538
#if __cplusplus >= 201103L
1539
    template<typename _Arg>
1540
#endif
1541
    typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1542
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1543
#if __cplusplus >= 201103L
1544
    _M_insert_equal_(const_iterator __position, _Arg&& __v)
1545
#else
1546
    _M_insert_equal_(const_iterator __position, const _Val& __v)
1547
#endif
1548
    {
1549
      pair<_Base_ptr, _Base_ptr> __res
1550
        = _M_get_insert_hint_equal_pos(__position, _KeyOfValue()(__v));
1551
 
1552
      if (__res.second)
1553
        return _M_insert_(__res.first, __res.second,
1554
                          _GLIBCXX_FORWARD(_Arg, __v));
1555
 
1556
      return _M_insert_equal_lower(_GLIBCXX_FORWARD(_Arg, __v));
1557
    }
1558
 
1559
#if __cplusplus >= 201103L
1560
  template<typename _Key, typename _Val, typename _KeyOfValue,
1561
           typename _Compare, typename _Alloc>
1562
    typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1563
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1564
    _M_insert_node(_Base_ptr __x, _Base_ptr __p, _Link_type __z)
1565
    {
1566
      bool __insert_left = (__x != 0 || __p == _M_end()
1567
                            || _M_impl._M_key_compare(_S_key(__z),
1568
                                                      _S_key(__p)));
1569
 
1570
      _Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
1571
                                    this->_M_impl._M_header);
1572
      ++_M_impl._M_node_count;
1573
      return iterator(__z);
1574
    }
1575
 
1576
  template<typename _Key, typename _Val, typename _KeyOfValue,
1577
           typename _Compare, typename _Alloc>
1578
    typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1579
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1580
    _M_insert_lower_node(_Base_ptr __p, _Link_type __z)
1581
    {
1582
      bool __insert_left = (__p == _M_end()
1583
                            || !_M_impl._M_key_compare(_S_key(__p),
1584
                                                       _S_key(__z)));
1585
 
1586
      _Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
1587
                                    this->_M_impl._M_header);
1588
      ++_M_impl._M_node_count;
1589
      return iterator(__z);
1590
    }
1591
 
1592
  template<typename _Key, typename _Val, typename _KeyOfValue,
1593
           typename _Compare, typename _Alloc>
1594
    typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1595
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1596
    _M_insert_equal_lower_node(_Link_type __z)
1597
    {
1598
      _Link_type __x = _M_begin();
1599
      _Link_type __y = _M_end();
1600
      while (__x != 0)
1601
        {
1602
          __y = __x;
1603
          __x = !_M_impl._M_key_compare(_S_key(__x), _S_key(__z)) ?
1604
                _S_left(__x) : _S_right(__x);
1605
        }
1606
      return _M_insert_lower_node(__y, __z);
1607
    }
1608
 
1609
  template<typename _Key, typename _Val, typename _KeyOfValue,
1610
           typename _Compare, typename _Alloc>
1611
    template<typename... _Args>
1612
      pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
1613
                             _Compare, _Alloc>::iterator, bool>
1614
      _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1615
      _M_emplace_unique(_Args&&... __args)
1616
      {
1617
        _Link_type __z = _M_create_node(std::forward<_Args>(__args)...);
1618
 
1619
        __try
1620
          {
1621
            typedef pair<iterator, bool> _Res;
1622
            auto __res = _M_get_insert_unique_pos(_S_key(__z));
1623
            if (__res.second)
1624
              return _Res(_M_insert_node(__res.first, __res.second, __z), true);
1625
 
1626
            _M_destroy_node(__z);
1627
            return _Res(iterator(static_cast<_Link_type>(__res.first)), false);
1628
          }
1629
        __catch(...)
1630
          {
1631
            _M_destroy_node(__z);
1632
            __throw_exception_again;
1633
          }
1634
      }
1635
 
1636
  template<typename _Key, typename _Val, typename _KeyOfValue,
1637
           typename _Compare, typename _Alloc>
1638
    template<typename... _Args>
1639
      typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1640
      _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1641
      _M_emplace_equal(_Args&&... __args)
1642
      {
1643
        _Link_type __z = _M_create_node(std::forward<_Args>(__args)...);
1644
 
1645
        __try
1646
          {
1647
            auto __res = _M_get_insert_equal_pos(_S_key(__z));
1648
            return _M_insert_node(__res.first, __res.second, __z);
1649
          }
1650
        __catch(...)
1651
          {
1652
            _M_destroy_node(__z);
1653
            __throw_exception_again;
1654
          }
1655
      }
1656
 
1657
  template<typename _Key, typename _Val, typename _KeyOfValue,
1658
           typename _Compare, typename _Alloc>
1659
    template<typename... _Args>
1660
      typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1661
      _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1662
      _M_emplace_hint_unique(const_iterator __pos, _Args&&... __args)
1663
      {
1664
        _Link_type __z = _M_create_node(std::forward<_Args>(__args)...);
1665
 
1666
        __try
1667
          {
1668
            auto __res = _M_get_insert_hint_unique_pos(__pos, _S_key(__z));
1669
 
1670
            if (__res.second)
1671
              return _M_insert_node(__res.first, __res.second, __z);
1672
 
1673
            _M_destroy_node(__z);
1674
            return iterator(static_cast<_Link_type>(__res.first));
1675
          }
1676
        __catch(...)
1677
          {
1678
            _M_destroy_node(__z);
1679
            __throw_exception_again;
1680
          }
1681
      }
1682
 
1683
  template<typename _Key, typename _Val, typename _KeyOfValue,
1684
           typename _Compare, typename _Alloc>
1685
    template<typename... _Args>
1686
      typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1687
      _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1688
      _M_emplace_hint_equal(const_iterator __pos, _Args&&... __args)
1689
      {
1690
        _Link_type __z = _M_create_node(std::forward<_Args>(__args)...);
1691
 
1692
        __try
1693
          {
1694
            auto __res = _M_get_insert_hint_equal_pos(__pos, _S_key(__z));
1695
 
1696
            if (__res.second)
1697
              return _M_insert_node(__res.first, __res.second, __z);
1698
 
1699
            return _M_insert_equal_lower_node(__z);
1700
          }
1701
        __catch(...)
1702
          {
1703
            _M_destroy_node(__z);
1704
            __throw_exception_again;
1705
          }
1706
      }
1707
#endif
1708
 
1709
  template<typename _Key, typename _Val, typename _KoV,
1710
           typename _Cmp, typename _Alloc>
1711
    template<class _II>
1712
      void
1713
      _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>::
1714
      _M_insert_unique(_II __first, _II __last)
1715
      {
1716
        for (; __first != __last; ++__first)
1717
          _M_insert_unique_(end(), *__first);
1718
      }
1719
 
1720
  template<typename _Key, typename _Val, typename _KoV,
1721
           typename _Cmp, typename _Alloc>
1722
    template<class _II>
1723
      void
1724
      _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>::
1725
      _M_insert_equal(_II __first, _II __last)
1726
      {
1727
        for (; __first != __last; ++__first)
1728
          _M_insert_equal_(end(), *__first);
1729
      }
1730
 
1731
  template<typename _Key, typename _Val, typename _KeyOfValue,
1732
           typename _Compare, typename _Alloc>
1733
    void
1734
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1735
    _M_erase_aux(const_iterator __position)
1736
    {
1737
      _Link_type __y =
1738
        static_cast<_Link_type>(_Rb_tree_rebalance_for_erase
1739
                                (const_cast<_Base_ptr>(__position._M_node),
1740
                                 this->_M_impl._M_header));
1741
      _M_destroy_node(__y);
1742
      --_M_impl._M_node_count;
1743
    }
1744
 
1745
  template<typename _Key, typename _Val, typename _KeyOfValue,
1746
           typename _Compare, typename _Alloc>
1747
    void
1748
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1749
    _M_erase_aux(const_iterator __first, const_iterator __last)
1750
    {
1751
      if (__first == begin() && __last == end())
1752
        clear();
1753
      else
1754
        while (__first != __last)
1755
          erase(__first++);
1756
    }
1757
 
1758
  template<typename _Key, typename _Val, typename _KeyOfValue,
1759
           typename _Compare, typename _Alloc>
1760
    typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type
1761
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1762
    erase(const _Key& __x)
1763
    {
1764
      pair<iterator, iterator> __p = equal_range(__x);
1765
      const size_type __old_size = size();
1766
      erase(__p.first, __p.second);
1767
      return __old_size - size();
1768
    }
1769
 
1770
  template<typename _Key, typename _Val, typename _KeyOfValue,
1771
           typename _Compare, typename _Alloc>
1772
    void
1773
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1774
    erase(const _Key* __first, const _Key* __last)
1775
    {
1776
      while (__first != __last)
1777
        erase(*__first++);
1778
    }
1779
 
1780
  template<typename _Key, typename _Val, typename _KeyOfValue,
1781
           typename _Compare, typename _Alloc>
1782
    typename _Rb_tree<_Key, _Val, _KeyOfValue,
1783
                      _Compare, _Alloc>::iterator
1784
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1785
    find(const _Key& __k)
1786
    {
1787
      iterator __j = _M_lower_bound(_M_begin(), _M_end(), __k);
1788
      return (__j == end()
1789
              || _M_impl._M_key_compare(__k,
1790
                                        _S_key(__j._M_node))) ? end() : __j;
1791
    }
1792
 
1793
  template<typename _Key, typename _Val, typename _KeyOfValue,
1794
           typename _Compare, typename _Alloc>
1795
    typename _Rb_tree<_Key, _Val, _KeyOfValue,
1796
                      _Compare, _Alloc>::const_iterator
1797
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1798
    find(const _Key& __k) const
1799
    {
1800
      const_iterator __j = _M_lower_bound(_M_begin(), _M_end(), __k);
1801
      return (__j == end()
1802
              || _M_impl._M_key_compare(__k,
1803
                                        _S_key(__j._M_node))) ? end() : __j;
1804
    }
1805
 
1806
  template<typename _Key, typename _Val, typename _KeyOfValue,
1807
           typename _Compare, typename _Alloc>
1808
    typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type
1809
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1810
    count(const _Key& __k) const
1811
    {
1812
      pair<const_iterator, const_iterator> __p = equal_range(__k);
1813
      const size_type __n = std::distance(__p.first, __p.second);
1814
      return __n;
1815
    }
1816
 
1817
  _GLIBCXX_PURE unsigned int
1818
  _Rb_tree_black_count(const _Rb_tree_node_base* __node,
1819
                       const _Rb_tree_node_base* __root) throw ();
1820
 
1821
  template<typename _Key, typename _Val, typename _KeyOfValue,
1822
           typename _Compare, typename _Alloc>
1823
    bool
1824
    _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::__rb_verify() const
1825
    {
1826
      if (_M_impl._M_node_count == 0 || begin() == end())
1827
        return _M_impl._M_node_count == 0 && begin() == end()
1828
               && this->_M_impl._M_header._M_left == _M_end()
1829
               && this->_M_impl._M_header._M_right == _M_end();
1830
 
1831
      unsigned int __len = _Rb_tree_black_count(_M_leftmost(), _M_root());
1832
      for (const_iterator __it = begin(); __it != end(); ++__it)
1833
        {
1834
          _Const_Link_type __x = static_cast<_Const_Link_type>(__it._M_node);
1835
          _Const_Link_type __L = _S_left(__x);
1836
          _Const_Link_type __R = _S_right(__x);
1837
 
1838
          if (__x->_M_color == _S_red)
1839
            if ((__L && __L->_M_color == _S_red)
1840
                || (__R && __R->_M_color == _S_red))
1841
              return false;
1842
 
1843
          if (__L && _M_impl._M_key_compare(_S_key(__x), _S_key(__L)))
1844
            return false;
1845
          if (__R && _M_impl._M_key_compare(_S_key(__R), _S_key(__x)))
1846
            return false;
1847
 
1848
          if (!__L && !__R && _Rb_tree_black_count(__x, _M_root()) != __len)
1849
            return false;
1850
        }
1851
 
1852
      if (_M_leftmost() != _Rb_tree_node_base::_S_minimum(_M_root()))
1853
        return false;
1854
      if (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root()))
1855
        return false;
1856
      return true;
1857
    }
1858
 
1859
_GLIBCXX_END_NAMESPACE_VERSION
1860
} // namespace
1861
 
1862
#endif

powered by: WebSVN 2.1.0

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