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: test_dash_coverage.info Lines: 265 267 99.3 %
Date: 2026-06-25 07:23:51 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    43154184 :     color_ref(uintptr_type* r_):r(r_){}
     146             :     color_ref(const color_ref& x):r(x.r){}
     147             :     
     148    12509181 :     operator ordered_index_color()const
     149             :     {
     150    12509181 :       return ordered_index_color(*r&uintptr_type(1));
     151             :     }
     152             :     
     153     9067911 :     color_ref& operator=(ordered_index_color c)
     154             :     {
     155     9067911 :       *r&=~uintptr_type(1);
     156     9067911 :       *r|=uintptr_type(c);
     157     9067911 :       return *this;
     158             :     }
     159             :     
     160      342670 :     color_ref& operator=(const color_ref& x)
     161             :     {
     162      342670 :       return operator=(x.operator ordered_index_color());
     163             :     }
     164             :     
     165             :   private:
     166             :     uintptr_type* r;
     167             :   };
     168             :   
     169             :   struct parent_ref
     170             :   {
     171    97906028 :     parent_ref(uintptr_type* r_):r(r_){}
     172     2979850 :     parent_ref(const parent_ref& x):r(x.r){}
     173             :     
     174    49720077 :     operator pointer()const
     175             :     {
     176    49720077 :       return (pointer)(void*)(*r&~uintptr_type(1));
     177             :     }
     178             :     
     179     6006326 :     parent_ref& operator=(pointer p)
     180             :     {
     181     6006326 :       *r=((uintptr_type)(void*)p)|(*r&uintptr_type(1));
     182     6006326 :       return *this;
     183             :     }
     184             :     
     185     2106944 :     parent_ref& operator=(const parent_ref& x)
     186             :     {
     187     2106944 :       return operator=(x.operator pointer());
     188             :     }
     189             : 
     190    22408241 :     pointer operator->()const
     191             :     {
     192    22408241 :       return operator pointer();
     193             :     }
     194             : 
     195             :   private:
     196             :     uintptr_type* r;
     197             :   };
     198             :   
     199    21577092 :   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    48953014 :   parent_ref parent(){return parent_ref(&parentcolor_);}
     206             :   pointer    parent()const
     207             :   {
     208             :     return (pointer)(void*)(parentcolor_&~uintptr_type(1));
     209             :   }
     210             : 
     211    52979331 :   pointer& left(){return left_;}
     212             :   pointer  left()const{return left_;}
     213    39553976 :   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     3564384 :   static void increment(pointer& x)
     267             :   {
     268     3564384 :     if(x->right()!=pointer(0)){
     269     1763605 :       x=x->right();
     270     3439946 :       while(x->left()!=pointer(0))x=x->left();
     271     1763605 :     }
     272             :     else{
     273     1800779 :       pointer y=x->parent();
     274     3754811 :       while(x==y->right()){
     275     1954032 :         x=y;
     276     1954032 :         y=y->parent();
     277             :       }
     278     1800779 :       if(x->right()!=y)x=y;
     279             :     }
     280     3564384 :   }
     281             : 
     282     4549499 :   static void decrement(pointer& x)
     283             :   {
     284     4549499 :     if(x->color()==red&&x->parent()->parent()==x){
     285           0 :       x=x->right();
     286           0 :     }
     287     4549499 :     else if(x->left()!=pointer(0)){
     288     2229961 :       pointer y=x->left();
     289     4081863 :       while(y->right()!=pointer(0))y=y->right();
     290     2229961 :       x=y;
     291     2229961 :     }else{
     292     2319538 :       pointer y=x->parent();
     293     4285444 :       while(x==y->left()){
     294     1965906 :         x=y;
     295     1965906 :         y=y->parent();
     296             :       }
     297     2319538 :       x=y;
     298             :     }
     299     4549499 :   }
     300             : 
     301             :   /* algorithmic stuff */
     302             : 
     303      389142 :   static void rotate_left(pointer x,parent_ref root)
     304             :   {
     305      389142 :     pointer y=x->right();
     306      389142 :     x->right()=y->left();
     307      389142 :     if(y->left()!=pointer(0))y->left()->parent()=x;
     308      389142 :     y->parent()=x->parent();
     309             :     
     310      389142 :     if(x==root)                    root=y;
     311      382057 :     else if(x==x->parent()->left())x->parent()->left()=y;
     312      120722 :     else                           x->parent()->right()=y;
     313      389142 :     y->left()=x;
     314      389142 :     x->parent()=y;
     315      389142 :     AugmentPolicy::rotate_left(x,y);
     316      389142 :   }
     317             : 
     318        9113 :   static pointer minimum(pointer x)
     319             :   {
     320        9113 :     while(x->left()!=pointer(0))x=x->left();
     321        9113 :     return x;
     322             :   }
     323             : 
     324      308154 :   static pointer maximum(pointer x)
     325             :   {
     326      308154 :     while(x->right()!=pointer(0))x=x->right();
     327      308154 :     return x;
     328             :   }
     329             : 
     330     1100783 :   static void rotate_right(pointer x,parent_ref root)
     331             :   {
     332     1100783 :     pointer y=x->left();
     333     1100783 :     x->left()=y->right();
     334     1100783 :     if(y->right()!=pointer(0))y->right()->parent()=x;
     335     1100783 :     y->parent()=x->parent();
     336             : 
     337     1100783 :     if(x==root)                     root=y;
     338     1089754 :     else if(x==x->parent()->right())x->parent()->right()=y;
     339      463516 :     else                            x->parent()->left()=y;
     340     1100783 :     y->right()=x;
     341     1100783 :     x->parent()=y;
     342     1100783 :     AugmentPolicy::rotate_right(x,y);
     343     1100783 :   }
     344             : 
     345     1113941 :   static void rebalance(pointer x,parent_ref root)
     346             :   {
     347     1113941 :     x->color()=red;
     348     2564783 :     while(x!=root&&x->parent()->color()==red){
     349     1450842 :       if(x->parent()==x->parent()->parent()->left()){
     350     1153736 :         pointer y=x->parent()->parent()->right();
     351     1153736 :         if(y!=pointer(0)&&y->color()==red){
     352      633258 :           x->parent()->color()=black;
     353      633258 :           y->color()=black;
     354      633258 :           x->parent()->parent()->color()=red;
     355      633258 :           x=x->parent()->parent();
     356      633258 :         }
     357             :         else{
     358      520478 :           if(x==x->parent()->right()){
     359       31192 :             x=x->parent();
     360       31192 :             rotate_left(x,root);
     361       31192 :           }
     362      520478 :           x->parent()->color()=black;
     363      520478 :           x->parent()->parent()->color()=red;
     364      520478 :           rotate_right(x->parent()->parent(),root);
     365             :         }
     366     1153736 :       }
     367             :       else{
     368      297106 :         pointer y=x->parent()->parent()->left();
     369      297106 :         if(y!=pointer(0)&&y->color()==red){
     370       57335 :           x->parent()->color()=black;
     371       57335 :           y->color()=black;
     372       57335 :           x->parent()->parent()->color()=red;
     373       57335 :           x=x->parent()->parent();
     374       57335 :         }
     375             :         else{
     376      239771 :           if(x==x->parent()->left()){
     377      202307 :             x=x->parent();
     378      202307 :             rotate_right(x,root);
     379      202307 :           }
     380      239771 :           x->parent()->color()=black;
     381      239771 :           x->parent()->parent()->color()=red;
     382      239771 :           rotate_left(x->parent()->parent(),root);
     383             :         }
     384             :       }
     385             :     }
     386     1113941 :     root->color()=black;
     387     1113941 :   }
     388             : 
     389     1113941 :   static void link(
     390             :     pointer x,ordered_index_side side,pointer position,pointer header)
     391             :   {
     392     1113941 :     if(side==to_left){
     393      811182 :       position->left()=x;  /* also makes leftmost=x when parent==header */
     394      811182 :       if(position==header){
     395        1388 :         header->parent()=x;
     396        1388 :         header->right()=x;
     397        1388 :       }
     398      809794 :       else if(position==header->left()){
     399      329353 :         header->left()=x;  /* maintain leftmost pointing to min node */
     400      329353 :       }
     401      811182 :     }
     402             :     else{
     403      302759 :       position->right()=x;
     404      302759 :       if(position==header->right()){
     405       32852 :         header->right()=x; /* maintain rightmost pointing to max node */
     406       32852 :       }
     407             :     }
     408     1113941 :     x->parent()=position;
     409     1113941 :     x->left()=pointer(0);
     410     1113941 :     x->right()=pointer(0);
     411     1113941 :     AugmentPolicy::add(x,pointer(header->parent()));
     412     1113941 :     ordered_index_node_impl::rebalance(x,header->parent());
     413     1113941 :   }
     414             : 
     415     1107326 :   static pointer rebalance_for_extract(
     416             :     pointer z,parent_ref root,pointer& leftmost,pointer& rightmost)
     417             :   {
     418     1107326 :     pointer y=z;
     419     1107326 :     pointer x=pointer(0);
     420     1107326 :     pointer x_parent=pointer(0);
     421     1107326 :     if(y->left()==pointer(0)){    /* z has at most one non-null child. y==z. */
     422      582596 :       x=y->right();               /* x might be null */
     423      582596 :     }
     424             :     else{
     425      524730 :       if(y->right()==pointer(0)){ /* z has exactly one non-null child. y==z. */
     426      327598 :         x=y->left();              /* x is not null */
     427      327598 :       }
     428             :       else{                       /* z has two non-null children.  Set y to */
     429      197132 :         y=y->right();             /* z's successor. x might be null.        */
     430      563574 :         while(y->left()!=pointer(0))y=y->left();
     431      197132 :         x=y->right();
     432             :       }
     433             :     }
     434     1107326 :     AugmentPolicy::remove(y,pointer(root));
     435     1107326 :     if(y!=z){
     436      197132 :       AugmentPolicy::copy(z,y);
     437      197132 :       z->left()->parent()=y;   /* relink y in place of z. y is z's successor */
     438      197132 :       y->left()=z->left();
     439      197132 :       if(y!=z->right()){
     440      146516 :         x_parent=y->parent();
     441      146516 :         if(x!=pointer(0))x->parent()=y->parent();
     442      146516 :         y->parent()->left()=x; /* y must be a child of left */
     443      146516 :         y->right()=z->right();
     444      146516 :         z->right()->parent()=y;
     445      146516 :       }
     446             :       else{
     447       50616 :         x_parent=y;
     448             :       }
     449             : 
     450      197132 :       if(root==z)                    root=y;
     451      194677 :       else if(z->parent()->left()==z)z->parent()->left()=y;
     452       85136 :       else                           z->parent()->right()=y;
     453      197132 :       y->parent()=z->parent();
     454      197132 :       ordered_index_color c=y->color();
     455      197132 :       y->color()=z->color();
     456      197132 :       z->color()=c;
     457      197132 :       y=z;                    /* y now points to node to be actually deleted */
     458      197132 :     }
     459             :     else{                     /* y==z */
     460      910194 :       x_parent=y->parent();
     461      910194 :       if(x!=pointer(0))x->parent()=y->parent();   
     462      910194 :       if(root==z){
     463        2394 :         root=x;
     464        2394 :       }
     465             :       else{
     466      907800 :         if(z->parent()->left()==z)z->parent()->left()=x;
     467      745071 :         else                      z->parent()->right()=x;
     468             :       }
     469      910194 :       if(leftmost==z){
     470       27216 :         if(z->right()==pointer(0)){ /* z->left() must be null also */
     471       18103 :           leftmost=z->parent();
     472       18103 :         }
     473             :         else{              
     474        9113 :           leftmost=minimum(x);      /* makes leftmost==header if z==root */
     475             :         }
     476       27216 :       }
     477      910194 :       if(rightmost==z){
     478      658214 :         if(z->left()==pointer(0)){  /* z->right() must be null also */
     479      350060 :           rightmost=z->parent();
     480      350060 :         }
     481             :         else{                   /* x==z->left() */
     482      308154 :           rightmost=maximum(x); /* makes rightmost==header if z==root */
     483             :         }
     484      658214 :       }
     485             :     }
     486     1107326 :     if(y->color()!=red){
     487     3170130 :       while(x!=root&&(x==pointer(0)|| x->color()==black)){
     488      831262 :         if(x==x_parent->left()){
     489      101511 :           pointer w=x_parent->right();
     490      101511 :           if(w->color()==red){
     491       24624 :             w->color()=black;
     492       24624 :             x_parent->color()=red;
     493       24624 :             rotate_left(x_parent,root);
     494       24624 :             w=x_parent->right();
     495       24624 :           }
     496      189815 :           if((w->left()==pointer(0)||w->left()->color()==black) &&
     497       88304 :              (w->right()==pointer(0)||w->right()->color()==black)){
     498       67976 :             w->color()=red;
     499       67976 :             x=x_parent;
     500       67976 :             x_parent=x_parent->parent();
     501       67976 :           } 
     502             :           else{
     503       66566 :             if(w->right()==pointer(0 )
     504       33535 :                 || w->right()->color()==black){
     505        7214 :               if(w->left()!=pointer(0)) w->left()->color()=black;
     506        7214 :               w->color()=red;
     507        7214 :               rotate_right(w,root);
     508        7214 :               w=x_parent->right();
     509        7214 :             }
     510       33535 :             w->color()=x_parent->color();
     511       33535 :             x_parent->color()=black;
     512       33535 :             if(w->right()!=pointer(0))w->right()->color()=black;
     513       33535 :             rotate_left(x_parent,root);
     514       33535 :             break;
     515             :           }
     516       67976 :         } 
     517             :         else{                   /* same as above,with right <-> left */
     518      729751 :           pointer w=x_parent->left();
     519      729751 :           if(w->color()==red){
     520      258781 :             w->color()=black;
     521      258781 :             x_parent->color()=red;
     522      258781 :             rotate_right(x_parent,root);
     523      258781 :             w=x_parent->left();
     524      258781 :           }
     525     1377261 :           if((w->right()==pointer(0)||w->right()->color()==black) &&
     526      647510 :              (w->left()==pointer(0)||w->left()->color()==black)){
     527      617748 :             w->color()=red;
     528      617748 :             x=x_parent;
     529      617748 :             x_parent=x_parent->parent();
     530      617748 :           }
     531             :           else{
     532      112003 :             if(w->left()==pointer(0)||w->left()->color()==black){
     533       60020 :               if(w->right()!=pointer(0))w->right()->color()=black;
     534       60020 :               w->color()=red;
     535       60020 :               rotate_left(w,root);
     536       60020 :               w=x_parent->left();
     537       60020 :             }
     538      112003 :             w->color()=x_parent->color();
     539      112003 :             x_parent->color()=black;
     540      112003 :             if(w->left()!=pointer(0))w->left()->color()=black;
     541      112003 :             rotate_right(x_parent,root);
     542      112003 :             break;
     543             :           }
     544             :         }
     545             :       }
     546      902668 :       if(x!=pointer(0))x->color()=black;
     547      902668 :     }
     548     1107326 :     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      191744 :   impl_color_ref      color(){return trampoline::color();}
     615             :   ordered_index_color color()const{return trampoline::color();}
     616     3173061 :   impl_parent_ref     parent(){return trampoline::parent();}
     617             :   impl_pointer        parent()const{return trampoline::parent();}
     618    18619089 :   impl_pointer&       left(){return trampoline::left();}
     619             :   impl_pointer        left()const{return trampoline::left();}
     620     7873210 :   impl_pointer&       right(){return trampoline::right();}
     621             :   impl_pointer        right()const{return trampoline::right();}
     622             : 
     623    12946520 :   impl_pointer impl()
     624             :   {
     625    12946520 :     return static_cast<impl_pointer>(
     626    12946520 :       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    33882033 :   static ordered_index_node* from_impl(impl_pointer x)
     636             :   {
     637    33882033 :     return
     638    33882033 :       static_cast<ordered_index_node*>(
     639             :         static_cast<trampoline*>(
     640    33882033 :           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     3564384 :   static void increment(ordered_index_node*& x)
     654             :   {
     655     3564384 :     impl_pointer xi=x->impl();
     656     3564384 :     trampoline::increment(xi);
     657     3564384 :     x=from_impl(xi);
     658     3564384 :   }
     659             : 
     660     4549499 :   static void decrement(ordered_index_node*& x)
     661             :   {
     662     4549499 :     impl_pointer xi=x->impl();
     663     4549499 :     trampoline::decrement(xi);
     664     4549499 :     x=from_impl(xi);
     665     4549499 :   }
     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