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/] [ext/] [pb_ds/] [detail/] [pat_trie_/] [pat_trie_base.hpp] - Blame information for rev 35

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 35 ultra_embe
// -*- C++ -*-
2
 
3
// Copyright (C) 2005, 2006, 2009, 2011, 2012 Free Software Foundation, Inc.
4
//
5
// This file is part of the GNU ISO C++ Library.  This library is free
6
// software; you can redistribute it and/or modify it under the terms
7
// of the GNU General Public License as published by the Free Software
8
// Foundation; either version 3, or (at your option) any later
9
// version.
10
 
11
// This library is distributed in the hope that it will be useful, but
12
// WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
// General Public License for more details.
15
 
16
// Under Section 7 of GPL version 3, you are granted additional
17
// permissions described in the GCC Runtime Library Exception, version
18
// 3.1, as published by the Free Software Foundation.
19
 
20
// You should have received a copy of the GNU General Public License and
21
// a copy of the GCC Runtime Library Exception along with this program;
22
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23
// <http://www.gnu.org/licenses/>.
24
 
25
// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
26
 
27
// Permission to use, copy, modify, sell, and distribute this software
28
// is hereby granted without fee, provided that the above copyright
29
// notice appears in all copies, and that both that copyright notice
30
// and this permission notice appear in supporting documentation. None
31
// of the above authors, nor IBM Haifa Research Laboratories, make any
32
// representation about the suitability of this software for any
33
// purpose. It is provided "as is" without express or implied
34
// warranty.
35
 
36
/**
37
 * @file pat_trie_/pat_trie_base.hpp
38
 * Contains the base class for a patricia tree.
39
 */
40
 
41
#ifndef PB_DS_PAT_TRIE_BASE
42
#define PB_DS_PAT_TRIE_BASE
43
 
44
#include <debug/debug.h>
45
 
