659 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			659 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| /* Copyright 2003-2015 Joaquin M Lopez Munoz.
 | |
|  * Distributed under the Boost Software License, Version 1.0.
 | |
|  * (See accompanying file LICENSE_1_0.txt or copy at
 | |
|  * http://www.boost.org/LICENSE_1_0.txt)
 | |
|  *
 | |
|  * See http://www.boost.org/libs/multi_index for library home page.
 | |
|  *
 | |
|  * The internal implementation of red-black trees is based on that of SGI STL
 | |
|  * stl_tree.h file: 
 | |
|  *
 | |
|  * Copyright (c) 1996,1997
 | |
|  * Silicon Graphics Computer Systems, Inc.
 | |
|  *
 | |
|  * Permission to use, copy, modify, distribute and sell this software
 | |
|  * and its documentation for any purpose is hereby granted without fee,
 | |
|  * provided that the above copyright notice appear in all copies and
 | |
|  * that both that copyright notice and this permission notice appear
 | |
|  * in supporting documentation.  Silicon Graphics makes no
 | |
|  * representations about the suitability of this software for any
 | |
|  * purpose.  It is provided "as is" without express or implied warranty.
 | |
|  *
 | |
|  *
 | |
|  * Copyright (c) 1994
 | |
|  * Hewlett-Packard Company
 | |
|  *
 | |
|  * Permission to use, copy, modify, distribute and sell this software
 | |
|  * and its documentation for any purpose is hereby granted without fee,
 | |
|  * provided that the above copyright notice appear in all copies and
 | |
|  * that both that copyright notice and this permission notice appear
 | |
|  * in supporting documentation.  Hewlett-Packard Company makes no
 | |
|  * representations about the suitability of this software for any
 | |
|  * purpose.  It is provided "as is" without express or implied warranty.
 | |
|  *
 | |
|  */
 | |
| 
 | |
| #ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_NODE_HPP
 | |
| #define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_NODE_HPP
 | |
| 
 | |
| #if defined(_MSC_VER)
 | |
| #pragma once
 | |
| #endif
 | |
| 
 | |
| #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
 | |
| #include <cstddef>
 | |
| #include <boost/detail/allocator_utilities.hpp>
 | |
| #include <boost/multi_index/detail/raw_ptr.hpp>
 | |
| 
 | |
| #if !defined(BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES)
 | |
| #include <boost/mpl/and.hpp>
 | |
| #include <boost/mpl/if.hpp>
 | |
| #include <boost/multi_index/detail/uintptr_type.hpp>
 | |
| #include <boost/type_traits/alignment_of.hpp>
 | |
| #include <boost/type_traits/is_same.hpp>
 | |
| #endif
 | |
| 
 | |
