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
							 |