46
namespace __gnu_pbds
47
{
48
  namespace detail
49
  {
50
    /// Base type for PATRICIA trees.
51
    struct pat_trie_base
52
    {
53
      /**
54
       *  @brief  Three types of nodes.
55
       *
56
       *  i_node is used by _Inode, leaf_node by _Leaf, and head_node by _Head.
57
       */
58
      enum node_type
59
        {
60
          i_node,
61
          leaf_node,
62
          head_node
63
        };
64
 
65
      /// Metadata base primary template.
66
      template<typename Metadata, typename _Alloc>
67
        struct _Metadata
68
        {
69
          typedef Metadata                                      metadata_type;
70
          typedef _Alloc                                        allocator_type;
71
          typedef typename _Alloc::template rebind<Metadata>    __rebind_m;
72
          typedef typename __rebind_m::other::const_reference  const_reference;
73
 
74
          const_reference
75
          get_metadata() const
76
          { return m_metadata; }
77
 
78
          metadata_type                                         m_metadata;
79
        };
80
 
81
      /// Specialization for null metadata.
82
      template<typename _Alloc>
83
        struct _Metadata<null_type, _Alloc>
84
        {
85
          typedef null_type                                     metadata_type;
86
          typedef _Alloc                                        allocator_type;
87
        };
88
 
89
 
90
      /// Node base.
91
      template<typename _ATraits, typename Metadata>
92
      struct _Node_base
93
      : public Metadata
94
      {
95
      private:
96
        typedef typename Metadata::allocator_type               _Alloc;
97
 
98
      public:
99
        typedef _Alloc                                          allocator_type;
100
        typedef _ATraits                                        access_traits;
101
        typedef typename _ATraits::type_traits                  type_traits;
102
        typedef typename _Alloc::template rebind<_Node_base>    __rebind_n;
103
        typedef typename __rebind_n::other::pointer             node_pointer;
104
 
105
        node_pointer                                            m_p_parent;
106
        const node_type                                         m_type;
107
 
108
        _Node_base(node_type type) : m_type(type)
109
        { }
110
 
111
        typedef typename _Alloc::template rebind<_ATraits>    __rebind_at;
112
        typedef typename __rebind_at::other::const_pointer    a_const_pointer;
113
        typedef typename _ATraits::const_iterator             a_const_iterator;
114
 
115
#ifdef _GLIBCXX_DEBUG
116
        typedef std::pair<a_const_iterator, a_const_iterator> node_debug_info;
117
 
118
        void
119
        assert_valid(a_const_pointer p_traits,
120
                     const char* __file, int __line) const
121
        { assert_valid_imp(p_traits, __file, __line); }
122
 
123
        virtual node_debug_info
124
        assert_valid_imp(a_const_pointer, const char*, int) const = 0;
125
#endif
126
      };
127
 
128
 
129
    /// Head node for PATRICIA tree.
130
    template<typename _ATraits, typename Metadata>
131
    struct _Head
132
    : public _Node_base<_ATraits, Metadata>
133
    {
134
      typedef _Node_base<_ATraits, Metadata>                    base_type;
135
      typedef typename base_type::type_traits                   type_traits;
136
      typedef typename base_type::node_pointer                  node_pointer;
137
 
138
      node_pointer                                              m_p_min;
139
      node_pointer                                              m_p_max;
140
 
141
      _Head() : base_type(head_node) { }
142
 
143
#ifdef _GLIBCXX_DEBUG
144
      typedef typename base_type::node_debug_info              node_debug_info;
145
      typedef typename base_type::a_const_pointer              a_const_pointer;
146
 
147
      virtual node_debug_info
148
      assert_valid_imp(a_const_pointer, const char* __file, int __line) const
149
      {
150
        _GLIBCXX_DEBUG_VERIFY_AT(false,
151
                                 _M_message("Assertion from %1;:%2;")
152
                                 ._M_string(__FILE__)._M_integer(__LINE__),
153
                                 __file, __line);
154
        return node_debug_info();
155
      }
156
#endif
157
    };
158
 
159
 
160
    /// Leaf node for PATRICIA tree.
161
    template<typename _ATraits, typename Metadata>
162
    struct _Leaf
163
    : public _Node_base<_ATraits, Metadata>
164
    {
165
      typedef _Node_base<_ATraits, Metadata>                    base_type;
166
      typedef typename base_type::type_traits                   type_traits;
167
      typedef typename type_traits::value_type                  value_type;
168
      typedef typename type_traits::reference                   reference;
169
      typedef typename type_traits::const_reference             const_reference;
170
 
171
    private:
172
      value_type                                                m_value;
173
 
174
      _Leaf(const _Leaf&);
175
 
176
    public:
177
      _Leaf(const_reference other)
178
      : base_type(leaf_node), m_value(other) { }
179
 
180
      reference
181
      value()
182
      { return m_value; }
183
 
184
      const_reference
185
      value() const
186
      { return m_value; }
187
 
188
#ifdef _GLIBCXX_DEBUG
189
      typedef typename base_type::node_debug_info               node_debug_info;
190
      typedef typename base_type::a_const_pointer               a_const_pointer;
191
 
192
      virtual node_debug_info
193
      assert_valid_imp(a_const_pointer p_traits,
194
                       const char* __file, int __line) const
195
      {
196
        PB_DS_DEBUG_VERIFY(base_type::m_type == leaf_node);
197
        node_debug_info ret;
198
        const_reference r_val = value();
199
        return std::make_pair(p_traits->begin(p_traits->extract_key(r_val)),
200
                              p_traits->end(p_traits->extract_key(r_val)));
201
      }
202
 
203
      virtual
204
      ~_Leaf() { }
205
#endif
206
    };
207
 
208
 
209
    /// Internal node type, PATRICIA tree.
210
    template<typename _ATraits, typename Metadata>
211
    struct _Inode
212
    : public _Node_base<_ATraits, Metadata>
213
    {
214
      typedef _Node_base<_ATraits, Metadata>                    base_type;
215
      typedef typename base_type::type_traits                   type_traits;
216
      typedef typename base_type::access_traits                 access_traits;
217
      typedef typename type_traits::value_type                  value_type;
218
      typedef typename base_type::allocator_type                _Alloc;
219
      typedef _Alloc                                            allocator_type;
220
      typedef typename _Alloc::size_type                        size_type;
221
 
222
    private:
223
      typedef typename base_type::a_const_pointer              a_const_pointer;
224
      typedef typename base_type::a_const_iterator            a_const_iterator;
225
 
226
      typedef typename base_type::node_pointer                  node_pointer;
227
      typedef typename _Alloc::template rebind<base_type>       __rebind_n;
228
      typedef typename __rebind_n::other::const_pointer      node_const_pointer;
229
 
230
      typedef _Leaf<_ATraits, Metadata>                         leaf;
231
      typedef typename _Alloc::template rebind<leaf>::other     __rebind_l;
232
      typedef typename __rebind_l::pointer                      leaf_pointer;
233
      typedef typename __rebind_l::const_pointer            leaf_const_pointer;
234
 
235
      typedef typename _Alloc::template rebind<_Inode>::other   __rebind_in;
236
      typedef typename __rebind_in::pointer                     inode_pointer;
237
      typedef typename __rebind_in::const_pointer           inode_const_pointer;
238
 
239
      inline size_type
240
      get_pref_pos(a_const_iterator, a_const_iterator, a_const_pointer) const;
241
 
242
    public:
243
      typedef typename _Alloc::template rebind<node_pointer>::other __rebind_np;
244
      typedef typename __rebind_np::pointer             node_pointer_pointer;
245
      typedef typename __rebind_np::reference           node_pointer_reference;
246
 
247
      enum
248
        {
249
          arr_size = _ATraits::max_size + 1
250
        };
251
      PB_DS_STATIC_ASSERT(min_arr_size, arr_size >= 2);
252
 
253
 
254
      /// Constant child iterator.
255
      struct const_iterator
256
      {
257
        node_pointer_pointer                            m_p_p_cur;
258
        node_pointer_pointer                            m_p_p_end;
259
 
260
        typedef std::forward_iterator_tag               iterator_category;
261
        typedef typename _Alloc::difference_type        difference_type;
262
        typedef node_pointer                            value_type;
263
        typedef node_pointer_pointer                    pointer;
264
        typedef node_pointer_reference                  reference;
265
 
266
        const_iterator(node_pointer_pointer p_p_cur = 0,
267
                       node_pointer_pointer p_p_end = 0)
268
        : m_p_p_cur(p_p_cur), m_p_p_end(p_p_end)
269
        { }
270
 
271
        bool
272
        operator==(const const_iterator& other) const
273
        { return m_p_p_cur == other.m_p_p_cur; }
274
 
275
        bool
276
        operator!=(const const_iterator& other) const
277
        { return m_p_p_cur != other.m_p_p_cur; }
278
 
279
        const_iterator&
280
        operator++()
281
        {
282
          do
283
            ++m_p_p_cur;
284
          while (m_p_p_cur != m_p_p_end && *m_p_p_cur == 0);
285
          return *this;
286
        }
287
 
288
        const_iterator
289
        operator++(int)
290
        {
291
          const_iterator ret_it(*this);
292
          operator++();
293
          return ret_it;
294
        }
295
 
296
        const node_pointer_pointer
297
        operator->() const
298
        {
299
          _GLIBCXX_DEBUG_ONLY(assert_referencible();)
300
          return m_p_p_cur;
301
        }
302
 
303
        node_const_pointer
304
        operator*() const
305
        {
306
          _GLIBCXX_DEBUG_ONLY(assert_referencible();)
307
          return *m_p_p_cur;
308
        }
309
 
310
      protected:
311
#ifdef _GLIBCXX_DEBUG
312
        void
313
        assert_referencible() const
314
        { _GLIBCXX_DEBUG_ASSERT(m_p_p_cur != m_p_p_end && *m_p_p_cur != 0); }
315
#endif
316
      };
317
 
318
 
319
      /// Child iterator.
320
      struct iterator : public const_iterator
321
      {
322
      public:
323
        typedef std::forward_iterator_tag               iterator_category;
324
        typedef typename _Alloc::difference_type        difference_type;
325
        typedef node_pointer                            value_type;
326
        typedef node_pointer_pointer                    pointer;
327
        typedef node_pointer_reference                  reference;
328
 
329
        inline
330
        iterator(node_pointer_pointer p_p_cur = 0,
331
                 node_pointer_pointer p_p_end = 0)
332
        : const_iterator(p_p_cur, p_p_end) { }
333
 
334
        bool
335
        operator==(const iterator& other) const
336
        { return const_iterator::m_p_p_cur == other.m_p_p_cur; }
337
 
338
        bool
339
        operator!=(const iterator& other) const
340
        { return const_iterator::m_p_p_cur != other.m_p_p_cur; }
341
 
342
        iterator&
343
        operator++()
344
        {
345
          const_iterator::operator++();
346
          return *this;
347
        }
348
 
349
        iterator
350
        operator++(int)
351
        {
352
          iterator ret_it(*this);
353
          operator++();
354
          return ret_it;
355
        }
356
 
357
        node_pointer_pointer
358
        operator->()
359
        {
360
          _GLIBCXX_DEBUG_ONLY(const_iterator::assert_referencible();)
361
          return const_iterator::m_p_p_cur;
362
        }
363
 
364
        node_pointer
365
        operator*()
366
        {
367
          _GLIBCXX_DEBUG_ONLY(const_iterator::assert_referencible();)
368
          return *const_iterator::m_p_p_cur;
369
        }
370
      };
371
 
372
 
373
      _Inode(size_type, const a_const_iterator);
374
 
375
      void
376
      update_prefixes(a_const_pointer);
377
 
378
      const_iterator
379
      begin() const;
380
 
381
      iterator
382
      begin();
383
 
384
      const_iterator
385
      end() const;
386
 
387
      iterator
388
      end();
389
 
390
      inline node_pointer
391
      get_child_node(a_const_iterator, a_const_iterator, a_const_pointer);
392
 
393
      inline node_const_pointer
394
      get_child_node(a_const_iterator, a_const_iterator, a_const_pointer) const;
395
 
396
      inline iterator
397
      get_child_it(a_const_iterator, a_const_iterator, a_const_pointer);
398
 
399
      inline node_pointer
400
      get_lower_bound_child_node(a_const_iterator, a_const_iterator,
401
                                 size_type, a_const_pointer);
402
 
403
      inline node_pointer
404
      add_child(node_pointer, a_const_iterator, a_const_iterator,
405
                a_const_pointer);
406
 
407
      inline node_const_pointer
408
      get_join_child(node_const_pointer, a_const_pointer) const;
409
 
410
      inline node_pointer
411
      get_join_child(node_pointer, a_const_pointer);
412
 
413
      void
414
      remove_child(node_pointer);
415
 
416
      void
417
      remove_child(iterator);
418
 
419
      void
420
      replace_child(node_pointer, a_const_iterator, a_const_iterator,
421
                    a_const_pointer);
422
 
423
      inline a_const_iterator
424
      pref_b_it() const;
425
 
426
      inline a_const_iterator
427
      pref_e_it() const;
428
 
429
      bool
430
      should_be_mine(a_const_iterator, a_const_iterator, size_type,
431
                     a_const_pointer) const;
432
 
433
      leaf_pointer
434
      leftmost_descendant();
435
 
436
      leaf_const_pointer
437
      leftmost_descendant() const;
438
 
439
      leaf_pointer
440
      rightmost_descendant();
441
 
442
      leaf_const_pointer
443
      rightmost_descendant() const;
444
 
445
#ifdef _GLIBCXX_DEBUG
446
      typedef typename base_type::node_debug_info              node_debug_info;
447
 
448
      virtual node_debug_info
449
      assert_valid_imp(a_const_pointer, const char*, int) const;
450
#endif
451
 
452
      size_type
453
      get_e_ind() const
454
      { return m_e_ind; }
455
 
456
    private:
457
      _Inode(const _Inode&);
458
 
459
      size_type
460
      get_begin_pos() const;
461
 
462
      static __rebind_l                 s_leaf_alloc;
463
      static __rebind_in                s_inode_alloc;
464
 
465
      const size_type                   m_e_ind;
466
      a_const_iterator                  m_pref_b_it;
467
      a_const_iterator                  m_pref_e_it;
468
      node_pointer                      m_a_p_children[arr_size];
469
    };
470
 
471
#define PB_DS_CONST_IT_C_DEC \
472
    _CIter<Node, Leaf, Head, Inode, Is_Forward_Iterator>
473
 
474
#define PB_DS_CONST_ODIR_IT_C_DEC \
475
    _CIter<Node, Leaf, Head, Inode, !Is_Forward_Iterator>
476
 
477
#define PB_DS_IT_C_DEC \
478
    _Iter<Node, Leaf, Head, Inode, Is_Forward_Iterator>
479
 
480
#define PB_DS_ODIR_IT_C_DEC \
481
    _Iter<Node, Leaf, Head, Inode, !Is_Forward_Iterator>
482
 
483
 
484
    /// Const iterator.
485
    template<typename Node, typename Leaf, typename Head, typename Inode,
486
             bool Is_Forward_Iterator>
487
    class _CIter
488
    {
489
    public:
490
      // These types are all the same for the first four template arguments.
491
      typedef typename Node::allocator_type             allocator_type;
492
      typedef typename Node::type_traits                type_traits;
493
 
494
      typedef std::bidirectional_iterator_tag           iterator_category;
495
      typedef typename allocator_type::difference_type  difference_type;
496
      typedef typename type_traits::value_type          value_type;
497
      typedef typename type_traits::pointer             pointer;
498
      typedef typename type_traits::reference           reference;
499
      typedef typename type_traits::const_pointer       const_pointer;
500
      typedef typename type_traits::const_reference     const_reference;
501
 
502
      typedef allocator_type                            _Alloc;
503
      typedef typename _Alloc::template rebind<Node>    __rebind_n;
504
      typedef typename __rebind_n::other::pointer       node_pointer;
505
      typedef typename _Alloc::template rebind<Leaf>    __rebind_l;
506
      typedef typename __rebind_l::other::pointer       leaf_pointer;
507
      typedef typename __rebind_l::other::const_pointer leaf_const_pointer;
508
      typedef typename _Alloc::template rebind<Head>    __rebind_h;
509
      typedef typename __rebind_h::other::pointer       head_pointer;
510
 
511
      typedef typename _Alloc::template rebind<Inode> __rebind_in;
512
      typedef typename __rebind_in::other::pointer      inode_pointer;
513
      typedef typename Inode::iterator                  inode_iterator;
514
 
515
      node_pointer                                      m_p_nd;
516
 
517
      _CIter(node_pointer p_nd = 0) : m_p_nd(p_nd)
518
      { }
519
 
520
      _CIter(const PB_DS_CONST_ODIR_IT_C_DEC& other)
521
      : m_p_nd(other.m_p_nd)
522
      { }
523
 
524
      _CIter&
525
      operator=(const _CIter& other)
526
      {
527
        m_p_nd = other.m_p_nd;
528
        return *this;
529
      }
530
 
531
      _CIter&
532
      operator=(const PB_DS_CONST_ODIR_IT_C_DEC& other)
533
      {
534
        m_p_nd = other.m_p_nd;
535
        return *this;
536
      }
537
 
538
      const_pointer
539
      operator->() const
540
      {
541
        _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == leaf_node);
542
        return &static_cast<leaf_pointer>(m_p_nd)->value();
543
      }
544
 
545
      const_reference
546
      operator*() const
547
      {
548
        _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == leaf_node);
549
        return static_cast<leaf_pointer>(m_p_nd)->value();
550
      }
551
 
552
      bool
553
      operator==(const _CIter& other) const
554
      { return m_p_nd == other.m_p_nd; }
555
 
556
      bool
557
      operator==(const PB_DS_CONST_ODIR_IT_C_DEC& other) const
558
      { return m_p_nd == other.m_p_nd; }
559
 
560
      bool
561
      operator!=(const _CIter& other) const
562
      { return m_p_nd != other.m_p_nd; }
563
 
564
      bool
565
      operator!=(const PB_DS_CONST_ODIR_IT_C_DEC& other) const
566
      { return m_p_nd != other.m_p_nd; }
567
 
568
      _CIter&
569
      operator++()
570
      {
571
        inc(integral_constant<int, Is_Forward_Iterator>());
572
        return *this;
573
      }
574
 
575
      _CIter
576
      operator++(int)
577
      {
578
        _CIter ret_it(m_p_nd);
579
        operator++();
580
        return ret_it;
581
      }
582
 
583
      _CIter&
584
      operator--()
585
      {
586
        dec(integral_constant<int, Is_Forward_Iterator>());
587
        return *this;
588
      }
589
 
590
      _CIter
591
      operator--(int)
592
      {
593
        _CIter ret_it(m_p_nd);
594
        operator--();
595
        return ret_it;
596
      }
597
 
598
    protected:
599
      void
600
      inc(false_type)
601
      { dec(true_type()); }
602
 
603
      void
604
      inc(true_type)
605
      {
606
        if (m_p_nd->m_type == head_node)
607
          {
608
            m_p_nd = static_cast<head_pointer>(m_p_nd)->m_p_min;
609
            return;
610
          }
611
 
612
        node_pointer p_y = m_p_nd->m_p_parent;
613
        while (p_y->m_type != head_node && get_larger_sibling(m_p_nd) == 0)
614
          {
615
            m_p_nd = p_y;
616
            p_y = p_y->m_p_parent;
617
          }
618
 
619
        if (p_y->m_type == head_node)
620
          {
621
            m_p_nd = p_y;
622
            return;
623
          }
624
        m_p_nd = leftmost_descendant(get_larger_sibling(m_p_nd));
625
      }
626
 
627
      void
628
      dec(false_type)
629
      { inc(true_type()); }
630
 
631
      void
632
      dec(true_type)
633
      {
634
        if (m_p_nd->m_type == head_node)
635
          {
636
            m_p_nd = static_cast<head_pointer>(m_p_nd)->m_p_max;
637
            return;
638
          }
639
 
640
        node_pointer p_y = m_p_nd->m_p_parent;
641
        while (p_y->m_type != head_node && get_smaller_sibling(m_p_nd) == 0)
642
          {
643
            m_p_nd = p_y;
644
            p_y = p_y->m_p_parent;
645
          }
646
 
647
        if (p_y->m_type == head_node)
648
          {
649
            m_p_nd = p_y;
650
            return;
651
          }
652
        m_p_nd = rightmost_descendant(get_smaller_sibling(m_p_nd));
653
      }
654
 
655
      static node_pointer
656
      get_larger_sibling(node_pointer p_nd)
657
      {
658
        inode_pointer p_parent = static_cast<inode_pointer>(p_nd->m_p_parent);
659
 
660
        inode_iterator it = p_parent->begin();
661
        while (*it != p_nd)
662
          ++it;
663
 
664
        inode_iterator next_it = it;
665
        ++next_it;
666
        return (next_it == p_parent->end())? 0 : *next_it;
667
      }
668
 
669
      static node_pointer
670
      get_smaller_sibling(node_pointer p_nd)
671
      {
672
        inode_pointer p_parent = static_cast<inode_pointer>(p_nd->m_p_parent);
673
 
674
        inode_iterator it = p_parent->begin();
675
        if (*it == p_nd)
676
          return 0;
677
 
678
        inode_iterator prev_it;
679
        do
680
          {
681
            prev_it = it;
682
            ++it;
683
            if (*it == p_nd)
684
              return *prev_it;
685
          }
686
        while (true);
687
 
688
        _GLIBCXX_DEBUG_ASSERT(false);
689
        return 0;
690
      }
691
 
692
      static leaf_pointer
693
      leftmost_descendant(node_pointer p_nd)
694
      {
695
        if (p_nd->m_type == leaf_node)
696
          return static_cast<leaf_pointer>(p_nd);
697
        return static_cast<inode_pointer>(p_nd)->leftmost_descendant();
698
      }
699
 
700
      static leaf_pointer
701
      rightmost_descendant(node_pointer p_nd)
702
      {
703
        if (p_nd->m_type == leaf_node)
704
          return static_cast<leaf_pointer>(p_nd);
705
        return static_cast<inode_pointer>(p_nd)->rightmost_descendant();
706
      }
707
    };
708
 
709
 
710
    /// Iterator.
711
    template<typename Node, typename Leaf, typename Head, typename Inode,
712
             bool Is_Forward_Iterator>
713
    class _Iter
714
    : public _CIter<Node, Leaf, Head, Inode, Is_Forward_Iterator>
715
    {
716
    public:
717
      typedef _CIter<Node, Leaf, Head, Inode, Is_Forward_Iterator>
718
                                                        base_type;
719
      typedef typename base_type::allocator_type        allocator_type;
720
      typedef typename base_type::type_traits           type_traits;
721
      typedef typename type_traits::value_type          value_type;
722
      typedef typename type_traits::pointer             pointer;
723
      typedef typename type_traits::reference           reference;
724
 
725
      typedef typename base_type::node_pointer          node_pointer;
726
      typedef typename base_type::leaf_pointer          leaf_pointer;
727
      typedef typename base_type::leaf_const_pointer    leaf_const_pointer;
728
      typedef typename base_type::head_pointer          head_pointer;
729
      typedef typename base_type::inode_pointer         inode_pointer;
730
 
731
      _Iter(node_pointer p_nd = 0)
732
      : base_type(p_nd) { }
733
 
734
      _Iter(const PB_DS_ODIR_IT_C_DEC& other)
735
      : base_type(other.m_p_nd) { }
736
 
737
      _Iter&
738
      operator=(const _Iter& other)
739
      {
740
        base_type::m_p_nd = other.m_p_nd;
741
        return *this;
742
      }
743
 
744
      _Iter&
745
      operator=(const PB_DS_ODIR_IT_C_DEC& other)
746
      {
747
        base_type::m_p_nd = other.m_p_nd;
748
        return *this;
749
      }
750
 
751
      pointer
752
      operator->() const
753
      {
754
        _GLIBCXX_DEBUG_ASSERT(base_type::m_p_nd->m_type == leaf_node);
755
        return &static_cast<leaf_pointer>(base_type::m_p_nd)->value();
756
      }
757
 
758
      reference
759
      operator*() const
760
      {
761
        _GLIBCXX_DEBUG_ASSERT(base_type::m_p_nd->m_type == leaf_node);
762
        return static_cast<leaf_pointer>(base_type::m_p_nd)->value();
763
      }
764
 
765
      _Iter&
766
      operator++()
767
      {
768
        base_type::operator++();
769
        return *this;
770
      }
771
 
772
      _Iter
773
      operator++(int)
774
      {
775
        _Iter ret(base_type::m_p_nd);
776
        operator++();
777
        return ret;
778
      }
779
 
780
      _Iter&
781
      operator--()
782
      {
783
        base_type::operator--();
784
        return *this;
785
      }
786
 
787
      _Iter
788
      operator--(int)
789
      {
790
        _Iter ret(base_type::m_p_nd);
791
        operator--();
792
        return ret;
793
      }
794
    };
795
 
796
#undef PB_DS_CONST_ODIR_IT_C_DEC
797
#undef PB_DS_ODIR_IT_C_DEC
798
 
799
 
800
#define PB_DS_PAT_TRIE_NODE_CONST_ITERATOR_C_DEC \
801
    _Node_citer<Node, Leaf, Head, Inode, _CIterator, Iterator, _ATraits, _Alloc>
802
 
803
#define PB_DS_PAT_TRIE_NODE_ITERATOR_C_DEC \
804
    _Node_iter<Node, Leaf, Head, Inode, _CIterator, Iterator, _ATraits, _Alloc>
805
 
806
    /// Node const iterator.
807
    template<typename Node,
808
             typename Leaf,
809
             typename Head,
810
             typename Inode,
811
             typename _CIterator,
812
             typename Iterator,
813
             typename _Alloc>
814
    class _Node_citer
815
    {
816
    protected:
817
      typedef typename _Alloc::template rebind<Node>    __rebind_n;
818
      typedef typename __rebind_n::other::pointer       node_pointer;
819
 
820
      typedef typename _Alloc::template rebind<Leaf>    __rebind_l;
821
      typedef typename __rebind_l::other::pointer       leaf_pointer;
822
      typedef typename __rebind_l::other::const_pointer leaf_const_pointer;
823
 
824
      typedef typename _Alloc::template rebind<Inode>   __rebind_in;
825
      typedef typename __rebind_in::other::pointer      inode_pointer;
826
      typedef typename __rebind_in::other::const_pointer inode_const_pointer;
827
 
828
      typedef typename Node::a_const_pointer            a_const_pointer;
829
      typedef typename Node::a_const_iterator           a_const_iterator;
830
 
831
    private:
832
      a_const_iterator
833
      pref_begin() const
834
      {
835
        if (m_p_nd->m_type == leaf_node)
836
          {
837
            leaf_const_pointer lcp = static_cast<leaf_const_pointer>(m_p_nd);
838
            return m_p_traits->begin(m_p_traits->extract_key(lcp->value()));
839
          }
840
        _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == i_node);
841
        return static_cast<inode_const_pointer>(m_p_nd)->pref_b_it();
842
      }
843
 
844
      a_const_iterator
845
      pref_end() const
846
      {
847
        if (m_p_nd->m_type == leaf_node)
848
          {
849
            leaf_const_pointer lcp = static_cast<leaf_const_pointer>(m_p_nd);
850
            return m_p_traits->end(m_p_traits->extract_key(lcp->value()));
851
          }
852
        _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == i_node);
853
        return static_cast<inode_const_pointer>(m_p_nd)->pref_e_it();
854
      }