| namespace boost{
 | |
| 
 | |
| namespace multi_index{
 | |
| 
 | |
| namespace detail{
 | |
| 
 | |
| /* definition of red-black nodes for ordered_index */
 | |
| 
 | |
| enum ordered_index_color{red=false,black=true};
 | |
| enum ordered_index_side{to_left=false,to_right=true};
 | |
| 
 | |
| template<typename AugmentPolicy,typename Allocator>
 | |
| struct ordered_index_node_impl; /* fwd decl. */
 | |
| 
 | |
| template<typename AugmentPolicy,typename Allocator>
 | |
| struct ordered_index_node_std_base
 | |
| {
 | |
|   typedef typename
 | |
|   boost::detail::allocator::rebind_to<
 | |
|     Allocator,
 | |
|     ordered_index_node_impl<AugmentPolicy,Allocator>
 | |
|   >::type::pointer                                   pointer;
 | |
|   typedef typename
 | |
|   boost::detail::allocator::rebind_to<
 | |
|     Allocator,
 | |
|     ordered_index_node_impl<AugmentPolicy,Allocator>
 | |
|   >::type::const_pointer                             const_pointer;
 | |
|   typedef ordered_index_color&                       color_ref;
 | |
|   typedef pointer&                                   parent_ref;
 | |
| 
 | |
|   ordered_index_color& color(){return color_;}
 | |
|   ordered_index_color  color()const{return color_;}
 | |
|   pointer&             parent(){return parent_;}
 | |
|   pointer              parent()const{return parent_;}
 | |
|   pointer&             left(){return left_;}
 | |
|   pointer              left()const{return left_;}
 | |
|   pointer&             right(){return right_;}
 | |
|   pointer              right()const{return right_;}
 | |
| 
 | |
| private:
 | |
|   ordered_index_color color_; 
 | |
|   pointer             parent_;
 | |
|   pointer             left_;
 | |
|   pointer             right_;
 | |
| };
 | |
| 
 | |
| #if !defined(BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES)
 | |
| /* If ordered_index_node_impl has even alignment, we can use the least
 | |
|  * significant bit of one of the ordered_index_node_impl pointers to
 | |
|  * store color information. This typically reduces the size of
 | |
|  * ordered_index_node_impl by 25%.
 | |
|  */
 | |
| 
 | |
| #if defined(BOOST_MSVC)
 | |
| /* This code casts pointers to an integer type that has been computed
 | |
|  * to be large enough to hold the pointer, however the metaprogramming
 | |
|  * logic is not always spotted by the VC++ code analyser that issues a
 | |
|  * long list of warnings.
 | |
|  */
 | |
| 
 | |
| #pragma warning(push)
 | |
| #pragma warning(disable:4312 4311)
 | |
| #endif
 | |
| 
 | |
| template<typename AugmentPolicy,typename Allocator>
 | |
| struct ordered_index_node_compressed_base
 | |
| {
 | |
|   typedef ordered_index_node_impl<
 | |
|     AugmentPolicy,Allocator>*            pointer;
 | |
|   typedef const ordered_index_node_impl<
 | |
|     AugmentPolicy,Allocator>*            const_pointer;
 | |
| 
 | |
|   struct color_ref
 | |
|   {
 | |
|     color_ref(uintptr_type* r_):r(r_){}
 | |
|     
 | |
|     operator ordered_index_color()const
 | |
|     {
 | |
|       return ordered_index_color(*r&uintptr_type(1));
 | |
|     }
 | |
|     
 | |
|     color_ref& operator=(ordered_index_color c)
 | |
|     {
 | |
|       *r&=~uintptr_type(1);
 | |
|       *r|=uintptr_type(c);
 | |
|       return *this;
 | |
|     }
 | |
|     
 | |
|     color_ref& operator=(const color_ref& x)
 | |
|     {
 | |
|       return operator=(x.operator ordered_index_color());
 | |
|     }
 | |
|     
 | |
|   private:
 | |
|     uintptr_type* r;
 | |
|   };
 | |
|   
 | |
|   struct parent_ref
 | |
|   {
 | |
|     parent_ref(uintptr_type* r_):r(r_){}
 | |
|     
 | |
|     operator pointer()const
 | |
|     {
 | |
|       return (pointer)(void*)(*r&~uintptr_type(1));
 | |
|     }
 | |
|     
 | |
|     parent_ref& operator=(pointer p)
 | |
|     {
 | |
|       *r=((uintptr_type)(void*)p)|(*r&uintptr_type(1));
 | |
|       return *this;
 | |
|     }
 | |
|     
 | |
|     parent_ref& operator=(const parent_ref& x)
 | |
|     {
 | |
|       return operator=(x.operator pointer());
 | |
|     }
 | |
| 
 | |
|     pointer operator->()const
 | |
|     {
 | |
|       return operator pointer();
 | |
|     }
 | |
| 
 | |
|   private:
 | |
|     uintptr_type* r;
 | |
|   };
 | |
|   
 | |
|   color_ref           color(){return color_ref(&parentcolor_);}
 | |
|   ordered_index_color color()const
 | |
|   {
 | |
|     return ordered_index_color(parentcolor_&uintptr_type(1));
 | |
|   }
 | |
| 
 | |
|   parent_ref parent(){return parent_ref(&parentcolor_);}
 | |
|   pointer    parent()const
 | |
|   {
 | |
|     return (pointer)(void*)(parentcolor_&~uintptr_type(1));
 | |
|   }
 | |
| 
 | |
|   pointer& left(){return left_;}
 | |
|   pointer  left()const{return left_;}
 | |
|   pointer& right(){return right_;}
 | |
|   pointer  right()const{return right_;}
 | |
| 
 | |
| private:
 | |
|   uintptr_type parentcolor_;
 | |
|   pointer      left_;
 | |
|   pointer      right_;
 | |
| };
 | |
| #if defined(BOOST_MSVC)
 | |
| #pragma warning(pop)
 | |
| #endif
 | |
| #endif
 | |
| 
 | |
| template<typename AugmentPolicy,typename Allocator>
 | |
| struct ordered_index_node_impl_base:
 | |
| 
 | |
| #if !defined(BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES)
 | |
|   AugmentPolicy::template augmented_node<
 | |
|     typename mpl::if_c<
 | |
|       !(has_uintptr_type::value)||
 | |
|       (alignment_of<
 | |
|         ordered_index_node_compressed_base<AugmentPolicy,Allocator>
 | |
|        >::value%2)||
 | |
|       !(is_same<
 | |
|         typename boost::detail::allocator::rebind_to<
 | |
|           Allocator,
 | |
|           ordered_index_node_impl<AugmentPolicy,Allocator>
 | |
|         >::type::pointer,
 | |
|         ordered_index_node_impl<AugmentPolicy,Allocator>*>::value),
 | |
|       ordered_index_node_std_base<AugmentPolicy,Allocator>,
 | |
|       ordered_index_node_compressed_base<AugmentPolicy,Allocator>
 | |
|     >::type
 | |
|   >::type
 | |
| #else
 | |
|   AugmentPolicy::template augmented_node<
 | |
|     ordered_index_node_std_base<AugmentPolicy,Allocator>
 | |
|   >::type
 | |
| #endif
 | |
| 
 | |
| {};
 | |
| 
 | |
| template<typename AugmentPolicy,typename Allocator>
 | |
| struct ordered_index_node_impl:
 | |
|   ordered_index_node_impl_base<AugmentPolicy,Allocator>
 | |
| {
 | |
| private:
 | |
|   typedef ordered_index_node_impl_base<AugmentPolicy,Allocator> super;
 | |
| 
 | |
| public:
 | |
|   typedef typename super::color_ref                             color_ref;
 | |
|   typedef typename super::parent_ref                            parent_ref;
 | |
|   typedef typename super::pointer                               pointer;
 | |
|   typedef typename super::const_pointer                         const_pointer;
 | |
| 
 | |
|   /* interoperability with bidir_node_iterator */
 | |
| 
 | |
|   static void increment(pointer& x)
 | |
|   {
 | |
|     if(x->right()!=pointer(0)){
 | |
|       x=x->right();
 | |
|       while(x->left()!=pointer(0))x=x->left();
 | |
|     }
 | |
|     else{
 | |
|       pointer y=x->parent();
 | |
|       while(x==y->right()){
 | |
|         x=y;
 | |
|         y=y->parent();
 | |
|       }
 | |
|       if(x->right()!=y)x=y;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   static void decrement(pointer& x)
 | |
|   {
 | |
|     if(x->color()==red&&x->parent()->parent()==x){
 | |
|       x=x->right();
 | |
|     }
 | |
|     else if(x->left()!=pointer(0)){
 | |
|       pointer y=x->left();
 | |
|       while(y->right()!=pointer(0))y=y->right();
 | |
|       x=y;
 | |
|     }else{
 | |
|       pointer y=x->parent();
 | |
|       while(x==y->left()){
 | |
|         x=y;
 | |
|         y=y->parent();
 | |
|       }
 | |
|       x=y;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* algorithmic stuff */
 | |
| 
 | |
|   static void rotate_left(pointer x,parent_ref root)
 | |
|   {
 | |
|     pointer y=x->right();
 | |
|     x->right()=y->left();
 | |
|     if(y->left()!=pointer(0))y->left()->parent()=x;
 | |
|     y->parent()=x->parent();
 | |
|     
 | |
|     if(x==root)                    root=y;
 | |
|     else if(x==x->parent()->left())x->parent()->left()=y;
 | |
|     else                           x->parent()->right()=y;
 | |
|     y->left()=x;
 | |
|     x->parent()=y;
 | |
|     AugmentPolicy::rotate_left(x,y);
 | |
|   }
 | |
| 
 | |
|   static pointer minimum(pointer x)
 | |
|   {
 | |
|     while(x->left()!=pointer(0))x=x->left();
 | |
|     return x;
 | |
|   }
 | |
| 
 | |
|   static pointer maximum(pointer x)
 | |
|   {
 | |
|     while(x->right()!=pointer(0))x=x->right();
 | |
|     return x;
 | |
|   }
 | |
| 
 | |
|   static void rotate_right(pointer x,parent_ref root)
 | |
|   {
 | |
|     pointer y=x->left();
 | |
|     x->left()=y->right();
 | |
|     if(y->right()!=pointer(0))y->right()->parent()=x;
 | |
|     y->parent()=x->parent();
 | |
| 
 | |
|     if(x==root)                     root=y;
 | |
|     else if(x==x->parent()->right())x->parent()->right()=y;
 | |
|     else                            x->parent()->left()=y;
 | |
|     y->right()=x;
 | |
|     x->parent()=y;
 | |
|     AugmentPolicy::rotate_right(x,y);
 | |
|   }
 | |
| 
 | |
|   static void rebalance(pointer x,parent_ref root)
 | |
|   {
 | |
|     x->color()=red;
 | |
|     while(x!=root&&x->parent()->color()==red){
 | |
|       if(x->parent()==x->parent()->parent()->left()){
 | |
|         pointer y=x->parent()->parent()->right();
 | |
|         if(y!=pointer(0)&&y->color()==red){
 | |
|           x->parent()->color()=black;
 | |
|           y->color()=black;
 | |
|           x->parent()->parent()->color()=red;
 | |
|           x=x->parent()->parent();
 | |
|         }
 | |
|         else{
 | |
|           if(x==x->parent()->right()){
 | |
|             x=x->parent();
 | |
|             rotate_left(x,root);
 | |
|           }
 | |
|           x->parent()->color()=black;
 | |
|           x->parent()->parent()->color()=red;
 | |
|           rotate_right(x->parent()->parent(),root);
 | |
|         }
 | |
|       }
 | |
|       else{
 | |
|         pointer y=x->parent()->parent()->left();
 | |
|         if(y!=pointer(0)&&y->color()==red){
 | |
|           x->parent()->color()=black;
 | |
|           y->color()=black;
 | |
|           x->parent()->parent()->color()=red;
 | |
|           x=x->parent()->parent();
 | |
|         }
 | |
|         else{
 | |
|           if(x==x->parent()->left()){
 | |
|             x=x->parent();
 | |
|             rotate_right(x,root);
 | |
|           }
 | |
|           x->parent()->color()=black;
 | |
|           x->parent()->parent()->color()=red;
 | |
|           rotate_left(x->parent()->parent(),root);
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     root->color()=black;
 | |
|   }
 | |
| 
 | |
|   static void link(
 | |
|     pointer x,ordered_index_side side,pointer position,pointer header)
 | |
|   {
 | |
|     if(side==to_left){
 | |
|       position->left()=x;  /* also makes leftmost=x when parent==header */
 | |
|       if(position==header){
 | |
|         header->parent()=x;
 | |
|         header->right()=x;
 | |
|       }
 | |
|       else if(position==header->left()){
 | |
|         header->left()=x;  /* maintain leftmost pointing to min node */
 | |
|       }
 | |
|     }
 | |
|     else{
 | |
|       position->right()=x;
 | |
|       if(position==header->right()){
 | |
|         header->right()=x; /* maintain rightmost pointing to max node */
 | |
|       }
 | |
|     }
 | |
|     x->parent()=position;
 | |
|     x->left()=pointer(0);
 | |
|     x->right()=pointer(0);
 | |
|     AugmentPolicy::add(x,pointer(header->parent()));
 | |
|     ordered_index_node_impl::rebalance(x,header->parent());
 | |
|   }
 | |
| 
 | |
|   static pointer rebalance_for_erase(
 | |
|     pointer z,parent_ref root,pointer& leftmost,pointer& rightmost)
 | |
|   {
 | |
|     pointer y=z;
 | |
|     pointer x=pointer(0);
 | |
|     pointer x_parent=pointer(0);
 | |
|     if(y->left()==pointer(0)){    /* z has at most one non-null child. y==z. */
 | |
|       x=y->right();               /* x might be null */
 | |
|     }
 | |
|     else{
 | |
|       if(y->right()==pointer(0)){ /* z has exactly one non-null child. y==z. */
 | |
|         x=y->left();              /* x is not null */
 | |
|       }
 | |
|       else{                       /* z has two non-null children.  Set y to */
 | |
|         y=y->right();             /* z's successor. x might be null.        */
 | |
|         while(y->left()!=pointer(0))y=y->left();
 | |
|         x=y->right();
 | |
|       }
 | |
|     }
 | |
|     AugmentPolicy::remove(y,pointer(root));
 | |
|     if(y!=z){
 | |
|       AugmentPolicy::copy(z,y);
 | |
|       z->left()->parent()=y;   /* relink y in place of z. y is z's successor */
 | |
|       y->left()=z->left();
 | |
|       if(y!=z->right()){
 | |
|         x_parent=y->parent();
 | |
|         if(x!=pointer(0))x->parent()=y->parent();
 | |
|         y->parent()->left()=x; /* y must be a child of left */
 | |
|         y->right()=z->right();
 | |
|         z->right()->parent()=y;
 | |
|       }
 | |
|       else{
 | |
|         x_parent=y;
 | |
|       }
 | |
| 
 | |
|       if(root==z)                    root=y;
 | |
|       else if(z->parent()->left()==z)z->parent()->left()=y;
 | |
|       else                           z->parent()->right()=y;
 | |
|       y->parent()=z->parent();
 | |
|       ordered_index_color c=y->color();
 | |
|       y->color()=z->color();
 | |
|       z->color()=c;
 | |
|       y=z;                    /* y now points to node to be actually deleted */
 | |
|     }
 | |
|     else{                     /* y==z */
 | |
|       x_parent=y->parent();
 | |
|       if(x!=pointer(0))x->parent()=y->parent();   
 | |
|       if(root==z){
 | |
|         root=x;
 | |
|       }
 | |
|       else{
 | |
|         if(z->parent()->left()==z)z->parent()->left()=x;
 | |
|         else                      z->parent()->right()=x;
 | |
|       }
 | |
|       if(leftmost==z){
 | |
|         if(z->right()==pointer(0)){ /* z->left() must be null also */
 | |
|           leftmost=z->parent();
 | |
|         }
 | |
|         else{              
 | |
|           leftmost=minimum(x);      /* makes leftmost==header if z==root */
 | |
|         }
 | |
|       }
 | |
|       if(rightmost==z){
 | |
|         if(z->left()==pointer(0)){  /* z->right() must be null also */
 | |
|           rightmost=z->parent();
 | |
|         }
 | |
|         else{                   /* x==z->left() */
 | |
|           rightmost=maximum(x); /* makes rightmost==header if z==root */
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     if(y->color()!=red){
 | |
|       while(x!=root&&(x==pointer(0)|| x->color()==black)){
 | |
|         if(x==x_parent->left()){
 | |
|           pointer w=x_parent->right();
 | |
|           if(w->color()==red){
 | |
|             w->color()=black;
 | |
|             x_parent->color()=red;
 | |
|             rotate_left(x_parent,root);
 | |
|             w=x_parent->right();
 | |
|           }
 | |
|           if((w->left()==pointer(0)||w->left()->color()==black) &&
 | |
|              (w->right()==pointer(0)||w->right()->color()==black)){
 | |
|             w->color()=red;
 | |
|             x=x_parent;
 | |
|             x_parent=x_parent->parent();
 | |
|           } 
 | |
|           else{
 | |
|             if(w->right()==pointer(0 )
 | |
|                 || w->right()->color()==black){
 | |
|               if(w->left()!=pointer(0)) w->left()->color()=black;
 | |
|               w->color()=red;
 | |
|               rotate_right(w,root);
 | |
|               w=x_parent->right();
 | |
|             }
 | |
|             w->color()=x_parent->color();
 | |
|             x_parent->color()=black;
 | |
|             if(w->right()!=pointer(0))w->right()->color()=black;
 | |
|             rotate_left(x_parent,root);
 | |
|             break;
 | |
|           }
 | |
|         } 
 | |
|         else{                   /* same as above,with right <-> left */
 | |
|           pointer w=x_parent->left();
 | |
|           if(w->color()==red){
 | |
|             w->color()=black;
 | |
|             x_parent->color()=red;
 | |
|             rotate_right(x_parent,root);
 | |
|             w=x_parent->left();
 | |
|           }
 | |
|           if((w->right()==pointer(0)||w->right()->color()==black) &&
 | |
|              (w->left()==pointer(0)||w->left()->color()==black)){
 | |
|             w->color()=red;
 | |
|             x=x_parent;
 | |
|             x_parent=x_parent->parent();
 | |
|           }
 | |
|           else{
 | |
|             if(w->left()==pointer(0)||w->left()->color()==black){
 | |
|               if(w->right()!=pointer(0))w->right()->color()=black;
 | |
|               w->color()=red;
 | |
|               rotate_left(w,root);
 | |
|               w=x_parent->left();
 | |
|             }
 | |
|             w->color()=x_parent->color();
 | |
|             x_parent->color()=black;
 | |
|             if(w->left()!=pointer(0))w->left()->color()=black;
 | |
|             rotate_right(x_parent,root);
 | |
|             break;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|       if(x!=pointer(0))x->color()=black;
 | |
|     }
 | |
|     return y;
 | |
|   }
 | |
| 
 | |
|   static void restore(pointer x,pointer position,pointer header)
 | |
|   {
 | |
|     if(position->left()==pointer(0)||position->left()==header){
 | |
|       link(x,to_left,position,header);
 | |
|     }
 | |
|     else{
 | |
|       decrement(position);
 | |
|       link(x,to_right,position,header);
 | |
|     }
 | |
|   }
 | |
| 
 | |
| #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
 | |
|   /* invariant stuff */
 | |
| 
 | |
|   static std::size_t black_count(pointer node,pointer root)
 | |
|   {
 | |
|     if(node==pointer(0))return 0;
 | |
|     std::size_t sum=0;
 | |
|     for(;;){
 | |
|       if(node->color()==black)++sum;
 | |
|       if(node==root)break;
 | |
|       node=node->parent();
 | |
|     } 
 | |
|     return sum;
 | |
|   }
 | |
| #endif
 | |
| };
 | |
| 
 | |
| template<typename AugmentPolicy,typename Super>
 | |
| struct ordered_index_node_trampoline:
 | |
|   ordered_index_node_impl<
 | |
|     AugmentPolicy,
 | |
|     typename boost::detail::allocator::rebind_to<
 | |
|       typename Super::allocator_type,
 | |
|       char
 | |
|     >::type
 | |
|   >
 | |
| {
 | |
|   typedef ordered_index_node_impl<
 | |
|     AugmentPolicy,
 | |
|     typename boost::detail::allocator::rebind_to<
 | |
|       typename Super::allocator_type,
 | |
|       char
 | |
|     >::type
 | |
|   > impl_type;
 | |
| };
 | |
| 
 | |
| template<typename AugmentPolicy,typename Super>
 | |
| struct ordered_index_node:
 | |
|   Super,ordered_index_node_trampoline<AugmentPolicy,Super>
 | |
| {
 | |
| private:
 | |
|   typedef ordered_index_node_trampoline<AugmentPolicy,Super> trampoline;
 | |
| 
 | |
| public:
 | |
|   typedef typename trampoline::impl_type     impl_type;
 | |
|   typedef typename trampoline::color_ref     impl_color_ref;
 | |
|   typedef typename trampoline::parent_ref    impl_parent_ref;
 | |
|   typedef typename trampoline::pointer       impl_pointer;
 | |
|   typedef typename trampoline::const_pointer const_impl_pointer;
 | |
| 
 | |
|   impl_color_ref      color(){return trampoline::color();}
 | |
|   ordered_index_color color()const{return trampoline::color();}
 | |
|   impl_parent_ref     parent(){return trampoline::parent();}
 | |
|   impl_pointer        parent()const{return trampoline::parent();}
 | |
|   impl_pointer&       left(){return trampoline::left();}
 | |
|   impl_pointer        left()const{return trampoline::left();}
 | |
|   impl_pointer&       right(){return trampoline::right();}
 | |
|   impl_pointer        right()const{return trampoline::right();}
 | |
| 
 | |
|   impl_pointer impl()
 | |
|   {
 | |
|     return static_cast<impl_pointer>(
 | |
|       static_cast<impl_type*>(static_cast<trampoline*>(this)));
 | |
|   }
 | |
| 
 | |
|   const_impl_pointer impl()const
 | |
|   {
 | |
|     return static_cast<const_impl_pointer>(
 | |
|       static_cast<const impl_type*>(static_cast<const trampoline*>(this)));
 | |
|   }
 | |
| 
 | |
|   static ordered_index_node* from_impl(impl_pointer x)
 | |
|   {
 | |
|     return
 | |
|       static_cast<ordered_index_node*>(
 | |
|         static_cast<trampoline*>(
 | |
|           raw_ptr<impl_type*>(x)));
 | |
|   }
 | |
| 
 | |
|   static const ordered_index_node* from_impl(const_impl_pointer x)
 | |
|   {
 | |
|     return
 | |
|       static_cast<const ordered_index_node*>(
 | |
|         static_cast<const trampoline*>(
 | |
|           raw_ptr<const impl_type*>(x)));
 | |
|   }
 | |
| 
 | |
|   /* interoperability with bidir_node_iterator */
 | |
| 
 | |
|   static void increment(ordered_index_node*& x)
 | |
|   {
 | |
|     impl_pointer xi=x->impl();
 | |
|     trampoline::increment(xi);
 | |
|     x=from_impl(xi);
 | |
|   }
 | |
| 
 | |
|   static void decrement(ordered_index_node*& x)
 | |
|   {
 | |
|     impl_pointer xi=x->impl();
 | |
|     trampoline::decrement(xi);
 | |
|     x=from_impl(xi);
 | |
|   }
 | |
| };
 | |
| 
 | |
| } /* namespace multi_index::detail */
 | |
| 
 | |
| } /* namespace multi_index */
 | |
| 
 | |
| } /* namespace boost */
 | |
| 
 | |
| #endif
 | 
