LCOV - code coverage report
Current view: top level - opt/homebrew/include/boost/multi_index/detail - ord_index_node.hpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 265 267 99.3 %
Date: 2026-06-25 07:23:43 Functions: 66 66 100.0 %

          Line data    Source code
       1             : /* Copyright 2003-2020 Joaquin M Lopez Munoz.
       2             :  * Distributed under the Boost Software License, Version 1.0.
       3             :  * (See accompanying file LICENSE_1_0.txt or copy at
       4             :  * http://www.boost.org/LICENSE_1_0.txt)
       5             :  *
       6             :  * See http://www.boost.org/libs/multi_index for library home page.
       7             :  *
       8             :  * The internal implementation of red-black trees is based on that of SGI STL
       9             :  * stl_tree.h file: 
      10             :  *
      11             :  * Copyright (c) 1996,1997
      12             :  * Silicon Graphics Computer Systems, Inc.
      13             :  *
      14             :  * Permission to use, copy, modify, distribute and sell this software
      15             :  * and its documentation for any purpose is hereby granted without fee,
      16             :  * provided that the above copyright notice appear in all copies and
      17             :  * that both that copyright notice and this permission notice appear
      18             :  * in supporting documentation.  Silicon Graphics makes no
      19             :  * representations about the suitability of this software for any
      20             :  * purpose.  It is provided "as is" without express or implied warranty.
      21             :  *
      22             :  *
      23             :  * Copyright (c) 1994
      24             :  * Hewlett-Packard Company
      25             :  *
      26             :  * Permission to use, copy, modify, distribute and sell this software
      27             :  * and its documentation for any purpose is hereby granted without fee,
      28             :  * provided that the above copyright notice appear in all copies and
      29             :  * that both that copyright notice and this permission notice appear
      30             :  * in supporting documentation.  Hewlett-Packard Company makes no
      31             :  * representations about the suitability of this software for any
      32             :  * purpose.  It is provided "as is" without express or implied warranty.
      33             :  *
      34             :  */
      35             : 
      36             : #ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_NODE_HPP
      37             : #define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_NODE_HPP
      38             : 
      39             : #if defined(_MSC_VER)
      40             : #pragma once
      41             : #endif
      42             : 
      43             : #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
      44             : #include <cstddef>
      45             : #include <boost/multi_index/detail/allocator_traits.hpp>
      46             : #include <boost/multi_index/detail/raw_ptr.hpp>
      47             : 
      48             : #if !defined(BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES)
      49             : #include <boost/mpl/and.hpp>
      50             : #include <boost/mpl/if.hpp>
      51             : #include <boost/multi_index/detail/uintptr_type.hpp>
      52             : #include <boost/type_traits/alignment_of.hpp>
      53             : #include <boost/type_traits/is_same.hpp>
      54             : #endif
      55             : 
      56             : namespace boost{
      57             : 
      58             : namespace multi_index{
      59             : 
      60             : namespace detail{
      61             : 
      62             : /* definition of red-black nodes for ordered_index */
      63             : 
      64             : enum ordered_index_color{red=false,black=true};
      65             : enum ordered_index_side{to_left=false,to_right=true};
      66             : 
      67             : template<typename AugmentPolicy,typename Allocator>
      68             : struct ordered_index_node_impl; /* fwd decl. */
      69             : 
      70             : template<typename AugmentPolicy,typename Allocator>
      71             : struct ordered_index_node_traits
      72             : {
      73             :   typedef typename rebind_alloc_for<
      74             :     Allocator,
      75             :     ordered_index_node_impl<AugmentPolicy,Allocator>
      76             :   >::type                                            allocator;
      77             :   typedef allocator_traits<allocator>                alloc_traits;
      78             :   typedef typename alloc_traits::pointer             pointer;
      79             :   typedef typename alloc_traits::const_pointer       const_pointer;
      80             :   typedef typename alloc_traits::difference_type     difference_type;
      81             :   typedef typename alloc_traits::size_type           size_type;
      82             : };
      83             : 
      84             : template<typename AugmentPolicy,typename Allocator>
      85             : struct ordered_index_node_std_base
      86             : {
      87             :   typedef ordered_index_node_traits<
      88             :     AugmentPolicy,Allocator>                    node_traits;
      89             :   typedef typename node_traits::allocator       node_allocator;
      90             :   typedef typename node_traits::pointer         pointer;
      91             :   typedef typename node_traits::const_pointer   const_pointer;
      92             :   typedef typename node_traits::difference_type difference_type;
      93             :   typedef typename node_traits::size_type       size_type;
      94             :   typedef ordered_index_color&                  color_ref;
      95             :   typedef pointer&                              parent_ref;
      96             : 
      97             :   ordered_index_color& color(){return color_;}
      98             :   ordered_index_color  color()const{return color_;}
      99             :   pointer&             parent(){return parent_;}
     100             :   pointer              parent()const{return parent_;}
     101             :   pointer&             left(){return left_;}
     102             :   pointer              left()const{return left_;}
     103             :   pointer&             right(){return right_;}
     104             :   pointer              right()const{return right_;}
     105             : 
     106             : private:
     107             :   ordered_index_color color_; 
     108             :   pointer             parent_;
     109             :   pointer             left_;
     110             :   pointer             right_;
     111             : };
     112             : 
     113             : #if !defined(BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES)
     114             : /* If ordered_index_node_impl has even alignment, we can use the least
     115             :  * significant bit of one of the ordered_index_node_impl pointers to
     116             :  * store color information. This typically reduces the size of
     117             :  * ordered_index_node_impl by 25%.
     118             :  */
     119             : 
     120             : #if defined(BOOST_MSVC)
     121             : /* This code casts pointers to an integer type that has been computed
     122             :  * to be large enough to hold the pointer, however the metaprogramming
     123             :  * logic is not always spotted by the VC++ code analyser that issues a
     124             :  * long list of warnings.
     125             :  */
     126             : 
     127             : #pragma warning(push)
     128             : #pragma warning(disable:4312 4311)
     129             : #endif
     130             : 
     131             : template<typename AugmentPolicy,typename Allocator>
     132             : struct ordered_index_node_compressed_base
     133             : {
     134             :   typedef ordered_index_node_traits<
     135             :     AugmentPolicy,Allocator>                    node_traits;
     136             :   typedef ordered_index_node_impl<
     137             :     AugmentPolicy,Allocator>*                   pointer;
     138             :   typedef const ordered_index_node_impl<
     139             :     AugmentPolicy,Allocator>*                   const_pointer;
     140             :   typedef typename node_traits::difference_type difference_type;
     141             :   typedef typename node_traits::size_type       size_type;
     142             : 
     143             :   struct color_ref
     144             :   {
     145    47509212 :     color_ref(uintptr_type* r_):r(r_){}
     146             :     color_ref(const color_ref& x):r(x.r){}
     147             :     
     148    13579288 :     operator ordered_index_color()const
     149             :     {
     150    13579288 :       return ordered_index_color(*r&uintptr_type(1));
     151             :     }
     152             :     
     153    10175318 :     color_ref& operator=(ordered_index_color c)
     154             :     {
     155    10175318 :       *r&=~uintptr_type(1);
     156    10175318 :       *r|=uintptr_type(c);
     157    10175318 :       return *this;
     158             :     }
     159             :     
     160      396850 :     color_ref& operator=(const color_ref& x)
     161             :     {
     162      396850 :       return operator=(x.operator ordered_index_color());
     163             :     }
     164             :     
     165             :   private:
     166             :     uintptr_type* r;
     167             :   };
     168             :   
     169             :   struct parent_ref
     170             :   {
     171   108288242 :     parent_ref(uintptr_type* r_):r(r_){}
     172     3253382 :     parent_ref(const parent_ref& x):r(x.r){}
     173             :     
     174    54912504 :     operator pointer()const
     175             :     {
     176    54912504 :       return (pointer)(void*)(*r&~uintptr_type(1));
     177             :     }
     178             :     
     179     6774692 :     parent_ref& operator=(pointer p)
     180             :     {
     181     6774692 :       *r=((uintptr_type)(void*)p)|(*r&uintptr_type(1));
     182     6774692 :       return *this;
     183             :     }
     184             :     
     185     2303101 :     parent_ref& operator=(const parent_ref& x)
     186             :     {
     187     2303101 :       return operator=(x.operator pointer());
     188             :     }
     189             : 
     190    24626931 :     pointer operator->()const
     191             :     {
     192    24626931 :       return operator pointer();
     193             :     }
     194             : 
     195             :   private:
     196             :     uintptr_type* r;
     197             :   };
     198             :   
     199    23754606 :   color_ref           color(){return color_ref(&parentcolor_);}
     200             :   ordered_index_color color()const
     201             :   {
     202             :     return ordered_index_color(parentcolor_&uintptr_type(1));
     203             :   }
     204             : 
     205    54144121 :   parent_ref parent(){return parent_ref(&parentcolor_);}
     206             :   pointer    parent()const
     207             :   {
     208             :     return (pointer)(void*)(parentcolor_&~uintptr_type(1));
     209             :   }
     210             : 
     211    56775316 :   pointer& left(){return left_;}
     212             :   pointer  left()const{return left_;}
     213    43207651 :   pointer& right(){return right_;}
     214             :   pointer  right()const{return right_;}
     215             : 
     216             : private:
     217             :   uintptr_type parentcolor_;
     218             :   pointer      left_;
     219             :   pointer      right_;
     220             : };
     221             : #if defined(BOOST_MSVC)
     222             : #pragma warning(pop)
     223             : #endif
     224             : #endif
     225             : 
     226             : template<typename AugmentPolicy,typename Allocator>
     227             : struct ordered_index_node_impl_base:
     228             : 
     229             : #if !defined(BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES)
     230             :   AugmentPolicy::template augmented_node<
     231             :     typename mpl::if_c<
     232             :       !(has_uintptr_type::value)||
     233             :       (alignment_of<
     234             :         ordered_index_node_compressed_base<AugmentPolicy,Allocator>
     235             :        >::value%2)||
     236             :       !(is_same<
     237             :         typename ordered_index_node_traits<AugmentPolicy,Allocator>::pointer,
     238             :         ordered_index_node_impl<AugmentPolicy,Allocator>*>::value),
     239             :       ordered_index_node_std_base<AugmentPolicy,Allocator>,
     240             :       ordered_index_node_compressed_base<AugmentPolicy,Allocator>
     241             :     >::type
     242             :   >::type
     243             : #else
     244             :   AugmentPolicy::template augmented_node<
     245             :     ordered_index_node_std_base<AugmentPolicy,Allocator>
     246             :   >::type
     247             : #endif
     248             : 
     249             : {};
     250             : 
     251             : template<typename AugmentPolicy,typename Allocator>
     252             : struct ordered_index_node_impl:
     253             :   ordered_index_node_impl_base<AugmentPolicy,Allocator>
     254             : {
     255             : private:
     256             :   typedef ordered_index_node_impl_base<AugmentPolicy,Allocator> super;
     257             : 
     258             : public:
     259             :   typedef typename super::color_ref                             color_ref;
     260             :   typedef typename super::parent_ref                            parent_ref;
     261             :   typedef typename super::pointer                               pointer;
     262             :   typedef typename super::const_pointer                         const_pointer;
     263             : 
     264             :   /* interoperability with bidir_node_iterator */
     265             : 
     266     3828085 :   static void increment(pointer& x)
     267             :   {
     268     3828085 :     if(x->right()!=pointer(0)){
     269     1843676 :       x=x->right();
     270     3570552 :       while(x->left()!=pointer(0))x=x->left();
     271     1843676 :     }
     272             :     else{
     273     1984409 :       pointer y=x->parent();
     274     4348080 :       while(x==y->right()){
     275     2363671 :         x=y;
     276     2363671 :         y=y->parent();
     277             :       }
     278     1984409 :       if(x->right()!=y)x=y;
     279             :     }
     280     3828085 :   }
     281             : 
     282     4752950 :   static void decrement(pointer& x)
     283             :   {
     284     4752950 :     if(x->color()==red&&x->parent()->parent()==x){
     285           0 :       x=x->right();
     286           0 :     }
     287     4752950 :     else if(x->left()!=pointer(0)){
     288     2297224 :       pointer y=x->left();
     289     4181893 :       while(y->right()!=pointer(0))y=y->right();
     290     2297224 :       x=y;
     291     2297224 :     }else{
     292     2455726 :       pointer y=x->parent();
     293     4512841 :       while(x==y->left()){
     294     2057115 :         x=y;
     295     2057115 :         y=y->parent();
     296             :       }
     297     2455726 :       x=y;
     298             :     }
     299     4752950 :   }
     300             : 
     301             :   /* algorithmic stuff */
     302             : 
     303      459771 :   static void rotate_left(pointer x,parent_ref root)
     304             :   {
     305      459771 :     pointer y=x->right();
     306      459771 :     x->right()=y->left();
     307      459771 :     if(y->left()!=pointer(0))y->left()->parent()=x;
     308      459771 :     y->parent()=x->parent();
     309             :     
     310      459771 :     if(x==root)                    root=y;
     311      448471 :     else if(x==x->parent()->left())x->parent()->left()=y;
     312      156205 :     else                           x->parent()->right()=y;
     313      459771 :     y->left()=x;
     314      459771 :     x->parent()=y;
     315      459771 :     AugmentPolicy::rotate_left(x,y);
     316      459771 :   }
     317             : 
     318       23286 :   static pointer minimum(pointer x)
     319             :   {
     320       23286 :     while(x->left()!=pointer(0))x=x->left();
     321       23286 :     return x;
     322             :   }
     323             : 
     324      317690 :   static pointer maximum(pointer x)
     325             :   {
     326      317690 :     while(x->right()!=pointer(0))x=x->right();
     327      317690 :     return x;
     328             :   }
     329             : 
     330     1166920 :   static void rotate_right(pointer x,parent_ref root)
     331             :   {
     332     1166920 :     pointer y=x->left();
     333     1166920 :     x->left()=y->right();
     334     1166920 :     if(y->right()!=pointer(0))y->right()->parent()=x;
     335     1166920 :     y->parent()=x->parent();
     336             : 
     337     1166920 :     if(x==root)                     root=y;
     338     1147645 :     else if(x==x->parent()->right())x->parent()->right()=y;
     339      490653 :     else                            x->parent()->left()=y;
     340     1166920 :     y->right()=x;
     341     1166920 :     x->parent()=y;
     342     1166920 :     AugmentPolicy::rotate_right(x,y);
     343     1166920 :   }
     344             : 
     345     1261820 :   static void rebalance(pointer x,parent_ref root)
     346             :   {
     347     1261820 :     x->color()=red;
     348     2852568 :     while(x!=root&&x->parent()->color()==red){
     349     1590748 :       if(x->parent()==x->parent()->parent()->left()){
     350     1215659 :         pointer y=x->parent()->parent()->right();
     351     1215659 :         if(y!=pointer(0)&&y->color()==red){
     352      662521 :           x->parent()->color()=black;
     353      662521 :           y->color()=black;
     354      662521 :           x->parent()->parent()->color()=red;
     355      662521 :           x=x->parent()->parent();
     356      662521 :         }
     357             :         else{
     358      553138 :           if(x==x->parent()->right()){
     359       37460 :             x=x->parent();
     360       37460 :             rotate_left(x,root);
     361       37460 :           }
     362      553138 :           x->parent()->color()=black;
     363      553138 :           x->parent()->parent()->color()=red;
     364      553138 :           rotate_right(x->parent()->parent(),root);
     365             :         }
     366     1215659 :       }
     367             :       else{
     368      375089 :         pointer y=x->parent()->parent()->left();
     369      375089 :         if(y!=pointer(0)&&y->color()==red){
     370       95209 :           x->parent()->color()=black;
     371       95209 :           y->color()=black;
     372       95209 :           x->parent()->parent()->color()=red;
     373       95209 :           x=x->parent()->parent();
     374       95209 :         }
     375             :         else{
     376      279880 :           if(x==x->parent()->left()){
     377      210085 :             x=x->parent();
     378      210085 :             rotate_right(x,root);
     379      210085 :           }
     380      279880 :           x->parent()->color()=black;
     381      279880 :           x->parent()->parent()->color()=red;
     382      279880 :           rotate_left(x->parent()->parent(),root);
     383             :         }
     384             :       }
     385             :     }
     386     1261820 :     root->color()=black;
     387     1261820 :   }
     388             : 
     389     1261820 :   static void link(
     390             :     pointer x,ordered_index_side side,pointer position,pointer header)
     391             :   {
     392     1261820 :     if(side==to_left){
     393      896905 :       position->left()=x;  /* also makes leftmost=x when parent==header */
     394      896905 :       if(position==header){
     395       15788 :         header->parent()=x;
     396       15788 :         header->right()=x;
     397       15788 :       }
     398      881117 :       else if(position==header->left()){
     399      362989 :         header->left()=x;  /* maintain leftmost pointing to min node */
     400      362989 :       }
     401      896905 :     }
     402             :     else{
     403      364915 :       position->right()=x;
     404      364915 :       if(position==header->right()){
     405       69276 :         header->right()=x; /* maintain rightmost pointing to max node */
     406       69276 :       }
     407             :     }
     408     1261820 :     x->parent()=position;
     409     1261820 :     x->left()=pointer(0);
     410     1261820 :     x->right()=pointer(0);
     411     1261820 :     AugmentPolicy::add(x,pointer(header->parent()));
     412     1261820 :     ordered_index_node_impl::rebalance(x,header->parent());
     413     1261820 :   }
     414             : 
     415     1248950 :   static pointer rebalance_for_extract(
     416             :     pointer z,parent_ref root,pointer& leftmost,pointer& rightmost)
     417             :   {
     418     1248950 :     pointer y=z;
     419     1248950 :     pointer x=pointer(0);
     420     1248950 :     pointer x_parent=pointer(0);
     421     1248950 :     if(y->left()==pointer(0)){    /* z has at most one non-null child. y==z. */
     422      683657 :       x=y->right();               /* x might be null */
     423      683657 :     }
     424             :     else{
     425      565293 :       if(y->right()==pointer(0)){ /* z has exactly one non-null child. y==z. */
     426      341199 :         x=y->left();              /* x is not null */
     427      341199 :       }
     428             :       else{                       /* z has two non-null children.  Set y to */
     429      224094 :         y=y->right();             /* z's successor. x might be null.        */
     430      609105 :         while(y->left()!=pointer(0))y=y->left();
     431      224094 :         x=y->right();
     432             :       }
     433             :     }
     434     1248950 :     AugmentPolicy::remove(y,pointer(root));
     435     1248950 :     if(y!=z){
     436      224094 :       AugmentPolicy::copy(z,y);
     437      224094 :       z->left()->parent()=y;   /* relink y in place of z. y is z's successor */
     438      224094 :       y->left()=z->left();
     439      224094 :       if(y!=z->right()){
     440      157723 :         x_parent=y->parent();
     441      157723 :         if(x!=pointer(0))x->parent()=y->parent();
     442      157723 :         y->parent()->left()=x; /* y must be a child of left */
     443      157723 :         y->right()=z->right();
     444      157723 :         z->right()->parent()=y;
     445      157723 :       }
     446             :       else{
     447       66371 :         x_parent=y;
     448             :       }
     449             : 
     450      224094 :       if(root==z)                    root=y;
     451      218440 :       else if(z->parent()->left()==z)z->parent()->left()=y;
     452       98267 :       else                           z->parent()->right()=y;
     453      224094 :       y->parent()=z->parent();
     454      224094 :       ordered_index_color c=y->color();
     455      224094 :       y->color()=z->color();
     456      224094 :       z->color()=c;
     457      224094 :       y=z;                    /* y now points to node to be actually deleted */
     458      224094 :     }
     459             :     else{                     /* y==z */
     460     1024856 :       x_parent=y->parent();
     461     1024856 :       if(x!=pointer(0))x->parent()=y->parent();   
     462     1024856 :       if(root==z){
     463       19461 :         root=x;
     464       19461 :       }
     465             :       else{
     466     1005395 :         if(z->parent()->left()==z)z->parent()->left()=x;
     467      781925 :         else                      z->parent()->right()=x;
     468             :       }
     469     1024856 :       if(leftmost==z){
     470       80320 :         if(z->right()==pointer(0)){ /* z->left() must be null also */
     471       57034 :           leftmost=z->parent();
     472       57034 :         }
     473             :         else{              
     474       23286 :           leftmost=minimum(x);      /* makes leftmost==header if z==root */
     475             :         }
     476       80320 :       }
     477     1024856 :       if(rightmost==z){
     478      694659 :         if(z->left()==pointer(0)){  /* z->right() must be null also */
     479      376969 :           rightmost=z->parent();
     480      376969 :         }
     481             :         else{                   /* x==z->left() */
     482      317690 :           rightmost=maximum(x); /* makes rightmost==header if z==root */
     483             :         }
     484      694659 :       }
     485             :     }
     486     1248950 :     if(y->color()!=red){
     487     3491354 :       while(x!=root&&(x==pointer(0)|| x->color()==black)){
     488      922966 :         if(x==x_parent->left()){
     489      148108 :           pointer w=x_parent->right();
     490      148108 :           if(w->color()==red){
     491       31938 :             w->color()=black;
     492       31938 :             x_parent->color()=red;
     493       31938 :             rotate_left(x_parent,root);
     494       31938 :             w=x_parent->right();
     495       31938 :           }
     496      274434 :           if((w->left()==pointer(0)||w->left()->color()==black) &&
     497      126326 :              (w->right()==pointer(0)||w->right()->color()==black)){
     498      100685 :             w->color()=red;
     499      100685 :             x=x_parent;
     500      100685 :             x_parent=x_parent->parent();
     501      100685 :           } 
     502             :           else{
     503       90772 :             if(w->right()==pointer(0 )
     504       47423 :                 || w->right()->color()==black){
     505       12120 :               if(w->left()!=pointer(0)) w->left()->color()=black;
     506       12120 :               w->color()=red;
     507       12120 :               rotate_right(w,root);
     508       12120 :               w=x_parent->right();
     509       12120 :             }
     510       47423 :             w->color()=x_parent->color();
     511       47423 :             x_parent->color()=black;
     512       47423 :             if(w->right()!=pointer(0))w->right()->color()=black;
     513       47423 :             rotate_left(x_parent,root);
     514       47423 :             break;
     515             :           }
     516      100685 :         } 
     517             :         else{                   /* same as above,with right <-> left */
     518      774858 :           pointer w=x_parent->left();
     519      774858 :           if(w->color()==red){
     520      266244 :             w->color()=black;
     521      266244 :             x_parent->color()=red;
     522      266244 :             rotate_right(x_parent,root);
     523      266244 :             w=x_parent->left();
     524      266244 :           }
     525     1461460 :           if((w->right()==pointer(0)||w->right()->color()==black) &&
     526      686602 :              (w->left()==pointer(0)||w->left()->color()==black)){
     527      649525 :             w->color()=red;
     528      649525 :             x=x_parent;
     529      649525 :             x_parent=x_parent->parent();
     530      649525 :           }
     531             :           else{
     532      125333 :             if(w->left()==pointer(0)||w->left()->color()==black){
     533       63070 :               if(w->right()!=pointer(0))w->right()->color()=black;
     534       63070 :               w->color()=red;
     535       63070 :               rotate_left(w,root);
     536       63070 :               w=x_parent->left();
     537       63070 :             }
     538      125333 :             w->color()=x_parent->color();
     539      125333 :             x_parent->color()=black;
     540      125333 :             if(w->left()!=pointer(0))w->left()->color()=black;
     541      125333 :             rotate_right(x_parent,root);
     542      125333 :             break;
     543             :           }
     544             :         }
     545             :       }
     546     1008966 :       if(x!=pointer(0))x->color()=black;
     547     1008966 :     }
     548     1248950 :     return y;
     549             :   }
     550             : 
     551             :   static void restore(pointer x,pointer position,pointer header)
     552             :   {
     553             :     if(position->left()==pointer(0)||position->left()==header){
     554             :       link(x,to_left,position,header);
     555             :     }
     556             :     else{
     557             :       decrement(position);
     558             :       link(x,to_right,position,header);
     559             :     }
     560             :   }
     561             : 
     562             : #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
     563             :   /* invariant stuff */
     564             : 
     565             :   static std::size_t black_count(pointer node,pointer root)
     566             :   {
     567             :     if(node==pointer(0))return 0;
     568             :     std::size_t sum=0;
     569             :     for(;;){
     570             :       if(node->color()==black)++sum;
     571             :       if(node==root)break;
     572             :       node=node->parent();
     573             :     } 
     574             :     return sum;
     575             :   }
     576             : #endif
     577             : };
     578             : 
     579             : template<typename AugmentPolicy,typename Super>
     580             : struct ordered_index_node_trampoline:
     581             :   ordered_index_node_impl<
     582             :     AugmentPolicy,
     583             :     typename rebind_alloc_for<
     584             :       typename Super::allocator_type,
     585             :       char
     586             :     >::type
     587             :   >
     588             : {
     589             :   typedef ordered_index_node_impl<
     590             :     AugmentPolicy,
     591             :     typename rebind_alloc_for<
     592             :       typename Super::allocator_type,
     593             :       char
     594             :     >::type
     595             :   > impl_type;
     596             : };
     597             : 
     598             : template<typename AugmentPolicy,typename Super>
     599             : struct ordered_index_node:
     600             :   Super,ordered_index_node_trampoline<AugmentPolicy,Super>
     601             : {
     602             : private:
     603             :   typedef ordered_index_node_trampoline<AugmentPolicy,Super> trampoline;
     604             : 
     605             : public:
     606             :   typedef typename trampoline::impl_type       impl_type;
     607             :   typedef typename trampoline::color_ref       impl_color_ref;
     608             :   typedef typename trampoline::parent_ref      impl_parent_ref;
     609             :   typedef typename trampoline::pointer         impl_pointer;
     610             :   typedef typename trampoline::const_pointer   const_impl_pointer;
     611             :   typedef typename trampoline::difference_type difference_type;
     612             :   typedef typename trampoline::size_type       size_type;
     613             : 
     614      335190 :   impl_color_ref      color(){return trampoline::color();}
     615             :   ordered_index_color color()const{return trampoline::color();}
     616     3731875 :   impl_parent_ref     parent(){return trampoline::parent();}
     617             :   impl_pointer        parent()const{return trampoline::parent();}
     618    19748907 :   impl_pointer&       left(){return trampoline::left();}
     619             :   impl_pointer        left()const{return trampoline::left();}
     620     8759348 :   impl_pointer&       right(){return trampoline::right();}
     621             :   impl_pointer        right()const{return trampoline::right();}
     622             : 
     623    14285825 :   impl_pointer impl()
     624             :   {
     625    14285825 :     return static_cast<impl_pointer>(
     626    14285825 :       static_cast<impl_type*>(static_cast<trampoline*>(this)));
     627             :   }
     628             : 
     629             :   const_impl_pointer impl()const
     630             :   {
     631             :     return static_cast<const_impl_pointer>(
     632             :       static_cast<const impl_type*>(static_cast<const trampoline*>(this)));
     633             :   }
     634             : 
     635    36068745 :   static ordered_index_node* from_impl(impl_pointer x)
     636             :   {
     637    36068745 :     return
     638    36068745 :       static_cast<ordered_index_node*>(
     639             :         static_cast<trampoline*>(
     640    36068745 :           raw_ptr<impl_type*>(x)));
     641             :   }
     642             : 
     643             :   static const ordered_index_node* from_impl(const_impl_pointer x)
     644             :   {
     645             :     return
     646             :       static_cast<const ordered_index_node*>(
     647             :         static_cast<const trampoline*>(
     648             :           raw_ptr<const impl_type*>(x)));
     649             :   }
     650             : 
     651             :   /* interoperability with bidir_node_iterator */
     652             : 
     653     3828085 :   static void increment(ordered_index_node*& x)
     654             :   {
     655     3828085 :     impl_pointer xi=x->impl();
     656     3828085 :     trampoline::increment(xi);
     657     3828085 :     x=from_impl(xi);
     658     3828085 :   }
     659             : 
     660     4752950 :   static void decrement(ordered_index_node*& x)
     661             :   {
     662     4752950 :     impl_pointer xi=x->impl();
     663     4752950 :     trampoline::decrement(xi);
     664     4752950 :     x=from_impl(xi);
     665     4752950 :   }
     666             : };
     667             : 
     668             : } /* namespace multi_index::detail */
     669             : 
     670             : } /* namespace multi_index */
     671             : 
     672             : } /* namespace boost */
     673             : 
     674             : #endif

Generated by: LCOV version 1.16