855
 
856
    public:
857
      typedef trivial_iterator_tag                      iterator_category;
858
      typedef trivial_iterator_difference_type          difference_type;
859
      typedef typename _Alloc::size_type                size_type;
860
 
861
      typedef _CIterator                                value_type;
862
      typedef value_type                                reference;
863
      typedef value_type                                const_reference;
864
 
865
      /// Metadata type.
866
      typedef typename Node::metadata_type              metadata_type;
867
 
868
      /// Const metadata reference type.
869
      typedef typename _Alloc::template rebind<metadata_type> __rebind_m;
870
      typedef typename __rebind_m::other                __rebind_ma;
871
      typedef typename __rebind_ma::const_reference    metadata_const_reference;
872
 
873
      inline
874
      _Node_citer(node_pointer p_nd = 0, a_const_pointer p_traits = 0)
875
      : m_p_nd(const_cast<node_pointer>(p_nd)), m_p_traits(p_traits)
876
      { }
877
 
878
      /// Subtree valid prefix.
879
      std::pair<a_const_iterator, a_const_iterator>
880
      valid_prefix() const
881
      { return std::make_pair(pref_begin(), pref_end()); }
882
 
883
      /// Const access; returns the __const iterator* associated with
884
      /// the current leaf.
885
      const_reference
886
      operator*() const
887
      {
888
        _GLIBCXX_DEBUG_ASSERT(num_children() == 0);
889
        return _CIterator(m_p_nd);
890
      }
891
 
892
      /// Metadata access.
893
      metadata_const_reference
894
      get_metadata() const
895
      { return m_p_nd->get_metadata(); }
896
 
897
      /// Returns the number of children in the corresponding node.
898
      size_type
899
      num_children() const
900
      {
901
        if (m_p_nd->m_type == leaf_node)
902
          return 0;
903
        _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == i_node);
904
        inode_pointer inp = static_cast<inode_pointer>(m_p_nd);
905
        return std::distance(inp->begin(), inp->end());
906
      }
907
 
908
      /// Returns a __const node __iterator to the corresponding node's
909
      /// i-th child.
910
      _Node_citer
911
      get_child(size_type i) const
912
      {
913
        _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == i_node);
914
        inode_pointer inp = static_cast<inode_pointer>(m_p_nd);
915
        typename Inode::iterator it = inp->begin();
916
        std::advance(it, i);
917
        return _Node_citer(*it, m_p_traits);
918
      }
919
 
920
      /// Compares content to a different iterator object.
921
      bool
922
      operator==(const _Node_citer& other) const
923
      { return m_p_nd == other.m_p_nd; }
924
 
925
      /// Compares content (negatively) to a different iterator object.
926
      bool
927
      operator!=(const _Node_citer& other) const
928
      { return m_p_nd != other.m_p_nd; }
929
 
930
      node_pointer                      m_p_nd;
931
      a_const_pointer                   m_p_traits;
932
    };
933
 
934
 
935
    /// Node iterator.
936
    template<typename Node,
937
             typename Leaf,
938
             typename Head,
939
             typename Inode,
940
             typename _CIterator,
941
             typename Iterator,
942
             typename _Alloc>
943
    class _Node_iter
944
    : public _Node_citer<Node, Leaf, Head, Inode, _CIterator, Iterator, _Alloc>
945
    {
946
    private:
947
      typedef _Node_citer<Node, Leaf, Head, Inode,
948
                          _CIterator, Iterator, _Alloc> base_type;
949
      typedef typename _Alloc::template rebind<Node>    __rebind_n;
950
      typedef typename __rebind_n::other::pointer       node_pointer;
951
      typedef typename base_type::inode_pointer         inode_pointer;
952
      typedef typename base_type::a_const_pointer       a_const_pointer;
953
      typedef Iterator                                  iterator;
954
 
955
    public:
956
      typedef typename base_type::size_type             size_type;
957
 
958
      typedef Iterator                                  value_type;
959
      typedef value_type                                reference;
960
      typedef value_type                                const_reference;
961
 
962
      _Node_iter(node_pointer p_nd = 0, a_const_pointer p_traits = 0)
963
      : base_type(p_nd, p_traits)
964
      { }
965
 
966
      /// Access; returns the iterator*  associated with the current leaf.
967
      reference
968
      operator*() const
969
      {
970
        _GLIBCXX_DEBUG_ASSERT(base_type::num_children() == 0);
971
        return iterator(base_type::m_p_nd);
972
      }
973
 
974
      /// Returns a node __iterator to the corresponding node's i-th child.
975
      _Node_iter
976
      get_child(size_type i) const
977
      {
978
        _GLIBCXX_DEBUG_ASSERT(base_type::m_p_nd->m_type == i_node);
979
 
980
        typename Inode::iterator it =
981
          static_cast<inode_pointer>(base_type::m_p_nd)->begin();
982
 
983
        std::advance(it, i);
984
        return _Node_iter(*it, base_type::m_p_traits);
985
      }
986
    };
987
    };
988
 
989
 
990
#define PB_DS_CLASS_T_DEC \
991
    template<typename _ATraits, typename Metadata>
992
 
993
#define PB_DS_CLASS_C_DEC \
994
    pat_trie_base::_Inode<_ATraits, Metadata>
995
 
996
    PB_DS_CLASS_T_DEC
997
    typename PB_DS_CLASS_C_DEC::__rebind_l
998
    PB_DS_CLASS_C_DEC::s_leaf_alloc;
999
 
1000
    PB_DS_CLASS_T_DEC
1001
    typename PB_DS_CLASS_C_DEC::__rebind_in
1002
    PB_DS_CLASS_C_DEC::s_inode_alloc;
1003
 
1004
    PB_DS_CLASS_T_DEC
1005
    inline typename PB_DS_CLASS_C_DEC::size_type
1006
    PB_DS_CLASS_C_DEC::
1007
    get_pref_pos(a_const_iterator b_it, a_const_iterator e_it,
1008
                 a_const_pointer p_traits) const
1009
    {
1010
      if (static_cast<std::size_t>(std::distance(b_it, e_it)) <= m_e_ind)
1011
        return 0;
1012
      std::advance(b_it, m_e_ind);
1013
      return 1 + p_traits->e_pos(*b_it);
1014
    }
1015
 
1016
    PB_DS_CLASS_T_DEC
1017
    PB_DS_CLASS_C_DEC::
1018
    _Inode(size_type len, const a_const_iterator it)
1019
    : base_type(i_node), m_e_ind(len), m_pref_b_it(it), m_pref_e_it(it)
1020
    {
1021
      std::advance(m_pref_e_it, m_e_ind);
1022
      std::fill(m_a_p_children, m_a_p_children + arr_size,
1023
                static_cast<node_pointer>(0));
1024
    }
1025
 
1026
    PB_DS_CLASS_T_DEC
1027
    void
1028
    PB_DS_CLASS_C_DEC::
1029
    update_prefixes(a_const_pointer p_traits)
1030
    {
1031
      node_pointer p_first = *begin();
1032
      if (p_first->m_type == leaf_node)
1033
        {
1034
          leaf_const_pointer p = static_cast<leaf_const_pointer>(p_first);
1035
          m_pref_b_it = p_traits->begin(access_traits::extract_key(p->value()));
1036
        }
1037
      else
1038
        {
1039
          inode_pointer p = static_cast<inode_pointer>(p_first);
1040
          _GLIBCXX_DEBUG_ASSERT(p_first->m_type == i_node);
1041
          m_pref_b_it = p->pref_b_it();
1042
        }
1043
      m_pref_e_it = m_pref_b_it;
1044
      std::advance(m_pref_e_it, m_e_ind);
1045
    }
1046
 
1047
    PB_DS_CLASS_T_DEC
1048
    typename PB_DS_CLASS_C_DEC::const_iterator
1049
    PB_DS_CLASS_C_DEC::
1050
    begin() const
1051
    {
1052
      typedef node_pointer_pointer pointer_type;
1053
      pointer_type p = const_cast<pointer_type>(m_a_p_children);
1054
      return const_iterator(p + get_begin_pos(), p + arr_size);
1055
    }
1056
 
1057
    PB_DS_CLASS_T_DEC
1058
    typename PB_DS_CLASS_C_DEC::iterator
1059
    PB_DS_CLASS_C_DEC::
1060
    begin()
1061
    {
1062
      return iterator(m_a_p_children + get_begin_pos(),
1063
                      m_a_p_children + arr_size);
1064
    }
1065
 
1066
    PB_DS_CLASS_T_DEC
1067
    typename PB_DS_CLASS_C_DEC::const_iterator
1068
    PB_DS_CLASS_C_DEC::
1069
    end() const
1070
    {
1071
      typedef node_pointer_pointer pointer_type;
1072
      pointer_type p = const_cast<pointer_type>(m_a_p_children) + arr_size;
1073
      return const_iterator(p, p);
1074
    }
1075
 
1076
    PB_DS_CLASS_T_DEC
1077
    typename PB_DS_CLASS_C_DEC::iterator
1078
    PB_DS_CLASS_C_DEC::
1079
    end()
1080
    { return iterator(m_a_p_children + arr_size, m_a_p_children + arr_size); }
1081
 
1082
    PB_DS_CLASS_T_DEC
1083
    inline typename PB_DS_CLASS_C_DEC::node_pointer
1084
    PB_DS_CLASS_C_DEC::
1085
    get_child_node(a_const_iterator b_it, a_const_iterator e_it,
1086
                   a_const_pointer p_traits)
1087
    {
1088
      const size_type i = get_pref_pos(b_it, e_it, p_traits);
1089
      _GLIBCXX_DEBUG_ASSERT(i < arr_size);
1090
      return m_a_p_children[i];
1091
    }
1092
 
1093
    PB_DS_CLASS_T_DEC
1094
    inline typename PB_DS_CLASS_C_DEC::iterator
1095
    PB_DS_CLASS_C_DEC::
1096
    get_child_it(a_const_iterator b_it, a_const_iterator e_it,
1097
                 a_const_pointer p_traits)
1098
    {
1099
      const size_type i = get_pref_pos(b_it, e_it, p_traits);
1100
      _GLIBCXX_DEBUG_ASSERT(i < arr_size);
1101
      _GLIBCXX_DEBUG_ASSERT(m_a_p_children[i] != 0);
1102
      return iterator(m_a_p_children + i, m_a_p_children + i);
1103
    }
1104
 
1105
    PB_DS_CLASS_T_DEC
1106
    inline typename PB_DS_CLASS_C_DEC::node_const_pointer
1107
    PB_DS_CLASS_C_DEC::
1108
    get_child_node(a_const_iterator b_it, a_const_iterator e_it,
1109
                   a_const_pointer p_traits) const
1110
    { return const_cast<node_pointer>(get_child_node(b_it, e_it, p_traits)); }
1111
 
1112
    PB_DS_CLASS_T_DEC
1113
    typename PB_DS_CLASS_C_DEC::node_pointer
1114
    PB_DS_CLASS_C_DEC::
1115
    get_lower_bound_child_node(a_const_iterator b_it, a_const_iterator e_it,
1116
                               size_type checked_ind,
1117
                               a_const_pointer p_traits)
1118
    {
1119
      if (!should_be_mine(b_it, e_it, checked_ind, p_traits))
1120
        {
1121
          if (p_traits->cmp_prefixes(b_it, e_it, m_pref_b_it,
1122
                                     m_pref_e_it, true))
1123
            return leftmost_descendant();
1124
          return rightmost_descendant();
1125
        }
1126
 
1127
      size_type i = get_pref_pos(b_it, e_it, p_traits);
1128
      _GLIBCXX_DEBUG_ASSERT(i < arr_size);
1129
 
1130
      if (m_a_p_children[i] != 0)
1131
        return m_a_p_children[i];
1132
 
1133
      while (++i < arr_size)
1134
        if (m_a_p_children[i] != 0)
1135
          {
1136
            const node_type& __nt = m_a_p_children[i]->m_type;
1137
            node_pointer ret = m_a_p_children[i];
1138
 
1139
            if (__nt == leaf_node)
1140
              return ret;
1141
 
1142
            _GLIBCXX_DEBUG_ASSERT(__nt == i_node);
1143
            inode_pointer inp = static_cast<inode_pointer>(ret);
1144
            return inp->leftmost_descendant();
1145
          }
1146
 
1147
      return rightmost_descendant();
1148
    }
1149
 
1150
    PB_DS_CLASS_T_DEC
1151
    inline typename PB_DS_CLASS_C_DEC::node_pointer
1152
    PB_DS_CLASS_C_DEC::
1153
    add_child(node_pointer p_nd, a_const_iterator b_it, a_const_iterator e_it,
1154
              a_const_pointer p_traits)
1155
    {
1156
      const size_type i = get_pref_pos(b_it, e_it, p_traits);
1157
      _GLIBCXX_DEBUG_ASSERT(i < arr_size);
1158
      if (m_a_p_children[i] == 0)
1159
        {
1160
          m_a_p_children[i] = p_nd;
1161
          p_nd->m_p_parent = this;
1162
          return p_nd;
1163
        }
1164
      return m_a_p_children[i];
1165
    }
1166
 
1167
    PB_DS_CLASS_T_DEC
1168
    typename PB_DS_CLASS_C_DEC::node_const_pointer
1169
    PB_DS_CLASS_C_DEC::
1170
    get_join_child(node_const_pointer p_nd,
1171
                   a_const_pointer p_tr) const
1172
    {
1173
      node_pointer p = const_cast<node_pointer>(p_nd);
1174
      return const_cast<inode_pointer>(this)->get_join_child(p, p_tr);
1175
    }
1176
 
1177
    PB_DS_CLASS_T_DEC
1178
    typename PB_DS_CLASS_C_DEC::node_pointer
1179
    PB_DS_CLASS_C_DEC::
1180
    get_join_child(node_pointer p_nd, a_const_pointer p_traits)
1181
    {
1182
      size_type i;
1183
      a_const_iterator b_it;
1184
      a_const_iterator e_it;
1185
      if (p_nd->m_type == leaf_node)
1186
        {
1187
          leaf_const_pointer p = static_cast<leaf_const_pointer>(p_nd);
1188
 
1189
          typedef typename type_traits::key_const_reference kcr;
1190
          kcr r_key = access_traits::extract_key(p->value());
1191
          b_it = p_traits->begin(r_key);
1192
          e_it = p_traits->end(r_key);
1193
        }
1194
      else
1195
        {
1196
          b_it = static_cast<inode_pointer>(p_nd)->pref_b_it();
1197
          e_it = static_cast<inode_pointer>(p_nd)->pref_e_it();
1198
        }
1199
      i = get_pref_pos(b_it, e_it, p_traits);
1200
      _GLIBCXX_DEBUG_ASSERT(i < arr_size);
1201
      return m_a_p_children[i];
1202
    }
1203
 
1204
    PB_DS_CLASS_T_DEC
1205
    void
1206
    PB_DS_CLASS_C_DEC::
1207
    remove_child(node_pointer p_nd)
1208
    {
1209
      size_type i = 0;
1210
      for (; i < arr_size; ++i)
1211
        if (m_a_p_children[i] == p_nd)
1212
          {
1213
            m_a_p_children[i] = 0;
1214
            return;
1215
          }
1216
      _GLIBCXX_DEBUG_ASSERT(i != arr_size);
1217
    }
1218
 
1219
    PB_DS_CLASS_T_DEC
1220
    void
1221
    PB_DS_CLASS_C_DEC::
1222
    remove_child(iterator it)
1223
    { *it.m_p_p_cur = 0; }
1224
 
1225
    PB_DS_CLASS_T_DEC
1226
    void
1227
    PB_DS_CLASS_C_DEC::
1228
    replace_child(node_pointer p_nd, a_const_iterator b_it,
1229
                  a_const_iterator e_it,
1230
                  a_const_pointer p_traits)
1231
    {
1232
      const size_type i = get_pref_pos(b_it, e_it, p_traits);
1233
      _GLIBCXX_DEBUG_ASSERT(i < arr_size);
1234
      m_a_p_children[i] = p_nd;
1235
      p_nd->m_p_parent = this;
1236
    }
1237
 
1238
    PB_DS_CLASS_T_DEC
1239
    inline typename PB_DS_CLASS_C_DEC::a_const_iterator
1240
    PB_DS_CLASS_C_DEC::
1241
    pref_b_it() const
1242
    { return m_pref_b_it; }
1243
 
1244
    PB_DS_CLASS_T_DEC
1245
    inline typename PB_DS_CLASS_C_DEC::a_const_iterator
1246
    PB_DS_CLASS_C_DEC::
1247
    pref_e_it() const
1248
    { return m_pref_e_it; }
1249
 
1250
    PB_DS_CLASS_T_DEC
1251
    bool
1252
    PB_DS_CLASS_C_DEC::
1253
    should_be_mine(a_const_iterator b_it, a_const_iterator e_it,
1254
                   size_type checked_ind,
1255
                   a_const_pointer p_traits) const
1256
    {
1257
      if (m_e_ind == 0)
1258
        return true;
1259
 
1260
      const size_type num_es = std::distance(b_it, e_it);
1261
      if (num_es < m_e_ind)
1262
        return false;
1263
 
1264
      a_const_iterator key_b_it = b_it;
1265
      std::advance(key_b_it, checked_ind);
1266
      a_const_iterator key_e_it = b_it;
1267
      std::advance(key_e_it, m_e_ind);
1268
 
1269
      a_const_iterator value_b_it = m_pref_b_it;
1270
      std::advance(value_b_it, checked_ind);
1271
      a_const_iterator value_e_it = m_pref_b_it;
1272
      std::advance(value_e_it, m_e_ind);
1273
 
1274
      return p_traits->equal_prefixes(key_b_it, key_e_it, value_b_it,
1275
                                      value_e_it);
1276
    }
1277
 
1278
    PB_DS_CLASS_T_DEC
1279
    typename PB_DS_CLASS_C_DEC::leaf_pointer
1280
    PB_DS_CLASS_C_DEC::
1281
    leftmost_descendant()
1282
    {
1283
      node_pointer p_pot = *begin();
1284
      if (p_pot->m_type == leaf_node)
1285
        return (static_cast<leaf_pointer>(p_pot));
1286
      _GLIBCXX_DEBUG_ASSERT(p_pot->m_type == i_node);
1287
      return static_cast<inode_pointer>(p_pot)->leftmost_descendant();
1288
    }
1289
 
1290
    PB_DS_CLASS_T_DEC
1291
    typename PB_DS_CLASS_C_DEC::leaf_const_pointer
1292
    PB_DS_CLASS_C_DEC::
1293
    leftmost_descendant() const
1294
    { return const_cast<inode_pointer>(this)->leftmost_descendant(); }
1295
 
1296
    PB_DS_CLASS_T_DEC
1297
    typename PB_DS_CLASS_C_DEC::leaf_pointer
1298
    PB_DS_CLASS_C_DEC::
1299
    rightmost_descendant()
1300
    {
1301
      const size_type num_children = std::distance(begin(), end());
1302
      _GLIBCXX_DEBUG_ASSERT(num_children >= 2);
1303
 
1304
      iterator it = begin();
1305
      std::advance(it, num_children - 1);
1306
      node_pointer p_pot =* it;
1307
      if (p_pot->m_type == leaf_node)
1308
        return static_cast<leaf_pointer>(p_pot);
1309
      _GLIBCXX_DEBUG_ASSERT(p_pot->m_type == i_node);
1310
      return static_cast<inode_pointer>(p_pot)->rightmost_descendant();
1311
    }
1312
 
1313
    PB_DS_CLASS_T_DEC
1314
    typename PB_DS_CLASS_C_DEC::leaf_const_pointer
1315
    PB_DS_CLASS_C_DEC::
1316
    rightmost_descendant() const
1317
    { return const_cast<inode_pointer>(this)->rightmost_descendant(); }
1318
 
1319
    PB_DS_CLASS_T_DEC
1320
    typename PB_DS_CLASS_C_DEC::size_type
1321
    PB_DS_CLASS_C_DEC::
1322
    get_begin_pos() const
1323
    {
1324
      size_type i = 0;
1325
      for (; i < arr_size && m_a_p_children[i] == 0; ++i)
1326
        ;
1327
      return i;
1328
    }
1329
 
1330
#ifdef _GLIBCXX_DEBUG
1331
    PB_DS_CLASS_T_DEC
1332
    typename PB_DS_CLASS_C_DEC::node_debug_info
1333
    PB_DS_CLASS_C_DEC::
1334
    assert_valid_imp(a_const_pointer p_traits,
1335
                     const char* __file, int __line) const
1336
    {
1337
      PB_DS_DEBUG_VERIFY(base_type::m_type == i_node);
1338
      PB_DS_DEBUG_VERIFY(static_cast<size_type>(std::distance(pref_b_it(), pref_e_it())) == m_e_ind);
1339
      PB_DS_DEBUG_VERIFY(std::distance(begin(), end()) >= 2);
1340
 
1341
      for (typename _Inode::const_iterator it = begin(); it != end(); ++it)
1342
        {
1343
          node_const_pointer p_nd = *it;
1344
          PB_DS_DEBUG_VERIFY(p_nd->m_p_parent == this);
1345
          node_debug_info child_ret = p_nd->assert_valid_imp(p_traits,
1346
                                                             __file, __line);
1347
 
1348
          PB_DS_DEBUG_VERIFY(static_cast<size_type>(std::distance(child_ret.first, child_ret.second)) >= m_e_ind);
1349
          PB_DS_DEBUG_VERIFY(should_be_mine(child_ret.first, child_ret.second, 0, p_traits));
1350
          PB_DS_DEBUG_VERIFY(get_pref_pos(child_ret.first, child_ret.second, p_traits) == static_cast<size_type>(it.m_p_p_cur - m_a_p_children));
1351
        }
1352
      return std::make_pair(pref_b_it(), pref_e_it());
1353
    }
1354
#endif
1355
 
1356
#undef PB_DS_CLASS_T_DEC
1357
#undef PB_DS_CLASS_C_DEC
1358
  } // namespace detail
1359
} // namespace __gnu_pbds
1360
 
1361
#endif

powered by: WebSVN 2.1.0

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